diff options
author | Werner Schweer <ws.seh.de> | 2007-06-19 21:59:35 +0000 |
---|---|---|
committer | Werner Schweer <ws.seh.de> | 2007-06-19 21:59:35 +0000 |
commit | ac7a811fc7d8929f99b35915197ed0ea4f13e870 (patch) | |
tree | d77bc073bc144ca355e5bce1c94126a687828666 | |
parent | 788205306cafe1638c95a356ed5b32a5936ee140 (diff) |
update
-rw-r--r-- | muse/synti/organ/CMakeLists.txt | 2 | ||||
-rw-r--r-- | muse/synti/organ/organ.cpp | 97 | ||||
-rw-r--r-- | muse/synti/organ/organ.h | 21 | ||||
-rw-r--r-- | 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 @@ <rect> <x>0</x> <y>0</y> - <width>270</width> - <height>275</height> + <width>424</width> + <height>335</height> </rect> </property> <property name="sizePolicy" > @@ -54,187 +54,366 @@ background-color: gray; } </string> </property> - <layout class="QGridLayout" > - <property name="leftMargin" > - <number>9</number> - </property> - <property name="topMargin" > - <number>9</number> - </property> - <property name="rightMargin" > - <number>9</number> - </property> - <property name="bottomMargin" > - <number>9</number> - </property> - <property name="horizontalSpacing" > - <number>6</number> - </property> - <property name="verticalSpacing" > - <number>6</number> - </property> - <item row="0" column="0" > - <widget class="QLabel" name="name" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="font" > - <font> - <pointsize>-1</pointsize> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text" > - <string>O-1</string> - </property> - <property name="alignment" > - <set>Qt::AlignCenter</set> - </property> - </widget> + <layout class="QVBoxLayout" > + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="name" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font" > + <font> + <pointsize>-1</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text" > + <string>O-1</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox" > + <property name="title" > + <string>Reverb</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="Awl::Knob" name="reverbRoomSize" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="scaleValueColor" > + <color> + <red>255</red> + <green>255</green> + <blue>0</blue> + </color> + </property> + <property name="maxValue" > + <double>127.000000000000000</double> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Room</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLabel" name="label_2" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Mix</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="Awl::Knob" name="reverbMix" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="scaleValueColor" > + <color> + <red>255</red> + <green>255</green> + <blue>0</blue> + </color> + </property> + <property name="maxValue" > + <double>127.000000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="vibratoOn" > + <property name="title" > + <string>Vibrato</string> + </property> + <property name="checkable" > + <bool>true</bool> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="Awl::Knob" name="vibratoFreq" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="scaleValueColor" > + <color> + <red>255</red> + <green>255</green> + <blue>0</blue> + </color> + </property> + <property name="maxValue" > + <double>127.000000000000000</double> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="Awl::Knob" name="vibratoDepth" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="scaleValueColor" > + <color> + <red>255</red> + <green>255</green> + <blue>0</blue> + </color> + </property> + <property name="maxValue" > + <double>127.000000000000000</double> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label_3" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Freq</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLabel" name="label_4" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Depth</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> </item> - <item rowspan="2" row="1" column="0" colspan="2" > - <widget class="QGroupBox" name="GroupBox1" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title" > - <string>Drawbars</string> - </property> - <layout class="QHBoxLayout" > - <item> - <widget class="Awl::Drawbar" name="drawbar16" > - <property name="value" > - <double>4.319999999999999</double> - </property> - <property name="sliderColor" > - <color> - <red>60</red> - <green>60</green> - <blue>60</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar513" > - <property name="value" > - <double>5.039999999999999</double> - </property> - <property name="sliderColor" > - <color> - <red>60</red> - <green>60</green> - <blue>60</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar8" > - <property name="value" > - <double>8.000000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>240</red> - <green>240</green> - <blue>240</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar4" > - <property name="value" > - <double>8.000000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>240</red> - <green>240</green> - <blue>240</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar223" > - <property name="value" > - <double>8.000000000000000</double> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar2" > - <property name="value" > - <double>0.000000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>240</red> - <green>240</green> - <blue>240</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar135" > - <property name="value" > - <double>0.000000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>128</red> - <green>102</green> - <blue>86</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar113" > - <property name="value" > - <double>2.160000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>128</red> - <green>102</green> - <blue>86</blue> - </color> - </property> - </widget> - </item> - <item> - <widget class="Awl::Drawbar" name="drawbar1" > - <property name="value" > - <double>0.000000000000000</double> - </property> - <property name="sliderColor" > - <color> - <red>240</red> - <green>240</green> - <blue>240</blue> - </color> - </property> - </widget> - </item> - </layout> - </widget> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QGroupBox" name="GroupBox1" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title" > + <string>Drawbars</string> + </property> + <layout class="QHBoxLayout" > + <item> + <widget class="Awl::Drawbar" name="drawbar16" > + <property name="value" > + <double>4.319999999999999</double> + </property> + <property name="sliderColor" > + <color> + <red>60</red> + <green>60</green> + <blue>60</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar513" > + <property name="value" > + <double>5.039999999999999</double> + </property> + <property name="sliderColor" > + <color> + <red>60</red> + <green>60</green> + <blue>60</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar8" > + <property name="minimumSize" > + <size> + <width>0</width> + <height>150</height> + </size> + </property> + <property name="value" > + <double>8.000000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>240</red> + <green>240</green> + <blue>240</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar4" > + <property name="value" > + <double>8.000000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>240</red> + <green>240</green> + <blue>240</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar223" > + <property name="value" > + <double>8.000000000000000</double> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar2" > + <property name="value" > + <double>0.000000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>240</red> + <green>240</green> + <blue>240</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar135" > + <property name="value" > + <double>4.800000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>128</red> + <green>102</green> + <blue>86</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar113" > + <property name="value" > + <double>2.160000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>128</red> + <green>102</green> + <blue>86</blue> + </color> + </property> + </widget> + </item> + <item> + <widget class="Awl::Drawbar" name="drawbar1" > + <property name="value" > + <double>0.000000000000000</double> + </property> + <property name="sliderColor" > + <color> + <red>240</red> + <green>240</green> + <blue>240</blue> + </color> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> </item> </layout> </widget> <layoutdefault spacing="6" margin="11" /> <customwidgets> <customwidget> + <class>Awl::Knob</class> + <extends>QWidget</extends> + <header>awl/knob.h</header> + </customwidget> + <customwidget> <class>Awl::Drawbar</class> <extends>Awl::Slider</extends> <header>awl/drawbar.h</header> |