diff options
Diffstat (limited to 'synth')
-rw-r--r-- | synth/Makefile | 2 | ||||
-rw-r--r-- | synth/channel.cpp | 157 | ||||
-rw-r--r-- | synth/channel.h | 1 | ||||
-rw-r--r-- | synth/communication.cpp | 16 | ||||
-rw-r--r-- | synth/communication.h | 22 | ||||
-rw-r--r-- | synth/globals.cpp | 1 | ||||
-rw-r--r-- | synth/globals.h | 1 | ||||
-rw-r--r-- | synth/in_synth_cli.cpp | 55 | ||||
-rw-r--r-- | synth/jack.cpp | 35 | ||||
-rw-r--r-- | synth/main.cpp | 9 |
10 files changed, 221 insertions, 78 deletions
diff --git a/synth/Makefile b/synth/Makefile index 5a308e3..2f16297 100644 --- a/synth/Makefile +++ b/synth/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -g 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 note_loader.o in_synth_cli.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 in_synth_cli.o communication.o BIN=synth DEPENDFILE = .depend diff --git a/synth/channel.cpp b/synth/channel.cpp index fe28e7d..dbfcc48 100644 --- a/synth/channel.cpp +++ b/synth/channel.cpp @@ -100,82 +100,86 @@ void Channel::note_on(int note, int vel) { pressed_keys.insert(note); - if ( (n_voices==1) && (!notes.empty()) ) //we're in monomode - { - //no need to create a new note; reuse the existing - NoteSkel *n; //i'm lazy - n= *(notes.begin()); - - if (n->get_program() != program) + if (program_lock[program]==false) + { + if ( (n_voices==1) && (!notes.empty()) ) //we're in monomode { - //if the program has changed, kill the previous note and - //create a new one - n->destroy(); - notes.clear(); + //no need to create a new note; reuse the existing + NoteSkel *n; //i'm lazy + n= *(notes.begin()); - NoteSkel *newnote=NULL; - if (curr_prg.create_func==NULL) - newnote = new Note(note,(float)vel/128.0, - curr_prg, - portamento_frames, pitchbend, - program, - curr_vol_factor); - else - newnote = curr_prg.create_func(note,(float)vel/128.0, - curr_prg, - portamento_frames, pitchbend, - program, - curr_vol_factor); - - notes.push_back(newnote); - } - else //program did not change - { - //if not still active, don't do portamento - n->set_note(note,n->still_active()); - n->set_vel((float)vel/128.0); - if ((legato_pedal_pressed==false) || !n->still_active()) n->reattack(); - n->set_vol_factor(curr_vol_factor); - //no need to push back. would become #1 instead of #1 + if (n->get_program() != program) + { + //if the program has changed, kill the previous note and + //create a new one + n->destroy(); + notes.clear(); + + NoteSkel *newnote=NULL; + if (curr_prg.create_func==NULL) + newnote = new Note(note,(float)vel/128.0, + curr_prg, + portamento_frames, pitchbend, + program, + curr_vol_factor); + else + newnote = curr_prg.create_func(note,(float)vel/128.0, + curr_prg, + portamento_frames, pitchbend, + program, + curr_vol_factor); + + notes.push_back(newnote); + } + else //program did not change + { + //if not still active, don't do portamento + n->set_note(note,n->still_active()); + n->set_vel((float)vel/128.0); + if ((legato_pedal_pressed==false) || !n->still_active()) n->reattack(); + n->set_vol_factor(curr_vol_factor); + //no need to push back. would become #1 instead of #1 + } } - } - else //we're in polymode - { - bool neednewnote=true; - //if (always_reattack) always_reattack is always true when in polymode - for (it=notes.begin(); it!=notes.end(); it++) - if ( ((*it)->get_note()==note) && ((*it)->get_program()==program) ) - { - neednewnote=false; - (*it)->reattack(); - (*it)->set_vel((float)vel/128.0); - (*it)->set_vol_factor(curr_vol_factor); - notes.push_back(*it); //reorder notes - notes.erase(it); - break; - } - - if (neednewnote) + else //we're in polymode { - NoteSkel *newnote=NULL; - if (curr_prg.create_func==NULL) - newnote = new Note(note,(float)vel/128.0, - curr_prg, - portamento_frames, pitchbend, - program, - curr_vol_factor); - else - newnote = curr_prg.create_func(note,(float)vel/128.0, - curr_prg, - portamento_frames, pitchbend, - program, - curr_vol_factor); - - notes.push_back(newnote); - } + bool neednewnote=true; + //if (always_reattack) always_reattack is always true when in polymode + for (it=notes.begin(); it!=notes.end(); it++) + if ( ((*it)->get_note()==note) && ((*it)->get_program()==program) ) + { + neednewnote=false; + (*it)->reattack(); + (*it)->set_vel((float)vel/128.0); + (*it)->set_vol_factor(curr_vol_factor); + notes.push_back(*it); //reorder notes + notes.erase(it); + break; + } + + if (neednewnote) + { + NoteSkel *newnote=NULL; + if (curr_prg.create_func==NULL) + newnote = new Note(note,(float)vel/128.0, + curr_prg, + portamento_frames, pitchbend, + program, + curr_vol_factor); + else + newnote = curr_prg.create_func(note,(float)vel/128.0, + curr_prg, + portamento_frames, pitchbend, + program, + curr_vol_factor); + + notes.push_back(newnote); + } - apply_voice_limit(); + apply_voice_limit(); + } } + // else (if the program is locked) simply ignore the note-on } else //note off { @@ -418,6 +422,19 @@ void Channel::panic() } } +void Channel::kill_program(int prog) +{ + list<NoteSkel*>::iterator it; + for (it=notes.begin(); it!=notes.end();) + if ((*it)->get_program()==prog) + { + (*it)->destroy(); + it=notes.erase(it); + } + else + it++; +} + void Channel::release_all() { list<NoteSkel*>::iterator it; diff --git a/synth/channel.h b/synth/channel.h index 9727ab8..c0eee5c 100644 --- a/synth/channel.h +++ b/synth/channel.h @@ -28,6 +28,7 @@ class Channel void cleanup(); void release_all(); void panic(); + void kill_program(int prog); void set_real_portamento_frames(); void set_portamento_time(int val); void set_portamento(int val); diff --git a/synth/communication.cpp b/synth/communication.cpp new file mode 100644 index 0000000..f21e46f --- /dev/null +++ b/synth/communication.cpp @@ -0,0 +1,16 @@ +#include "communication.h" + +pthread_mutex_t suspend_request_mutex; +suspend_request_t suspend_request; + +void init_communication() +{ + pthread_mutex_init(&suspend_request_mutex, NULL); + + suspend_request.done=true; +} + +void uninit_communication() +{ + pthread_mutex_destroy(&suspend_request_mutex); +} diff --git a/synth/communication.h b/synth/communication.h new file mode 100644 index 0000000..27f7186 --- /dev/null +++ b/synth/communication.h @@ -0,0 +1,22 @@ +#ifndef __COMMUNICATION_H__ +#define __COMMUNICATION_H__ + +#include <pthread.h> + +struct suspend_request_t +{ + int prog; //if negative, all programs are affected + bool suspend; //true->suspend, false->use them again + bool done; //must be set to false by the requester, + //must be set to true after processing by the requestee +}; + + +extern pthread_mutex_t suspend_request_mutex; +extern suspend_request_t suspend_request; + + + +void init_communication(); +void uninit_communication(); +#endif diff --git a/synth/globals.cpp b/synth/globals.cpp index 6a84353..427eebe 100644 --- a/synth/globals.cpp +++ b/synth/globals.cpp @@ -54,6 +54,7 @@ string programfile[128]; program_t *program_settings; +bool program_lock[128]; Channel *channel[N_CHANNELS]; diff --git a/synth/globals.h b/synth/globals.h index ffc1de5..b91efef 100644 --- a/synth/globals.h +++ b/synth/globals.h @@ -65,6 +65,7 @@ extern string programfile[128]; extern program_t *program_settings; +extern bool program_lock[128]; extern Channel *channel[N_CHANNELS]; diff --git a/synth/in_synth_cli.cpp b/synth/in_synth_cli.cpp index 7aa1d8e..4334978 100644 --- a/synth/in_synth_cli.cpp +++ b/synth/in_synth_cli.cpp @@ -1,9 +1,13 @@ #include <iostream> #include <string> #include <signal.h> +#include <unistd.h> +#include <stdlib.h> #include "in_synth_cli.h" #include "util.h" +#include "communication.h" +#include "globals.h" using namespace std; @@ -14,16 +18,53 @@ void signal_handler(int sig) cout << endl << PROMPT << flush; } +void do_request(int prg_no, bool susp) +{ + pthread_mutex_lock(&suspend_request_mutex); + + suspend_request.prog=prg_no; + suspend_request.suspend=susp; + suspend_request.done=false; + + pthread_mutex_unlock(&suspend_request_mutex); + + + + while (true) + { + usleep(100000); + + pthread_mutex_lock(&suspend_request_mutex); + if (suspend_request.done) + { + pthread_mutex_unlock(&suspend_request_mutex); + break; + } + else + pthread_mutex_unlock(&suspend_request_mutex); + } +} + +void lock_and_load_program(int prg_no, string file) +{ + do_request(prg_no, true); + + //TODO load the program + usleep(5000000); + + do_request(prg_no, false); +} + void do_in_synth_cli() { string input; string command; string params; + int num; if (signal(2,signal_handler)==SIG_ERR) - { - cout << "WARNING: failed to set signal handler!" << endl; - } + output_warning("WARNING: failed to set signal handler in the in-synth-cli. pressing enter will\n" + " kill the synth, so be careful. this is not fatal"); while (true) @@ -43,7 +84,8 @@ void do_in_synth_cli() cout << "error: expected program-number, found '"<<params<<"'"<<endl; else { - //TODO: load program + num=atoi(params.c_str()); + lock_and_load_program(num, programfile[num]); } } else if (command=="load") @@ -58,7 +100,10 @@ void do_in_synth_cli() cout << "error: expected program-file to load, found nothing"<<endl; else { - //TODO: load program + num=atoi(params.c_str()); + lock_and_load_program(num, file); + + programfile[num]=file; } } else if (command!="") diff --git a/synth/jack.cpp b/synth/jack.cpp index 0c98855..fbf1ea0 100644 --- a/synth/jack.cpp +++ b/synth/jack.cpp @@ -9,6 +9,7 @@ #include "globals.h" #include "jack.h" +#include "communication.h" using namespace std; @@ -23,6 +24,28 @@ jack_port_t *out_port2[N_CHANNELS]; jack_client_t *jack_client = NULL; +void manage_program_lock(int prog, bool lock) //TODO woandershinschieben? +{ + program_lock[prog]=lock; + + if (lock) + for (int i=0;i<N_CHANNELS;i++) + channel[i]->kill_program(prog); +} + +void process_request() +{ + if (suspend_request.prog==-1) + for (int i=0;i<128;i++) + manage_program_lock(i,suspend_request.suspend); + else + manage_program_lock(suspend_request.prog,suspend_request.suspend); + + suspend_request.done=true; +} + + + void maybe_calc_stuff() //TODO woandershinschieben? lfo.cpp oder so? { static int lfocnt=0; @@ -263,6 +286,17 @@ int process_callback(jack_nframes_t nframes, void *notused) return 0; } + + + pthread_mutex_lock(&suspend_request_mutex); + if (suspend_request.done==false) + process_request(); + pthread_mutex_unlock(&suspend_request_mutex); + + + + + for (i=0;i<N_CHANNELS;i++) { outbuf[i]=(jack_default_audio_sample_t*) jack_port_get_buffer(out_port[i], nframes); @@ -500,4 +534,3 @@ int process_callback(jack_nframes_t nframes, void *notused) return 0; } - diff --git a/synth/main.cpp b/synth/main.cpp index 8bcfe39..d063d41 100644 --- a/synth/main.cpp +++ b/synth/main.cpp @@ -14,6 +14,7 @@ #include "globals.h" #include "note_loader.h" #include "in_synth_cli.h" +#include "communication.h" using namespace std; @@ -24,6 +25,8 @@ void dump_options(); int main(int argc, char** argv) { + init_communication(); + for (int i=0;i<N_LFOS;i++) lfo_freq_hz[i]=0; @@ -103,6 +106,8 @@ int main(int argc, char** argv) for (i=0;i<128;i++) { + program_lock[i]=false; + if (programfile[i]!="") { try @@ -177,7 +182,9 @@ int main(int argc, char** argv) void cleanup() { exit_jack(); - + + uninit_communication(); + for (int i=0;i<N_CHANNELS;i++) { delete channel[i]; |