zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit a0dcbd2d726e3744671cce64b99592b394f47087
parent a33bcc7c6e8f8e2557785fb0eb348d571ab5c83f
Author: fundamental <[email protected]>
Date:   Mon, 28 Dec 2009 14:59:58 -0500

Nio: moving midi driver into AlsaEngine

Diffstat:
Msrc/Input/CMakeLists.txt | 2+-
Msrc/Nio/AlsaEngine.cpp | 284++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/Nio/AlsaEngine.h | 28++++++++++++++--------------
Msrc/Nio/MidiIn.cpp | 1-
Msrc/Nio/MidiIn.h | 16----------------
Msrc/main.cpp | 10+++++-----
6 files changed, 158 insertions(+), 183 deletions(-)

diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt @@ -1,4 +1,4 @@ -set(AlsaMidiInput ${ALSA_FOUND} CACHE BOOL "Include ALSA Midi input") +#set(AlsaMidiInput ${ALSA_FOUND} CACHE BOOL "Include ALSA Midi input") set(zynaddsubfx_input_SRCS MidiIn.cpp NULLMidiIn.cpp diff --git a/src/Nio/AlsaEngine.cpp b/src/Nio/AlsaEngine.cpp @@ -25,6 +25,7 @@ using namespace std; #include "../Misc/Util.h" #include "../Misc/Config.h" #include "../Misc/Master.h" +#include "InMgr.h" #include "AlsaEngine.h" AlsaEngine::AlsaEngine(OutMgr *out) @@ -38,9 +39,9 @@ AlsaEngine::AlsaEngine(OutMgr *out) audio.alsaId = -1; audio.pThread = 0; -// midi.handle = NULL; -// midi.alsaId = -1; -// midi.pThread = 0; + midi.handle = NULL; + midi.alsaId = -1; + midi.pThread = 0; } @@ -50,36 +51,26 @@ AlsaEngine::~AlsaEngine() } -//bool AlsaEngine::openMidi() -//{ -// midi.device = config.cfg.midiDevice; -// if (!midi.device.size()) -// midi.device = "default"; -// string port_name = "input"; -// if (snd_seq_open(&midi.handle, midi.device.c_str(), SND_SEQ_OPEN_INPUT, 0)) -// { -// cerr << "Error, failed to open alsa midi device: " << midi.device << endl; -// goto bail_out; -// } -// snd_seq_client_info_t *seq_info; -// snd_seq_client_info_alloca(&seq_info); -// snd_seq_get_client_info(midi.handle, seq_info); -// midi.alsaId = snd_seq_client_info_get_client(seq_info); -// snd_seq_set_client_name(midi.handle, midiClientName().c_str()); -// if (0 > snd_seq_create_simple_port(midi.handle, port_name.c_str(), -// SND_SEQ_PORT_CAP_WRITE -// | SND_SEQ_PORT_CAP_SUBS_WRITE, -// SND_SEQ_PORT_TYPE_SYNTH)) -// { -// cerr << "Error, failed to acquire alsa midi port" << endl; -// goto bail_out; -// } -// return true; -// -//bail_out: -// Close(); -// return false; -//} +bool AlsaEngine::openMidi() +{ + int alsaport; + midi.handle = NULL; + + if(snd_seq_open(&midi.handle, "default", SND_SEQ_OPEN_INPUT, 0) != 0) + return false; + + snd_seq_set_client_name(midi.handle, "ZynAddSubFX"); + + alsaport = snd_seq_create_simple_port( + midi.handle, + "ZynAddSubFX", + SND_SEQ_PORT_CAP_WRITE + | SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_SYNTH); + if(alsaport < 0) + return false; + return true; +} string AlsaEngine::audioClientName() @@ -90,13 +81,13 @@ string AlsaEngine::audioClientName() return name; } -//string AlsaEngine::midiClientName() -//{ -// string name = "zynaddsubfx"; -// if (!config.cfg.nameTag.empty()) -// name += ("-" + config.cfg.nameTag); -// return name; -//} +string AlsaEngine::midiClientName() +{ + string name = "zynaddsubfx"; + if (!config.cfg.nameTag.empty()) + name += ("-" + config.cfg.nameTag); + return name; +} void *AlsaEngine::_AudioThread(void *arg) { @@ -201,6 +192,7 @@ bool AlsaEngine::Start() return true; if(!OpenStuff()) return false; + openMidi(); pthread_attr_t attr; enabled = true; @@ -209,18 +201,13 @@ bool AlsaEngine::Start() pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&audio.pThread, &attr, _AudioThread, this); -// if (NULL != midi.handle) -// { -// chk = pthread_attr_init(&attr); -// chk = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -// chk = pthread_create(&midi.pThread, &attr, _MidiThread, this); -// } + if (NULL != midi.handle) + { + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&midi.pThread, &attr, _MidiThread, this); + } return true; - -bail_out: - cerr << "Error - bail out of AlsaEngine::Start()" << endl; - Stop(); - return false; } @@ -236,104 +223,109 @@ void AlsaEngine::Stop() cerr << "Error, failed to cancel Alsa audio thread" << endl; snd_pcm_drain(handle); snd_pcm_close(handle); - //if (NULL != midi.handle && midi.pThread) - // if (pthread_cancel(midi.pThread)) - // cerr << "Error, failed to cancel Alsa midi thread" << endl; + if (NULL != midi.handle && midi.pThread) + if (pthread_cancel(midi.pThread)) + cerr << "Error, failed to cancel Alsa midi thread" << endl; + //Stop midi + if(midi.handle) + snd_seq_close(midi.handle); + + cout << "foo" << endl; } -//void *AlsaEngine::_MidiThread(void *arg) -//{ -// return static_cast<AlsaEngine*>(arg)->MidiThread(); -//} - - -//void *AlsaEngine::MidiThread(void) -//{ -// snd_seq_event_t *event; -// unsigned char channel; -// unsigned char note; -// unsigned char velocity; -// int ctrltype; -// int par; -// int chk; -// set_realtime(); -// while (!threadStop) -// { -// while ((chk = snd_seq_event_input(midi.handle, &event)) > 0) -// { -// if (!event) -// continue; -// par = event->data.control.param; -// switch (event->type) -// { -// case SND_SEQ_EVENT_NOTEON: -// if (event->data.note.note) -// { -// channel = event->data.note.channel; -// note = event->data.note.note; -// velocity = event->data.note.velocity; -// setMidiNote(channel, note, velocity); -// } -// break; -// -// case SND_SEQ_EVENT_NOTEOFF: -// channel = event->data.note.channel; -// note = event->data.note.note; -// setMidiNote(channel, note); -// break; -// -// case SND_SEQ_EVENT_PITCHBEND: -// channel = event->data.control.channel; -// ctrltype = C_pitchwheel; -// par = event->data.control.value; -// setMidiController(channel, ctrltype, par); -// break; -// -// case SND_SEQ_EVENT_CONTROLLER: -// channel = event->data.control.channel; -// ctrltype = event->data.control.param; -// par = event->data.control.value; -// setMidiController(channel, ctrltype, par); -// break; -// -// case SND_SEQ_EVENT_RESET: // reset to power-on state -// channel = event->data.control.channel; -// ctrltype = C_resetallcontrollers; -// setMidiController(channel, ctrltype, 0); -// break; -// -// case SND_SEQ_EVENT_PORT_SUBSCRIBED: // ports connected -// if (config.cfg.verbose) -// cout << "Info, alsa midi port connected" << endl; -// break; -// -// case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: // ports disconnected -// if (config.cfg.verbose) -// cout << "Info, alsa midi port disconnected" << endl; -// break; -// -// case SND_SEQ_EVENT_SYSEX: // system exclusive -// case SND_SEQ_EVENT_SENSING: // midi device still there -// break; -// -// default: -// if (config.cfg.verbose) -// cout << "Info, other non-handled midi event, type: " -// << (int)event->type << endl; -// break; -// } -// snd_seq_free_event(event); -// } -// if (chk < 0) -// { -// if (config.cfg.verbose) -// cerr << "Error, ALSA midi input read failed: " << chk << endl; -// return NULL; -// } -// } -// return NULL; -//} +void *AlsaEngine::_MidiThread(void *arg) +{ + return static_cast<AlsaEngine*>(arg)->MidiThread(); +} + + +void *AlsaEngine::MidiThread(void) +{ + snd_seq_event_t *event; + unsigned char channel; + unsigned char note; + unsigned char velocity; + int ctrltype; + int par; + int chk; + set_realtime(); + while (enabled()) + { + while ((chk = snd_seq_event_input(midi.handle, &event)) > 0) + { + if (!event) + continue; + par = event->data.control.param; + switch (event->type) + { + case SND_SEQ_EVENT_NOTEON: + if (event->data.note.note) + { + channel = event->data.note.channel; + note = event->data.note.note; + velocity = event->data.note.velocity; + sysIn->putEvent(MidiNote(note, channel, velocity)); + } + break; + + case SND_SEQ_EVENT_NOTEOFF: + channel = event->data.note.channel; + note = event->data.note.note; + sysIn->putEvent(MidiNote(note, channel)); + break; + + case SND_SEQ_EVENT_PITCHBEND: + channel = event->data.control.channel; + ctrltype = C_pitchwheel; + par = event->data.control.value; + sysIn->putEvent(MidiCtl(ctrltype, channel, par)); + break; + + case SND_SEQ_EVENT_CONTROLLER: + channel = event->data.control.channel; + ctrltype = event->data.control.param; + par = event->data.control.value; + sysIn->putEvent(MidiCtl(ctrltype, channel, par)); + break; + + case SND_SEQ_EVENT_RESET: // reset to power-on state + channel = event->data.control.channel; + ctrltype = C_resetallcontrollers; + sysIn->putEvent(MidiCtl(ctrltype, channel, 0)); + break; + + case SND_SEQ_EVENT_PORT_SUBSCRIBED: // ports connected + if (true) + cout << "Info, alsa midi port connected" << endl; + break; + + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: // ports disconnected + if (true) + cout << "Info, alsa midi port disconnected" << endl; + break; + + case SND_SEQ_EVENT_SYSEX: // system exclusive + case SND_SEQ_EVENT_SENSING: // midi device still there + break; + + default: + if (true) + cout << "Info, other non-handled midi event, type: " + << (int)event->type << endl; + break; + } + snd_seq_free_event(event); + } + if (chk < 0) + { + if (true) + cerr << "Error, ALSA midi input read failed: " << chk << endl; + return NULL; + } + } + return NULL; +} const short *AlsaEngine::interleave(const Stereo<Sample> smps)const { diff --git a/src/Nio/AlsaEngine.h b/src/Nio/AlsaEngine.h @@ -26,18 +26,18 @@ #include <queue> #include "AudioOut.h" -//include "MidiIn.h" +#include "MidiIn.h" #include "OutMgr.h" #include "../Misc/Stereo.h" #include "../Samples/Sample.h" -class AlsaEngine : public AudioOut//, MidiIn +class AlsaEngine : public AudioOut, MidiIn { public: AlsaEngine(OutMgr *out); ~AlsaEngine(); - //bool openMidi(); + bool openMidi(); bool Start(); void Stop(); @@ -45,15 +45,15 @@ class AlsaEngine : public AudioOut//, MidiIn unsigned int getBuffersize() { return audio.period_size; }; std::string audioClientName(); - //std::string midiClientName(); + std::string midiClientName(); int audioClientId() { return audio.alsaId; }; - //int midiClientId() { return midi.alsaId; }; + int midiClientId() { return midi.alsaId; }; protected: void *AudioThread(); static void *_AudioThread(void *arg); - //void *MidiThread(oid); - //static void *_MidiThread(); + void *MidiThread(); + static void *_MidiThread(void *arg); private: bool prepHwparams(); @@ -63,7 +63,7 @@ class AlsaEngine : public AudioOut//, MidiIn bool xrunRecover(); bool alsaBad(int op_result, std::string err_msg); void closeAudio(); - //void closeMidi(); + void closeMidi(); snd_pcm_sframes_t (*pcmWrite)(snd_pcm_t *handle, const void *data, snd_pcm_uframes_t nframes); @@ -83,12 +83,12 @@ class AlsaEngine : public AudioOut//, MidiIn pthread_t pThread; } audio; - //struct { - // std::string device; - // snd_seq_t *handle; - // int alsaId; - // pthread_t pThread; - //} midi; + struct { + std::string device; + snd_seq_t *handle; + int alsaId; + pthread_t pThread; + } midi; //from alsa example long loops; diff --git a/src/Nio/MidiIn.cpp b/src/Nio/MidiIn.cpp @@ -20,7 +20,6 @@ */ -#include "../globals.h" #include "MidiIn.h" int MidiIn::getcontroller(unsigned char b) diff --git a/src/Nio/MidiIn.h b/src/Nio/MidiIn.h @@ -23,26 +23,10 @@ #ifndef MIDI_IN_H #define MIDI_IN_H -#include "../globals.h" - -enum MidiCmdType { - MidiNull, MidiNoteOFF, MidiNoteON, MidiController -}; -#define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes - /**This class is inherited by all the Midi input classes*/ class MidiIn { public: - /**Get the command,channel and parameters of the MIDI - * - * \todo make pure virtual - * @param cmdtype the referece to the variable that will store the type - * @param cmdchan the channel for the event - * @param parameters for the event*/ - virtual void getmidicmd(MidiCmdType &cmdtype, - unsigned char &cmdchan, - int *cmdparams) = 0; static int getcontroller(unsigned char b); }; diff --git a/src/main.cpp b/src/main.cpp @@ -40,9 +40,10 @@ extern Dump dump; #include "Nio/OutMgr.h" +#include "Nio/InMgr.h" #warning TODO remove conditional include block - +#if 0 #include "Input/MidiIn.h" #ifdef ALSAMIDIIN @@ -60,6 +61,7 @@ extern Dump dump; #ifdef WINMIDIIN #include "Input/WINMidiIn.h" #endif +#endif #ifndef DISABLE_GUI #ifdef QT_GUI @@ -210,7 +212,7 @@ void initprogram() master = new Master(); master->swaplr = swaplr; - +#if 0 #if defined(ALSAMIDIIN) Midi = new ALSAMidiIn(); #elif defined(OSSMIDIIN) @@ -218,14 +220,12 @@ void initprogram() #else // defined(NONEMIDIIN) || (defined(VSTMIDIIN)) Midi = new NULLMidiIn(); #endif +#endif sysOut = new OutMgr(master); sysOut->run(); sysIn = new InMgr(master); - ALSAMidiIn *alsamidi = dynamic_cast<ALSAMidiIn *>(Midi); - cout << "run" << endl; - alsamidi->run(); #ifndef DISABLE_GUI ui = new MasterUI(master, &Pexitprogram);