commit 7346fef91b2b73e444a90da70f6c02c4c30f2bd8
parent 3a1b2c8c80e33c865f9cf872341873e8adc580ae
Author: paulnasca <paulnasca>
Date: Wed, 1 Nov 2006 15:58:36 +0000
*** empty log message ***
Diffstat:
11 files changed, 162 insertions(+), 24 deletions(-)
diff --git a/AUTHORS.txt b/AUTHORS.txt
@@ -3,5 +3,5 @@ Main author:
Contributors:
Gerald Folcher (legato, mono notes memory)
- Lars Luthman (zombie fix)
+ Lars Luthman (zombie fix,jack midi, LASH support)
diff --git a/ChangeLog b/ChangeLog
@@ -811,6 +811,7 @@
- Inlocuit fl_ask cu fl_choice in fisierele .fl
- In mod prestabilit nu se mai seteaza volumul la efectul 0
- Efectele sunt numerotare de la 1 si in la "send to" din partui
+01 Nov 2006 - Adaugat patch-urile de Jack Midi si LASH de Lars Luthman
diff --git a/src/Input/ALSAMidiIn.C b/src/Input/ALSAMidiIn.C
@@ -94,3 +94,14 @@ void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmd
};
+int ALSAMidiIn::getalsaid() {
+ if (midi_handle) {
+ snd_seq_client_info_t* seq_info;
+ snd_seq_client_info_malloc(&seq_info);
+ snd_seq_get_client_info(midi_handle, seq_info);
+ int id = snd_seq_client_info_get_client(seq_info);
+ snd_seq_client_info_free(seq_info);
+ return id;
+ }
+ return -1;
+}
diff --git a/src/Input/ALSAMidiIn.h b/src/Input/ALSAMidiIn.h
@@ -32,6 +32,7 @@ class ALSAMidiIn:public MidiIn{
ALSAMidiIn();
~ALSAMidiIn();
void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams);
+ int getalsaid();
private:
snd_seq_t *midi_handle;
diff --git a/src/Makefile b/src/Makefile
@@ -70,6 +70,12 @@ CXXFLAGS += `pkg-config --cflags jack`
LIBS+= `pkg-config --libs jack`
endif
+ifeq ($(LINUX_USE_LASH),YES)
+CXXFLAGS += `pkg-config --cflags lash-1.0` -DUSE_LASH
+LIBS+= `pkg-config --libs lash-1.0`
+endif
+
+
objects=main.o
SUBDIRS=DSP Effects Input Misc Output Params Synth Seq
diff --git a/src/Makefile.inc b/src/Makefile.inc
@@ -42,6 +42,9 @@ LINUX_AUDIOOUT=OSS
LINUX_DSSI=NO
#LINUX_DSSI=YES
+#Next line sets if the LASH session handler will be used
+LINUX_USE_LASH=YES
+#LINUX_USE_LASH=NO
# W I N D O W S C O N F I G U R A T I O N
diff --git a/src/Misc/Makefile b/src/Misc/Makefile
@@ -2,6 +2,10 @@ include ../Makefile.inc
objects=Bank.o Master.o Microtonal.o Part.o Util.o Config.o Dump.o XMLwrapper.o
+ifeq ($(LINUX_USE_LASH),YES)
+objects += LASHClient.o
+endif
+
all: $(objects)
diff --git a/src/Output/JACKaudiooutput.C b/src/Output/JACKaudiooutput.C
@@ -21,11 +21,13 @@
*/
#include <stdlib.h>
+#include <jack/midiport.h>
#include "JACKaudiooutput.h"
Master *jackmaster;
jack_client_t *jackclient;
-jack_port_t *outport_left,*outport_right;
+char jackname[100];
+jack_port_t *outport_left,*outport_right,*midi_inport;
int jackprocess(jack_nframes_t nframes,void *arg);
int jacksrate(jack_nframes_t nframes,void *arg);
@@ -34,13 +36,12 @@ void jackshutdown(void *arg);
bool JACKaudiooutputinit(Master *master_){
jackmaster=master_;
jackclient=0;
- char tmpstr[100];
for (int i=0;i<15;i++){
- if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i);
- else snprintf(tmpstr,100,"ZynAddSubFX");
- jackclient=jack_client_new(tmpstr);
- if (jackclient!=0) break;
+ if (i!=0) snprintf(jackname,100,"ZynAddSubFX_%d",i);
+ else snprintf(jackname,100,"ZynAddSubFX");
+ jackclient=jack_client_new(jackname);
+ if (jackclient!=0) break;
};
if (jackclient==0) {
@@ -60,6 +61,8 @@ bool JACKaudiooutputinit(Master *master_){
JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0);
outport_right=jack_port_register(jackclient,"out_2",
JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0);
+ midi_inport=jack_port_register(jackclient,"midi_input",
+ JACK_DEFAULT_MIDI_TYPE,JackPortIsInput|JackPortIsTerminal,0);
if (jack_activate(jackclient)){
fprintf(stderr,"Cannot activate jack client\n");
@@ -78,6 +81,7 @@ int jackprocess(jack_nframes_t nframes,void *arg){
jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes);
if (!pthread_mutex_trylock(&jackmaster->mutex)) {
+ JACKhandlemidi(nframes);
jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr);
pthread_mutex_unlock(&jackmaster->mutex);
}
@@ -102,4 +106,58 @@ void jackshutdown(void *arg){
};
+void JACKhandlemidi(unsigned long frames) {
+
+ // We must have the master mutex before we run this function
+
+ // XXX This is really nasty, not only do we lose the sample accuracy of
+ // JACK MIDI, but any accuracy at all below the buffer size
+
+ void* midi_buf = jack_port_get_buffer(midi_inport, frames);
+ jack_midi_event_t jack_midi_event;
+ jack_nframes_t event_index = 0;
+ jack_nframes_t event_count =
+ jack_midi_port_get_info(midi_buf, frames)->event_count;
+ unsigned char* midi_data;
+ unsigned char type, chan;
+
+ while (event_index < event_count) {
+
+ jack_midi_event_get(&jack_midi_event, midi_buf, event_index, frames);
+ midi_data = jack_midi_event.buffer;
+ type = midi_data[0] & 0xF0;
+ chan = midi_data[0] & 0x0F;
+
+ switch (type) {
+
+ case 0x80: /* note-off */
+ jackmaster->NoteOff(chan, midi_data[1]);
+ break;
+
+ case 0x90: /* note-on */
+ jackmaster->NoteOn(chan, midi_data[1], midi_data[2]);
+ break;
+
+ case 0xB0: /* controller */
+ jackmaster->SetController(chan, midi_data[1], midi_data[2]);
+ break;
+
+ case 0xE0: /* pitch bend */
+ jackmaster->SetController(chan, C_pitchwheel,
+ ((midi_data[2] << 7) | midi_data[1]));
+ break;
+
+ /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */
+ }
+
+ event_index++;
+ }
+
+}
+
+const char* JACKgetname() {
+ if (jackclient != NULL)
+ return jackname;
+ return NULL;
+}
diff --git a/src/Output/JACKaudiooutput.h b/src/Output/JACKaudiooutput.h
@@ -40,6 +40,8 @@
bool JACKaudiooutputinit(Master *master_);
void JACKfinish();
+void JACKhandlemidi(unsigned long frames);
+const char* JACKgetname();
#endif
diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl
@@ -1705,10 +1705,15 @@ simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]);} {}
updatepanel();} {}
}
- Function {do_load_master()} {} {
+ Function {do_load_master(char* file = NULL)} {} {
code {char *filename;
-filename=fl_file_chooser("Open:","({*.xmz})",NULL,0);
-if (filename==NULL) return;
+ if (file == NULL) {
+ filename=fl_file_chooser("Open:","({*.xmz})",NULL,0);
+ if (filename==NULL) return;
+ }
+ else {
+ filename = file;
+ }
pthread_mutex_lock(&master->mutex);
@@ -1729,20 +1734,23 @@ if (result>=0) setfilelabel(filename);
if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a zynaddsubfx parameters file.");
else if (result<0) fl_alert("Error: Could not load the file.");} {}
}
- Function {do_save_master()} {} {
+ Function {do_save_master(char* file = NULL)} {} {
code {char *filename;
-int result=0;
-
-filename=fl_file_chooser("Save:","({*.xmz})",NULL,0);
-if (filename==NULL) return;
-filename=fl_filename_setext(filename,".xmz");
-
-result=fileexists(filename);
-if (result) {
- result=0;
- if (!fl_choice("The file exists. \\nOverwrite it?","No","Yes",NULL)) return;
-
-};
+ int result=0;
+ if (file == NULL) {
+ filename=fl_file_chooser("Save:","({*.xmz})",NULL,0);
+ if (filename==NULL) return;
+ filename=fl_filename_setext(filename,".xmz");
+ result=fileexists(filename);
+ if (result) {
+ result=0;
+ if (!fl_choice("The file exists. Overwrite it?","No","Yes",NULL)) return;
+
+ }
+ }
+ else {
+ filename = file;
+ }
pthread_mutex_lock(&master->mutex);
diff --git a/src/main.C b/src/main.C
@@ -83,6 +83,11 @@ bool usejackit=false;
OSSaudiooutput *audioout;
#endif
+#ifdef USE_LASH
+#include "Misc/LASHClient.h"
+LASHClient *lash;
+#endif
+
MidiIn *Midi;
int Pexitprogram=0;//if the UI set this to 1, the program will exit
@@ -180,7 +185,26 @@ void *thread2(void *arg){
void *thread3(void *arg){
#ifndef DISABLE_GUI
ui->showUI();
- while (Pexitprogram==0) Fl::wait();
+ while (Pexitprogram==0) {
+#ifdef USE_LASH
+ std::string filename;
+ switch (lash->checkevents(filename)) {
+ case LASHClient::Save:
+ ui->do_save_master(const_cast<char*>(filename.c_str()));
+ lash->confirmevent(LASHClient::Save);
+ break;
+ case LASHClient::Restore:
+ ui->do_load_master(const_cast<char*>(filename.c_str()));
+ lash->confirmevent(LASHClient::Restore);
+ break;
+ case LASHClient::Quit:
+ Pexitprogram = 1;
+ default:
+ break;
+ }
+#endif
+ Fl::wait();
+ }
#endif
return(0);
};
@@ -312,6 +336,10 @@ void exitprogram(){
delete(Midi);
delete(master);
+#ifdef USE_LASH
+ delete(lash);
+#endif
+
// pthread_mutex_unlock(&master->mutex);
delete(denormalkillbuf);
delete(OscilGen::tmpsmps);
@@ -345,6 +373,11 @@ void exitprogram(){
#ifndef VSTAUDIOOUT
int main(int argc, char *argv[]){
+
+#ifdef USE_LASH
+ lash = new LASHClient(&argc, &argv);
+#endif
+
config.init();
dump.startnow();
int noui=0;
@@ -492,6 +525,17 @@ int main(int argc, char *argv[]){
initprogram();
+#ifdef USE_LASH
+#ifdef ALSAMIDIIN
+ ALSAMidiIn* alsamidi = dynamic_cast<ALSAMidiIn*>(Midi);
+ if (alsamidi)
+ lash->setalsaid(alsamidi->getalsaid());
+#endif
+#ifdef JACKAUDIOOUT
+ lash->setjackname(JACKgetname());
+#endif
+#endif
+
if (strlen(loadfile)>1){
int tmp=master->loadXML(loadfile);
if (tmp<0) {