Some changes and fixes. Hope it will produce sound and not noise...

pull/1/head
Holger Wirtz 8 years ago
parent 96470269a0
commit 90b9828b5b
  1. 1
      src/.gitignore
  2. 13
      src/Makefile
  3. 108
      src/dexed-test.cpp
  4. 6
      src/dexed-test.sh
  5. 153
      src/dexed.cpp
  6. 2
      src/msfa/.gitignore
  7. 3
      src/msfa/controllers.h

1
src/.gitignore vendored

@ -1,2 +1,3 @@
*.peg
dexed.lv2/
*.gch

@ -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

@ -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 <cstdint>
#include <limits>
template<class T> float normalize(const T x) {
const float valMin = std::numeric_limits<T>::min();
const float valMax = std::numeric_limits<T>::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;i<sizeof(init_voice);i++) {
data[i] = init_voice[i];
}
controllers.values_[kControllerPitchRange] = 3;
controllers.values_[kControllerPitchStep] = 0;
controllers.masterTune = 0;
controllers.values_[kControllerPitch] = 0x2000;
controllers.modwheel_cc = 0;
controllers.foot_cc = 0;
controllers.breath_cc = 0;
controllers.aftertouch_cc = 0;
controllers.core=&engineMsfa;
lfo.reset(data + 137);
voice.dx7_note=new Dx7Note;
unsigned char key=64;
unsigned char velocity=100;
voice.midi_note=key+data[144] - 24;
voice.keydown=true;
voice.live=false;
voice.sustained=false;
lfo.keydown();
if(voice.live==false)
{
voice.dx7_note->init(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());
}
}
}

@ -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

@ -87,6 +87,8 @@ void Dexed::set_params(void)
{
TRACE("Hi");
refreshVoice=true;
// OP6
onParam(0,static_cast<char>(*p(p_op6_eg_rate_1)));
onParam(1,static_cast<char>(*p(p_op6_eg_rate_2)));
@ -251,9 +253,6 @@ void Dexed::run (uint32_t sample_count)
const LV2_Atom_Sequence* seq = p<LV2_Atom_Sequence> (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;i<ev->body.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<float> (outbuf16_[i])) * level;
output[j] = (static_cast<float> (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<float> (outbuf16_[i])) * level;
output[j] = (static_cast<float> (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<int32_t, N> 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<int32_t, N> 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) {

@ -0,0 +1,2 @@
*.o
*.gch

@ -20,10 +20,7 @@
#include "synth.h"
#include <stdio.h>
#include <string.h>
#ifdef DEBUG
#include "trace.h"
#endif
#ifdef _WIN32
#define snprintf _snprintf

Loading…
Cancel
Save