From b703eab295330e6f81564fbb39a10a1a2fdd2f54 Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Sun, 27 Dec 2009 11:30:35 +0000 Subject: moved old qt4 branch --- muse_qt4_evolution/synti/organ/CMakeLists.txt | 50 + muse_qt4_evolution/synti/organ/organ.cpp | 621 ++++++++++++ muse_qt4_evolution/synti/organ/organ.h | 151 +++ muse_qt4_evolution/synti/organ/organgui.cpp | 184 ++++ muse_qt4_evolution/synti/organ/organgui.h | 48 + muse_qt4_evolution/synti/organ/organgui.ui | 791 +++++++++++++++ muse_qt4_evolution/synti/organ/reverb.cpp | 163 +++ muse_qt4_evolution/synti/organ/reverb.h | 204 ++++ muse_qt4_evolution/synti/organ/routing.cpp | 1343 +++++++++++++++++++++++++ 9 files changed, 3555 insertions(+) create mode 100644 muse_qt4_evolution/synti/organ/CMakeLists.txt create mode 100644 muse_qt4_evolution/synti/organ/organ.cpp create mode 100644 muse_qt4_evolution/synti/organ/organ.h create mode 100644 muse_qt4_evolution/synti/organ/organgui.cpp create mode 100644 muse_qt4_evolution/synti/organ/organgui.h create mode 100644 muse_qt4_evolution/synti/organ/organgui.ui create mode 100644 muse_qt4_evolution/synti/organ/reverb.cpp create mode 100644 muse_qt4_evolution/synti/organ/reverb.h create mode 100644 muse_qt4_evolution/synti/organ/routing.cpp (limited to 'muse_qt4_evolution/synti/organ') diff --git a/muse_qt4_evolution/synti/organ/CMakeLists.txt b/muse_qt4_evolution/synti/organ/CMakeLists.txt new file mode 100644 index 00000000..01540c88 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/CMakeLists.txt @@ -0,0 +1,50 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +QT4_WRAP_CPP ( organ_mocs organgui.h ) +QT4_WRAP_UI ( organ_uis organgui.ui ) + +add_library ( organ SHARED + organ.cpp + organgui.cpp + reverb.cpp + routing.cpp + organgui.h + ${organ_mocs} + ${organ_uis} + ) + +# - tell cmake to name target organ.so instead of +# liborgan.so +# - use precompiled header files +# +set_target_properties ( organ + PROPERTIES PREFIX "" + COMPILE_FLAGS "-O2 -include ${PROJECT_BINARY_DIR}/all-pic.h" + ) + +target_link_libraries(organ + synti + awl + ${QT_LIBRARIES} + ) + +install_targets ( /${CMAKE_INSTALL_LIBDIR}/${MusE_INSTALL_NAME}/synthi/ organ ) + diff --git a/muse_qt4_evolution/synti/organ/organ.cpp b/muse_qt4_evolution/synti/organ/organ.cpp new file mode 100644 index 00000000..7c83a463 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/organ.cpp @@ -0,0 +1,621 @@ +//========================================================= +// 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; } + } + diff --git a/muse_qt4_evolution/synti/organ/organ.h b/muse_qt4_evolution/synti/organ/organ.h new file mode 100644 index 00000000..971e6cc9 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/organ.h @@ -0,0 +1,151 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: organ.h,v 1.5 2004/04/15 13:46:18 wschweer Exp $ +// +// Parts of this file taken from: +// Organ - Additive Organ Synthesizer Voice +// Copyright (c) 1999, 2000 David A. Bartold +// +// (C) Copyright 2001-2007 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __ORGAN_H__ +#define __ORGAN_H__ + +#include "muse/midictrl.h" +#include "libsynti/mess2.h" + +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; +static const int NO_WHEELS = 91; +static const int NO_ELEMENTS = 194; + +enum { + DRAWBAR0 = CTRL_RPN14_OFFSET, DRAWBAR1, DRAWBAR2, + DRAWBAR3, DRAWBAR4, DRAWBAR5, DRAWBAR6, DRAWBAR7, DRAWBAR8, + REVERB_ON, REVERB_ROOM_SIZE, REVERB_MIX, + VIBRATO_ON, VIBRATO_FREQ, VIBRATO_DEPTH, + PERC_ON, PERC_GAIN, PERC_DECAY, PERC_HARMONY, + ROTARY_ON, ROT1_FREQ, ROT1_DEPTH, ROT2_FREQ, ROT2_DEPTH + }; + +//--------------------------------------------------------- +// Wheel +//--------------------------------------------------------- + +struct Wheel { + unsigned frameStep; + unsigned accu; + + int refCount; + bool active; + float gain[NO_BUSES]; + + // envelopes: + float* env[NO_BUSES]; + int envCount[NO_BUSES]; + float deltaGain[NO_BUSES]; + }; + +//--------------------------------------------------------- +// Elem +//--------------------------------------------------------- + +struct Elem { + char wheel; + char bus; + float level; + + Elem() { bus = -1; } + Elem(char w, char b, float l) : wheel(w), bus(b), level(l) {} + }; + +//--------------------------------------------------------- +// Organ +//--------------------------------------------------------- + +class Organ : public Mess2 { + static int useCount; + + static float* waveTable; + static double cb2amp_tab[MAX_ATTENUATION]; + static double cb2amp(int cb); + static Elem routing[NO_KEYS][NO_ELEMENTS]; + static float* attackEnv; + static float* releaseEnv; + static int envSize; + static float keyCompression[NO_VOICES]; + + OrganGui* gui; + Reverb* reverb; + bool reverbOn; + double volume; + + unsigned vibratoStep; + unsigned vibratoAccu; + + bool vibratoOn; + double vibratoFreq; + double vibratoDepth; + + // key compression + float keyCompressionDelta; + float keyCompressionValue; + int keyCompressionCount; + + // percussion + int percussionBus; // usually drawbar 3 or drawbar 4 + bool percussionOn; + double percDecay; + 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]; + QList pressedKeys; + QList activeWheels; + + 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); + virtual bool setController(int channel, int ctrl, int val); + virtual bool sysex(int, const unsigned char*); + + virtual bool guiVisible() const; + virtual void showGui(bool); + virtual bool hasGui() const { return true; } + virtual void getGeometry(int* x, int* y, int* w, int* h) const; + virtual void setGeometry(int x, int y, int w, int h); + + public: + friend class OrganGui; + Organ(int sampleRate); + ~Organ(); + bool init(const char* name); + }; + +#endif + diff --git a/muse_qt4_evolution/synti/organ/organgui.cpp b/muse_qt4_evolution/synti/organ/organgui.cpp new file mode 100644 index 00000000..c00d23fb --- /dev/null +++ b/muse_qt4_evolution/synti/organ/organgui.cpp @@ -0,0 +1,184 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: organgui.cpp,v 1.21 2005/12/16 15:36:51 wschweer Exp $ +// +// This is a simple GUI implemented with QT for +// organ software synthesizer. +// +// (C) Copyright 2001-2007 Werner Schweer (ws@seh.de) +//========================================================= + +#include "organgui.h" +#include "muse/midi.h" +#include "muse/midictrl.h" +#include "awl/knob.h" + +//--------------------------------------------------------- +// OrganGui +//--------------------------------------------------------- + +OrganGui::OrganGui() + : QWidget(0), + MessGui() + { + setupUi(this); + QSocketNotifier* s = new QSocketNotifier(readFd, QSocketNotifier::Read); + connect(s, SIGNAL(activated(int)), SLOT(readMessage(int))); + + map = new QSignalMapper(this); + QList wl = findChildren(); + foreach(QWidget* w, wl) { + int idx = Mess2::controllerIdx(w->objectName().toAscii().data()); + if (idx == -1) + continue; + w->setProperty("ctrlIdx", idx); + map->setMapping(w, w); + const char* cname = w->metaObject()->className(); + if (strcmp(cname, "QSlider") == 0) { + QSlider* slider = (QSlider*)w; + w->setProperty("ctrlType", 0); + connect(slider, SIGNAL(valueChanged(int)), map, SLOT(map())); + } + else if (strcmp(cname, "QCheckBox") == 0) { + w->setProperty("ctrlType", 1); + connect(w, SIGNAL(toggled(bool)), map, SLOT(map())); + } + else if (strcmp(cname, "QGroupBox") == 0) { + w->setProperty("ctrlType", 2); + connect(w, SIGNAL(toggled(bool)), map, SLOT(map())); + } + else if (strcmp(cname, "Awl::Knob") == 0) { + w->setProperty("ctrlType", 3); + connect(w, SIGNAL(valueChanged(double,int)), map, SLOT(map())); + } + else if (strcmp(cname, "QPushButton") == 0) { + w->setProperty("ctrlType", 4); + connect(w, SIGNAL(toggled(bool)), map, SLOT(map())); + } + else if (strcmp(cname, "Awl::Drawbar") == 0) { + Awl::Drawbar* drawbar = (Awl::Drawbar*)w; + w->setProperty("ctrlType", 5); + connect(drawbar, SIGNAL(valueChanged(double,int)), map, SLOT(map())); + } + else + printf("Gui Element <%s> not supported\n", cname); + } + ignoreControllerChange = false; + connect(map, SIGNAL(mapped(QWidget*)), this, SLOT(ctrlChanged(QWidget*))); + } + +//--------------------------------------------------------- +// ctrlChanged +//--------------------------------------------------------- + +void OrganGui::ctrlChanged(QWidget* w) + { + if (ignoreControllerChange) + return; + int ctrlIdx = w->property("ctrlIdx").toInt(); + int ctrlType = w->property("ctrlType").toInt(); + int value = 0; + + switch(ctrlType) { + case 0: // QSlider + value = ((QSlider*)w)->value(); + break; + case 1: + value = ((QCheckBox*)w)->isChecked(); + break; + case 2: + value = ((QGroupBox*)w)->isChecked(); + break; + case 3: + value = lrint(((Awl::Knob*)w)->value()); + break; + case 4: + value = ((QPushButton*)w)->isChecked(); + break; + case 5: + value = lrint(((Awl::Drawbar*)w)->value()); + break; + default: + printf("OrganGui::ctrlChanged: illegal ctrlType %d\n", ctrlType); + break; + } + int id = Mess2::controllerId(ctrlIdx); + sendController(0, id, value); // to synth + } + +//--------------------------------------------------------- +// setParam +//--------------------------------------------------------- + +void OrganGui::setParam(int ctrlId, int val) + { + int ctrlIdx = Mess2::controllerIdx(ctrlId); + if (ctrlIdx == -1) + return; + setParamIdx(ctrlIdx, val); + } + +//--------------------------------------------------------- +// setParamIdx +// set controller value in gui +//--------------------------------------------------------- + +void OrganGui::setParamIdx(int ctrlIdx, int val) + { + const char* name = Organ::controllerName(ctrlIdx); + if (name == 0) + return; + ignoreControllerChange = true; + QList wl = findChildren(name); + + foreach(QWidget* w, wl) { + int ctrlType = w->property("ctrlType").toInt(); + switch(ctrlType) { + case 0: + ((QSlider*)w)->setValue(val); + break; + case 1: + ((QCheckBox*)w)->setChecked(val); + break; + case 2: + ((QGroupBox*)w)->setChecked(val); + break; + case 3: + ((Awl::Knob*)w)->setValue(double(val)); + break; + case 4: + ((QPushButton*)w)->setChecked(val); + break; + case 5: + ((Awl::Drawbar*)w)->setValue(double(val)); + break; + default: + printf("OrganGui::setParamIdx: illegal ctrlType %d\n", ctrlType); + break; + } + } + ignoreControllerChange = false; + } + +//--------------------------------------------------------- +// processEvent +//--------------------------------------------------------- + +void OrganGui::processEvent(const MidiEvent& ev) + { + if (ev.type() == ME_CONTROLLER) + setParam(ev.dataA(), ev.dataB()); + else + printf("OrganGui::illegal event type received\n"); + } + +//--------------------------------------------------------- +// readMessage +//--------------------------------------------------------- + +void OrganGui::readMessage(int) + { + MessGui::readMessage(); + } + diff --git a/muse_qt4_evolution/synti/organ/organgui.h b/muse_qt4_evolution/synti/organ/organgui.h new file mode 100644 index 00000000..c691b1a1 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/organgui.h @@ -0,0 +1,48 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: organgui.h,v 1.8 2005/10/04 21:37:44 lunar_shuttle Exp $ +// +// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __ORGANGUI_H__ +#define __ORGANGUI_H__ + +#include "ui_organgui.h" +#include "organ.h" +#include "libsynti/gui.h" +#include "libsynti/midievent.h" + +class QSignalMapper; + +#define NUM_GUI_CONTROLLER 18 + +//--------------------------------------------------------- +// OrganGui +//--------------------------------------------------------- + +class OrganGui : public QWidget, public Ui::OrganGuiBase, public MessGui { + Q_OBJECT + + bool ignoreControllerChange; + + QSignalMapper* map; + virtual void processEvent(const MidiEvent&); + + protected: + void setParam(int, int); + void setParamIdx(int ctrlIdx, int val); + + private slots: + void ctrlChanged(QWidget*); + void readMessage(int); + + public: + friend class Organ; + friend class Mess2; + OrganGui(); + }; + +#endif + diff --git a/muse_qt4_evolution/synti/organ/organgui.ui b/muse_qt4_evolution/synti/organ/organgui.ui new file mode 100644 index 00000000..297042c7 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/organgui.ui @@ -0,0 +1,791 @@ + + OrganGuiBase + + + + 0 + 0 + 611 + 342 + + + + + 0 + 0 + + + + MusE: Organ + + + QWidget { +background-color: rgb(93,106,121); +color: rgb(240, 240, 240); +} +QLabel#name { +font-size: 64px; +font-weight: bold; +} +Awl--Drawbar { +font-size: 10px; +} +Awl--Knob { +font-size: 10px; +} + +QGroupBox::indicator:checked { +background-color: yellow; +} +QGroupBox::indicator:unchecked { +background-color: gray; +} +QCheckBox::indicator:checked:disabled { +background-color: darkGray; +} +QCheckBox::indicator:unchecked:disabled { +background-color: gray; +} +QCheckBox::indicator:checked:enabled { +background-color: yellow; +} +QCheckBox::indicator:unchecked:enabled { +background-color: gray; +} + + + + + + + + + + 0 + 0 + + + + + -1 + 75 + true + + + + O-1 + + + Qt::AlignCenter + + + + + + + Percussion + + + 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 + + + + 5 + + + + 255 + 255 + 0 + + + + 8.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + Gain + + + Qt::AlignCenter + + + + + + + Decay + + + Qt::AlignCenter + + + + + + + Harmony + + + Qt::AlignCenter + + + + + + + + + + Reverb + + + true + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + 0 + 0 + + + + Room + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Mix + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 5 + + + + 255 + 255 + 0 + + + + 127.000000000000000 + + + 8.000000000000000 + + + 20.000000000000000 + + + + + + + + + + Vibrato + + + 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 + + + + Freq + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Depth + + + Qt::AlignCenter + + + + + + + + + + + + + + + 0 + 0 + + + + UPPER MANUAL + + + + + + 4.000000000000000 + + + + 60 + 60 + 60 + + + + + + + + 5.000000000000000 + + + + 60 + 60 + 60 + + + + + + + + + 0 + 150 + + + + 8.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 8.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 8.000000000000000 + + + + 128 + 102 + 86 + + + + + + + + 0.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + 5.000000000000000 + + + + 128 + 102 + 86 + + + + + + + + 2.000000000000000 + + + + 128 + 102 + 86 + + + + + + + + 0.000000000000000 + + + + 240 + 240 + 240 + + + + + + + + + + + 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 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Awl::Knob + QWidget +
awl/knob.h
+
+ + Awl::Drawbar + Awl::Slider +
awl/drawbar.h
+
+
+ + +
diff --git a/muse_qt4_evolution/synti/organ/reverb.cpp b/muse_qt4_evolution/synti/organ/reverb.cpp new file mode 100644 index 00000000..72775bc5 --- /dev/null +++ b/muse_qt4_evolution/synti/organ/reverb.cpp @@ -0,0 +1,163 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// based on "freeverb" written by Jezar at Dreampoint, +// June 2000 +// +// (C) Copyright 2007 Werner Schweer (ws@seh.de) +//========================================================= + +#include "reverb.h" + +//--------------------------------------------------------- +// Reverb +//--------------------------------------------------------- + +Reverb::Reverb() + { + // Tie the components to their buffers + combL[0].setbuffer(bufcombL1,combtuningL1); + combR[0].setbuffer(bufcombR1,combtuningR1); + combL[1].setbuffer(bufcombL2,combtuningL2); + combR[1].setbuffer(bufcombR2,combtuningR2); + combL[2].setbuffer(bufcombL3,combtuningL3); + combR[2].setbuffer(bufcombR3,combtuningR3); + combL[3].setbuffer(bufcombL4,combtuningL4); + combR[3].setbuffer(bufcombR4,combtuningR4); + combL[4].setbuffer(bufcombL5,combtuningL5); + combR[4].setbuffer(bufcombR5,combtuningR5); + combL[5].setbuffer(bufcombL6,combtuningL6); + combR[5].setbuffer(bufcombR6,combtuningR6); + combL[6].setbuffer(bufcombL7,combtuningL7); + combR[6].setbuffer(bufcombR7,combtuningR7); + combL[7].setbuffer(bufcombL8,combtuningL8); + combR[7].setbuffer(bufcombR8,combtuningR8); + allpassL[0].setbuffer(bufallpassL1,allpasstuningL1); + allpassR[0].setbuffer(bufallpassR1,allpasstuningR1); + allpassL[1].setbuffer(bufallpassL2,allpasstuningL2); + allpassR[1].setbuffer(bufallpassR2,allpasstuningR2); + allpassL[2].setbuffer(bufallpassL3,allpasstuningL3); + allpassR[2].setbuffer(bufallpassR3,allpasstuningR3); + allpassL[3].setbuffer(bufallpassL4,allpasstuningL4); + allpassR[3].setbuffer(bufallpassR4,allpasstuningR4); + + // Set default values + allpassL[0].setfeedback(0.5f); + allpassR[0].setfeedback(0.5f); + allpassL[1].setfeedback(0.5f); + allpassR[1].setfeedback(0.5f); + allpassL[2].setfeedback(0.5f); + allpassR[2].setfeedback(0.5f); + allpassL[3].setfeedback(0.5f); + allpassR[3].setfeedback(0.5f); + + setRoomSize(.5); + setMix(.5); + setdamp(.5); + setwidth(initialwidth); + + // Buffer will be full of rubbish - so we MUST mute them + + for (int i = 0; i < numcombs; i++) { + combL[i].mute(); + combR[i].mute(); + } + for (int i=0;i= bufsize) + bufidx = 0; + return output; + } + void mute() { + memset(buffer, 0, sizeof(float) * bufsize); + } + void setfeedback(float val) { feedback = val; } + float getfeedback() { return feedback; } + }; + +//--------------------------------------------------------- +// comb +//--------------------------------------------------------- + +class comb + { + float feedback; + float filterstore; + float damp1; + float damp2; + float *buffer; + int bufsize; + int bufidx; + + public: + comb() { + filterstore = 0; + bufidx = 0; + } + void setbuffer(float *buf, int size) { + buffer = buf; + bufsize = size; + } + float process(float input) { + float output = buffer[bufidx]; + undenormalise(output); + filterstore = (output*damp2) + (filterstore*damp1); + undenormalise(filterstore); + buffer[bufidx] = input + (filterstore*feedback); + if (++bufidx >= bufsize) + bufidx = 0; + return output; + } + void mute() { + for (int i=0; i