From ac7a811fc7d8929f99b35915197ed0ea4f13e870 Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Tue, 19 Jun 2007 21:59:35 +0000 Subject: update --- muse/synti/organ/CMakeLists.txt | 2 + muse/synti/organ/organ.cpp | 97 ++++++-- muse/synti/organ/organ.h | 21 +- muse/synti/organ/organgui.ui | 531 +++++++++++++++++++++++++++------------- 4 files changed, 443 insertions(+), 208 deletions(-) diff --git a/muse/synti/organ/CMakeLists.txt b/muse/synti/organ/CMakeLists.txt index 2dd6aa3f..5eba6b94 100644 --- a/muse/synti/organ/CMakeLists.txt +++ b/muse/synti/organ/CMakeLists.txt @@ -24,6 +24,8 @@ QT4_WRAP_UI ( organ_uis organgui.ui ) add_library ( organ SHARED organ.cpp organgui.cpp + reverb.cpp + vibrato.cpp organgui.h ${organ_mocs} ${organ_uis} diff --git a/muse/synti/organ/organ.cpp b/muse/synti/organ/organ.cpp index f8f6057c..a140c1d7 100644 --- a/muse/synti/organ/organ.cpp +++ b/muse/synti/organ/organ.cpp @@ -5,9 +5,11 @@ // // Parts of this file taken from: // Organ - Additive Organ Synthesizer Voice -// Copyright (c) 1999, 2000 David A. Bartold +// Copyright (C) 1999, 2000 David A. Bartold +// Some information was gathered form the "beatrix" organ +// from Fredrik Kilander // -// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2001-2007 Werner Schweer (ws@seh.de) //========================================================= #include "muse/midi.h" @@ -15,16 +17,15 @@ #include "organ.h" #include "organgui.h" +#include "reverb.h" -int Organ::resolution; -int Organ::resolution256; float* Organ::attackEnv; float* Organ::releaseEnv; -int Organ::envSize; +int Organ::envSize; float* Organ::waveTable; -int Organ::useCount = 0; +int Organ::useCount; double Organ::cb2amp_tab[MAX_ATTENUATION]; -unsigned Organ::freq256[128][NO_BUSES]; + Elem Organ::routing[NO_KEYS][NO_ELEMENTS] = { #if 1 { Elem(0,0,0.003210), Elem(0,1,0.000105), Elem(0,2,0.004516), Elem(0,3,0.000095), Elem(0,4,0.000080), Elem(0,5,0.000088), Elem(0,6,0.000116), Elem(0,7,0.000213), @@ -1371,34 +1372,33 @@ double Organ::cb2amp(int cb) return cb2amp_tab[cb]; } -static const int SHIFT = 10; -static const int RESO = 1024; +static const unsigned SHIFT = 16; +static const double RESO = 256.0 * 256.0 * 256.0 * 256.0; +static const unsigned resolution = 256 * 256; // 16 Bit //--------------------------------------------------------- // Organ //--------------------------------------------------------- Organ::Organ(int sr) - : Mess2(1) + : Mess2(2) { setSampleRate(sr); gui = 0; + reverb = new Reverb(); ++useCount; if (useCount > 1) return; - resolution = sr / 1000; - resolution256 = resolution << SHIFT; - // centibels to amplitude conversion for (int i = 0; i < MAX_ATTENUATION; i++) cb2amp_tab[i] = pow(10.0, double(i) / -200.0); // Initialize sine table. waveTable = new float[resolution]; - for (int i = 0; i < resolution; i++) - waveTable[i] = sin (i * 2.0 * M_PI / double(resolution)); + for (unsigned i = 0; i < resolution; i++) + waveTable[i] = sin (double(i) * 2.0 * M_PI / double(resolution)); // Initialize envelope tables @@ -1420,7 +1420,13 @@ Organ::Organ(int sr) addController("drawbar135", DRAWBAR6, 0, 8, 0); addController("drawbar113", DRAWBAR7, 0, 8, 0); addController("drawbar1", DRAWBAR8, 0, 8, 0); - addController("volume", CTRL_VOLUME, 0, 127, 100); + addController("reverbRoomSize", REVERB_ROOM_SIZE, 0, 127, 60); + addController("reverbMix", REVERB_MIX, 0, 127, 100); + addController("vibratoOn", VIBRATO_ON, 0, 1, 1); + addController("vibratoFreq", VIBRATO_FREQ, 0, 127, 100); + addController("vibratoDepth", VIBRATO_DEPTH, 0, 127, 50); + + addController("volume", CTRL_VOLUME, 0, 127, 100); } //--------------------------------------------------------- @@ -1431,6 +1437,8 @@ Organ::~Organ() { if (gui) delete gui; + delete reverb; + --useCount; if (useCount == 0) { delete[] waveTable; @@ -1461,18 +1469,22 @@ bool Organ::init(const char* name) static const int gearB[12] = { 104,82,73,36,67,11,32,40,37, 8,46,35 }; static const int teeth[] = { 2, 4, 8, 16, 32, 64, 128, 192 }; - srand(22); + vibratoFreq = 7.25; + vibratoDepth = 0.005; + vibratoStep = lrint(vibratoFreq * RESO / double(sampleRate())); + vibratoAccu = 0; + for (int i = 0; i < NO_WHEELS; ++i) { int note = i % 12; int octave = i / 12; if (octave == 7) note += 5; // in 60Hz organs, the motor turns at 1200 RPM (20 revolutions /sec) - double freq = 20.0 * teeth[octave] * gearA[note] / gearB[note]; - wheels[i].freq256 = lrint(freq * double(resolution256) / double(sampleRate())); - wheels[i].accu = rand() % resolution256; - wheels[i].refCount = 0; - wheels[i].active = false; + double freq = 20.0 * teeth[octave] * gearA[note] / gearB[note]; + wheels[i].frameStep = lrint(freq * RESO / double(sampleRate())); + wheels[i].accu = 0; + wheels[i].refCount = 0; + wheels[i].active = false; for (int k = 0; k < NO_BUSES; ++k) wheels[i].envCount[k] = 0; } @@ -1503,12 +1515,27 @@ void Organ::process(float** ports, int offset, int sampleCount) printf("Organ::process(): unknown event\n"); } - float* buffer = *ports + offset; + float* buffer = ports[0] + offset; memset(buffer, 0, sizeof(float) * sampleCount); + + float vibrato[sampleCount]; + if (vibratoOn) { + // + // compute partial vibrato sinus + // + for (int i = 0; i < sampleCount; ++i) { + vibratoAccu += vibratoStep; + vibrato[i] = waveTable[vibratoAccu >> SHIFT] * vibratoDepth; + } + } + foreach(Wheel* w, activeWheels) { for (int i = 0; i < sampleCount; ++i) { - w->accu = (w->accu + w->freq256) % resolution256; + unsigned step = w->frameStep; + if (vibratoOn) + step += lrint(step * vibrato[i]); + w->accu += step; float val = waveTable[w->accu >> SHIFT]; for (int k = 0; k < NO_BUSES; ++k) { @@ -1533,6 +1560,7 @@ void Organ::process(float** ports, int offset, int sampleCount) } for (int i = 0; i < sampleCount; ++i) buffer[i] *= volume; +// reverb->process(buffer, ports[1], sampleCount); } //--------------------------------------------------------- @@ -1637,6 +1665,27 @@ void Organ::setController(int ctrlId, int data) drawBarGain[db] = float(data) / 8.0; } break; + case REVERB_ROOM_SIZE: + reverb->setRoomSize(float(data) / 127.0); + break; + + case REVERB_MIX: + reverb->setMix(float(data) / 127.0); + break; + + case VIBRATO_ON: + vibratoOn = data != 0; + break; + + case VIBRATO_FREQ: + vibratoFreq = float(data) * 6.0 / 127.0 + 4; + vibratoStep = lrint(vibratoFreq * RESO / double(sampleRate())); + break; + + case VIBRATO_DEPTH: + vibratoDepth = float(data) / 127.0 * .01; + break; + case CTRL_VOLUME: data &= 0x7f; volume = data == 0 ? 0.0 : cb2amp(int(200 * log10((127.0 * 127)/(data*data)))); diff --git a/muse/synti/organ/organ.h b/muse/synti/organ/organ.h index 92f63114..5d90e824 100644 --- a/muse/synti/organ/organ.h +++ b/muse/synti/organ/organ.h @@ -7,7 +7,7 @@ // Organ - Additive Organ Synthesizer Voice // Copyright (c) 1999, 2000 David A. Bartold // -// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2001-2007 Werner Schweer (ws@seh.de) //========================================================= #ifndef __ORGAN_H__ @@ -19,6 +19,7 @@ static const int NO_VOICES = 128; // max polyphony static const int NO_KEYS = 97 - 36; class OrganGui; +class Reverb; static const int MAX_ATTENUATION = 960; static const int NO_BUSES = 9; @@ -28,9 +29,8 @@ static const int NO_ELEMENTS = 194; enum { DRAWBAR0 = CTRL_RPN14_OFFSET, DRAWBAR1, DRAWBAR2, DRAWBAR3, DRAWBAR4, DRAWBAR5, DRAWBAR6, DRAWBAR7, DRAWBAR8, - ATTACK_LO, DECAY_LO, SUSTAIN_LO, RELEASE_LO, - ATTACK_HI, DECAY_HI, SUSTAIN_HI, RELEASE_HI, - BRASS, FLUTE, REED, VELO + REVERB_ROOM_SIZE, REVERB_MIX, + VIBRATO_ON, VIBRATO_FREQ, VIBRATO_DEPTH }; //--------------------------------------------------------- @@ -38,7 +38,7 @@ enum { //--------------------------------------------------------- struct Wheel { - unsigned freq256; + unsigned frameStep; unsigned accu; int refCount; @@ -78,17 +78,22 @@ class Organ : public Mess2 { static float* waveTable; static double cb2amp_tab[MAX_ATTENUATION]; - static unsigned freq256[128][NO_BUSES]; static double cb2amp(int cb); static Elem routing[NO_KEYS][NO_ELEMENTS]; static float* attackEnv; static float* releaseEnv; static int envSize; - static int resolution; - static int resolution256; + Reverb* reverb; double volume; + unsigned vibratoStep; + unsigned vibratoAccu; + + bool vibratoOn; + double vibratoFreq; + double vibratoDepth; + float drawBarGain[NO_BUSES]; Wheel wheels[NO_WHEELS]; Voice voices[NO_VOICES]; diff --git a/muse/synti/organ/organgui.ui b/muse/synti/organ/organgui.ui index 74e52f07..4b5de0c6 100644 --- a/muse/synti/organ/organgui.ui +++ b/muse/synti/organ/organgui.ui @@ -5,8 +5,8 @@ 0 0 - 270 - 275 + 424 + 335 @@ -54,186 +54,365 @@ background-color: gray; } - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - - -1 - 75 - true - - - - O-1 - - - Qt::AlignCenter - - + + + + + + + + 0 + 0 + + + + + -1 + 75 + true + + + + O-1 + + + Qt::AlignCenter + + + + + + + Reverb + + + + + + + 0 + 0 + + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + + + + + + 0 + 0 + + + + Room + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Mix + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + + + + + + + + Vibrato + + + true + + + + + + + 0 + 0 + + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + + + + + + 0 + 0 + + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + + + + + + 0 + 0 + + + + Freq + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Depth + + + Qt::AlignCenter + + + + + + + - - - - - 0 - 0 - - - - Drawbars - - - - - - 4.319999999999999 - - - - 60 - 60 - 60 - - - - - - - - 5.039999999999999 - - - - 60 - 60 - 60 - - - - - - - - 8.000000000000000 - - - - 240 - 240 - 240 - - - - - - - - 8.000000000000000 - - - - 240 - 240 - 240 - - - - - - - - 8.000000000000000 - - - - - - - 0.000000000000000 - - - - 240 - 240 - 240 - - - - - - - - 0.000000000000000 - - - - 128 - 102 - 86 - - - - - - - - 2.160000000000000 - - - - 128 - 102 - 86 - - - - - - - - 0.000000000000000 - - - - 240 - 240 - 240 - - - - - - + + + + + + + 0 + 0 + + + + Drawbars + + + + + + 4.319999999999999 + + + + 60 + 60 + 60 + + + + + + + + 5.039999999999999 + + + + 60 + 60 + 60 + + + + + + + + + 0 + 150 + + + + 8.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 8.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 8.000000000000000 + + + + + + + 0.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 4.800000000000000 + + + + 128 + 102 + 86 + + + + + + + + 2.160000000000000 + + + + 128 + 102 + 86 + + + + + + + + 0.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Awl::Knob + QWidget +
awl/knob.h
+
Awl::Drawbar Awl::Slider -- cgit v1.2.3