summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--synth/Makefile2
-rw-r--r--synth/in_synth_cli.cpp40
-rw-r--r--synth/jack.cpp37
-rw-r--r--synth/lfos.cpp77
-rw-r--r--synth/lfos.h9
-rw-r--r--synth/main.cpp22
7 files changed, 134 insertions, 56 deletions
diff --git a/TODO b/TODO
index 5b3b81c..0787b29 100644
--- a/TODO
+++ b/TODO
@@ -2,11 +2,12 @@
wenn man danach die noten spielen will. nicht reproduzierbar
TODO für den synth
+!!!o on-the-fly die LFOs ändern (frequenz, wellenform)
+
o zu testen: funktionieren no-release-envs auch in compilierten noten?
o funktioniert Channel::release_all bei gedrücktem HOLD oder SOSTENUTO?
- o on-the-fly die LFOs ändern (frequenz, wellenform)
o RAM aufräumen?
o beide parser: envelopes von oscs mit out=0 standardmäßig deaktivieren
diff --git a/synth/Makefile b/synth/Makefile
index 8109bc8..0db09da 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 communication.o shared_object_manager.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 shared_object_manager.o lfos.o
BIN=synth
DEPENDFILE = .depend
diff --git a/synth/in_synth_cli.cpp b/synth/in_synth_cli.cpp
index dd9260f..ece806b 100644
--- a/synth/in_synth_cli.cpp
+++ b/synth/in_synth_cli.cpp
@@ -9,6 +9,7 @@
#include "communication.h"
#include "globals.h"
#include "load.h"
+#include "lfos.h"
using namespace std;
@@ -64,6 +65,18 @@ void lock_and_load_program(int prg_no, string file)
do_request(prg_no, false);
}
+void lock_and_change_lfo(int lfo_no, float freq)
+{
+ do_request(-1, true);
+
+ uninit_lfo(lfo_no);
+ lfo_freq_hz[lfo_no]=freq;
+ init_lfo(lfo_no);
+
+ do_request(-1, false);
+}
+
+
void do_in_synth_cli()
{
string input;
@@ -470,6 +483,33 @@ void do_in_synth_cli()
cout << "error: channel-number must be one of 0.."<<N_CHANNELS-1<<endl;
}
}
+ else if ((command=="change_lfo") || (command=="lfo") || (command=="set_lfo"))
+ {
+ string freqstr, lfostr;
+ lfostr=trim_spaces(str_before(params,' ',params));
+ freqstr=trim_spaces(str_after(params,' ',""));
+
+ if ((!isnum(lfostr)) || (lfostr==""))
+ cout << "error: expected lfo-number, found '"<<lfostr<<"'"<<endl;
+ else if (! (isfloat(freqstr)&&freqstr!=""))
+ cout << "error: expected frequency, found '"<<freqstr<<"'"<<endl;
+ else
+ {
+ num=atoi(lfostr.c_str());
+ if ((num>=0) && (num<N_LFOS))
+ {
+ float freq;
+ freq=atof(freqstr.c_str());
+
+ if (freq>0)
+ lock_and_change_lfo(num,freq);
+ else
+ cout << "error: frequency must be a positive number"<<endl;
+ }
+ else
+ cout << "error: lfo-number must be one of 0.."<<N_LFOS-1<<endl;
+ }
+ }
else if (command!="")
{
cout << "error: unrecognized command '"<<command<<"'"<<endl;
diff --git a/synth/jack.cpp b/synth/jack.cpp
index fbf1ea0..d0a6169 100644
--- a/synth/jack.cpp
+++ b/synth/jack.cpp
@@ -10,6 +10,7 @@
#include "jack.h"
#include "communication.h"
+#include "lfos.h"
using namespace std;
@@ -46,40 +47,6 @@ void process_request()
-void maybe_calc_stuff() //TODO woandershinschieben? lfo.cpp oder so?
-{
- static int lfocnt=0;
- static int snhcnt=0;
-
- if (lfocnt==0)
- {
- lfocnt=lfo_update_frames;
-
- for (int i=0;i<N_LFOS;i++)
- {
- lfo_phase[i]=(lfo_phase[i]+1)%lfo_res[i];
- curr_lfo[i]=lfo[i][lfo_phase[i]];
- }
- }
-
- if (snhcnt==0)
- {
- snhcnt=sample_and_hold_frames;
-
- //temp ranges between -ONE and ONE
- fixed_t temp = (float(rand())/(RAND_MAX/2) - 1.0) * ONE;
-
- for (int i=0;i<N_LFO_LEVELS;i++)
- sample_and_hold[i]= temp*i/(N_LFO_LEVELS-1) + ONE;
-
- curr_lfo[SNH_LFO]=sample_and_hold;
- // could be moved to some init function, but looks clearer and
- // does not eat up the cpu too much ;)
- }
-
- lfocnt--;
- snhcnt--;
-}
@@ -479,7 +446,7 @@ int process_callback(jack_nframes_t nframes, void *notused)
}
}
- maybe_calc_stuff();
+ maybe_calc_lfos();
for (int j=0;j<N_CHANNELS;j++)
{
diff --git a/synth/lfos.cpp b/synth/lfos.cpp
new file mode 100644
index 0000000..5916937
--- /dev/null
+++ b/synth/lfos.cpp
@@ -0,0 +1,77 @@
+#include <math.h>
+#include <stdlib.h>
+
+#include "lfos.h"
+#include "globals.h"
+#include "fixed.h"
+#include "defines.h"
+
+void uninit_lfo(int i)
+{
+ if (lfo[i])
+ {
+ for (int j=0;j<lfo_res[i];j++)
+ delete [] lfo[i][j];
+
+ delete [] lfo[i];
+ lfo[i]=NULL;
+ }
+}
+
+void init_lfo(int i)
+{
+ //two possible divisions by zero are avoided, because
+ //values <= 0 will make the program use the default
+ //(nonzero) values.
+ lfo_res[i]=samp_rate/lfo_freq_hz[i]/lfo_update_frames;
+
+ lfo[i]=new fixed_t* [lfo_res[i]];
+ for (int j=0;j<lfo_res[i];j++)
+ {
+ lfo[i][j]=new fixed_t [N_LFO_LEVELS];
+ float temp=sin(j*2.0*3.141592654/lfo_res[i]);
+ for (int k=0;k<N_LFO_LEVELS;k++)
+ lfo[i][j][k]= (1.0 + temp*(float(LFO_MAX)*k/N_LFO_LEVELS)) * ONE;
+ }
+
+}
+
+void init_snh()
+{
+ sample_and_hold_frames=samp_rate/snh_freq_hz;
+}
+
+void maybe_calc_lfos()
+{
+ static int lfocnt=0;
+ static int snhcnt=0;
+
+ if (lfocnt==0)
+ {
+ lfocnt=lfo_update_frames;
+
+ for (int i=0;i<N_LFOS;i++)
+ {
+ lfo_phase[i]=(lfo_phase[i]+1)%lfo_res[i];
+ curr_lfo[i]=lfo[i][lfo_phase[i]];
+ }
+ }
+
+ if (snhcnt==0)
+ {
+ snhcnt=sample_and_hold_frames;
+
+ //temp ranges between -ONE and ONE
+ fixed_t temp = (float(rand())/(RAND_MAX/2) - 1.0) * ONE;
+
+ for (int i=0;i<N_LFO_LEVELS;i++)
+ sample_and_hold[i]= temp*i/(N_LFO_LEVELS-1) + ONE;
+
+ curr_lfo[SNH_LFO]=sample_and_hold;
+ // could be moved to some init function, but looks clearer and
+ // does not eat up the cpu too much ;)
+ }
+
+ lfocnt--;
+ snhcnt--;
+}
diff --git a/synth/lfos.h b/synth/lfos.h
new file mode 100644
index 0000000..e8e207b
--- /dev/null
+++ b/synth/lfos.h
@@ -0,0 +1,9 @@
+#ifndef __LFOS_H__
+#define __LFOS_H__
+
+void maybe_calc_lfos();
+void init_snh();
+void init_lfo(int i);
+void uninit_lfo(int i);
+
+#endif
diff --git a/synth/main.cpp b/synth/main.cpp
index 2aaf406..f4dcd54 100644
--- a/synth/main.cpp
+++ b/synth/main.cpp
@@ -14,6 +14,7 @@
#include "in_synth_cli.h"
#include "communication.h"
#include "note_loader.h"
+#include "lfos.h"
using namespace std;
@@ -77,28 +78,11 @@ int main(int argc, char** argv)
init_default_program(default_program);
- //two possible divisions by zero are avoided, because
- //values <= 0 will make the program use the default
- //(nonzero) values.
- for (i=0;i<N_LFOS;i++)
- lfo_res[i]=samp_rate/lfo_freq_hz[i]/lfo_update_frames;
- sample_and_hold_frames=samp_rate/snh_freq_hz;
-
- for (i=0;i<N_LFOS;i++)
- {
- lfo[i]=new fixed_t* [lfo_res[i]];
- for (j=0;j<lfo_res[i];j++)
- lfo[i][j]=new fixed_t [N_LFO_LEVELS];
- }
+ init_snh();
for (i=0;i<N_LFOS;i++)
- for (j=0;j<lfo_res[i];j++)
- {
- float temp=sin(j*2.0*3.141592654/lfo_res[i]);
- for (int k=0;k<N_LFO_LEVELS;k++)
- lfo[i][j][k]= (1.0 + temp*(float(LFO_MAX)*k/N_LFO_LEVELS)) * ONE;
- }
+ init_lfo(i);
program_settings=new program_t[128];