summaryrefslogtreecommitdiff
path: root/synth
diff options
context:
space:
mode:
authorFlorian Jung <flo@thinkpad.(none)>2011-01-09 19:09:05 +0100
committerFlorian Jung <flo@thinkpad.(none)>2011-01-09 19:09:05 +0100
commitdf97e0ebb7f6591c50f3a588cb2a74901d38ac4a (patch)
treeaa68ab5a73388d57636a4e5c9058b9dcc0f21e90 /synth
parentaa1c06213e695be1dcb5980b638d8ce81efb4f51 (diff)
Merged branch for compiled notes
The synthesizer is now able to load and use compiled, optimized shared objects of programs. There's also a note-compiler which creates the code for such objects. TODO: - let the note-compiler automatically compile OR rename it to code-emitter
Diffstat (limited to 'synth')
-rw-r--r--synth/.depend50
-rw-r--r--synth/Makefile4
-rw-r--r--synth/channel.cpp75
-rw-r--r--synth/channel.h4
-rw-r--r--synth/globals.cpp2
-rw-r--r--synth/globals.h2
-rw-r--r--synth/jack.cpp46
-rw-r--r--synth/main.cpp25
-rw-r--r--synth/note.cpp87
-rw-r--r--synth/note.h32
-rw-r--r--synth/note_funcs.h20
-rw-r--r--synth/note_loader.cpp54
-rw-r--r--synth/note_loader.h13
-rw-r--r--synth/note_skel.cpp74
-rw-r--r--synth/note_skel.h56
-rw-r--r--synth/parser.cpp4
-rw-r--r--synth/programs.cpp7
-rw-r--r--synth/programs.h6
-rw-r--r--synth/util.cpp2
19 files changed, 409 insertions, 154 deletions
diff --git a/synth/.depend b/synth/.depend
index 3a0b0ed..fb0d8aa 100644
--- a/synth/.depend
+++ b/synth/.depend
@@ -1,25 +1,31 @@
-channel.o: channel.cpp channel.h fixed.h programs.h note.h envelope.h \
- filter.h defines.h util.h globals.h
-cli.o: cli.cpp util.h programs.h fixed.h globals.h channel.h note.h \
- envelope.h filter.h defines.h load.h
+channel.o: channel.cpp channel.h fixed.h programs.h note_funcs.h \
+ note_skel.h defines.h util.h globals.h note.h envelope.h filter.h
+cli.o: cli.cpp util.h programs.h fixed.h note_funcs.h globals.h channel.h \
+ note_skel.h defines.h load.h
defines.o: defines.cpp defines.h
-envelope.o: envelope.cpp envelope.h programs.h fixed.h
+envelope.o: envelope.cpp envelope.h programs.h fixed.h note_funcs.h
filter.o: filter.cpp filter.h fixed.h defines.h globals.h programs.h \
- channel.h note.h envelope.h util.h
-globals.o: globals.cpp globals.h programs.h fixed.h channel.h note.h \
- envelope.h filter.h defines.h util.h
-jack.o: jack.cpp defines.h globals.h programs.h fixed.h channel.h note.h \
- envelope.h filter.h util.h jack.h
-load.o: load.cpp util.h programs.h fixed.h globals.h channel.h note.h \
- envelope.h filter.h defines.h
+ note_funcs.h channel.h note_skel.h util.h
+globals.o: globals.cpp globals.h programs.h fixed.h note_funcs.h \
+ channel.h note_skel.h defines.h util.h
+jack.o: jack.cpp defines.h globals.h programs.h fixed.h note_funcs.h \
+ channel.h note_skel.h util.h jack.h
+load.o: load.cpp util.h programs.h fixed.h note_funcs.h globals.h \
+ channel.h note_skel.h defines.h
main.o: main.cpp jack.h load.h cli.h parser.h fixed.h programs.h \
- channel.h note.h envelope.h filter.h defines.h util.h globals.h
-note.o: note.cpp note.h programs.h fixed.h envelope.h filter.h globals.h \
- channel.h defines.h util.h
-parser.o: parser.cpp parser.h fixed.h programs.h defines.h globals.h \
- channel.h note.h envelope.h filter.h util.h readwave.h
-programs.o: programs.cpp programs.h fixed.h globals.h channel.h note.h \
- envelope.h filter.h defines.h util.h
-readwave.o: readwave.cpp readwave.h programs.h fixed.h util.h
-util.o: util.cpp util.h programs.h fixed.h globals.h channel.h note.h \
- envelope.h filter.h defines.h
+ note_funcs.h channel.h note_skel.h defines.h util.h globals.h \
+ note_loader.h
+note.o: note.cpp note.h programs.h fixed.h note_funcs.h envelope.h \
+ filter.h note_skel.h globals.h channel.h defines.h util.h
+note_skel.o: note_skel.cpp note_skel.h programs.h fixed.h note_funcs.h \
+ globals.h channel.h defines.h util.h
+parser.o: parser.cpp parser.h fixed.h programs.h note_funcs.h defines.h \
+ globals.h channel.h note_skel.h util.h readwave.h
+programs.o: programs.cpp programs.h fixed.h note_funcs.h globals.h \
+ channel.h note_skel.h defines.h util.h
+readwave.o: readwave.cpp readwave.h programs.h fixed.h note_funcs.h \
+ util.h
+util.o: util.cpp util.h programs.h fixed.h note_funcs.h globals.h \
+ channel.h note_skel.h defines.h
+note_loader.o: note_loader.cpp note_loader.h programs.h fixed.h \
+ note_funcs.h globals.h channel.h note_skel.h defines.h util.h
diff --git a/synth/Makefile b/synth/Makefile
index f84441c..c1d6dab 100644
--- a/synth/Makefile
+++ b/synth/Makefile
@@ -1,9 +1,9 @@
CXX=g++
-CFLAGS=-Wall -g
+CFLAGS=-Wall -O2
CXXFLAGS=$(CFLAGS)
LDFLAGS=-lm `pkg-config --cflags --libs jack`
-OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o
+OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o
BIN=synth
DEPENDFILE = .depend
diff --git a/synth/channel.cpp b/synth/channel.cpp
index 6446b0f..0042162 100644
--- a/synth/channel.cpp
+++ b/synth/channel.cpp
@@ -3,6 +3,11 @@
#include "math.h"
#include "globals.h"
+#include "note.h"
+
+#include "note_funcs.h"
+
+
Channel::Channel()
{
volume=ONE;
@@ -32,11 +37,11 @@ Channel::~Channel()
void Channel::cleanup()
{
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end(); it++)
if ((*it)->still_active()==false)
{
- delete *it;
+ (*it)->destroy();
it=notes.erase(it);
}
}
@@ -45,7 +50,7 @@ fixed_t Channel::get_sample()
{
fixed_t sum=0;
- for (list<Note*>::iterator it=notes.begin(); it!=notes.end(); it++)
+ for (list<NoteSkel*>::iterator it=notes.begin(); it!=notes.end(); it++)
sum+=(*it)->get_sample();
return sum*volume >>SCALE;
@@ -82,14 +87,14 @@ void Channel::note_off(int note)
void Channel::really_do_note_off(int note)
{
- for (list<Note*>::iterator it=notes.begin(); it!=notes.end(); it++)
+ for (list<NoteSkel*>::iterator it=notes.begin(); it!=notes.end(); it++)
if ((*it)->get_note()==note)
(*it)->release();
}
void Channel::note_on(int note, int vel)
{
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
if (vel>0) //note on
{
pressed_keys.insert(note);
@@ -97,22 +102,29 @@ void Channel::note_on(int note, int vel)
if ( (n_voices==1) && (!notes.empty()) ) //we're in monomode
{
//no need to create a new note; reuse the existing
- Note *n; //i'm lazy
+ NoteSkel *n; //i'm lazy
n= *(notes.begin());
if (n->get_program() != program)
{
//if the program has changed, kill the previous note and
//create a new one
- delete n;
+ n->destroy();
notes.clear();
- notes.push_back( new Note(note,(float)vel/128.0,
- curr_prg,
- portamento_frames,
- pitchbend,
- program) );
-
+ NoteSkel *newnote=NULL;
+ if (curr_prg.create_func==NULL)
+ newnote = new Note(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+ else
+ newnote = curr_prg.create_func(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+
+ notes.push_back(newnote);
}
else //program did not change
{
@@ -139,11 +151,22 @@ void Channel::note_on(int note, int vel)
}
if (neednewnote)
- notes.push_back( new Note(note,(float)vel/128.0,
- curr_prg,
- portamento_frames,
- pitchbend,
- program) );
+ {
+ NoteSkel *newnote=NULL;
+ if (curr_prg.create_func==NULL)
+ newnote = new Note(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+ else
+ newnote = curr_prg.create_func(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+
+ notes.push_back(newnote);
+ }
+
apply_voice_limit();
}
}
@@ -171,7 +194,7 @@ void Channel::apply_voice_limit()
int diff=notes.size()-n_voices;
if (diff>0)
{
- list<Note*>::iterator it=notes.begin();
+ list<NoteSkel*>::iterator it=notes.begin();
if (quick_release)
for (int i=0;i<diff;i++)
@@ -182,7 +205,7 @@ void Channel::apply_voice_limit()
else
for (int i=0;i<diff;i++)
{
- delete (*it);
+ (*it)->destroy();
it=notes.erase(it);
}
}
@@ -259,7 +282,7 @@ void Channel::recalc_param(const parameter_t &par, program_t &prg)
// waveform etc it's in int (i.e., val/ONE is very small, while
// val is what we want)
- for (list<Note*>::iterator it=notes.begin(); it!=notes.end(); it++)
+ for (list<NoteSkel*>::iterator it=notes.begin(); it!=notes.end(); it++)
(*it)->set_param(par, val);
curr_prg.set_param(par, val);
@@ -320,7 +343,7 @@ void Channel::set_real_portamento_frames()
else
portamento_frames=0;
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end(); it++)
(*it)->set_portamento_frames(portamento_frames);
}
@@ -374,17 +397,17 @@ void Channel::set_legato_pedal(bool newstate)
void Channel::panic()
{
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end();)
{
- delete *it;
+ (*it)->destroy();
it=notes.erase(it);
}
}
void Channel::release_all()
{
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end(); it++)
(*it)->release();
}
@@ -399,7 +422,7 @@ void Channel::set_pitch_bend(float val)
{
pitchbend=pow(2.0,val/12.0)*ONE;
- list<Note*>::iterator it;
+ list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end(); it++)
(*it)->set_pitchbend(pitchbend);
}
diff --git a/synth/channel.h b/synth/channel.h
index f673294..b0a855a 100644
--- a/synth/channel.h
+++ b/synth/channel.h
@@ -7,7 +7,7 @@
#include "fixed.h"
#include "programs.h"
-#include "note.h"
+#include "note_skel.h"
#include "defines.h"
#include "util.h"
@@ -55,7 +55,7 @@ class Channel
fixed_t pitchbend;
float max_pitchbend;
- std::list<Note*> notes;
+ std::list<NoteSkel*> notes;
bool do_portamento;
diff --git a/synth/globals.cpp b/synth/globals.cpp
index e932fcb..6a84353 100644
--- a/synth/globals.cpp
+++ b/synth/globals.cpp
@@ -3,7 +3,7 @@
fixed_t **lfo[N_LFOS];
fixed_t *curr_lfo[N_LFOS+1];
-fixed_t wave[N_WAVEFORMS][WAVE_RES];
+fixed_t* wave[N_WAVEFORMS];
fixed_t sample_and_hold[N_LFO_LEVELS];
diff --git a/synth/globals.h b/synth/globals.h
index efbbe72..ffc1de5 100644
--- a/synth/globals.h
+++ b/synth/globals.h
@@ -14,7 +14,7 @@ using namespace std;
extern fixed_t **lfo[N_LFOS];
extern fixed_t *curr_lfo[N_LFOS+1];
-extern fixed_t wave[N_WAVEFORMS][WAVE_RES];
+extern fixed_t* wave[N_WAVEFORMS];
extern fixed_t sample_and_hold[N_LFO_LEVELS];
diff --git a/synth/jack.cpp b/synth/jack.cpp
index 093e9b5..3949722 100644
--- a/synth/jack.cpp
+++ b/synth/jack.cpp
@@ -12,7 +12,7 @@
using namespace std;
-//#define DO_DEBUGGING_EVENTS
+#define DO_DEBUGGING_EVENTS
jack_port_t *midi_in;
jack_port_t *out_port[N_CHANNELS];
@@ -317,7 +317,7 @@ int process_callback(jack_nframes_t nframes, void *notused)
}
else if (tmp2==0)
{
- if (lastframe>tmp+44100*2)
+ if (lastframe>tmp+44100*1)
{
tmp2=1;
cout << "BÄÄM" << endl;
@@ -326,17 +326,53 @@ int process_callback(jack_nframes_t nframes, void *notused)
}
else if (tmp2==1)
{
- if (lastframe>tmp+44100*4)
+ if (lastframe>tmp+44100*2)
{
tmp2=2;
channel[0]->event(0x90,87,5);
- channel[0]->set_controller(57, 127);
+ channel[0]->set_controller(58, 0);
+ cout << "BÄÄM2" << endl;
+ }
+ }
+ else if (tmp2==2)
+ {
+ if (lastframe>tmp+44100*3)
+ {
+ tmp2=3;
+ channel[0]->event(0x90,90,127);
+ cout << "BÄÄM2" << endl;
+ }
+ }
+ else if (tmp2==3)
+ {
+ if (lastframe>tmp+44100*4)
+ {
+ tmp2=4;
+ channel[0]->event(0x90,60,96);
+ cout << "BÄÄM2" << endl;
+ }
+ }
+ else if (tmp2==4)
+ {
+ if (lastframe>tmp+44100*5)
+ {
+ tmp2=5;
+ channel[0]->event(0x90,63,32);
+ cout << "BÄÄM2" << endl;
+ }
+ }
+ else if (tmp2==5)
+ {
+ if (lastframe>tmp+44100*6)
+ {
+ tmp2=6;
+ channel[0]->event(0x90,66,60);
cout << "BÄÄM2" << endl;
}
}
else
{
- if (lastframe>tmp+44100*10)
+ if (lastframe>tmp+44100*8)
{
cout << "finished" << endl;
exit(0);
diff --git a/synth/main.cpp b/synth/main.cpp
index 95444cb..1c8dd4c 100644
--- a/synth/main.cpp
+++ b/synth/main.cpp
@@ -12,6 +12,7 @@
#include "programs.h"
#include "defines.h"
#include "globals.h"
+#include "note_loader.h"
using namespace std;
@@ -106,6 +107,23 @@ int main(int argc, char** argv)
try
{
program_settings[i]=parse(programfile[i]);
+
+ // try to load the appropriate .so file
+ if (access( (programfile[i]+".so").c_str(), R_OK ) == 0)
+ {
+ try
+ {
+ load_note_from_so(programfile[i]+".so", program_settings[i]);
+ output_verbose("NOTE: loaded shared object for program '"+programfile[i]+"'");
+ }
+ catch (string err)
+ {
+ output_note("NOTE: could not load shared object '"+programfile[i]+".so"+"':\n"
+ " "+err+"\n"
+ " this is not fatal, the note has been loaded properly, but generic\n"
+ " unoptimized (slow) code will be used.");
+ }
+ }
}
catch (string err)
{
@@ -121,7 +139,9 @@ int main(int argc, char** argv)
}
}
-
+ for (i=0;i<N_WAVEFORMS;i++)
+ wave[i]=new fixed_t[WAVE_RES];
+
for (i=0;i<WAVE_RES;i++)
{
wave[0][i]=sin(i*2.0*3.141592654/WAVE_RES)*ONE;
@@ -165,6 +185,9 @@ void cleanup()
channel[i]=NULL;
}
+ for (int i=0;i<128;i++)
+ maybe_unload_note(program_settings[i]);
+
delete [] program_settings;
}
diff --git a/synth/note.cpp b/synth/note.cpp
index a9a5a42..b6bfa22 100644
--- a/synth/note.cpp
+++ b/synth/note.cpp
@@ -1,4 +1,3 @@
-#include <string>
#include <cmath>
#include "note.h"
@@ -17,8 +16,12 @@ inline fixed_t init_custom_osc_phase(int len, fixed_t sr)
Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)
{
+
curr_prg=&prg;
+
+
+
n_oscillators=prg.n_osc;
@@ -62,17 +65,8 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr
}
- portamento_frames=0;
- set_portamento_frames(pf);
-
- set_note(n);
- freq=dest_freq;
- set_vel(v);
do_ksl();
- pitchbend=pb;
-
- program=prg_no;
filter_params=prg.filter_settings;
orig.filter_params=prg.filter_settings;
@@ -88,6 +82,22 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr
sync_factor=prg.sync_factor;
sync_phase=0;
+
+
+
+
+ portamento_frames=0;
+ set_portamento_frames(pf);
+
+ set_note(n);
+ freq=dest_freq;
+ set_vel(v);
+
+ pitchbend=pb;
+
+ program=prg_no;
+
+
}
Note::~Note()
@@ -262,52 +272,6 @@ void Note::reattack()
filter_envelope->reattack();
}
-void Note::set_pitchbend(fixed_t pb)
-{
- pitchbend=pb;
-}
-
-void Note::set_freq(float f)
-{
- old_freq=freq;
- dest_freq=f*ONE;
- portamento_t=0;
-
- do_ksr();
-}
-
-void Note::set_freq(float f, bool do_port)
-{
- set_freq(f);
-
- if (!do_port)
- old_freq=dest_freq;
-}
-
-void Note::set_note(int n)
-{
- note=n;
- set_freq(440.0*pow(2.0,(float)(n-69)/12.0));
-}
-
-void Note::set_note(int n, bool do_port)
-{
- note=n;
- set_freq(440.0*pow(2.0,(float)(n-69)/12.0), do_port);
-}
-
-int Note::get_note()
-{
- return note;
-}
-
-void Note::set_vel(float v)
-{
- vel=v*ONE;
-
- recalc_factors();
- apply_pfactor();
-}
void Note::do_ksl()
{ //osc.ksl is in Bel/octave (i.e. dB/10)
@@ -328,12 +292,6 @@ void Note::do_ksr()
envelope[i]->set_ratefactor(1.0 / pow(freq>>SCALE, oscillator[i].ksr));
}
-void Note::set_portamento_frames(jack_nframes_t t)
-{
- portamento_frames=t;
- portamento_t=0;
-}
-
fixed_t Note::get_sample()
{
if (freq!=dest_freq)
@@ -450,3 +408,8 @@ fixed_t Note::get_sample()
return out;
}
}
+
+void Note::destroy()
+{
+ delete this;
+}
diff --git a/synth/note.h b/synth/note.h
index 26ce379..03a7180 100644
--- a/synth/note.h
+++ b/synth/note.h
@@ -7,27 +7,22 @@
#include "envelope.h"
#include "fixed.h"
#include "filter.h"
+#include "note_skel.h"
-class Note
+class Note : public NoteSkel
{
public:
Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no);
~Note();
fixed_t get_sample();
- int get_note();
- void set_note(int n);
- void set_note(int n, bool do_port);
- void set_freq(float f);
- void set_freq(float f, bool do_port);
- void set_pitchbend(fixed_t pb);
- void set_vel(float v);
- void set_portamento_frames(jack_nframes_t f);
+
void release_quickly(jack_nframes_t maxt);
void release();
void reattack();
bool still_active();
void set_param(const parameter_t &p, fixed_t v);
- int get_program(){return program;}
+
+ void destroy();
private:
void do_ksl();
@@ -37,10 +32,6 @@ class Note
void apply_pfactor();
Envelope **envelope;
-
- fixed_t freq, dest_freq, old_freq;
- fixed_t vel;
- jack_nframes_t portamento_t, portamento_frames;
int env_frame_counter;
@@ -55,12 +46,6 @@ class Note
pfactor_value_t pfactor;
- int note;
- int program;
- program_t *curr_prg;
-
- fixed_t pitchbend;
-
LowPassFilter filter;
Envelope *filter_envelope;
filter_params_t filter_params;
@@ -71,13 +56,6 @@ class Note
oscillator_t *oscillator;
filter_params_t filter_params;
} orig;
-
-/* *einstellungen: oszillatoren, deren lautstärke etc.
- * note
- * lautstärke
- * *pitchbend
- * *portamento time
- */
};
diff --git a/synth/note_funcs.h b/synth/note_funcs.h
new file mode 100644
index 0000000..2a9d3c0
--- /dev/null
+++ b/synth/note_funcs.h
@@ -0,0 +1,20 @@
+#ifndef __NOTE_FUNCS_H
+#define __NOTE_FUNCS_H
+
+#include <jack/jack.h>
+
+#include "fixed.h"
+#include <string>
+
+using namespace std;
+
+class NoteSkel;
+struct program_t;
+
+typedef void output_note_func_t(string s);
+typedef string IntToStr_func_t(int i);
+
+typedef NoteSkel* create_func_t (int, float, program_t&, jack_nframes_t, fixed_t, int);
+typedef void init_func_t(int sr, int fupfr, fixed_t **w, fixed_t **clfo, output_note_func_t* out_n, IntToStr_func_t* its);
+
+#endif
diff --git a/synth/note_loader.cpp b/synth/note_loader.cpp
new file mode 100644
index 0000000..28613b9
--- /dev/null
+++ b/synth/note_loader.cpp
@@ -0,0 +1,54 @@
+
+#include <iostream>
+#include <dlfcn.h>
+
+#include "note_loader.h"
+#include "programs.h"
+#include "note_funcs.h"
+#include "globals.h"
+
+using namespace std;
+
+void load_note_from_so(string file, program_t &prog)
+{
+ void *handle;
+
+ handle = dlopen(file.c_str(), RTLD_LAZY);
+
+ if (handle==NULL)
+ throw string("could not open shared object (")+string(dlerror())+string(")");
+
+ try
+ {
+ prog.create_func=(create_func_t*) dlsym(handle,"create_note");
+ if (prog.create_func==NULL)
+ throw string("could not find symbol create_note in shared object (")+dlerror()+")";
+
+ init_func_t* initfunc=(init_func_t*) dlsym(handle,"init_vars");
+ if (initfunc==NULL)
+ throw string("could not find symbol init_vars in shared object (")+dlerror()+")";
+
+ initfunc(samp_rate, filter_update_frames, wave, curr_lfo, &output_note, &IntToStr);
+
+
+
+ prog.dl_handle=handle;
+ }
+ catch (string err)
+ {
+ prog.create_func=NULL;
+ prog.dl_handle=NULL;
+ dlclose(handle);
+ throw err;
+ }
+}
+
+void maybe_unload_note(program_t &prog)
+{
+ if (prog.dl_handle)
+ {
+ dlclose(prog.dl_handle);
+ prog.dl_handle=NULL;
+ prog.create_func=NULL;
+ }
+}
diff --git a/synth/note_loader.h b/synth/note_loader.h
new file mode 100644
index 0000000..6731da1
--- /dev/null
+++ b/synth/note_loader.h
@@ -0,0 +1,13 @@
+#ifndef __NOTE_LOADER_H__
+#define __NOTE_LOADER_H__
+
+#include <string>
+#include <jack/jack.h>
+
+#include "programs.h"
+
+using namespace std;
+
+void load_note_from_so(string file, program_t &prog); //throws string
+void maybe_unload_note(program_t &prog);
+#endif
diff --git a/synth/note_skel.cpp b/synth/note_skel.cpp
new file mode 100644
index 0000000..b028ca4
--- /dev/null
+++ b/synth/note_skel.cpp
@@ -0,0 +1,74 @@
+#include <cmath>
+
+#include "note_skel.h"
+#include "globals.h"
+#include "defines.h"
+
+using namespace std;
+
+NoteSkel::NoteSkel()
+{
+}
+
+NoteSkel::~NoteSkel()
+{
+
+}
+
+void NoteSkel::set_pitchbend(fixed_t pb)
+{
+ pitchbend=pb;
+}
+
+void NoteSkel::set_freq(float f)
+{
+ old_freq=freq;
+ dest_freq=f*ONE;
+ portamento_t=0;
+
+ do_ksr();
+}
+
+void NoteSkel::set_freq(float f, bool do_port)
+{
+ set_freq(f);
+
+ if (!do_port)
+ old_freq=dest_freq;
+}
+
+void NoteSkel::set_note(int n)
+{
+ note=n;
+ set_freq(440.0*pow(2.0,(float)(n-69)/12.0));
+}
+
+void NoteSkel::set_note(int n, bool do_port)
+{
+ note=n;
+ set_freq(440.0*pow(2.0,(float)(n-69)/12.0), do_port);
+}
+
+int NoteSkel::get_note()
+{
+ return note;
+}
+
+void NoteSkel::set_vel(float v)
+{
+ vel=v*ONE;
+
+ recalc_factors();
+ apply_pfactor();
+}
+
+void NoteSkel::set_portamento_frames(jack_nframes_t t)
+{
+ portamento_frames=t;
+ portamento_t=0;
+}
+
+int NoteSkel::get_program()
+{
+ return program;
+}
diff --git a/synth/note_skel.h b/synth/note_skel.h
new file mode 100644
index 0000000..6aebb8b
--- /dev/null
+++ b/synth/note_skel.h
@@ -0,0 +1,56 @@
+#ifndef __NOTE_SKEL_H__
+#define __NOTE_SKEL_H__
+
+#include <jack/jack.h>
+
+#include "programs.h"
+#include "fixed.h"
+
+class NoteSkel
+{
+ public:
+ NoteSkel();
+ virtual ~NoteSkel();
+ virtual fixed_t get_sample()=0;
+
+ int get_program();
+ int get_note();
+ void set_note(int n);
+ void set_note(int n, bool do_port);
+ void set_freq(float f);
+ void set_freq(float f, bool do_port);
+ void set_pitchbend(fixed_t pb);
+ void set_vel(float v);
+ void set_portamento_frames(jack_nframes_t f);
+
+ virtual void release_quickly(jack_nframes_t maxt)=0;
+ virtual void release()=0;
+ virtual void reattack()=0;
+ virtual bool still_active()=0;
+
+ virtual void set_param(const parameter_t &p, fixed_t v)=0;
+
+ virtual void destroy()=0;
+
+ protected:
+ virtual void do_ksl()=0;
+ virtual void do_ksr()=0;
+
+ virtual void recalc_factors()=0;
+ virtual void apply_pfactor()=0;
+
+ fixed_t freq, dest_freq, old_freq;
+ fixed_t vel;
+ jack_nframes_t portamento_t, portamento_frames;
+
+ pfactor_value_t pfactor;
+
+ int note;
+ int program;
+ program_t *curr_prg;
+
+ fixed_t pitchbend;
+};
+
+
+#endif
diff --git a/synth/parser.cpp b/synth/parser.cpp
index 96648d6..5da2175 100644
--- a/synth/parser.cpp
+++ b/synth/parser.cpp
@@ -1,5 +1,3 @@
-//uniniten
-
#include <cstdlib>
#include <fstream>
@@ -286,7 +284,7 @@ program_t parse(string fn)
pfactor_formula_t pfactor;
- fixed_t sync_factor;
+ fixed_t sync_factor=0;
diff --git a/synth/programs.cpp b/synth/programs.cpp
index be82fed..094f209 100644
--- a/synth/programs.cpp
+++ b/synth/programs.cpp
@@ -49,6 +49,9 @@ program_t::program_t()
pfactor.fm=NULL;
pfactor.out=NULL;
+
+ create_func=NULL;
+ dl_handle=NULL;
}
program_t::~program_t()
@@ -115,6 +118,10 @@ program_t& program_t::operator=(const program_t &that)
memcpy(this->pfactor.fm[i], that.pfactor.fm[i], sizeof(param_factor_t)*n_osc);
}
+
+ this->create_func=that.create_func;
+ this->dl_handle=that.dl_handle;
+
return *this;
}
else
diff --git a/synth/programs.h b/synth/programs.h
index e0b409c..9d8d8cc 100644
--- a/synth/programs.h
+++ b/synth/programs.h
@@ -7,6 +7,7 @@
#include <list>
#include "fixed.h"
+#include "note_funcs.h"
#include <jack/jack.h>
using namespace std;
@@ -173,7 +174,10 @@ struct program_t
pfactor_formula_t pfactor;
-
+
+ void *dl_handle;
+ create_func_t *create_func;
+
program_t();
~program_t();
diff --git a/synth/util.cpp b/synth/util.cpp
index ca213fd..51e6fda 100644
--- a/synth/util.cpp
+++ b/synth/util.cpp
@@ -192,7 +192,7 @@ string extract_val(string s)
if (p!=string::npos)
return s.substr(p+1);
else
- return "";
+ return s;
}
string fileext(string f)