diff --git a/src/.gitignore b/src/.gitignore index 5d2ec9d..b879682 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,2 +1,3 @@ *.peg dexed.lv2/ +*.gch diff --git a/src/Makefile b/src/Makefile index da46e8a..0f89dd6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,6 @@ -DEBUG=-DDEBUG=1 +#DEBUG=-DDEBUG=0 BUNDLE=dexed.lv2 -#INSTALL_DIR=/home/pi/zynthian/zynthian-plugins/mod-lv2 -INSTALL_DIR=/usr/local/lib/lv2 +INSTALL_DIR=/home/pi/zynthian/zynthian-plugins/mod-lv2 TARGET=dexed.so OBJ=ringbuffer.o fm_core.o env.o lfo.o dx7note.o sin.o pitchenv.o fm_op_kernel.o freqlut.o exp2.o EngineMkI.o EngineOpl.o PluginFx.o trace.o CFLAGS=-fPIC -DPIC $(DEBUG) -std=c++11 -I. -I/usr/local/include/lvtk-2 @@ -26,13 +25,7 @@ $(BUNDLE): manifest.ttl Dexed.ttl dexed.so # cp -R modgui $(BUNDLE) dexed.so: $(OBJ) dexed.o - g++ -shared dexed.o $(OBJ) $(LDFLAGS) -o dexed.so - -#dexed-test: $(OBJ) dexed-test.o -# g++ -fPIC -DPIC dexed-test.o $(OBJ) $(LDFLAGS) -o dexed-test -# -#dexed-test.o: dexed-test.cpp -# $(CXX) $(CFLAGS) -Wall -c dexed-test.cpp + $(CXX) -shared dexed.o $(OBJ) $(LDFLAGS) -o dexed.so dexed.o: dexed.cpp dexed.peg $(CXX) $(CFLAGS) -Wall -c dexed.cpp diff --git a/src/dexed-test.cpp b/src/dexed-test.cpp deleted file mode 100644 index 93a8dde..0000000 --- a/src/dexed-test.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "EngineMkI.h" -#include "EngineOpl.h" -#include "msfa/exp2.h" -#include "msfa/sin.h" -#include "msfa/freqlut.h" -#include "msfa/controllers.h" -#include "msfa/dx7note.h" -#include "msfa/lfo.h" -#include "msfa/synth.h" -#include "msfa/fm_core.h" - -#include -#include - -template float normalize(const T x) { - const float valMin = std::numeric_limits::min(); - const float valMax = std::numeric_limits::max(); - return 2 * (x - valMin) / (valMax - valMin) - 1; // note: 0 does not become 0. -} - -struct ProcessorVoice { - int midi_note; - bool keydown; - bool sustained; - bool live; - Dx7Note *dx7_note; -}; - -// GLOBALS -FmCore engineMsfa; -EngineMkI engineMkI; -EngineOpl engineOpl; - -Lfo lfo; -Controllers controllers; -const int rate=44100; -const uint8_t init_voice[] = - { 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, - 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, - 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, - 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, - 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, - 99, 99, 99, 99, 99, 99, 99, 00, 39, 0, 0, 0, 0, 0, 0, 0, 99, 0, 1, 0, 7, - 99, 99, 99, 99, 50, 50, 50, 50, 0, 0, 1, 35, 0, 0, 0, 1, 0, 3, 24, - 73, 78, 73, 84, 32, 86, 79, 73, 67, 69 }; -uint8_t data[156]; // program data -ProcessorVoice voice; -uint8_t feedback_bitdepth=11; - -int main(int argc, char **argv) -{ - Exp2::init(); - Tanh::init(); - Sin::init(); - Freqlut::init(rate); - Lfo::init(rate); - PitchEnv::init(rate); - Env::init_sr(rate); - - uint32_t i; - - for(i=0;iinit(data, key, velocity, feedback_bitdepth); - voice.live=true; - } - if(data[136]) - voice.dx7_note->oscSync(); - - int32_t s; - for(i=0;i<256;++i) - { - if(voice.live==true) - { - voice.dx7_note->compute(&s, lfo.getsample(), lfo.getdelay(), &controllers); - float fs=normalize(s); - printf("%f %d %d\n",fs, lfo.getsample(), lfo.getdelay()); - } - } -} - diff --git a/src/dexed-test.sh b/src/dexed-test.sh deleted file mode 100644 index 92d6616..0000000 --- a/src/dexed-test.sh +++ /dev/null @@ -1,6 +0,0 @@ -set -x -make -g++ -std=c++11 -c dexed-test.cpp -g++ -std=c++11 dexed-test.o fm_core.o env.o lfo.o dx7note.o sin.o pitchenv.o fm_op_kernel.o freqlut.o exp2.o EngineMkI.o EngineOpl.o -lm -o dexed-test -./dexed-test - diff --git a/src/dexed.cpp b/src/dexed.cpp index 70d3628..8af215c 100644 --- a/src/dexed.cpp +++ b/src/dexed.cpp @@ -87,6 +87,8 @@ void Dexed::set_params(void) { TRACE("Hi"); + refreshVoice=true; + // OP6 onParam(0,static_cast(*p(p_op6_eg_rate_1))); onParam(1,static_cast(*p(p_op6_eg_rate_2))); @@ -251,9 +253,6 @@ 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; - float level=*p(p_output)*scaler; - - 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); @@ -263,7 +262,16 @@ void Dexed::run (uint32_t sample_count) // If it's midi, send it to the engine if (ev->body.type == m_midi_type) + { + set_params(); // pre_process: copy actual voice params ring_buffer_.Write ((uint8_t*) LV2_ATOM_BODY (&ev->body), ev->body.size); +#ifdef DEBUG + for(uint i=0;ibody.size;i++) + { + TRACE("midi msg %d: %d\n",i,((uint8_t*)LV2_ATOM_BODY(&ev->body))[i]); + } +#endif + } // render audio from the last frame until the timestamp of this event GetSamples (num_this_time, outbuf16_); @@ -272,7 +280,7 @@ void Dexed::run (uint32_t sample_count) // 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] = (static_cast (outbuf16_[i])) * level; + output[j] = (static_cast (outbuf16_[i])) * *p(p_output); last_frame = ev->time.frames; } @@ -287,7 +295,7 @@ void Dexed::run (uint32_t sample_count) num_this_time = sample_count - last_frame; GetSamples (num_this_time, outbuf16_); for (uint32_t i = 0, j = last_frame; i < num_this_time; ++i, ++j) - output[j] = (static_cast (outbuf16_[i])) * level; + output[j] = (static_cast (outbuf16_[i])) * *p(p_output); } fx.process(output, sample_count); @@ -295,90 +303,71 @@ void Dexed::run (uint32_t sample_count) void Dexed::GetSamples(int n_samples, int16_t *buffer) { - int i; - size_t input_offset; - - TransferInput(); - for (input_offset = 0; input_offset < input_buffer_index_; ) { - int bytes_available = input_buffer_index_ - input_offset; - int bytes_consumed = ProcessMidiMessage(input_buffer_ + input_offset, bytes_available); - if (bytes_consumed == 0) { - break; - } - input_offset += bytes_consumed; - } - ConsumeInput(input_offset); - - if ( refreshVoice ) { - for(i=0;i < MAX_ACTIVE_NOTES;i++) { - if ( voices[i].live ) - voices[i].dx7_note->update(data, voices[i].midi_note, feedback_bitdepth); - } - lfo.reset(data + 137); - refreshVoice = false; + size_t input_offset; + + TransferInput(); + for (input_offset = 0; input_offset < input_buffer_index_; ) { + int bytes_available = input_buffer_index_ - input_offset; + int bytes_consumed = ProcessMidiMessage(input_buffer_ + input_offset, bytes_available); + if (bytes_consumed == 0) { + break; } + input_offset += bytes_consumed; + } + ConsumeInput(input_offset); - // flush first events - for (i=0; i < n_samples && i < extra_buf_size_; i++) { - buffer[i] = extra_buf_[i]; + int i; + if ( refreshVoice ) { + for(i=0;i < MAX_ACTIVE_NOTES;i++) { + if ( voices[i].live ) + voices[i].dx7_note->update(data, voices[i].midi_note, feedback_bitdepth); } + 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 (int j = 0; j < extra_buf_size_ - n_samples; j++) { - extra_buf_[j] = extra_buf_[j + n_samples]; - } - extra_buf_size_ -= n_samples; - - // flush the events, they will be process in the next cycle - //while(getNextEvent(&it, n_samples)) { - // processMidiMessage(midiMsg); - // } - } else { - for (; i < n_samples; i += N) { - AlignedBuf audiobuf; - float sumbuf[N]; - - //while(getNextEvent(&it, i)) { - // processMidiMessage(midiMsg); - //} - - for (int j = 0; j < N; ++j) { - audiobuf.get()[j] = 0; - sumbuf[j] = 0; - } - int32_t lfovalue = lfo.getsample(); - int32_t lfodelay = lfo.getdelay(); + // remaining buffer is still to be processed + if (extra_buf_size_ > n_samples) { + for (int j = 0; j < extra_buf_size_ - n_samples; j++) { + extra_buf_[j] = extra_buf_[j + n_samples]; + } + extra_buf_size_ -= n_samples; + return; + } + for (; i < n_samples; i += N) { + AlignedBuf audiobuf; - for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { - if (voices[note].live) { - voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); - - for (int j=0; j < N; ++j) { - int32_t val = audiobuf.get()[j]; - - val = val >> 4; - int clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9; - float f = ((float) clip_val) / (float) 0x8000; - if( f > 1 ) f = 1; - if( f < -1 ) f = -1; - sumbuf[j] += f; - audiobuf.get()[j] = 0; - } - } - } + for (int j = 0; j < N; ++j) { + audiobuf.get()[j] = 0; + } + int32_t lfovalue = lfo.getsample(); + int32_t lfodelay = lfo.getdelay(); - int jmax = n_samples - i; - for (int 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; + for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) { + if (voices[note].live) { +TRACE("Voice-note: %d:%d\n",note,voices[note].midi_note); + voices[note].dx7_note->compute(audiobuf.get(), lfovalue, lfodelay, &controllers); + } } + + int jmax = n_samples - i; + for (int j = 0; j < N; ++j) { + int32_t val = audiobuf.get()[j] >> 4; + int clip_val = val < -(1 << 24) ? 0x8000 : val >= (1 << 24) ? 0x7fff : val >> 9; + // TODO: maybe some dithering? + if (j < jmax) { + buffer[i + j] = clip_val; + } else { + extra_buf_[j - jmax] = clip_val; + } + } + } + extra_buf_size_ = i - n_samples; } //void Dexed::processMidiMessage(const MidiMessage *msg) { diff --git a/src/msfa/.gitignore b/src/msfa/.gitignore new file mode 100644 index 0000000..a62c258 --- /dev/null +++ b/src/msfa/.gitignore @@ -0,0 +1,2 @@ +*.o +*.gch diff --git a/src/msfa/controllers.h b/src/msfa/controllers.h index cae40bd..5c5f6b5 100755 --- a/src/msfa/controllers.h +++ b/src/msfa/controllers.h @@ -20,10 +20,7 @@ #include "synth.h" #include #include - -#ifdef DEBUG #include "trace.h" -#endif #ifdef _WIN32 #define snprintf _snprintf