From 280335523c6d3e60384f54c42d07a5c4ed5898a0 Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Fri, 22 Jun 2007 14:30:01 +0000 Subject: updates --- muse/synti/organ/organ.cpp | 139 ++++++++++++++++++++++++----- muse/synti/organ/organ.h | 23 ++++- muse/synti/organ/organgui.ui | 203 ++++++++++++++++++++++++++++++++++++++++++- muse/synti/organ/reverb.cpp | 4 +- 4 files changed, 340 insertions(+), 29 deletions(-) diff --git a/muse/synti/organ/organ.cpp b/muse/synti/organ/organ.cpp index 50477cc7..3bb5f4cf 100644 --- a/muse/synti/organ/organ.cpp +++ b/muse/synti/organ/organ.cpp @@ -133,6 +133,12 @@ Organ::Organ(int sr) addController("percOn", PERC_ON, 0, 1, 1); addController("percSoft", PERC_SOFT, 0, 1, 0); addController("percSlow", PERC_SLOW, 0, 1, 1); + addController("percFirst", PERC_FIRST, 0, 1, 1); + addController("rotaryOn", ROTARY_ON, 0, 1, 0); + addController("rot1Freq", ROT1_FREQ, 0, 127, 100); + addController("rot1Depth", ROT1_DEPTH, 0, 127, 50); + addController("rot2Freq", ROT2_FREQ, 0, 127, 100); + addController("rot2Depth", ROT2_DEPTH, 0, 127, 50); } //--------------------------------------------------------- @@ -178,10 +184,11 @@ 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 }; - vibratoFreq = 7.25; - vibratoDepth = 0.005; - vibratoStep = lrint(vibratoFreq * RESO / double(sampleRate())); - vibratoAccu = 0; + vibratoAccu = 0; + rot1AccuL = 0; + rot1AccuR = 0x80000000; + rot2AccuL = 0; + rot2AccuR = 0x80000000; for (int i = 0; i < NO_WHEELS; ++i) { int note = i % 12; @@ -199,14 +206,12 @@ bool Organ::init(const char* name) } keyCompressionValue = 1.0; keyCompressionCount = 0; - percussionBus = 5; // 5 or 7 - percussionOn = true; - percussionEnvelopeCount = 0; + percGain = 0.0; return false; } //--------------------------------------------------------- -// write +// process //--------------------------------------------------------- void Organ::process(float** ports, int offset, int sampleCount) @@ -229,8 +234,17 @@ void Organ::process(float** ports, int offset, int sampleCount) float* buffer2 = ports[1] + offset; memset(buffer1, 0, sizeof(float) * sampleCount); memset(buffer2, 0, sizeof(float) * sampleCount); + float buffer3[sampleCount]; + float buffer4[sampleCount]; + memset(buffer3, 0, sizeof(float) * sampleCount); + memset(buffer4, 0, sizeof(float) * sampleCount); float vibrato[sampleCount]; + float rot1L[sampleCount]; + float rot1R[sampleCount]; + float rot2L[sampleCount]; + float rot2R[sampleCount]; + if (vibratoOn) { // // compute partial vibrato sinus @@ -240,22 +254,40 @@ void Organ::process(float** ports, int offset, int sampleCount) vibrato[i] = waveTable[vibratoAccu >> SHIFT] * vibratoDepth; } } + if (rotaryOn) { + for (int i = 0; i < sampleCount; ++i) { + rot1AccuL += rot1Step; + rot1L[i] = waveTable[rot1AccuL >> SHIFT] * rot1Depth; + rot1AccuR += rot1Step; + rot1R[i] = waveTable[rot1AccuR >> SHIFT] * rot1Depth; + rot2AccuL += rot2Step; + rot2L[i] = waveTable[rot2AccuL >> SHIFT] * rot2Depth; + rot2AccuR += rot2Step; + rot2R[i] = waveTable[rot2AccuR >> SHIFT] * rot2Depth; + } + } - foreach(Wheel* w, activeWheels) { + foreach (Wheel* w, activeWheels) { for (int i = 0; i < sampleCount; ++i) { unsigned step = w->frameStep; if (vibratoOn) - step += lrint(step * vibrato[i]); + step += unsigned(step * vibrato[i]); + w->accu += step; - float val = waveTable[w->accu >> SHIFT]; + unsigned off1 = unsigned(w->accu + (step * rot1L[i])); + unsigned off2 = unsigned(w->accu + (step * rot1R[i])); + float val1 = waveTable[off1 >> SHIFT]; + float val2 = waveTable[off2 >> SHIFT]; for (int k = 0; k < NO_BUSES; ++k) { int* envCnt = &(w->envCount[k]); + float v1, v2; if (*envCnt > 0) { (*envCnt)--; float gain = w->gain[k] - w->deltaGain[k] * w->env[k][*envCnt]; - buffer1[i] += val * gain * drawBarGain[k]; + v1 = val1 * gain; + v2 = val2 * gain; if ((*envCnt == 0) && (w->refCount == 0)) { int idx = activeWheels.indexOf(w); if (idx != -1) { @@ -265,26 +297,43 @@ void Organ::process(float** ports, int offset, int sampleCount) } } else { - buffer1[i] += val * w->gain[k] * drawBarGain[k]; + v1 = val1 * w->gain[k]; + v2 = val2 * w->gain[k]; } - if (percussionOn && k == percussionBus && percussionEnvelopeCount) { - // TODO + buffer1[i] += v1 * drawBarGain[k]; + buffer2[i] += v2 * drawBarGain[k]; + if (k == percussionBus) { + buffer3[i] += v1; + buffer4[i] += v2; } } } } - for (int i = 0; i < sampleCount; ++i) { - buffer1[i] *= volume * keyCompressionValue; - - if (keyCompressionCount) { - keyCompressionValue += keyCompressionDelta; - --keyCompressionCount; + if (percussionOn) { + for (int i = 0; i < sampleCount; ++i) { + buffer1[i] = buffer1[i] * volume * keyCompressionValue + + buffer3[i] * percGain; + buffer2[i] = buffer2[i] * volume * keyCompressionValue + + buffer4[i] * percGain; + percGain *= percussionEnvDecay; + if (keyCompressionCount) { + keyCompressionValue += keyCompressionDelta; + --keyCompressionCount; + } + } + } + else { + for (int i = 0; i < sampleCount; ++i) { + buffer1[i] *= volume * keyCompressionValue; + buffer2[i] *= volume * keyCompressionValue; + if (keyCompressionCount) { + keyCompressionValue += keyCompressionDelta; + --keyCompressionCount; + } } } if (reverbOn) reverb->process(buffer1, buffer2, sampleCount); - else - memcpy(buffer2, buffer1, sizeof(float) * sampleCount); } //--------------------------------------------------------- @@ -362,9 +411,22 @@ bool Organ::playNote(int /*channel*/, int pitch, int velo) } w->envCount[bus] = envSize; } + if (pressedKeys.isEmpty()) + percGain = percGainInit; return false; } +//--------------------------------------------------------- +// percussionChanged +//--------------------------------------------------------- + +void Organ::percussionChanged() + { + double decay = percussionSlow ? 4.0 : 1.0; + percGainInit = percussionSoft ? 0.5012 : 1.0; + percussionEnvDecay = exp(log(0.001/percGainInit) / (decay * double(sampleRate()))); + } + //--------------------------------------------------------- // setController //--------------------------------------------------------- @@ -407,12 +469,43 @@ void Organ::setController(int ctrlId, int data) break; case PERC_ON: + percussionOn = data != 0; break; case PERC_SOFT: + percussionSoft = data != 0; + percussionChanged(); break; case PERC_SLOW: + percussionSlow = data != 0; + percussionChanged(); + break; + + case PERC_FIRST: + percussionBus = data ? 3 : 4; + break; + + case ROTARY_ON: + rotaryOn = data != 0; + break; + + case ROT1_FREQ: + rot1Freq = float(data) * 6.0 / 127.0 + 0.67; + rot1Step = lrint(rot1Freq * RESO / double(sampleRate())); + break; + + case ROT1_DEPTH: + rot1Depth = float(data) / 127.0 * .01; + break; + + case ROT2_FREQ: + rot1Freq = float(data) * 5.0 / 127.0 + 0.5; + rot1Step = lrint(rot1Freq * RESO / double(sampleRate())); + break; + + case ROT2_DEPTH: + rot2Depth = float(data) / 127.0 * .01; break; case CTRL_VOLUME: diff --git a/muse/synti/organ/organ.h b/muse/synti/organ/organ.h index 6a90d67a..ac6ef156 100644 --- a/muse/synti/organ/organ.h +++ b/muse/synti/organ/organ.h @@ -31,7 +31,8 @@ enum { DRAWBAR3, DRAWBAR4, DRAWBAR5, DRAWBAR6, DRAWBAR7, DRAWBAR8, REVERB_ON, REVERB_ROOM_SIZE, REVERB_MIX, VIBRATO_ON, VIBRATO_FREQ, VIBRATO_DEPTH, - PERC_ON, PERC_SOFT, PERC_SLOW, + PERC_ON, PERC_SOFT, PERC_SLOW, PERC_FIRST, + ROTARY_ON, ROT1_FREQ, ROT1_DEPTH, ROT2_FREQ, ROT2_DEPTH }; //--------------------------------------------------------- @@ -101,8 +102,25 @@ class Organ : public Mess2 { // percussion int percussionBus; // usually drawbar 3 or drawbar 4 bool percussionOn; + bool percussionSlow; + bool percussionSoft; int percussionEnvelopeCount; - + double percussionEnvDecay; + double percGain; + double percGainInit; + + // rotary speaker emulation + bool rotaryOn; + double rot1Freq; // horn: 0,67 - 6,7 + double rot1Depth; + double rot2Freq; // drum: 0,5 - 5,5 + double rot2Depth; + unsigned rot1Step; + unsigned rot1AccuL; + unsigned rot1AccuR; + unsigned rot2Step; + unsigned rot2AccuL; + unsigned rot2AccuR; float drawBarGain[NO_BUSES]; Wheel wheels[NO_WHEELS]; @@ -111,6 +129,7 @@ class Organ : public Mess2 { void setController(int ctrl, int val); void changeKeyCompression(); + void percussionChanged(); virtual void process(float**, int, int); virtual bool playNote(int channel, int pitch, int velo); diff --git a/muse/synti/organ/organgui.ui b/muse/synti/organ/organgui.ui index c0643106..60eddb1b 100644 --- a/muse/synti/organ/organgui.ui +++ b/muse/synti/organ/organgui.ui @@ -6,7 +6,7 @@ 0 0 555 - 334 + 341 @@ -323,7 +323,7 @@ background-color: gray; - Drawbars + UPPER MANUAL @@ -393,6 +393,13 @@ background-color: gray; 8.000000000000000 + + + 128 + 102 + 86 + + @@ -454,6 +461,198 @@ background-color: gray; + + + + RotarySpeaker (test) + + + true + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + 0 + 0 + + + + f1 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + depth1 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + 0 + 0 + + + + f2 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + depth2 + + + Qt::AlignCenter + + + + + + diff --git a/muse/synti/organ/reverb.cpp b/muse/synti/organ/reverb.cpp index 18376a8f..72775bc5 100644 --- a/muse/synti/organ/reverb.cpp +++ b/muse/synti/organ/reverb.cpp @@ -143,7 +143,7 @@ void Reverb::process(float* l, float* r, int n) for (int i = 0; i < n; ++i) { float outL = 0.0; float outR = 0.0; - float input = l[i] * gain; + float input = (l[i] + r[i]) * gain; // Accumulate comb filters in parallel for (int k = 0; k < numcombs; k++) { @@ -157,7 +157,7 @@ void Reverb::process(float* l, float* r, int n) outR = allpassR[k].process(outR); } l[i] = outL * wet + l[i] * dry; - r[i] = outR * wet + l[i] * dry; + r[i] = outR * wet + r[i] * dry; } } -- cgit v1.2.3