diff --git a/MicroDexed.ino b/MicroDexed.ino index 041b7a6..1a016a6 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -11,6 +11,8 @@ #define AUDIO_BUFFER_SIZE 128 #define SAMPLEAUDIO_BUFFER_SIZE 44100 +#define MIDI_QUEUE_LOCK_TIMEOUT_MS 5 + #define TEST_MIDI 1 #define TEST_NOTE1 60 #define TEST_NOTE2 68 @@ -77,8 +79,13 @@ void setup() dexed->activate(); #ifdef TEST_MIDI - dexed->ProcessMidiMessage(0x90, TEST_NOTE1, 100); - dexed->ProcessMidiMessage(0x90, TEST_NOTE2, 60); + midi_queue_t m; + m.cmd = 0x90; + m.data1 = TEST_NOTE1; + m.data2 = 100; + midi_queue.enqueue(m); + m.data1 = TEST_NOTE2; + midi_queue.enqueue(m); #endif threads.addThread(audio_thread, 1); @@ -103,9 +110,11 @@ void loop() m.data1 = MIDI.getData1(); m.data2 = MIDI.getData2(); - while (!midi_queue_lock.try_lock()); - midi_queue.enqueue(m); - midi_queue_lock.unlock(); + if (midi_queue_lock.lock(MIDI_QUEUE_LOCK_TIMEOUT_MS)) + { + midi_queue.enqueue(m); + midi_queue_lock.unlock(); + } } } @@ -120,15 +129,19 @@ void audio_thread(void) audio_buffer = queue1.getBuffer(); if (audio_buffer == NULL) { - Serial.println("audio_buffer allocation problems!"); - return; + Serial.println(F("audio_buffer allocation problems!")); + continue; } - while (!midi_queue.isEmpty ()) + while (!midi_queue.isEmpty()) { - while (!midi_queue_lock.try_lock()); - midi_queue_t m = midi_queue.dequeue(); - dexed->ProcessMidiMessage(m.cmd, m.data1, m.data2); - midi_queue_lock.unlock(); + if (midi_queue_lock.lock(MIDI_QUEUE_LOCK_TIMEOUT_MS)) + { + midi_queue_t m = midi_queue.dequeue(); + dexed->ProcessMidiMessage(m.cmd, m.data1, m.data2); + midi_queue_lock.unlock(); + } + else + break; } dexed->GetSamples(AUDIO_BUFFER_SIZE, audio_buffer); diff --git a/dexed.cpp.offline b/dexed.cpp.offline deleted file mode 100644 index 4c8ed65..0000000 --- a/dexed.cpp.offline +++ /dev/null @@ -1,938 +0,0 @@ -/** - * - * Copyright (c) 2016-2017 Holger Wirtz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include "dexed.h" -#include "dexed_ttl.h" -#include "EngineMkI.h" -#include "EngineOpl.h" -#include "msfa/fm_core.h" -#include "msfa/exp2.h" -#include "msfa/sin.h" -#include "msfa/freqlut.h" -#include "msfa/controllers.h" -#include "PluginFx.h" -#include -#include - -Dexed::Dexed(double rate) : lvtk::Synth(p_n_ports, p_midi_in) -{ - uint8_t i; - - TRACE("--------------------------------------------------------------------------------"); - TRACE("Hi"); - - Exp2::init(); - Tanh::init(); - Sin::init(); - - Freqlut::init(rate); - Lfo::init(rate); - PitchEnv::init(rate); - Env::init_sr(rate); - fx.init(rate); - - if(!(engineMkI=new EngineMkI)) - { - TRACE("Cannot not create engine EngineMkI"); - exit(400); - } - if(!(engineOpl=new EngineOpl)) - { - if(engineMkI) - delete(engineMkI); - TRACE("Cannot not create engine EngineOpl"); - exit(401); - } - if(!(engineMsfa=new FmCore)) - { - if(engineMkI) - delete(engineMkI); - if(engineOpl) - delete(engineOpl); - TRACE("Cannot create engine FmCore"); - exit(402); - } - - for(i=0; i(data[i]); - TRACE("%d->%f",i,data_float[i]); - } - - max_notes=16; - currentNote = 0; - controllers.values_[kControllerPitch] = 0x2000; - controllers.values_[kControllerPitchRange] = 0; - controllers.values_[kControllerPitchStep] = 0; - controllers.modwheel_cc = 0; - controllers.foot_cc = 0; - controllers.breath_cc = 0; - controllers.aftertouch_cc = 0; - controllers.masterTune=0; - controllers.opSwitch=0x3f; // enable all operators - //controllers.opSwitch=0x00; - - bufsize_=256; - - if(!(outbuf_=new float[bufsize_])) - { - TRACE("Cannot create outbuf_ buffer"); - exit(404); - } - - lfo.reset(data+137); - - - setMonoMode(false); - - sustain = false; - - extra_buf_size_ = 0; - - memset(&voiceStatus, 0, sizeof(VoiceStatus)); - - setEngineType(DEXED_ENGINE_MODERN); - - //add_voices(new DexedVoice(rate)); - - add_audio_outputs(p_audio_out); - - TRACE("Bye"); -} - -Dexed::~Dexed() -{ - TRACE("Hi"); - - if(outbuf_!=NULL) - delete [] outbuf_; - - currentNote = -1; - - for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; ++note) - { - if ( voices[note].dx7_note != NULL ) - { - delete voices[note].dx7_note; - voices[note].dx7_note = NULL; - } - voices[note].keydown = false; - voices[note].sustained = false; - voices[note].live = false; - } - - if(engineMsfa) - delete(engineMkI); - if(engineOpl) - delete(engineMkI); - if(engineMkI) - delete(engineMkI); - - TRACE("Bye"); - TRACE("--------------------------------------------------------------------------------"); -} - -void Dexed::activate(void) -{ - TRACE("Hi"); - - Plugin::activate(); - panic(); - controllers.values_[kControllerPitchRange] = data[155]; - controllers.values_[kControllerPitchStep] = data[156]; - - TRACE("Bye"); -} - -void Dexed::deactivate(void) -{ - TRACE("Hi"); - - Plugin::deactivate(); - - TRACE("Bye"); -} - -void Dexed::set_params(void) -{ - //TRACE("Hi"); - - _param_change_counter=0; - - bool polymono=bool(*p(p_polymono)); - uint8_t engine=uint8_t(*p(p_engine)); - float f_gain=*p(p_output); - float f_cutoff=*p(p_cutoff); - float f_reso=*p(p_resonance); - - // Dexed-Unisono - if(isMonoMode()!=polymono) - setMonoMode(polymono); - - // Dexed-Engine - if(controllers.core==NULL || getEngineType()!=engine) - { - setEngineType(engine); - refreshVoice=true; - } - - // Dexed-Filter - if(fx.uiCutoff!=f_cutoff) - { - fx.uiCutoff=f_cutoff; - refreshVoice=true; - } - if(fx.uiReso!=f_reso) - { - fx.uiReso=f_reso; - refreshVoice=true; - } - if(fx.uiGain!=f_gain) - { - fx.uiGain=f_gain; - refreshVoice=true; - } - - // OP6 - onParam(0,*p(p_op6_eg_rate_1)); - onParam(1,*p(p_op6_eg_rate_2)); - onParam(2,*p(p_op6_eg_rate_3)); - onParam(3,*p(p_op6_eg_rate_4)); - onParam(4,*p(p_op6_eg_level_1)); - onParam(5,*p(p_op6_eg_level_2)); - onParam(6,*p(p_op6_eg_level_3)); - onParam(7,*p(p_op6_eg_level_4)); - onParam(8,*p(p_op6_kbd_lev_scl_brk_pt)); - onParam(9,*p(p_op6_kbd_lev_scl_lft_depth)); - onParam(10,*p(p_op6_kbd_lev_scl_rht_depth)); - onParam(11,*p(p_op6_kbd_lev_scl_lft_curve)); - onParam(12,*p(p_op6_kbd_lev_scl_rht_curve)); - onParam(13,*p(p_op6_kbd_rate_scaling)); - onParam(14,*p(p_op6_amp_mod_sensitivity)); - onParam(15,*p(p_op6_key_vel_sensitivity)); - onParam(16,*p(p_op6_operator_output_level)); - onParam(17,*p(p_op6_osc_mode)); - onParam(18,*p(p_op6_osc_freq_coarse)); - onParam(19,*p(p_op6_osc_freq_fine)); - onParam(20,*p(p_op6_osc_detune)+7); - // OP5 - onParam(21,*p(p_op5_eg_rate_1)); - onParam(22,*p(p_op5_eg_rate_2)); - onParam(23,*p(p_op5_eg_rate_3)); - onParam(24,*p(p_op5_eg_rate_4)); - onParam(25,*p(p_op5_eg_level_1)); - onParam(26,*p(p_op5_eg_level_2)); - onParam(27,*p(p_op5_eg_level_3)); - onParam(28,*p(p_op5_eg_level_4)); - onParam(29,*p(p_op5_kbd_lev_scl_brk_pt)); - onParam(30,*p(p_op5_kbd_lev_scl_lft_depth)); - onParam(31,*p(p_op5_kbd_lev_scl_rht_depth)); - onParam(32,*p(p_op5_kbd_lev_scl_lft_curve)); - onParam(33,*p(p_op5_kbd_lev_scl_rht_curve)); - onParam(34,*p(p_op5_kbd_rate_scaling)); - onParam(35,*p(p_op5_amp_mod_sensitivity)); - onParam(36,*p(p_op5_key_vel_sensitivity)); - onParam(37,*p(p_op5_operator_output_level)); - onParam(38,*p(p_op5_osc_mode)); - onParam(39,*p(p_op5_osc_freq_coarse)); - onParam(40,*p(p_op5_osc_freq_fine)); - onParam(41,*p(p_op5_osc_detune)+7); - // OP4 - onParam(42,*p(p_op4_eg_rate_1)); - onParam(43,*p(p_op4_eg_rate_2)); - onParam(44,*p(p_op4_eg_rate_3)); - onParam(45,*p(p_op4_eg_rate_4)); - onParam(46,*p(p_op4_eg_level_1)); - onParam(47,*p(p_op4_eg_level_2)); - onParam(48,*p(p_op4_eg_level_3)); - onParam(49,*p(p_op4_eg_level_4)); - onParam(50,*p(p_op4_kbd_lev_scl_brk_pt)); - onParam(51,*p(p_op4_kbd_lev_scl_lft_depth)); - onParam(52,*p(p_op4_kbd_lev_scl_rht_depth)); - onParam(53,*p(p_op4_kbd_lev_scl_lft_curve)); - onParam(54,*p(p_op4_kbd_lev_scl_rht_curve)); - onParam(55,*p(p_op4_kbd_rate_scaling)); - onParam(56,*p(p_op4_amp_mod_sensitivity)); - onParam(57,*p(p_op4_key_vel_sensitivity)); - onParam(58,*p(p_op4_operator_output_level)); - onParam(59,*p(p_op4_osc_mode)); - onParam(60,*p(p_op4_osc_freq_coarse)); - onParam(61,*p(p_op4_osc_freq_fine)); - onParam(62,*p(p_op4_osc_detune)+7); - // OP3 - onParam(63,*p(p_op3_eg_rate_1)); - onParam(64,*p(p_op3_eg_rate_2)); - onParam(65,*p(p_op3_eg_rate_3)); - onParam(66,*p(p_op3_eg_rate_4)); - onParam(67,*p(p_op3_eg_level_1)); - onParam(68,*p(p_op3_eg_level_2)); - onParam(69,*p(p_op3_eg_level_3)); - onParam(70,*p(p_op3_eg_level_4)); - onParam(71,*p(p_op3_kbd_lev_scl_brk_pt)); - onParam(72,*p(p_op3_kbd_lev_scl_lft_depth)); - onParam(73,*p(p_op3_kbd_lev_scl_rht_depth)); - onParam(74,*p(p_op3_kbd_lev_scl_lft_curve)); - onParam(75,*p(p_op3_kbd_lev_scl_rht_curve)); - onParam(76,*p(p_op3_kbd_rate_scaling)); - onParam(77,*p(p_op3_amp_mod_sensitivity)); - onParam(78,*p(p_op3_key_vel_sensitivity)); - onParam(79,*p(p_op3_operator_output_level)); - onParam(80,*p(p_op3_osc_mode)); - onParam(81,*p(p_op3_osc_freq_coarse)); - onParam(82,*p(p_op3_osc_freq_fine)); - onParam(83,*p(p_op3_osc_detune)+7); - // OP2 - onParam(84,*p(p_op2_eg_rate_1)); - onParam(85,*p(p_op2_eg_rate_2)); - onParam(86,*p(p_op2_eg_rate_3)); - onParam(87,*p(p_op2_eg_rate_4)); - onParam(88,*p(p_op2_eg_level_1)); - onParam(89,*p(p_op2_eg_level_2)); - onParam(90,*p(p_op2_eg_level_3)); - onParam(91,*p(p_op2_eg_level_4)); - onParam(92,*p(p_op2_kbd_lev_scl_brk_pt)); - onParam(93,*p(p_op2_kbd_lev_scl_lft_depth)); - onParam(94,*p(p_op2_kbd_lev_scl_rht_depth)); - onParam(95,*p(p_op2_kbd_lev_scl_lft_curve)); - onParam(96,*p(p_op2_kbd_lev_scl_rht_curve)); - onParam(97,*p(p_op2_kbd_rate_scaling)); - onParam(98,*p(p_op2_amp_mod_sensitivity)); - onParam(99,*p(p_op2_key_vel_sensitivity)); - onParam(100,*p(p_op2_operator_output_level)); - onParam(101,*p(p_op2_osc_mode)); - onParam(102,*p(p_op2_osc_freq_coarse)); - onParam(103,*p(p_op2_osc_freq_fine)); - onParam(104,*p(p_op2_osc_detune)+7); - // OP1 - onParam(105,*p(p_op1_eg_rate_1)); - onParam(106,*p(p_op1_eg_rate_2)); - onParam(107,*p(p_op1_eg_rate_3)); - onParam(108,*p(p_op1_eg_rate_4)); - onParam(109,*p(p_op1_eg_level_1)); - onParam(110,*p(p_op1_eg_level_2)); - onParam(111,*p(p_op1_eg_level_3)); - onParam(112,*p(p_op1_eg_level_4)); - onParam(113,*p(p_op1_kbd_lev_scl_brk_pt)); - onParam(114,*p(p_op1_kbd_lev_scl_lft_depth)); - onParam(115,*p(p_op1_kbd_lev_scl_rht_depth)); - onParam(116,*p(p_op1_kbd_lev_scl_lft_curve)); - onParam(117,*p(p_op1_kbd_lev_scl_rht_curve)); - onParam(118,*p(p_op1_kbd_rate_scaling)); - onParam(119,*p(p_op1_amp_mod_sensitivity)); - onParam(120,*p(p_op1_key_vel_sensitivity)); - onParam(121,*p(p_op1_operator_output_level)); - onParam(122,*p(p_op1_osc_mode)); - onParam(123,*p(p_op1_osc_freq_coarse)); - onParam(124,*p(p_op1_osc_freq_fine)); - onParam(125,*p(p_op1_osc_detune)+7); - // Global for all OPs - onParam(126,*p(p_pitch_eg_rate_1)); - onParam(127,*p(p_pitch_eg_rate_2)); - onParam(128,*p(p_pitch_eg_rate_3)); - onParam(129,*p(p_pitch_eg_rate_4)); - onParam(130,*p(p_pitch_eg_level_1)); - onParam(131,*p(p_pitch_eg_level_2)); - onParam(132,*p(p_pitch_eg_level_3)); - onParam(133,*p(p_pitch_eg_level_4)); - onParam(134,*p(p_algorithm_num)-1); - onParam(135,*p(p_feedback)); - onParam(136,*p(p_oscillator_sync)); - onParam(137,*p(p_lfo_speed)); - onParam(138,*p(p_lfo_delay)); - onParam(139,*p(p_lfo_pitch_mod_depth)); - onParam(140,*p(p_lfo_amp_mod_depth)); - onParam(141,*p(p_lfo_sync)); - onParam(142,*p(p_lfo_waveform)); - onParam(143,*p(p_pitch_mod_sensitivity)); - onParam(144,*p(p_transpose)); - // 10 bytes (145-154) are the name of the patch - // Controllers (added at the end of the data[]) - onParam(155,*p(p_pitch_bend_range)); - onParam(156,*p(p_pitch_bend_step)); - onParam(157,*p(p_mod_wheel_range)); - onParam(158,*p(p_mod_wheel_assign)); - onParam(159,*p(p_foot_ctrl_range)); - onParam(160,*p(p_foot_ctrl_assign)); - onParam(161,*p(p_breath_ctrl_range)); - onParam(162,*p(p_breath_ctrl_assign)); - onParam(163,*p(p_aftertouch_range)); - onParam(164,*p(p_aftertouch_assign)); - onParam(165,*p(p_master_tune)); - onParam(166,*p(p_op1_enable)); - onParam(167,*p(p_op2_enable)); - onParam(168,*p(p_op3_enable)); - onParam(169,*p(p_op4_enable)); - onParam(170,*p(p_op5_enable)); - onParam(171,*p(p_op6_enable)); - onParam(172,*p(p_number_of_voices)); - - if(_param_change_counter>PARAM_CHANGE_LEVEL) - { - panic(); - controllers.refresh(); - } - - //TRACE("Bye"); -} - -// override the run() method -void Dexed::run (uint32_t sample_count) -{ - const LV2_Atom_Sequence* seq = p (p_midi_in); - float* output = p(p_audio_out); - uint32_t last_frame = 0, num_this_time = 0; - bool drop_next_events=false; - - Plugin::run(sample_count); - - if(++_k_rate_counter%16) - set_params(); // pre_process: copy actual voice params - - for (LV2_Atom_Event* ev = lv2_atom_sequence_begin (&seq->body); - !lv2_atom_sequence_is_end(&seq->body, seq->atom.size, ev); - ev = lv2_atom_sequence_next (ev)) - { - num_this_time = ev->time.frames - last_frame; - - // If it's midi, send it to the engine - if (ev->body.type == m_midi_type) - { - drop_next_events|=ProcessMidiMessage((uint8_t*) LV2_ATOM_BODY (&ev->body),ev->body.size); - if(drop_next_events==true) - continue; - } - - // render audio from the last frame until the timestamp of this event - GetSamples (num_this_time, outbuf_); - - // i is the index of the engine's buf, which always starts at 0 (i think) - // j is the index of the plugin's float output buffer which will be the timestamp - // of the last processed atom event. - for (uint32_t i = 0, j = last_frame; i < num_this_time; ++i, ++j) - output[j]=outbuf_[i]; - - last_frame = ev->time.frames; - } - - // render remaining samples if any left - if (last_frame < sample_count) - { - // do the same thing as above except from last frame until the end of - // the processing cycles last sample. at this point, all events have - // already been handled. - - num_this_time = sample_count - last_frame; - GetSamples (num_this_time, outbuf_); - for (uint32_t i = 0, j = last_frame; i < num_this_time; ++i, ++j) - output[j] = outbuf_[i]; - } - - fx.process(output, sample_count); -} - -void Dexed::GetSamples(uint32_t n_samples, float* buffer) -{ - uint32_t i; - - if(refreshVoice) { - for(i=0;i < max_notes;i++) { - if ( voices[i].live ) - voices[i].dx7_note->update(data, voices[i].midi_note, voices[i].velocity); - } - lfo.reset(data+137); - refreshVoice = false; - } - - // flush first events - for (i=0; i < n_samples && i < extra_buf_size_; i++) { - buffer[i] = extra_buf_[i]; - } - - // remaining buffer is still to be processed - if (extra_buf_size_ > n_samples) { - for (uint32_t j = 0; j < extra_buf_size_ - n_samples; j++) { - extra_buf_[j] = extra_buf_[j + n_samples]; - } - extra_buf_size_ -= n_samples; - } - else - { - for (; i < n_samples; i += N) { - AlignedBuf audiobuf; - float sumbuf[N]; - - for (uint32_t j = 0; j < N; ++j) { - audiobuf.get()[j] = 0; - sumbuf[j] = 0.0; - } - - int32_t lfovalue = lfo.getsample(); - int32_t lfodelay = lfo.getdelay(); - - for (uint8_t note = 0; note < max_notes; ++note) { - if (voices[note].live) { - voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); - for (uint32_t j=0; j < N; ++j) { - int32_t val = audiobuf.get()[j]; - val = val >> 4; - int32_t clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9; - float f = static_cast(clip_val>>1)/0x8000; - if(f>1) f=1; - if(f<-1) f=-1; - sumbuf[j]+=f; - audiobuf.get()[j]=0; - } - } - } - - uint32_t jmax = n_samples - i; - for (uint32_t j = 0; j < N; ++j) { - if (j < jmax) - buffer[i + j] = sumbuf[j]; - else - extra_buf_[j - jmax] = sumbuf[j]; - } - } - extra_buf_size_ = i - n_samples; - } - - if(++_k_rate_counter%32 && !monoMode) - { - uint8_t op_carrier=controllers.core->get_carrier_operators(data[134]); // look for carriers - - for(i=0;i < max_notes;i++) - { - if(voices[i].live==true) - { - uint8_t op_amp=0; - uint8_t op_carrier_num=0; - - voices[i].dx7_note->peekVoiceStatus(voiceStatus); - - for(uint8_t op=0;op<6;op++) - { - uint8_t op_bit=static_cast(pow(2,op)); - - if((op_carrier&op_bit)>0) - { - // this voice is a carrier! - op_carrier_num++; - - //TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep); - - if(voiceStatus.amp[op]<=1069 && voiceStatus.ampStep[op]==4) // this voice produces no audio output - op_amp++; - } - } - if(op_amp==op_carrier_num) - { - // all carrier-operators are silent -> disable the voice - voices[i].live=false; - voices[i].sustained=false; - voices[i].keydown=false; - TRACE("Shutted down Voice[%2d]",i); - } - } -// TRACE("Voice[%2d] live=%d keydown=%d",i,voices[i].live,voices[i].keydown); - } - } -} - -bool Dexed::ProcessMidiMessage(const uint8_t *buf, uint32_t buf_size) { - TRACE("Hi"); - - uint8_t cmd = buf[0]; - - switch(cmd & 0xf0) { - case 0x80 : - TRACE("MIDI keyup event: %d",buf[1]); - keyup(buf[1]); - return(false); - break; - case 0x90 : - TRACE("MIDI keydown event: %d %d",buf[1],buf[2]); - keydown(buf[1], buf[2]); - return(false); - break; - case 0xb0 : { - uint8_t ctrl = buf[1]; - uint8_t value = buf[2]; - - switch(ctrl) { - case 1: - TRACE("MIDI modwheel event: %d %d",ctrl,value); - controllers.modwheel_cc = value; - controllers.refresh(); - break; - case 2: - TRACE("MIDI breath event: %d %d",ctrl,value); - controllers.breath_cc = value; - controllers.refresh(); - break; - case 4: - TRACE("MIDI footsw event: %d %d",ctrl,value); - controllers.foot_cc = value; - controllers.refresh(); - break; - case 64: - TRACE("MIDI sustain event: %d %d",ctrl,value); - sustain = value > 63; - if (!sustain) { - for (uint8_t note = 0; note < max_notes; note++) { - if (voices[note].sustained && !voices[note].keydown) { - voices[note].dx7_note->keyup(); - voices[note].sustained = false; - } - } - } - break; - case 120: - TRACE("MIDI all-sound-off: %d %d",ctrl,value); - panic(); - return(true); - break; - case 123: - TRACE("MIDI all-notes-off: %d %d",ctrl,value); - notes_off(); - return(true); - break; - } - break; - } - -// case 0xc0 : -// setCurrentProgram(buf[1]); -// break; - - // channel aftertouch - case 0xd0 : - TRACE("MIDI aftertouch 0xd0 event: %d %d",buf[1]); - controllers.aftertouch_cc = buf[1]; - controllers.refresh(); - break; - // pitchbend - case 0xe0 : - TRACE("MIDI pitchbend 0xe0 event: %d %d",buf[1],buf[2]); - controllers.values_[kControllerPitch] = buf[1] | (buf[2] << 7); - break; - - default: - TRACE("MIDI event unknown: cmd=%d, val1=%d, val2=%d",buf[0],buf[1],buf[2]); - break; - } - - TRACE("Bye"); - return(false); -} - -void Dexed::keydown(uint8_t pitch, uint8_t velo) { -TRACE("Hi"); -TRACE("pitch=%d, velo=%d\n",pitch,velo); - if ( velo == 0 ) { - keyup(pitch); - return; - } - - pitch += data[144] - 24; - - uint8_t note = currentNote; - uint8_t keydown_counter=0; - - for (uint8_t i=0; iinit(data, pitch, velo); - if ( data[136] ) - voices[note].dx7_note->oscSync(); - break; - } - else - keydown_counter++; - - note = (note + 1) % max_notes; - } - - if(keydown_counter==0) - lfo.keydown(); - if ( monoMode ) { - for(uint8_t i=0; itransferSignal(*voices[i].dx7_note); - break; - } - if ( voices[i].midi_note < pitch ) { - voices[i].live = false; - voices[note].dx7_note->transferState(*voices[i].dx7_note); - break; - } - return; - } - } - } - - voices[note].live = true; -TRACE("Bye"); -} - -void Dexed::keyup(uint8_t pitch) { -TRACE("Hi"); -TRACE("pitch=%d\n",pitch); - - pitch += data[144] - 24; - - uint8_t note; - for (note=0; note= max_notes ) { - TRACE("note-off not found???"); - return; - } - - if ( monoMode ) { - int8_t highNote = -1; - int8_t target = 0; - for (int8_t i=0; i highNote ) { - target = i; - highNote = voices[i].midi_note; - } - } - - if ( highNote != -1 ) { - voices[note].live = false; - voices[target].live = true; - voices[target].dx7_note->transferState(*voices[note].dx7_note); - } - } - - if ( sustain ) { - voices[note].sustained = true; - } else { - voices[note].dx7_note->keyup(); - } -TRACE("Bye"); -} - -void Dexed::onParam(uint8_t param_num,float param_val) -{ - int32_t tune; - - if(param_val!=data_float[param_num]) - { - TRACE("Parameter %d change from %f to %f",param_num, data_float[param_num], param_val); -#ifdef DEBUG - uint8_t tmp=data[param_num]; -#endif - - _param_change_counter++; - - if(param_num==144 || param_num==134 || param_num==172) - panic(); - - refreshVoice=true; - data[param_num]=static_cast(param_val); - data_float[param_num]=param_val; - - switch(param_num) - { - case 155: - controllers.values_[kControllerPitchRange]=data[param_num]; - break; - case 156: - controllers.values_[kControllerPitchStep]=data[param_num]; - break; - case 157: - TRACE("wheel.setRange(%d)",data[param_num]); - controllers.wheel.setRange(data[param_num]); - break; - case 158: - controllers.wheel.setTarget(data[param_num]); - break; - case 159: - controllers.foot.setRange(data[param_num]); - break; - case 160: - controllers.foot.setTarget(data[param_num]); - break; - case 161: - controllers.breath.setRange(data[param_num]); - break; - case 162: - controllers.breath.setTarget(data[param_num]); - break; - case 163: - controllers.at.setRange(data[param_num]); - break; - case 164: - controllers.at.setTarget(data[param_num]); - break; - case 165: - tune=param_val*0x4000; - controllers.masterTune=(tune<<11)*(1.0/12); - break; - case 166: - case 167: - case 168: - case 169: - case 170: - case 171: - controllers.opSwitch=(data[166]<<5)|(data[167]<<4)|(data[168]<<3)|(data[169]<<2)|(data[170]<<1)|data[171]; - break; - case 172: - max_notes=data[param_num]; - break; - } - - TRACE("Done: Parameter %d changed from %d to %d",param_num, tmp, data[param_num]); - } -} - -uint8_t Dexed::getEngineType() { - return engineType; -} - -void Dexed::setEngineType(uint8_t tp) { - TRACE("settings engine %d", tp); - - if(engineType==tp && controllers.core!=NULL) - return; - - switch (tp) { - case DEXED_ENGINE_MARKI: - TRACE("DEXED_ENGINE_MARKI:%d",DEXED_ENGINE_MARKI); - controllers.core = engineMkI; - break; - case DEXED_ENGINE_OPL: - TRACE("DEXED_ENGINE_OPL:%d",DEXED_ENGINE_OPL); - controllers.core = engineOpl; - break; - default: - TRACE("DEXED_ENGINE_MODERN:%d",DEXED_ENGINE_MODERN); - controllers.core = engineMsfa; - tp=DEXED_ENGINE_MODERN; - break; - } - engineType = tp; - panic(); - controllers.refresh(); -} - -bool Dexed::isMonoMode(void) { - return monoMode; -} - -void Dexed::setMonoMode(bool mode) { - if(monoMode==mode) - return; - - monoMode = mode; -} - -void Dexed::panic(void) { - for(uint8_t i=0;ioscSync(); - } - } - } -} - -void Dexed::notes_off(void) { - for(uint8_t i=0;i - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "synth.h" -#include "dexed.h" -#include "EngineMkI.h" -#include "EngineOpl.h" -#include "fm_core.h" -#include "exp2.h" -#include "sin.h" -#include "freqlut.h" -#include "controllers.h" -#include -#include - -Dexed::Dexed(double rate) : lvtk::Synth(p_n_ports, p_midi_in) -{ - uint8_t i; - - TRACE("--------------------------------------------------------------------------------"); - TRACE("Hi"); - - Exp2::init(); - Tanh::init(); - Sin::init(); - - Freqlut::init(rate); - Lfo::init(rate); - PitchEnv::init(rate); - Env::init_sr(rate); - fx.init(rate); - - engineMkI=new EngineMkI; - engineOpl=new EngineOpl; - engineMsfa=new FmCore; - - /* - if(!(engineMkI=new (std::nothrow) EngineMkI)) - TRACE("Cannot not create engine EngineMkI"); - if(!(engineOpl=new (std::nothrow) EngineOpl)) - { - delete(engineMkI); - TRACE("Cannot not create engine EngineOpl"); - } - if(!(engineMsfa=new (std::nothrow) FmCore)) - { - delete(engineMkI); - delete(engineOpl); - TRACE("Cannot create engine FmCore"); - } - */ - - for(i=0; i(data[i]); - TRACE("%d->%f",i,data_float[i]); - } - - max_notes=16; - currentNote = 0; - controllers.values_[kControllerPitch] = 0x2000; - controllers.values_[kControllerPitchRange] = 0; - controllers.values_[kControllerPitchStep] = 0; - controllers.modwheel_cc = 0; - controllers.foot_cc = 0; - controllers.breath_cc = 0; - controllers.aftertouch_cc = 0; - controllers.masterTune=0; - controllers.opSwitch=0x3f; // enable all operators - //controllers.opSwitch=0x00; - - bufsize_=256; - - outbuf_=new float[bufsize_]; - //if(!(outbuf_=new (std::nothrow) float[bufsize_])) - // TRACE("Cannot create outbuf_ buffer"); - - lfo.reset(data+137); - - setMonoMode(false); - - sustain = false; - - extra_buf_size_ = 0; - - memset(&voiceStatus, 0, sizeof(VoiceStatus)); - - setEngineType(DEXED_ENGINE_MODERN); - - //add_voices(new DexedVoice(rate)); - - add_audio_outputs(p_audio_out); - - TRACE("Bye"); -} - -Dexed::~Dexed() -{ - TRACE("Hi"); - - delete [] outbuf_; - - currentNote = -1; - - for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; ++note) - delete voices[note].dx7_note; - - delete(engineMsfa); - delete(engineOpl); - delete(engineMkI); - - TRACE("Bye"); - TRACE("--------------------------------------------------------------------------------"); -} - -void Dexed::activate(void) -{ - TRACE("Hi"); - - Plugin::activate(); - panic(); - controllers.values_[kControllerPitchRange] = data[155]; - controllers.values_[kControllerPitchStep] = data[156]; - - TRACE("Bye"); -} - -void Dexed::deactivate(void) -{ - TRACE("Hi"); - - Plugin::deactivate(); - - TRACE("Bye"); -} - -void Dexed::set_params(void) -{ - //TRACE("Hi"); - - _param_change_counter=0; - - bool polymono=bool(*p(p_polymono)); - uint8_t engine=uint8_t(*p(p_engine)); - float f_gain=*p(p_output); - float f_cutoff=*p(p_cutoff); - float f_reso=*p(p_resonance); - - // Dexed-Unisono - if(isMonoMode()!=polymono) - setMonoMode(polymono); - - // Dexed-Engine - if(controllers.core==NULL || getEngineType()!=engine) - { - setEngineType(engine); - refreshVoice=true; - } - - // Dexed-Filter - if(fx.uiCutoff!=f_cutoff) - { - fx.uiCutoff=f_cutoff; - refreshVoice=true; - } - if(fx.uiReso!=f_reso) - { - fx.uiReso=f_reso; - refreshVoice=true; - } - if(fx.uiGain!=f_gain) - { - fx.uiGain=f_gain; - refreshVoice=true; - } - - // OP6 - onParam(0,*p(p_op6_eg_rate_1)); - onParam(1,*p(p_op6_eg_rate_2)); - onParam(2,*p(p_op6_eg_rate_3)); - onParam(3,*p(p_op6_eg_rate_4)); - onParam(4,*p(p_op6_eg_level_1)); - onParam(5,*p(p_op6_eg_level_2)); - onParam(6,*p(p_op6_eg_level_3)); - onParam(7,*p(p_op6_eg_level_4)); - onParam(8,*p(p_op6_kbd_lev_scl_brk_pt)); - onParam(9,*p(p_op6_kbd_lev_scl_lft_depth)); - onParam(10,*p(p_op6_kbd_lev_scl_rht_depth)); - onParam(11,*p(p_op6_kbd_lev_scl_lft_curve)); - onParam(12,*p(p_op6_kbd_lev_scl_rht_curve)); - onParam(13,*p(p_op6_kbd_rate_scaling)); - onParam(14,*p(p_op6_amp_mod_sensitivity)); - onParam(15,*p(p_op6_key_vel_sensitivity)); - onParam(16,*p(p_op6_operator_output_level)); - onParam(17,*p(p_op6_osc_mode)); - onParam(18,*p(p_op6_osc_freq_coarse)); - onParam(19,*p(p_op6_osc_freq_fine)); - onParam(20,*p(p_op6_osc_detune)+7); - // OP5 - onParam(21,*p(p_op5_eg_rate_1)); - onParam(22,*p(p_op5_eg_rate_2)); - onParam(23,*p(p_op5_eg_rate_3)); - onParam(24,*p(p_op5_eg_rate_4)); - onParam(25,*p(p_op5_eg_level_1)); - onParam(26,*p(p_op5_eg_level_2)); - onParam(27,*p(p_op5_eg_level_3)); - onParam(28,*p(p_op5_eg_level_4)); - onParam(29,*p(p_op5_kbd_lev_scl_brk_pt)); - onParam(30,*p(p_op5_kbd_lev_scl_lft_depth)); - onParam(31,*p(p_op5_kbd_lev_scl_rht_depth)); - onParam(32,*p(p_op5_kbd_lev_scl_lft_curve)); - onParam(33,*p(p_op5_kbd_lev_scl_rht_curve)); - onParam(34,*p(p_op5_kbd_rate_scaling)); - onParam(35,*p(p_op5_amp_mod_sensitivity)); - onParam(36,*p(p_op5_key_vel_sensitivity)); - onParam(37,*p(p_op5_operator_output_level)); - onParam(38,*p(p_op5_osc_mode)); - onParam(39,*p(p_op5_osc_freq_coarse)); - onParam(40,*p(p_op5_osc_freq_fine)); - onParam(41,*p(p_op5_osc_detune)+7); - // OP4 - onParam(42,*p(p_op4_eg_rate_1)); - onParam(43,*p(p_op4_eg_rate_2)); - onParam(44,*p(p_op4_eg_rate_3)); - onParam(45,*p(p_op4_eg_rate_4)); - onParam(46,*p(p_op4_eg_level_1)); - onParam(47,*p(p_op4_eg_level_2)); - onParam(48,*p(p_op4_eg_level_3)); - onParam(49,*p(p_op4_eg_level_4)); - onParam(50,*p(p_op4_kbd_lev_scl_brk_pt)); - onParam(51,*p(p_op4_kbd_lev_scl_lft_depth)); - onParam(52,*p(p_op4_kbd_lev_scl_rht_depth)); - onParam(53,*p(p_op4_kbd_lev_scl_lft_curve)); - onParam(54,*p(p_op4_kbd_lev_scl_rht_curve)); - onParam(55,*p(p_op4_kbd_rate_scaling)); - onParam(56,*p(p_op4_amp_mod_sensitivity)); - onParam(57,*p(p_op4_key_vel_sensitivity)); - onParam(58,*p(p_op4_operator_output_level)); - onParam(59,*p(p_op4_osc_mode)); - onParam(60,*p(p_op4_osc_freq_coarse)); - onParam(61,*p(p_op4_osc_freq_fine)); - onParam(62,*p(p_op4_osc_detune)+7); - // OP3 - onParam(63,*p(p_op3_eg_rate_1)); - onParam(64,*p(p_op3_eg_rate_2)); - onParam(65,*p(p_op3_eg_rate_3)); - onParam(66,*p(p_op3_eg_rate_4)); - onParam(67,*p(p_op3_eg_level_1)); - onParam(68,*p(p_op3_eg_level_2)); - onParam(69,*p(p_op3_eg_level_3)); - onParam(70,*p(p_op3_eg_level_4)); - onParam(71,*p(p_op3_kbd_lev_scl_brk_pt)); - onParam(72,*p(p_op3_kbd_lev_scl_lft_depth)); - onParam(73,*p(p_op3_kbd_lev_scl_rht_depth)); - onParam(74,*p(p_op3_kbd_lev_scl_lft_curve)); - onParam(75,*p(p_op3_kbd_lev_scl_rht_curve)); - onParam(76,*p(p_op3_kbd_rate_scaling)); - onParam(77,*p(p_op3_amp_mod_sensitivity)); - onParam(78,*p(p_op3_key_vel_sensitivity)); - onParam(79,*p(p_op3_operator_output_level)); - onParam(80,*p(p_op3_osc_mode)); - onParam(81,*p(p_op3_osc_freq_coarse)); - onParam(82,*p(p_op3_osc_freq_fine)); - onParam(83,*p(p_op3_osc_detune)+7); - // OP2 - onParam(84,*p(p_op2_eg_rate_1)); - onParam(85,*p(p_op2_eg_rate_2)); - onParam(86,*p(p_op2_eg_rate_3)); - onParam(87,*p(p_op2_eg_rate_4)); - onParam(88,*p(p_op2_eg_level_1)); - onParam(89,*p(p_op2_eg_level_2)); - onParam(90,*p(p_op2_eg_level_3)); - onParam(91,*p(p_op2_eg_level_4)); - onParam(92,*p(p_op2_kbd_lev_scl_brk_pt)); - onParam(93,*p(p_op2_kbd_lev_scl_lft_depth)); - onParam(94,*p(p_op2_kbd_lev_scl_rht_depth)); - onParam(95,*p(p_op2_kbd_lev_scl_lft_curve)); - onParam(96,*p(p_op2_kbd_lev_scl_rht_curve)); - onParam(97,*p(p_op2_kbd_rate_scaling)); - onParam(98,*p(p_op2_amp_mod_sensitivity)); - onParam(99,*p(p_op2_key_vel_sensitivity)); - onParam(100,*p(p_op2_operator_output_level)); - onParam(101,*p(p_op2_osc_mode)); - onParam(102,*p(p_op2_osc_freq_coarse)); - onParam(103,*p(p_op2_osc_freq_fine)); - onParam(104,*p(p_op2_osc_detune)+7); - // OP1 - onParam(105,*p(p_op1_eg_rate_1)); - onParam(106,*p(p_op1_eg_rate_2)); - onParam(107,*p(p_op1_eg_rate_3)); - onParam(108,*p(p_op1_eg_rate_4)); - onParam(109,*p(p_op1_eg_level_1)); - onParam(110,*p(p_op1_eg_level_2)); - onParam(111,*p(p_op1_eg_level_3)); - onParam(112,*p(p_op1_eg_level_4)); - onParam(113,*p(p_op1_kbd_lev_scl_brk_pt)); - onParam(114,*p(p_op1_kbd_lev_scl_lft_depth)); - onParam(115,*p(p_op1_kbd_lev_scl_rht_depth)); - onParam(116,*p(p_op1_kbd_lev_scl_lft_curve)); - onParam(117,*p(p_op1_kbd_lev_scl_rht_curve)); - onParam(118,*p(p_op1_kbd_rate_scaling)); - onParam(119,*p(p_op1_amp_mod_sensitivity)); - onParam(120,*p(p_op1_key_vel_sensitivity)); - onParam(121,*p(p_op1_operator_output_level)); - onParam(122,*p(p_op1_osc_mode)); - onParam(123,*p(p_op1_osc_freq_coarse)); - onParam(124,*p(p_op1_osc_freq_fine)); - onParam(125,*p(p_op1_osc_detune)+7); - // Global for all OPs - onParam(126,*p(p_pitch_eg_rate_1)); - onParam(127,*p(p_pitch_eg_rate_2)); - onParam(128,*p(p_pitch_eg_rate_3)); - onParam(129,*p(p_pitch_eg_rate_4)); - onParam(130,*p(p_pitch_eg_level_1)); - onParam(131,*p(p_pitch_eg_level_2)); - onParam(132,*p(p_pitch_eg_level_3)); - onParam(133,*p(p_pitch_eg_level_4)); - onParam(134,*p(p_algorithm_num)-1); - onParam(135,*p(p_feedback)); - onParam(136,*p(p_oscillator_sync)); - onParam(137,*p(p_lfo_speed)); - onParam(138,*p(p_lfo_delay)); - onParam(139,*p(p_lfo_pitch_mod_depth)); - onParam(140,*p(p_lfo_amp_mod_depth)); - onParam(141,*p(p_lfo_sync)); - onParam(142,*p(p_lfo_waveform)); - onParam(143,*p(p_pitch_mod_sensitivity)); - onParam(144,*p(p_transpose)); - // 10 bytes (145-154) are the name of the patch - // Controllers (added at the end of the data[]) - onParam(155,*p(p_pitch_bend_range)); - onParam(156,*p(p_pitch_bend_step)); - onParam(157,*p(p_mod_wheel_range)); - onParam(158,*p(p_mod_wheel_assign)); - onParam(159,*p(p_foot_ctrl_range)); - onParam(160,*p(p_foot_ctrl_assign)); - onParam(161,*p(p_breath_ctrl_range)); - onParam(162,*p(p_breath_ctrl_assign)); - onParam(163,*p(p_aftertouch_range)); - onParam(164,*p(p_aftertouch_assign)); - onParam(165,*p(p_master_tune)); - onParam(166,*p(p_op1_enable)); - onParam(167,*p(p_op2_enable)); - onParam(168,*p(p_op3_enable)); - onParam(169,*p(p_op4_enable)); - onParam(170,*p(p_op5_enable)); - onParam(171,*p(p_op6_enable)); - onParam(172,*p(p_number_of_voices)); - - if(_param_change_counter>PARAM_CHANGE_LEVEL) - { - panic(); - controllers.refresh(); - } - - //TRACE("Bye"); -} - -// override the run() method -void Dexed::run (uint32_t sample_count) -{ - const LV2_Atom_Sequence* seq = p (p_midi_in); - float* output = p(p_audio_out); - uint32_t last_frame = 0, num_this_time = 0; - bool drop_next_events=false; - - Plugin::run(sample_count); - - if(++_k_rate_counter%16) - set_params(); // pre_process: copy actual voice params - - for (LV2_Atom_Event* ev = lv2_atom_sequence_begin (&seq->body); - !lv2_atom_sequence_is_end(&seq->body, seq->atom.size, ev); - ev = lv2_atom_sequence_next (ev)) - { - num_this_time = ev->time.frames - last_frame; - - // If it's midi, send it to the engine - if (ev->body.type == m_midi_type) - { - drop_next_events|=ProcessMidiMessage((uint8_t*) LV2_ATOM_BODY (&ev->body),ev->body.size); - if(drop_next_events==true) - continue; - } - - // render audio from the last frame until the timestamp of this event - GetSamples (num_this_time, outbuf_); - - // i is the index of the engine's buf, which always starts at 0 (i think) - // j is the index of the plugin's float output buffer which will be the timestamp - // of the last processed atom event. - for (uint32_t i = 0, j = last_frame; i < num_this_time; ++i, ++j) - output[j]=outbuf_[i]; - - last_frame = ev->time.frames; - } - - // render remaining samples if any left - if (last_frame < sample_count) - { - // do the same thing as above except from last frame until the end of - // the processing cycles last sample. at this point, all events have - // already been handled. - - num_this_time = sample_count - last_frame; - GetSamples (num_this_time, outbuf_); - for (uint32_t i = 0, j = last_frame; i < num_this_time; ++i, ++j) - output[j] = outbuf_[i]; - } - - fx.process(output, sample_count); -} - -void Dexed::GetSamples(uint32_t n_samples, float* buffer) -{ - uint32_t i; - - if(refreshVoice) { - for(i=0;i < max_notes;i++) { - if ( voices[i].live ) - voices[i].dx7_note->update(data, voices[i].midi_note, voices[i].velocity); - } - lfo.reset(data+137); - refreshVoice = false; - } - - // flush first events - for (i=0; i < n_samples && i < extra_buf_size_; i++) { - buffer[i] = extra_buf_[i]; - } - - // remaining buffer is still to be processed - if (extra_buf_size_ > n_samples) { - for (uint32_t j = 0; j < extra_buf_size_ - n_samples; j++) { - extra_buf_[j] = extra_buf_[j + n_samples]; - } - extra_buf_size_ -= n_samples; - } - else - { - for (; i < n_samples; i += N) { - AlignedBuf audiobuf; - float sumbuf[N]; - - for (uint32_t j = 0; j < N; ++j) { - audiobuf.get()[j] = 0; - sumbuf[j] = 0.0; - } - - int32_t lfovalue = lfo.getsample(); - int32_t lfodelay = lfo.getdelay(); - - for (uint8_t note = 0; note < max_notes; ++note) { - if (voices[note].live) { - voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); - for (uint32_t j=0; j < N; ++j) { - int32_t val = audiobuf.get()[j]; - val = val >> 4; - int32_t clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9; - float f = static_cast(clip_val>>1)/0x8000; - if(f>1) f=1; - if(f<-1) f=-1; - sumbuf[j]+=f; - audiobuf.get()[j]=0; - } - } - } - - uint32_t jmax = n_samples - i; - for (uint32_t j = 0; j < N; ++j) { - if (j < jmax) - buffer[i + j] = sumbuf[j]; - else - extra_buf_[j - jmax] = sumbuf[j]; - } - } - extra_buf_size_ = i - n_samples; - } - - if(++_k_rate_counter%32 && !monoMode) - { - uint8_t op_carrier=controllers.core->get_carrier_operators(data[134]); // look for carriers - - for(i=0;i < max_notes;i++) - { - if(voices[i].live==true) - { - uint8_t op_amp=0; - uint8_t op_carrier_num=0; - - voices[i].dx7_note->peekVoiceStatus(voiceStatus); - - for(uint8_t op=0;op<6;op++) - { - uint8_t op_bit=static_cast(pow(2,op)); - - if((op_carrier&op_bit)>0) - { - // this voice is a carrier! - op_carrier_num++; - - //TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep); - - if(voiceStatus.amp[op]<=1069 && voiceStatus.ampStep[op]==4) // this voice produces no audio output - op_amp++; - } - } - if(op_amp==op_carrier_num) - { - // all carrier-operators are silent -> disable the voice - voices[i].live=false; - voices[i].sustained=false; - voices[i].keydown=false; - TRACE("Shutted down Voice[%2d]",i); - } - } -// TRACE("Voice[%2d] live=%d keydown=%d",i,voices[i].live,voices[i].keydown); - } - } -} - -bool Dexed::ProcessMidiMessage(const uint8_t *buf, uint32_t buf_size) { - TRACE("Hi"); - - uint8_t cmd = buf[0]; - - switch(cmd & 0xf0) { - case 0x80 : - TRACE("MIDI keyup event: %d",buf[1]); - keyup(buf[1]); - return(false); - break; - case 0x90 : - TRACE("MIDI keydown event: %d %d",buf[1],buf[2]); - keydown(buf[1], buf[2]); - return(false); - break; - case 0xb0 : { - uint8_t ctrl = buf[1]; - uint8_t value = buf[2]; - - switch(ctrl) { - case 1: - TRACE("MIDI modwheel event: %d %d",ctrl,value); - controllers.modwheel_cc = value; - controllers.refresh(); - break; - case 2: - TRACE("MIDI breath event: %d %d",ctrl,value); - controllers.breath_cc = value; - controllers.refresh(); - break; - case 4: - TRACE("MIDI footsw event: %d %d",ctrl,value); - controllers.foot_cc = value; - controllers.refresh(); - break; - case 64: - TRACE("MIDI sustain event: %d %d",ctrl,value); - sustain = value > 63; - if (!sustain) { - for (uint8_t note = 0; note < max_notes; note++) { - if (voices[note].sustained && !voices[note].keydown) { - voices[note].dx7_note->keyup(); - voices[note].sustained = false; - } - } - } - break; - case 120: - TRACE("MIDI all-sound-off: %d %d",ctrl,value); - panic(); - return(true); - break; - case 123: - TRACE("MIDI all-notes-off: %d %d",ctrl,value); - notes_off(); - return(true); - break; - } - break; - } - -// case 0xc0 : -// setCurrentProgram(buf[1]); -// break; - - // channel aftertouch - case 0xd0 : - TRACE("MIDI aftertouch 0xd0 event: %d %d",buf[1]); - controllers.aftertouch_cc = buf[1]; - controllers.refresh(); - break; - // pitchbend - case 0xe0 : - TRACE("MIDI pitchbend 0xe0 event: %d %d",buf[1],buf[2]); - controllers.values_[kControllerPitch] = buf[1] | (buf[2] << 7); - break; - - default: - TRACE("MIDI event unknown: cmd=%d, val1=%d, val2=%d",buf[0],buf[1],buf[2]); - break; - } - - TRACE("Bye"); - return(false); -} - -void Dexed::keydown(uint8_t pitch, uint8_t velo) { -TRACE("Hi"); -TRACE("pitch=%d, velo=%d\n",pitch,velo); - if ( velo == 0 ) { - keyup(pitch); - return; - } - - pitch += data[144] - 24; - - uint8_t note = currentNote; - uint8_t keydown_counter=0; - - for (uint8_t i=0; iinit(data, pitch, velo); - if ( data[136] ) - voices[note].dx7_note->oscSync(); - break; - } - else - keydown_counter++; - - note = (note + 1) % max_notes; - } - - if(keydown_counter==0) - lfo.keydown(); - if ( monoMode ) { - for(uint8_t i=0; itransferSignal(*voices[i].dx7_note); - break; - } - if ( voices[i].midi_note < pitch ) { - voices[i].live = false; - voices[note].dx7_note->transferState(*voices[i].dx7_note); - break; - } - return; - } - } - } - - voices[note].live = true; -TRACE("Bye"); -} - -void Dexed::keyup(uint8_t pitch) { -TRACE("Hi"); -TRACE("pitch=%d\n",pitch); - - pitch += data[144] - 24; - - uint8_t note; - for (note=0; note= max_notes ) { - TRACE("note-off not found???"); - return; - } - - if ( monoMode ) { - int8_t highNote = -1; - int8_t target = 0; - for (int8_t i=0; i highNote ) { - target = i; - highNote = voices[i].midi_note; - } - } - - if ( highNote != -1 && voices[note].live ) { - voices[note].live = false; - voices[target].live = true; - voices[target].dx7_note->transferState(*voices[note].dx7_note); - } - } - - if ( sustain ) { - voices[note].sustained = true; - } else { - voices[note].dx7_note->keyup(); - } -TRACE("Bye"); -} - -void Dexed::onParam(uint8_t param_num,float param_val) -{ - int32_t tune; - - if(param_val!=data_float[param_num]) - { - TRACE("Parameter %d change from %f to %f",param_num, data_float[param_num], param_val); -#ifdef DEBUG - uint8_t tmp=data[param_num]; -#endif - - _param_change_counter++; - - if(param_num==144 || param_num==134 || param_num==172) - panic(); - - refreshVoice=true; - data[param_num]=static_cast(param_val); - data_float[param_num]=param_val; - - switch(param_num) - { - case 155: - controllers.values_[kControllerPitchRange]=data[param_num]; - break; - case 156: - controllers.values_[kControllerPitchStep]=data[param_num]; - break; - case 157: - controllers.wheel.setRange(data[param_num]); - controllers.wheel.setTarget(data[param_num+1]); - controllers.refresh(); - break; - case 158: - controllers.wheel.setRange(data[param_num-1]); - controllers.wheel.setTarget(data[param_num]); - controllers.refresh(); - break; - case 159: - controllers.foot.setRange(data[param_num]); - controllers.foot.setTarget(data[param_num+1]); - controllers.refresh(); - break; - case 160: - controllers.foot.setRange(data[param_num-1]); - controllers.foot.setTarget(data[param_num]); - controllers.refresh(); - break; - case 161: - controllers.breath.setRange(data[param_num]); - controllers.breath.setTarget(data[param_num+1]); - controllers.refresh(); - break; - case 162: - controllers.breath.setRange(data[param_num-1]); - controllers.breath.setTarget(data[param_num]); - controllers.refresh(); - break; - case 163: - controllers.at.setRange(data[param_num]); - controllers.at.setTarget(data[param_num+1]); - controllers.refresh(); - break; - case 164: - controllers.at.setRange(data[param_num-1]); - controllers.at.setTarget(data[param_num]); - controllers.refresh(); - break; - case 165: - tune=param_val*0x4000; - controllers.masterTune=(tune<<11)*(1.0/12); - break; - case 166: - case 167: - case 168: - case 169: - case 170: - case 171: - controllers.opSwitch=(data[166]<<5)|(data[167]<<4)|(data[168]<<3)|(data[169]<<2)|(data[170]<<1)|data[171]; - break; - case 172: - max_notes=data[param_num]; - break; - } - - TRACE("Done: Parameter %d changed from %d to %d",param_num, tmp, data[param_num]); - } -} - -uint8_t Dexed::getEngineType() { - return engineType; -} - -void Dexed::setEngineType(uint8_t tp) { - TRACE("settings engine %d", tp); - - if(engineType==tp && controllers.core!=NULL) - return; - - switch (tp) { - case DEXED_ENGINE_MARKI: - TRACE("DEXED_ENGINE_MARKI:%d",DEXED_ENGINE_MARKI); - controllers.core = engineMkI; - break; - case DEXED_ENGINE_OPL: - TRACE("DEXED_ENGINE_OPL:%d",DEXED_ENGINE_OPL); - controllers.core = engineOpl; - break; - default: - TRACE("DEXED_ENGINE_MODERN:%d",DEXED_ENGINE_MODERN); - controllers.core = engineMsfa; - tp=DEXED_ENGINE_MODERN; - break; - } - engineType = tp; - panic(); - controllers.refresh(); -} - -bool Dexed::isMonoMode(void) { - return monoMode; -} - -void Dexed::setMonoMode(bool mode) { - if(monoMode==mode) - return; - - monoMode = mode; -} - -void Dexed::panic(void) { - for(uint8_t i=0;ioscSync(); - } - } - } -} - -void Dexed::notes_off(void) { - for(uint8_t i=0;i */ - -static const char p_uri[] = "https://github.com/dcoredump/dexed.lv2"; - -enum p_port_enum { - p_midi_in, - p_audio_out, - p_cutoff, - p_resonance, - p_output, - p_engine, - p_number_of_voices, - p_polymono, - p_pitch_bend_range, - p_pitch_bend_step, - p_mod_wheel_range, - p_mod_wheel_assign, - p_foot_ctrl_range, - p_foot_ctrl_assign, - p_breath_ctrl_range, - p_breath_ctrl_assign, - p_aftertouch_range, - p_aftertouch_assign, - p_master_tune, - p_algorithm_num, - p_feedback, - p_oscillator_sync, - p_lfo_speed, - p_lfo_delay, - p_lfo_pitch_mod_depth, - p_lfo_amp_mod_depth, - p_lfo_sync, - p_lfo_waveform, - p_transpose, - p_pitch_mod_sensitivity, - p_pitch_eg_rate_1, - p_pitch_eg_rate_2, - p_pitch_eg_rate_3, - p_pitch_eg_rate_4, - p_pitch_eg_level_1, - p_pitch_eg_level_2, - p_pitch_eg_level_3, - p_pitch_eg_level_4, - p_op1_eg_rate_1, - p_op1_eg_rate_2, - p_op1_eg_rate_3, - p_op1_eg_rate_4, - p_op1_eg_level_1, - p_op1_eg_level_2, - p_op1_eg_level_3, - p_op1_eg_level_4, - p_op1_operator_output_level, - p_op1_osc_mode, - p_op1_osc_freq_coarse, - p_op1_osc_freq_fine, - p_op1_osc_detune, - p_op1_kbd_lev_scl_brk_pt, - p_op1_kbd_lev_scl_lft_depth, - p_op1_kbd_lev_scl_rht_depth, - p_op1_kbd_lev_scl_lft_curve, - p_op1_kbd_lev_scl_rht_curve, - p_op1_kbd_rate_scaling, - p_op1_amp_mod_sensitivity, - p_op1_key_vel_sensitivity, - p_op2_eg_rate_1, - p_op2_eg_rate_2, - p_op2_eg_rate_3, - p_op2_eg_rate_4, - p_op2_eg_level_1, - p_op2_eg_level_2, - p_op2_eg_level_3, - p_op2_eg_level_4, - p_op2_operator_output_level, - p_op2_osc_mode, - p_op2_osc_freq_coarse, - p_op2_osc_freq_fine, - p_op2_osc_detune, - p_op2_kbd_lev_scl_brk_pt, - p_op2_kbd_lev_scl_lft_depth, - p_op2_kbd_lev_scl_rht_depth, - p_op2_kbd_lev_scl_lft_curve, - p_op2_kbd_lev_scl_rht_curve, - p_op2_kbd_rate_scaling, - p_op2_amp_mod_sensitivity, - p_op2_key_vel_sensitivity, - p_op3_eg_rate_1, - p_op3_eg_rate_2, - p_op3_eg_rate_3, - p_op3_eg_rate_4, - p_op3_eg_level_1, - p_op3_eg_level_2, - p_op3_eg_level_3, - p_op3_eg_level_4, - p_op3_operator_output_level, - p_op3_osc_mode, - p_op3_osc_freq_coarse, - p_op3_osc_freq_fine, - p_op3_osc_detune, - p_op3_kbd_lev_scl_brk_pt, - p_op3_kbd_lev_scl_lft_depth, - p_op3_kbd_lev_scl_rht_depth, - p_op3_kbd_lev_scl_lft_curve, - p_op3_kbd_lev_scl_rht_curve, - p_op3_kbd_rate_scaling, - p_op3_amp_mod_sensitivity, - p_op3_key_vel_sensitivity, - p_op4_eg_rate_1, - p_op4_eg_rate_2, - p_op4_eg_rate_3, - p_op4_eg_rate_4, - p_op4_eg_level_1, - p_op4_eg_level_2, - p_op4_eg_level_3, - p_op4_eg_level_4, - p_op4_operator_output_level, - p_op4_osc_mode, - p_op4_osc_freq_coarse, - p_op4_osc_freq_fine, - p_op4_osc_detune, - p_op4_kbd_lev_scl_brk_pt, - p_op4_kbd_lev_scl_lft_depth, - p_op4_kbd_lev_scl_rht_depth, - p_op4_kbd_lev_scl_lft_curve, - p_op4_kbd_lev_scl_rht_curve, - p_op4_kbd_rate_scaling, - p_op4_amp_mod_sensitivity, - p_op4_key_vel_sensitivity, - p_op5_eg_rate_1, - p_op5_eg_rate_2, - p_op5_eg_rate_3, - p_op5_eg_rate_4, - p_op5_eg_level_1, - p_op5_eg_level_2, - p_op5_eg_level_3, - p_op5_eg_level_4, - p_op5_operator_output_level, - p_op5_osc_mode, - p_op5_osc_freq_coarse, - p_op5_osc_freq_fine, - p_op5_osc_detune, - p_op5_kbd_lev_scl_brk_pt, - p_op5_kbd_lev_scl_lft_depth, - p_op5_kbd_lev_scl_rht_depth, - p_op5_kbd_lev_scl_lft_curve, - p_op5_kbd_lev_scl_rht_curve, - p_op5_kbd_rate_scaling, - p_op5_amp_mod_sensitivity, - p_op5_key_vel_sensitivity, - p_op6_eg_rate_1, - p_op6_eg_rate_2, - p_op6_eg_rate_3, - p_op6_eg_rate_4, - p_op6_eg_level_1, - p_op6_eg_level_2, - p_op6_eg_level_3, - p_op6_eg_level_4, - p_op6_operator_output_level, - p_op6_osc_mode, - p_op6_osc_freq_coarse, - p_op6_osc_freq_fine, - p_op6_osc_detune, - p_op6_kbd_lev_scl_brk_pt, - p_op6_kbd_lev_scl_lft_depth, - p_op6_kbd_lev_scl_rht_depth, - p_op6_kbd_lev_scl_lft_curve, - p_op6_kbd_lev_scl_rht_curve, - p_op6_kbd_rate_scaling, - p_op6_amp_mod_sensitivity, - p_op6_key_vel_sensitivity, - p_op1_enable, - p_op2_enable, - p_op3_enable, - p_op4_enable, - p_op5_enable, - p_op6_enable, - p_n_ports -}; - -static const peg_data_t p_ports[] = { - { -3.40282e+38, 3.40282e+38, -3.40282e+38, 0, 0, 0 }, - { -3.40282e+38, 3.40282e+38, -3.40282e+38, 0, 0, 0 }, - { 0, 1, 1, 0, 0, 0 }, - { 0, 1, 0, 0, 0, 0 }, - { 0, 2, 1, 0, 0, 0 }, - { 0, 2, 0, 0, 1, 0 }, - { 1, 32, 16, 0, 1, 0 }, - { 0, 1, 0, 1, 1, 0 }, - { 0, 12, 1, 0, 1, 0 }, - { 0, 12, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 7, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 7, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 7, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 7, 0, 0, 1, 0 }, - { -1, 1, 0, 0, 0, 0 }, - { 1, 32, 5, 0, 1, 0 }, - { 0, 7, 6, 0, 1, 0 }, - { 0, 1, 0, 1, 1, 0 }, - { 0, 99, 34, 0, 1, 0 }, - { 0, 99, 33, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 1, 0, 1, 1, 0 }, - { 0, 5, 4, 0, 1, 0 }, - { 0, 48, 24, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 99, 94, 0, 1, 0 }, - { 0, 99, 67, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 60, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 96, 0, 1, 0 }, - { 0, 99, 25, 0, 1, 0 }, - { 0, 99, 25, 0, 1, 0 }, - { 0, 99, 67, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 75, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 1, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { -7, 7, 3, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 2, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 35, 0, 1, 0 }, - { 0, 99, 78, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 75, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 58, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 14, 0, 1, 0 }, - { 0, 100, 0, 0, 1, 0 }, - { -7, 7, 0, 0, 1, 0 }, - { 0, 100, 0, 0, 1, 0 }, - { 0, 100, 0, 0, 1, 0 }, - { 0, 100, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 7, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 1, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { -7, 7, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 2, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 29, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 89, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 1, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { -7, 7, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 6, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 1, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { -7, 7, -7, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 0, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 29, 0, 1, 0 }, - { 0, 99, 20, 0, 1, 0 }, - { 0, 99, 50, 0, 1, 0 }, - { 0, 99, 99, 0, 1, 0 }, - { 0, 99, 95, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 79, 0, 1, 0 }, - { 0, 1, 0, 0, 1, 0 }, - { 0, 31, 1, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { -7, 7, 7, 0, 1, 0 }, - { 0, 99, 41, 0, 1, 0 }, - { 0, 99, 0, 0, 1, 0 }, - { 0, 99, 19, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 3, 0, 1, 0 }, - { 0, 3, 0, 0, 1, 0 }, - { 0, 7, 6, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, - { 0, 1, 1, 0, 1, 0 }, -}; - - -#endif /* dexed_ttl_h */ diff --git a/dx7note.cpp b/dx7note.cpp index 97c039e..0bd6071 100644 --- a/dx7note.cpp +++ b/dx7note.cpp @@ -260,7 +260,8 @@ void Dx7Note::keyup() { pitchenv_.keydown(false); } -void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) { +//void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) { +void Dx7Note::update(const uint8_t patch[173], int midinote, int velocity) { int rates[4]; int levels[4]; for (int op = 0; op < 6; op++) { diff --git a/not_used/PluginFx.cpp b/not_used/PluginFx.cpp deleted file mode 100644 index c474565..0000000 --- a/not_used/PluginFx.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/** - * - * Copyright (c) 2013-2014 Pascal Gauthier. - * Copyright (c) 2013-2014 Filatov Vadim. - * - * Filter taken from the Obxd project : - * https://github.com/2DaT/Obxd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#define _USE_MATH_DEFINES -#include -#include "PluginFx.h" - -const float dc = 1e-18; - -inline static float tptpc(float& state,float inp,float cutoff) { - double v = (inp - state) * cutoff / (1 + cutoff); - double res = v + state; - state = res + v; - return res; -} - -inline static float tptlpupw(float & state , float inp , float cutoff , float srInv) { - cutoff = (cutoff * srInv)*M_PI; - double v = (inp - state) * cutoff / (1 + cutoff); - double res = v + state; - state = res + v; - return res; -} - -//static float linsc(float param,const float min,const float max) { -// return (param) * (max - min) + min; -//} - -static float logsc(float param, const float min,const float max,const float rolloff = 19.0f) { - return ((expf(param * logf(rolloff+1)) - 1.0f) / (rolloff)) * (max-min) + min; -} - -PluginFx::PluginFx() { - uiCutoff = 1; - uiReso = 0; - uiGain = 1; -} - -void PluginFx::init(int sr) { - mm=0; - s1=s2=s3=s4=c=d=0; - R24=0; - - mmch = (int)(mm * 3); - mmt = mm*3-mmch; - - sampleRate = sr; - sampleRateInv = 1/sampleRate; - float rcrate =sqrt((44000/sampleRate)); - rcor24 = (970.0 / 44000)*rcrate; - rcor24Inv = 1 / rcor24; - - bright = tan((sampleRate*0.5f-10) * M_PI * sampleRateInv); - - R = 1; - rcor = (480.0 / 44000)*rcrate; - rcorInv = 1 / rcor; - bandPassSw = false; - - pCutoff = -1; - pReso = -1; - - dc_r = 1.0-(126.0/sr); - dc_id = 0; - dc_od = 0; -} - -inline float PluginFx::NR24(float sample,float g,float lpc) { - float ml = 1 / (1+g); - float S = (lpc*(lpc*(lpc*s1 + s2) + s3) +s4)*ml; - float G = lpc*lpc*lpc*lpc; - float y = (sample - R24 * S) / (1 + R24*G); - return y + 1e-8; -}; - -inline float PluginFx::NR(float sample, float g) { - float y = ((sample- R * s1*2 - g*s1 - s2)/(1+ g*(2*R + g))) + dc; - return y; -} - -void PluginFx::process(float *work, int sampleSize) { - // very basic DC filter - float t_fd = work[0]; - work[0] = work[0] - dc_id + dc_r * dc_od; - dc_id = t_fd; - for (int i=1; i