diff --git a/SpiralSound/Midi.C b/SpiralSound/Midi.C index 23d2060..32125ee 100644 --- a/SpiralSound/Midi.C +++ b/SpiralSound/Midi.C @@ -17,7 +17,6 @@ */ #include "Midi.h" -#include "NoteTable.h" #include "unistd.h" #include "sys/types.h" #include "signal.h" @@ -44,31 +43,27 @@ static int NKEYS = 30; MidiDevice *MidiDevice::m_Singleton; string MidiDevice::m_DeviceName; - +string MidiDevice::m_AppName; + #if __APPLE__ #define read AppleRead #endif -MidiDevice::MidiDevice() : +void MidiDevice::Init(const string &name, Type t) +{ + if (!m_Singleton) + { + m_AppName=name; + m_Singleton=new MidiDevice(t); + } +} + +MidiDevice::MidiDevice(Type t) : m_Poly(1), m_Clock(1.0f), m_ClockCount(0) { -#ifdef ALSA_MIDI - seq_handle=AlsaOpen(); -#else - Open(); -#endif - -#ifdef KEYBOARD_SUPPORT - m_Oct=4; - m_CurrentVoice=0; - - for (int n=0; n<256; n++) - { - m_KeyVoice[n]=' '; - } -#endif + Open(t); } MidiDevice::~MidiDevice() @@ -97,10 +92,13 @@ void MidiDevice::Close() } -void MidiDevice::Open() +void MidiDevice::Open(Type t) { #if __APPLE__ AppleOpen(); +#else +#ifdef ALSA_MIDI + seq_handle=AlsaOpen(t); #else //if (!SpiralInfo::WANTMIDI) return; @@ -119,11 +117,16 @@ void MidiDevice::Open() } cerr<<"Opened midi device ["<15) { cerr<<"SendEvent: Invalid Midi device "<type == SND_SEQ_EVENT_NOTEON) && (ev->data.note.velocity == 0)) - { - ev->type = SND_SEQ_EVENT_NOTEOFF; + int seq_nfds, l1; + struct pollfd *pfds; + seq_nfds = snd_seq_poll_descriptors_count(seq_handle, POLLIN); + pfds = (struct pollfd *)alloca(sizeof(struct pollfd) * seq_nfds); + snd_seq_poll_descriptors(seq_handle, pfds, seq_nfds, POLLIN); + + for(;;) + { + cerr<<"poll"< 0) + { + for (l1 = 0; l1 < seq_nfds; l1++) + { + if (pfds[l1].revents > 0) + { + snd_seq_event_t *ev; + int l1; + MidiEvent::type MessageType=MidiEvent::NONE; + int Volume=0,Note=0,EventDevice=0; + cerr<<"found an event!"<type == SND_SEQ_EVENT_NOTEON) && (ev->data.note.velocity == 0)) + { + ev->type = SND_SEQ_EVENT_NOTEOFF; + } + + switch (ev->type) { + case SND_SEQ_EVENT_PITCHBEND: + MessageType=MidiEvent::CHANNELPRESSURE; + Volume = (char)((ev->data.control.value / 8192.0)*256); + break; + case SND_SEQ_EVENT_CONTROLLER: + MessageType=MidiEvent::PARAMETER; + Note = ev->data.control.param; + Volume = ev->data.control.value; + break; + case SND_SEQ_EVENT_NOTEON: + MessageType=MidiEvent::ON; + EventDevice = ev->data.control.channel; + Note = ev->data.note.note; + Volume = ev->data.note.velocity; + break; + case SND_SEQ_EVENT_NOTEOFF: + MessageType=MidiEvent::ON; + EventDevice = ev->data.control.channel; + Note = ev->data.note.note; + break; + } + pthread_mutex_lock(m_Mutex); + m_EventVec[EventDevice].push(MidiEvent(MessageType,Note,Volume)); + pthread_mutex_unlock(m_Mutex); + + snd_seq_free_event(ev); + } while (snd_seq_event_input_pending(seq_handle, 0) > 0); + } + } } - - switch (ev->type) { - case SND_SEQ_EVENT_PITCHBEND: - MessageType=MidiEvent::CHANNELPRESSURE; - Volume = (char)((ev->data.control.value / 8192.0)*256); - break; - case SND_SEQ_EVENT_CONTROLLER: - MessageType=MidiEvent::PARAMETER; - Note = ev->data.control.param; - Volume = ev->data.control.value; - break; - case SND_SEQ_EVENT_NOTEON: - MessageType=MidiEvent::ON; - EventDevice = ev->data.control.channel; - Note = ev->data.note.note; - Volume = ev->data.note.velocity; - break; - case SND_SEQ_EVENT_NOTEOFF: - MessageType=MidiEvent::ON; - EventDevice = ev->data.control.channel; - Note = ev->data.note.note; - break; - } - - m_EventVec[EventDevice].push(MidiEvent(MessageType,Note,Volume)); - - snd_seq_free_event(ev); - } while (snd_seq_event_input_pending(seq_handle, 0) > 0); - return (0); + } } -snd_seq_t *MidiDevice::AlsaOpen() +snd_seq_t *MidiDevice::AlsaOpen(Type t) { snd_seq_t *seq_handle; int client_id, port_id; - - if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) { - fprintf(stderr, "Error opening ALSA sequencer.\n"); - exit(1); - } - snd_seq_set_client_name(seq_handle, "spiralmodular"); - client_id = snd_seq_client_id(seq_handle); - if ((port_id = snd_seq_create_simple_port(seq_handle, "spiralmodular", - SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, - SND_SEQ_PORT_TYPE_APPLICATION) < 0)) { - fprintf(stderr, "Error creating sequencer port.\n"); - } + + if (t==WRITE) + { + if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) { + fprintf(stderr, "Error opening ALSA sequencer.\n"); + exit(1); + } + snd_seq_set_client_name(seq_handle, m_AppName.c_str()); + client_id = snd_seq_client_id(seq_handle); + if ((port_id = snd_seq_create_simple_port(seq_handle, m_AppName.c_str(), + SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_APPLICATION) < 0)) { + fprintf(stderr, "Error creating sequencer port.\n"); + } + } + else + { + if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) { + fprintf(stderr, "Error opening ALSA sequencer.\n"); + exit(1); + } + snd_seq_set_client_name(seq_handle, m_AppName.c_str()); + client_id = snd_seq_client_id(seq_handle); + if ((port_id = snd_seq_create_simple_port(seq_handle, m_AppName.c_str(), + SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_APPLICATION) < 0)) { + fprintf(stderr, "Error creating sequencer port.\n"); + } + } return(seq_handle); } diff --git a/SpiralSound/Midi.h b/SpiralSound/Midi.h index 5f736a5..6d48727 100644 --- a/SpiralSound/Midi.h +++ b/SpiralSound/Midi.h @@ -30,7 +30,7 @@ using namespace std; -//#define ALSA_MIDI +#define ALSA_MIDI #ifdef ALSA_MIDI #include @@ -63,28 +63,31 @@ class MidiDevice public: ~MidiDevice(); + enum Type{READ,WRITE}; + + static void Init(const string &name, Type t); static void SetDeviceName(string s) { m_DeviceName=s; } - static MidiDevice *Get() { if(!m_Singleton) m_Singleton=new MidiDevice; return m_Singleton; } + static MidiDevice *Get() { return m_Singleton; } static void PackUpAndGoHome() { if(m_Singleton) delete m_Singleton; m_Singleton=NULL; } - static void *MidiReaderCallback(void *o) { ((MidiDevice*)o)->CollectEvents(); return NULL; } - MidiEvent GetEvent(int Device); void SendEvent(int Device,const MidiEvent &Event); void SetPoly(int s) { m_Poly=s; } float GetClock() { return m_Clock; } - + private: - MidiDevice(); + MidiDevice(Type t); - void Open(); + void Open(Type t); void Close(); void CollectEvents(); void AddEvent(unsigned char* midi); void ReadByte(unsigned char *c); + + static void *MidiReaderCallback(void *o) { ((MidiDevice*)o)->CollectEvents(); return NULL; } int m_MidiFd; int m_MidiWrFd; @@ -98,12 +101,15 @@ private: static MidiDevice *m_Singleton; pthread_t m_MidiReader; - pthread_mutex_t* m_Mutex; + pthread_mutex_t* m_Mutex; + + static string m_AppName; #ifdef ALSA_MIDI - int AlsaCallback(); + static void *AlsaMidiReaderCallback(void *o) { ((MidiDevice*)o)->AlsaCollectEvents(); return NULL; } + void AlsaCollectEvents(); snd_seq_t *seq_handle; - snd_seq_t *AlsaOpen(); + snd_seq_t *AlsaOpen(Type t); #endif #if __APPLE__ diff --git a/SpiralSound/PluginManager.C b/SpiralSound/PluginManager.C index 81cb3cb..e0991d5 100644 --- a/SpiralSound/PluginManager.C +++ b/SpiralSound/PluginManager.C @@ -44,7 +44,7 @@ PluginID PluginManager::LoadPlugin(const char *PluginName) if (NewPlugin->Handle==NULL) { - SpiralInfo::Alert("Error loading plugin: \n"+string(dlerror())); + SpiralInfo::Alert("Error loading ["+string(PluginName)+"]: \n"+string(dlerror())); return PluginError; } diff --git a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C index d1dc9ab..3433146 100644 --- a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C +++ b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/SpiralSound/Plugins/MidiPlugin/Makefile.in b/SpiralSound/Plugins/MidiPlugin/Makefile.in index efc5a55..37074a4 100644 --- a/SpiralSound/Plugins/MidiPlugin/Makefile.in +++ b/SpiralSound/Plugins/MidiPlugin/Makefile.in @@ -11,7 +11,7 @@ CXXFLAGS= @CXXFLAGS@ INCPATH = -I/usr/X11R6/include LINK = g++ -shared LFLAGS = -LIBS = -L/usr/X11R6/lib @FLTK_LIBS@ -lGL -lXext -lX11 -ldl -pthread +LIBS = -L/usr/X11R6/lib @FLTK_LIBS@ -lGL -lXext -lX11 -ldl -pthread -lasound MOC = moc UIC = diff --git a/SpiralSound/Plugins/MidiPlugin/MidiPlugin.C b/SpiralSound/Plugins/MidiPlugin/MidiPlugin.C index 3b662ae..3636271 100644 --- a/SpiralSound/Plugins/MidiPlugin/MidiPlugin.C +++ b/SpiralSound/Plugins/MidiPlugin/MidiPlugin.C @@ -62,6 +62,11 @@ m_CurrentNote(0) { m_Version=2; + if (m_RefCount==0) + { + MidiDevice::Init("SpiralModular",MidiDevice::READ); + } + m_RefCount++; m_PluginInfo.Name="Midi"; diff --git a/SpiralSound/SpiralInfo.C b/SpiralSound/SpiralInfo.C index 22c324e..6e82136 100644 --- a/SpiralSound/SpiralInfo.C +++ b/SpiralSound/SpiralInfo.C @@ -139,6 +139,7 @@ void SpiralInfo::StreamInPrefs (istream &s) { if (st!="end") PLUGINVEC.push_back (st); } } + #if __APPLE__ // ignore custom paths, plugins are encapsulated in the app anyway // this prevents the program to fail if the user move the application icon diff --git a/main.cpp b/main.cpp index e106a4d..e348265 100644 --- a/main.cpp +++ b/main.cpp @@ -174,9 +174,10 @@ int main(int argc, char **argv) Fl::visual(FL_DOUBLE|FL_RGB); synth=new SynthModular; - + // setup the synth Fl_Window* win = synth->CreateWindow(); + synth->LoadPlugins(cmd_pluginPath); win->xclass(""); if (GUI) win->show(1, argv); // prevents stuff happening before the plugins have loaded