summaryrefslogtreecommitdiff
path: root/attic/muse_qt4_evolution/synti/organ/organ.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse_qt4_evolution/synti/organ/organ.cpp')
-rw-r--r--attic/muse_qt4_evolution/synti/organ/organ.cpp621
1 files changed, 0 insertions, 621 deletions
diff --git a/attic/muse_qt4_evolution/synti/organ/organ.cpp b/attic/muse_qt4_evolution/synti/organ/organ.cpp
deleted file mode 100644
index 7c83a463..00000000
--- a/attic/muse_qt4_evolution/synti/organ/organ.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-//=========================================================
-// MusE
-// Linux Music Editor
-// $Id: organ.cpp,v 1.23 2005/12/16 15:36:51 wschweer Exp $
-//
-// Parts of this file taken from:
-// Organ - Additive Organ Synthesizer Voice
-// Copyright (C) 1999, 2000 David A. Bartold
-// Some information was gathered form the "beatrix" organ
-// from Fredrik Kilander
-//
-// (C) Copyright 2001-2007 Werner Schweer (ws@seh.de)
-//=========================================================
-
-#include "muse/midi.h"
-#include "libsynti/midievent.h"
-
-#include "organ.h"
-#include "organgui.h"
-#include "reverb.h"
-
-float* Organ::attackEnv;
-float* Organ::releaseEnv;
-int Organ::envSize;
-float* Organ::waveTable;
-int Organ::useCount;
-double Organ::cb2amp_tab[MAX_ATTENUATION];
-float Organ::keyCompression[NO_VOICES];
-
-//---------------------------------------------------------
-// dBToGain
-//---------------------------------------------------------
-
-static double dBToGain(double dB)
- {
- return pow(10.0, (dB / 20.0));
- }
-
-//---------------------------------------------------------
-// cb2amp
-// convert centibel to amplification (0 - 96dB)
-//---------------------------------------------------------
-
-double Organ::cb2amp(int cb)
- {
- if (cb < 0)
- return 1.0;
- if (cb >= MAX_ATTENUATION)
- return 0.0;
- return cb2amp_tab[cb];
- }
-
-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(2)
- {
- setSampleRate(sr);
- gui = 0;
- reverb = new Reverb();
-
- ++useCount;
- if (useCount > 1)
- return;
-
- // 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 (unsigned i = 0; i < resolution; i++)
- waveTable[i] = sin (double(i) * 2.0 * M_PI / double(resolution));
-
- // Initialize envelope tables
-
- envSize = sr * 4 / 1000; // 4 msec
- attackEnv = new float[envSize];
- releaseEnv = new float[envSize];
-
- for (int i = 0; i < envSize; ++i) {
- attackEnv[i] = float(i) / float(envSize);
- releaseEnv[i] = float(i) / float(envSize);
- }
-
- // Initialize key compression table
-
- keyCompression[ 0] = 1.0;
- keyCompression[ 1] = 1.0;
- keyCompression[ 2] = dBToGain(-1.1598);
- keyCompression[ 3] = dBToGain(-2.0291);
- keyCompression[ 4] = dBToGain(-2.4987);
- keyCompression[ 5] = dBToGain(-2.9952);
- keyCompression[ 6] = dBToGain(-3.5218);
- keyCompression[ 7] = dBToGain(-4.0823);
- keyCompression[ 8] = dBToGain(-4.6815);
- keyCompression[ 9] = dBToGain(-4.9975);
- keyCompression[10] = dBToGain(-4.9998);
-
- /* Linear interpolation from u to v. */
-
- static const float u = -5.0;
- static const float v = -9.0;
- static const float m = 1.0 / (NO_VOICES - 12);
- for (int i = 11; i < NO_VOICES; i++) {
- keyCompression[i] = dBToGain(u + ((v - u) * float(i - 11) * m));
- }
-
- // Initialize controller table
-
- addController("drawbar16", DRAWBAR0, 0, 8, 8);
- addController("drawbar513", DRAWBAR1, 0, 8, 8);
- addController("drawbar8", DRAWBAR2, 0, 8, 8);
- addController("drawbar4", DRAWBAR3, 0, 8, 0);
- addController("drawbar223", DRAWBAR4, 0, 8, 0);
- addController("drawbar2", DRAWBAR5, 0, 8, 0);
- addController("drawbar135", DRAWBAR6, 0, 8, 0);
- addController("drawbar113", DRAWBAR7, 0, 8, 0);
- addController("drawbar1", DRAWBAR8, 0, 8, 0);
- addController("reverbOn", REVERB_ON, 0, 1, 0);
- 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);
- addController("percOn", PERC_ON, 0, 1, 1);
- addController("percGain", PERC_GAIN, 0, 127, 60);
- addController("percDecay", PERC_DECAY, 0, 127, 60);
- addController("percHarmony", PERC_HARMONY, 0, 8, 3);
- 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);
- }
-
-//---------------------------------------------------------
-// ~Organ
-//---------------------------------------------------------
-
-Organ::~Organ()
- {
- if (gui)
- delete gui;
- delete reverb;
-
- --useCount;
- if (useCount == 0) {
- delete[] waveTable;
- delete[] attackEnv;
- delete[] releaseEnv;
- }
- }
-
-//---------------------------------------------------------
-// init
-//---------------------------------------------------------
-
-bool Organ::init(const char* name)
- {
- gui = new OrganGui;
- gui->hide();
- gui->setWindowTitle(QString(name));
-
- //
- // Initialize controller
- //
- int idx = 0;
- foreach(SynthCtrl* c, ctrl) {
- setController(c->ctrl, c->init); // init synti
- gui->setParamIdx(idx, c->init); // init gui
- ++idx;
- }
-
- // see: http://www.dairiki.org/HammondWiki/GearRatio
- static const int gearA[12] = { 85, 71,67,35,69,12,37,49,48,11,67,54 };
- 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 };
-
- vibratoAccu = 0;
- rot1AccuL = 0;
- rot1AccuR = 0x80000000;
- rot2AccuL = 0;
- rot2AccuR = 0x80000000;
-
- 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].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;
- }
- keyCompressionValue = 1.0;
- keyCompressionCount = 0;
- percGain = 0.0;
- return false;
- }
-
-//---------------------------------------------------------
-// process
-//---------------------------------------------------------
-
-void Organ::process(float** ports, int offset, int sampleCount)
- {
- //
- // get and process all pending events from the
- // synthesizer GUI
- //
- while (gui->fifoSize()) {
- MidiEvent ev = gui->readEvent();
- if (ev.type() == ME_CONTROLLER) {
- setController(ev.dataA(), ev.dataB());
- sendEvent(ev);
- }
- else
- printf("Organ::process(): unknown event\n");
- }
-
- float* buffer1 = ports[0] + offset;
- float* buffer2 = ports[1] + offset;
- memset(buffer1, 0, sizeof(float) * sampleCount);
- memset(buffer2, 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) {
-
- unsigned step = w->frameStep;
- if (vibratoOn)
- step += unsigned(step * vibrato[i]);
-
- w->accu += step;
-
- int idx = w->accu >> SHIFT;
- float val1 = waveTable[idx];
- idx = (idx + 1) & 0xffff;
- float val2 = waveTable[idx];
- float val = val1 + (val2 - val1) * double(w->accu & 0xffff)/double(0x10000);
-
- for (int k = 0; k < NO_BUSES; ++k) {
- int* envCnt = &(w->envCount[k]);
- float v;
- if (*envCnt > 0) {
- (*envCnt)--;
- float gain = w->gain[k] - w->deltaGain[k] * w->env[k][*envCnt];
- v = val * gain;
- if ((*envCnt == 0) && (w->refCount == 0)) {
- int idx = activeWheels.indexOf(w);
- if (idx != -1) {
- activeWheels.removeAt(idx);
- w->active = false;
- }
- }
- }
- else {
- v = val * w->gain[k];
- }
- buffer1[i] += v * drawBarGain[k];
- if (k == percussionBus)
- buffer2[i] += v;
- }
- }
- }
- if (percussionOn) {
- for (int i = 0; i < sampleCount; ++i) {
- buffer1[i] = buffer1[i] * volume * keyCompressionValue
- + buffer2[i] * percGain;
- percGain *= percussionEnvDecay;
- if (keyCompressionCount) {
- keyCompressionValue += keyCompressionDelta;
- --keyCompressionCount;
- }
- }
- }
- else {
- for (int i = 0; i < sampleCount; ++i) {
- buffer1[i] *= volume * keyCompressionValue;
- if (keyCompressionCount) {
- keyCompressionValue += keyCompressionDelta;
- --keyCompressionCount;
- }
- }
- }
- memcpy(buffer2, buffer1, sizeof(float) * sampleCount);
- if (reverbOn)
- reverb->process(buffer1, buffer2, sampleCount);
- }
-
-//---------------------------------------------------------
-// changeKeyCompression
-//---------------------------------------------------------
-
-void Organ::changeKeyCompression()
- {
- float kc = keyCompression[pressedKeys.size()];
- keyCompressionCount = int(sampleRate() * .005); // 5 msec envelope
- if (keyCompressionCount < 2)
- keyCompressionCount = 2;
- keyCompressionDelta = (kc - keyCompressionValue) / keyCompressionCount;
- }
-
-//---------------------------------------------------------
-// playNote
-//---------------------------------------------------------
-
-bool Organ::playNote(int /*channel*/, int pitch, int velo)
- {
- if (pitch < 36 || pitch > 97)
- return false;
- if (velo == 0) {
- int idx = pressedKeys.indexOf(pitch);
- if (idx == -1) {
- printf("Organ: noteoff %d not found\n", pitch);
- return false;
- }
- pressedKeys.removeAt(idx);
- }
- else {
- if (pressedKeys.isEmpty())
- percGain = percGainInit;
- pressedKeys.append(pitch);
- }
- changeKeyCompression();
-
- for (int k = 0; k < NO_ELEMENTS; ++k) {
- const Elem* e = &routing[pitch - 36][k];
- if (e->bus == -1)
- break;
- Wheel* w = &wheels[int(e->wheel)];
- int bus = e->bus;
- float level = e->level;
-
- if (velo) {
- if (!w->active) {
- // activate wheel
- for (int k = 0; k < NO_BUSES; ++k) {
- w->gain[k] = 0.0;
- w->envCount[k] = 0;
- }
- activeWheels.append(w);
- w->active = true;
- }
- float deltaGain = level;
-
- if (w->envCount[bus]) {
- deltaGain += w->deltaGain[bus] * w->env[bus][w->envCount[bus]];
- }
- w->env[bus] = attackEnv;
- w->deltaGain[bus] = deltaGain;
- w->gain[bus] += level;
- w->refCount++;
- }
- else {
- float deltaGain = -level;
-
- if (w->envCount[bus]) {
- deltaGain += w->deltaGain[bus] * w->env[bus][w->envCount[bus]];
- }
- w->env[bus] = releaseEnv;
- w->deltaGain[bus] = deltaGain;
- w->gain[bus] -= level;
- if (w->refCount)
- w->refCount--;
- }
- w->envCount[bus] = envSize;
- }
- return false;
- }
-
-//---------------------------------------------------------
-// percussionChanged
-//---------------------------------------------------------
-
-void Organ::percussionChanged()
- {
- percussionEnvDecay = exp(log(0.001/percGainInit) / (percDecay * double(sampleRate())));
- }
-
-//---------------------------------------------------------
-// setController
-//---------------------------------------------------------
-
-void Organ::setController(int ctrlId, int data)
- {
- int ctrlIdx = controllerIdx(ctrlId);
- if (ctrlIdx != -1)
- ctrl[ctrlIdx]->val = data;
- switch (ctrlId) {
- case DRAWBAR0 ... DRAWBAR8:
- {
- int db = ctrlId - DRAWBAR0;
- 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 REVERB_ON:
- reverbOn = data != 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 PERC_ON:
- percussionOn = data != 0;
- break;
-
- case PERC_GAIN: // 0.01 - 0.4
- percGainInit = float(data) * .39 / 127.0 + 0.01;
- percussionChanged();
- break;
-
- case PERC_DECAY: // 0.5 - 4.5 sec
- percDecay = float(data) * 4.0 / 127.0 + 0.5;
- percussionChanged();
- break;
-
- case PERC_HARMONY:
- percussionBus = data;
- 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 * 1.0;
- 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 * 1.0;
- break;
-
- case CTRL_VOLUME:
- data &= 0x7f;
- volume = data == 0 ? 0.0 : cb2amp(int(200 * log10((127.0 * 127)/(data*data))));
- volume *= .04;
- break;
-
- case CTRL_ALL_SOUNDS_OFF:
- foreach(Wheel* w, activeWheels) {
- for (int k = 0; k < NO_ELEMENTS; ++k) {
- w->gain[k] = 0.0;
- w->envCount[k] = 0;
- }
- w->refCount = 0;
- }
- pressedKeys.clear();
- break;
-
- case CTRL_RESET_ALL_CTRL:
-// for (int i = 0; i < NUM_CONTROLLER; ++i)
-// setController(0, synthCtrl[i].num, synthCtrl[i].val);
- break;
- default:
- fprintf(stderr, "Organ:set unknown Ctrl 0x%x to 0x%x\n", ctrlId, data);
- return;
- }
- }
-
-//---------------------------------------------------------
-// setController
-//---------------------------------------------------------
-
-bool Organ::setController(int channel, int ctrlId, int data)
- {
- MidiEvent ev(0, channel, ME_CONTROLLER, ctrlId, data);
- gui->writeEvent(ev);
- setController(ctrlId, data);
- return false;
- }
-
-//---------------------------------------------------------
-// sysex
-//---------------------------------------------------------
-
-bool Organ::sysex(int n, const unsigned char* data)
- {
- int nn = ctrl.size() * sizeof(int);
- if (nn != n) {
- printf("unknown sysex %d %02x %02x\n", n, data[0], data[1]);
- return false;
- }
- const int* s = (const int*) data;
- for (int i = 0; i < ctrl.size(); ++i) {
- setController(0, ctrl[i]->ctrl, *s);
- setController(ctrl[i]->ctrl, *s);
- s++;
- }
- return false;
- }
-
-//---------------------------------------------------------
-// MESS
-//---------------------------------------------------------
-
-//---------------------------------------------------------
-// guiVisible
-//---------------------------------------------------------
-
-bool Organ::guiVisible() const
- {
- return gui->isVisible();
- }
-
-//---------------------------------------------------------
-// showGui
-//---------------------------------------------------------
-
-void Organ::showGui(bool val)
- {
- gui->setShown(val);
- }
-
-//---------------------------------------------------------
-// getGeometry
-//---------------------------------------------------------
-
-void Organ::getGeometry(int* x, int* y, int* w, int* h) const
- {
- QPoint pos(gui->pos());
- QSize size(gui->size());
- *x = pos.x();
- *y = pos.y();
- *w = size.width();
- *h = size.height();
- }
-
-//---------------------------------------------------------
-// setGeometry
-//---------------------------------------------------------
-
-void Organ::setGeometry(int x, int y, int w, int h)
- {
- gui->resize(QSize(w, h));
- gui->move(QPoint(x, y));
- }
-
-//---------------------------------------------------------
-// instantiate
-// construct a new synthesizer instance
-//---------------------------------------------------------
-
-static Mess* instantiate(int sr, const char* name)
- {
- Organ* synth = new Organ(sr);
- if (synth->init(name)) {
- delete synth;
- synth = 0;
- }
- return synth;
- }
-
-//---------------------------------------------------------
-// msynth_descriptor
-// Return a descriptor of the requested plugin type.
-//---------------------------------------------------------
-
-extern "C" {
- static MESS descriptor = {
- "Organ",
- "Organ; based on David A. Bartold's LADSPA plugin",
- "0.1", // version string
- MESS_MAJOR_VERSION, MESS_MINOR_VERSION,
- instantiate,
- };
-
- const MESS* mess_descriptor() { return &descriptor; }
- }
-