diff options
Diffstat (limited to 'attic/muse2-oom/muse2/synti/organ/organ.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/synti/organ/organ.cpp | 716 |
1 files changed, 0 insertions, 716 deletions
diff --git a/attic/muse2-oom/muse2/synti/organ/organ.cpp b/attic/muse2-oom/muse2/synti/organ/organ.cpp deleted file mode 100644 index 1aa87742..00000000 --- a/attic/muse2-oom/muse2/synti/organ/organ.cpp +++ /dev/null @@ -1,716 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: organ.cpp,v 1.15.2.8 2009/12/06 10:05:00 terminator356 Exp $ -// -// Parts of this file taken from: -// Organ - Additive Organ Synthesizer Voice -// Copyright (c) 1999, 2000 David A. Bartold -// -// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) -//========================================================= - -#include <cmath> -#include <stdio.h> - -#include "muse/midi.h" -//#include "libsynti/mpevent.h" -#include "muse/mpevent.h" - -#include "organ.h" -#include "organgui.h" - -//#define ORGAN_DEBUG - -SynthCtrl Organ::synthCtrl[] = { - { "harm0", HARM0, 0 }, - { "harm1", HARM1, 0 }, - { "harm2", HARM2, 0 }, - { "harm3", HARM3, 0 }, - { "harm4", HARM4, 0 }, - { "harm5", HARM5, 0 }, - { "attackLo", ATTACK_LO, 20 }, - { "decayLo", DECAY_LO, 20 }, - { "sustainLo", SUSTAIN_LO, 0 }, - { "releaseLo", RELEASE_LO, 20 }, - { "attackHi", ATTACK_HI, 10 }, - { "decayHi", DECAY_HI, 10 }, - { "sustainHi", SUSTAIN_HI, 0 }, - { "releaseHi", RELEASE_HI, 10 }, - { "brass", BRASS, 1 }, - { "flute", FLUTE, 1 }, - { "reed", REED, 1 }, - { "velocity", VELO, 0 }, - // next controller not send as init data - { "volume", CTRL_VOLUME, 100 }, - }; - -static int NUM_CONTROLLER = sizeof(Organ::synthCtrl)/sizeof(*(Organ::synthCtrl)); -static int NUM_INIT_CONTROLLER = NUM_CONTROLLER - 1; - -float* Organ::sine_table; -float* Organ::g_triangle_table; -float* Organ::g_pulse_table; -int Organ::useCount = 0; -double Organ::cb2amp_tab[MAX_ATTENUATION]; -unsigned Organ::freq256[128]; - -//--------------------------------------------------------- -// 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]; - } - -//--------------------------------------------------------- -// Organ -//--------------------------------------------------------- - -Organ::Organ(int sr) - : Mess(1) - { - idata = new int[NUM_CONTROLLER]; - setSampleRate(sr); - gui = 0; - - ++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); - - for (int i = 0; i < 128; ++i) { - double freq = 8.176 * exp(double(i)*log(2.0)/12.0); - freq256[i] = (int) (freq * ((double) RESOLUTION) / sr * 256.0); - } - int size = RESOLUTION; - int half = size / 2; - int slope = size / 10; - int i; - - // Initialize sine table. - sine_table = new float[size]; - for (i = 0; i < size; i++) - sine_table[i] = sin ((i * 2.0 * M_PI) / size) / 6.0; - - // Initialize triangle table. - g_triangle_table = new float[size]; - for (i = 0; i < half; i++) - g_triangle_table[i] = (4.0 / size * i - 1.0) / 6.0; - for (; i < size; i++) - g_triangle_table[i] = (4.0 / size * (size - i) - 1.0) / 6.0; - - // Initialize pulse table. - g_pulse_table = new float[size]; - for (i = 0; i < slope; i++) - g_pulse_table[i] = (((double) -i) / slope) / 6.0; - for (; i < half - slope; i++) - g_pulse_table[i] = -1.0 / 6.0; - for (; i < half + slope; i++) - g_pulse_table[i] = (((double) i - half) / slope) / 6.0; - for (; i < size - slope; i++) - g_pulse_table[i] = 1.0 / 6.0; - for (; i < size; i++) - g_pulse_table[i] = (((double) size - i) / slope) / 6.0; - } - -//--------------------------------------------------------- -// ~Organ -//--------------------------------------------------------- - -Organ::~Organ() - { - if (gui) - delete gui; - delete idata; - --useCount; - if (useCount == 0) { - delete[] g_pulse_table; - delete[] g_triangle_table; - delete[] sine_table; - } - } - -//--------------------------------------------------------- -// table_pos -//--------------------------------------------------------- - -static inline float table_pos (float* table, unsigned long freq_256, unsigned *accum) - { - *accum += freq_256; - while (*accum >= RESOLUTION * 256) - *accum -= RESOLUTION * 256; - return table[*accum >> 8]; - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -bool Organ::init(const char* name) - { - gui = new OrganGui; - gui->setWindowTitle(QString(name)); - gui->show(); - - for (int i = 0; i < NUM_CONTROLLER; ++i) - setController(0, synthCtrl[i].num, synthCtrl[i].val); - - for (int i = 0; i < VOICES; ++i) - voices[i].isOn = false; - return false; - } - -//--------------------------------------------------------- -// processMessages -// Called from host always, even if output path is unconnected. -//--------------------------------------------------------- - -void Organ::processMessages() -{ - //Process messages from the gui - // - // get and process all pending events from the - // synthesizer GUI - // - while (gui->fifoSize()) - { - MidiPlayEvent ev = gui->readEvent(); - if (ev.type() == ME_CONTROLLER) - { - // process local? - setController(ev.dataA(), ev.dataB()); - sendEvent(ev); - } - else - printf("Organ::process(): unknown event\n"); - } -} - -//--------------------------------------------------------- -// process -// Called from host, ONLY if output path is connected. -//--------------------------------------------------------- - -void Organ::process(float** ports, int offset, int sampleCount) - { - /* - // - // get and process all pending events from the - // synthesizer GUI - // - while (gui->fifoSize()) { - MidiPlayEvent ev = gui->readEvent(); - if (ev.type() == ME_CONTROLLER) { - // process local? - setController(ev.dataA(), ev.dataB()); - sendEvent(ev); - } - else - printf("Organ::process(): unknown event\n"); - } - */ - - float* buffer = *ports + offset; - for (int i = 0; i < VOICES; ++i) { - Voice* v = &voices[i]; - if (!v->isOn) - continue; - double vol = velo ? v->velocity : 1.0; - vol *= volume; - - unsigned freq_256 = freq256[v->pitch]; - unsigned* harm0_accum = &(v->harm0_accum); - unsigned* harm1_accum = &(v->harm1_accum); - unsigned* harm2_accum = &(v->harm2_accum); - unsigned* harm3_accum = &(v->harm3_accum); - unsigned* harm4_accum = &(v->harm4_accum); - unsigned* harm5_accum = &(v->harm5_accum); - - unsigned long freq_256_harm2, freq_256_harm3; - unsigned long freq_256_harm4, freq_256_harm5; - - float* reed_table = reed ? g_pulse_table : sine_table; - float* flute_table = flute ? g_triangle_table : sine_table; - - unsigned freq_256_harm0 = freq_256 / 2; - unsigned freq_256_harm1 = freq_256; - - if (brass) { - freq_256_harm2 = freq_256 * 2; - freq_256_harm3 = freq_256_harm2 * 2; - freq_256_harm4 = freq_256_harm3 * 2; - freq_256_harm5 = freq_256_harm4 * 2; - for (int i = 0; i < sampleCount; i++) { - int a1=0, a2=0; //prevent compiler warning: unitialized usage of vars a1 & a2 - switch(v->state1) { - case ATTACK: - if (v->envL1.step(&a1)) - break; - v->state1 = DECAY; - case DECAY: - if (v->envL2.step(&a1)) - break; - v->state1 = SUSTAIN; - case SUSTAIN: - a1 = sustain0; - break; - case RELEASE: - if (v->envL3.step(&a1)) - break; - v->state1 = OFF; - a1 = MAX_ATTENUATION; - break; - } - switch(v->state2) { - case ATTACK: - if (v->envH1.step(&a2)) - break; - v->state2 = DECAY; - case DECAY: - if (v->envH2.step(&a2)) - break; - v->state2 = SUSTAIN; - case SUSTAIN: - a2 = sustain1; - break; - case RELEASE: - if (v->envH3.step(&a2)) - break; - v->state2 = OFF; - a1 = MAX_ATTENUATION; - break; - } - if (v->state1 == OFF && v->state2 == OFF) { - v->isOn = false; - break; - } - buffer[i] += - (table_pos (sine_table, freq_256_harm0, harm0_accum) * harm0 - + table_pos (sine_table, freq_256_harm1, harm1_accum) * harm1 - + table_pos (reed_table, freq_256_harm2, harm2_accum) * harm2) - * cb2amp(a1) * vol - + (table_pos (sine_table, freq_256_harm3, harm3_accum) * harm3 - + table_pos (flute_table, freq_256_harm4, harm4_accum) * harm4 - + table_pos (flute_table, freq_256_harm5, harm5_accum) * harm5) - * cb2amp(a2) * vol; - } - } - else { - freq_256_harm2 = freq_256 * 3 / 2; - freq_256_harm3 = freq_256 * 2; - freq_256_harm4 = freq_256 * 3; - freq_256_harm5 = freq_256_harm3 * 2; - for (int i = 0; i < sampleCount; i++) { - int a1=0, a2=0;//prevent compiler warning: unitialized usage of vars a1 & a2 - switch(v->state1) { - case ATTACK: - if (v->envL1.step(&a1)) - break; - v->state1 = DECAY; - case DECAY: - if (v->envL2.step(&a1)) - break; - v->state1 = SUSTAIN; - case SUSTAIN: - a1 = sustain0; - break; - case RELEASE: - if (v->envL3.step(&a1)) - break; - v->state1 = OFF; - a1 = MAX_ATTENUATION; - break; - } - switch(v->state2) { - case ATTACK: - if (v->envH1.step(&a2)) - break; - v->state2 = DECAY; - case DECAY: - if (v->envH2.step(&a2)) - break; - v->state2 = SUSTAIN; - case SUSTAIN: - a2 = sustain1; - break; - case RELEASE: - if (v->envH3.step(&a2)) - break; - v->state2 = OFF; - a1 = MAX_ATTENUATION; - break; - } - if (v->state1 == OFF && v->state2 == OFF) { - v->isOn = false; - break; - } - buffer[i] += - (table_pos (sine_table, freq_256_harm0, harm0_accum) * harm0 - + table_pos (sine_table, freq_256_harm1, harm1_accum) * harm1 - + table_pos (sine_table, freq_256_harm2, harm2_accum) * harm2) - * cb2amp(a1) * vol - + (table_pos (reed_table, freq_256_harm3, harm3_accum) * harm3 - + table_pos (sine_table, freq_256_harm4, harm4_accum) * harm4 - + table_pos (flute_table, freq_256_harm5, harm5_accum) * harm5) - * cb2amp(a2) * vol; - } - } - } - } - -//--------------------------------------------------------- -// playNote -//--------------------------------------------------------- - -bool Organ::playNote(int channel, int pitch, int velo) - { - if (velo == 0) { - noteoff(channel, pitch); - return false; - } - for (int i = 0; i < VOICES; ++i) { - if (voices[i].isOn) - continue; - voices[i].isOn = true; - voices[i].pitch = pitch; - voices[i].channel = channel; - // velo is never 0 - voices[i].velocity = cb2amp(int(200 * log10((127.0 * 127)/(velo*velo)))); - voices[i].state1 = ATTACK; - voices[i].state2 = ATTACK; - voices[i].envL1.set(attack0, MAX_ATTENUATION, 0); - voices[i].envL2.set(decay0, MAX_ATTENUATION, sustain0); - voices[i].envL3.set(release0, sustain0, MAX_ATTENUATION); - - voices[i].envH1.set(attack1, MAX_ATTENUATION, 0); - voices[i].envH2.set(decay1, MAX_ATTENUATION, sustain1); - voices[i].envH3.set(release1, sustain1, MAX_ATTENUATION); - - voices[i].harm0_accum = 0; - voices[i].harm1_accum = 0; - voices[i].harm2_accum = 0; - voices[i].harm3_accum = 0; - voices[i].harm4_accum = 0; - voices[i].harm5_accum = 0; - return false; - } - printf("organ: voices overflow!\n"); - return false; - } - -//--------------------------------------------------------- -// noteoff -//--------------------------------------------------------- - -void Organ::noteoff(int channel, int pitch) - { - bool found = false; - for (int i = 0; i < VOICES; ++i) { - if (voices[i].isOn && (voices[i].pitch == pitch) - && (voices[i].channel == channel)) { - found = true; - voices[i].state1 = RELEASE; - voices[i].state2 = RELEASE; - } - } - if (!found) - printf("Organ: noteoff %d:%d not found\n", channel, pitch); - } - -//--------------------------------------------------------- -// setController -//--------------------------------------------------------- - -void Organ::setController(int ctrl, int data) - { - int sr = sampleRate(); - - // Changed By T356. - // Because of muse's auto-bias controllers, some of these negative-range - // controls need to apply the auto-bias correction. - - switch (ctrl) { - case HARM0: - //harm0 = cb2amp(-data); - harm0 = cb2amp(-data + 8192); - break; - case HARM1: - //harm1 = cb2amp(-data); - harm1 = cb2amp(-data + 8192); - break; - case HARM2: - //harm2 = cb2amp(-data); - harm2 = cb2amp(-data + 8192); - break; - case HARM3: - //harm3 = cb2amp(-data); - harm3 = cb2amp(-data + 8192); - break; - case HARM4: - //harm4 = cb2amp(-data); - harm4 = cb2amp(-data + 8192); - break; - case HARM5: - //harm5 = cb2amp(-data); - harm5 = cb2amp(-data + 8192); - break; - case ATTACK_LO: // maxval -> 500msec - attack0 = (data * sr) / 1000; - break; - case DECAY_LO: // maxval -> 5000msec - decay0 = (data * sr) / 1000; - break; - case SUSTAIN_LO: - //sustain0 = -data; - sustain0 = -data + 8192; - break; - case RELEASE_LO: - release0 = (data * sr) / 1000; - break; - case ATTACK_HI: - attack1 = (data * sr) / 1000; - break; - case DECAY_HI: - decay1 = (data * sr) / 1000; - break; - case SUSTAIN_HI: - //sustain1 = -data; - sustain1 = -data + 8192; - break; - case RELEASE_HI: - release1 = (data * sr) / 1000; - break; - case BRASS: - brass = data; - break; - case FLUTE: - flute = data; - break; - case REED: - reed = data; - break; - case VELO: - velo = data; - break; - case CTRL_VOLUME: - data &= 0x7f; - volume = data == 0 ? 0.0 : cb2amp(int(200 * log10((127.0 * 127)/(data*data)))); - break; - case CTRL_ALL_SOUNDS_OFF: - for (int i = 0; i < VOICES; ++i) - voices[i].isOn = false; - 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", ctrl, data); - return; - } - for (int i = 0; i < NUM_CONTROLLER; ++i) { - if (synthCtrl[i].num == ctrl) { - synthCtrl[i].val = data; - break; - } - } - } - -//--------------------------------------------------------- -// setController -//--------------------------------------------------------- - -bool Organ::setController(int channel, int ctrl, int data) - { - setController(ctrl, data); - - switch (ctrl) { - case HARM0: - case HARM1: - case HARM2: - case HARM3: - case HARM4: - case HARM5: - case ATTACK_LO: - case DECAY_LO: - case SUSTAIN_LO: - case RELEASE_LO: - case ATTACK_HI: - case DECAY_HI: - case SUSTAIN_HI: - case RELEASE_HI: - case BRASS: - case FLUTE: - case REED: - case VELO: - { - MidiPlayEvent ev(0, 0, channel, ME_CONTROLLER, ctrl, data); - #ifdef ORGAN_DEBUG - fprintf(stderr, "OrganGui:setController before gui->writeEvent ctrl:%d data:%d\n", ctrl, data); - #endif - - gui->writeEvent(ev); - } - break; - default: - break; - } - return false; - } - -//--------------------------------------------------------- -// sysex -//--------------------------------------------------------- - -bool Organ::sysex(int n, const unsigned char* data) - { - #ifdef ORGAN_DEBUG - printf("Organ: sysex\n"); - #endif - if (unsigned(n) != (NUM_INIT_CONTROLLER * sizeof(int))) { - printf("Organ: unknown sysex\n"); - return false; - } - int* s = (int*) data; - for (int i = 0; i < NUM_INIT_CONTROLLER; ++i) { - int val = *s++; - #ifdef ORGAN_DEBUG - printf("Organ: sysex before setController num:%d val:%d\n", synthCtrl[i].num, val); - #endif - setController(0, synthCtrl[i].num, val); - } - return false; - } - -//--------------------------------------------------------- -// getInitData -//--------------------------------------------------------- - -void Organ::getInitData(int* n, const unsigned char**p) const - { - int* d = idata; - for (int i = 0; i < NUM_INIT_CONTROLLER; ++i) - *d++ = synthCtrl[i].val; - *n = NUM_INIT_CONTROLLER * sizeof(int); // sizeof(idata); - *p = (unsigned char*)idata; - } - -//--------------------------------------------------------- -// MESS -//--------------------------------------------------------- - -//--------------------------------------------------------- -// getControllerInfo -//--------------------------------------------------------- - -int Organ::getControllerInfo(int id, const char** name, int* controller, - int* min, int* max, int* initval) const - { - if (id >= NUM_CONTROLLER) - return 0; - *controller = synthCtrl[id].num; - *name = synthCtrl[id].name; - *initval = synthCtrl[id].val; - - if(synthCtrl[id].num == CTRL_VOLUME) - { - *min = 0; - *max = 127; - } - else - gui->getControllerMinMax(id,min,max); - - //*min = 0; - //*max = 128*128-1; - return ++id; - } - -//--------------------------------------------------------- -// guiVisible -//--------------------------------------------------------- - -bool Organ::guiVisible() const - { - return gui->isVisible(); - } - -//--------------------------------------------------------- -// showGui -//--------------------------------------------------------- - -void Organ::showGui(bool val) - { - gui->setVisible(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, QWidget*, QString* /*projectPathPtr*/, 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, - }; - // We must compile with -fvisibility=hidden to avoid namespace - // conflicts with global variables. - // Only visible symbol is "mess_descriptor". - // (TODO: all plugins should be compiled this way) - - __attribute__ ((visibility("default"))) - const MESS* mess_descriptor() { return &descriptor; } - } - |