diff --git a/SpiralSound/Midi.C b/SpiralSound/Midi.C index ed39ec5..c3a0509 100644 --- a/SpiralSound/Midi.C +++ b/SpiralSound/Midi.C @@ -23,10 +23,6 @@ #include "signal.h" #include "pthread.h" -#ifdef KEYBOARD_SUPPORT -#include -#endif - static const int MIDI_SCANBUFSIZE=256; static const int MIDI_KEYOFFSET=0; @@ -45,9 +41,6 @@ static const unsigned char MIDI_CLOCK = 0xf8; static const unsigned char ACTIVE_SENSE = 0xfe; static int NKEYS = 30; -static char KEYMAP[30]={'z','s','x','d','c','v','g','b','h','n','j','m','q', - '2','w','3','e','r','5','t','6','y','7','u','i','9', - 'o','0','p','['}; MidiDevice *MidiDevice::m_Singleton; string MidiDevice::m_DeviceName; @@ -55,7 +48,13 @@ string MidiDevice::m_DeviceName; MidiDevice::MidiDevice() : m_Poly(1) { +#ifdef ALSA_MIDI + seq_handle=AlsaOpen(); +#else Open(); +#endif + + #ifdef KEYBOARD_SUPPORT m_Oct=4; @@ -70,7 +69,11 @@ m_Poly(1) MidiDevice::~MidiDevice() { +#ifdef ALSA_MIDI + snd_seq_close (seq_handle); +#else Close(); +#endif } void MidiDevice::Close() @@ -122,9 +125,17 @@ MidiEvent MidiDevice::GetEvent(int Device) return MidiEvent(MidiEvent::NONE,0,0); } -#ifdef KEYBOARD_SUPPORT - CheckKeyboard(); -#endif +#ifdef ALSA_MIDI + AlsaCallback(); + + if (m_EventVec[Device].size()==0) + { + return MidiEvent(MidiEvent::NONE,0,0); + } + + MidiEvent event(m_EventVec[Device].front()); + m_EventVec[Device].pop(); +#else pthread_mutex_lock(m_Mutex); if (m_EventVec[Device].size()==0) @@ -136,12 +147,13 @@ MidiEvent MidiDevice::GetEvent(int Device) MidiEvent event(m_EventVec[Device].front()); m_EventVec[Device].pop(); pthread_mutex_unlock(m_Mutex); - +#endif return event; } void MidiDevice::SendEvent(int Device,const MidiEvent &Event) { +#ifndef ALSA_MIDI if (Device<0 || Device>15) { cerr<<"SendEvent: Invalid Midi device "<=m_Poly) - { - m_CurrentVoice=0; - } - - // this should be the current voice we are using - m_KeyVoice[m_CurrentVoice]=KeyChar; - } + do { + snd_seq_event_input(seq_handle, &ev); + if ((ev->type == SND_SEQ_EVENT_NOTEON) && (ev->data.note.velocity == 0)) + { + ev->type = SND_SEQ_EVENT_NOTEOFF; } - else // it's not pressed down - { - //see if the note was pressed down last time - for (int n=0; ntype) { + 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)); - pthread_mutex_unlock(m_Mutex); - } + + 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 *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"); + } + return(seq_handle); +} + #endif + diff --git a/SpiralSound/Midi.h b/SpiralSound/Midi.h index b6afab5..adf4dc4 100644 --- a/SpiralSound/Midi.h +++ b/SpiralSound/Midi.h @@ -30,8 +30,11 @@ using namespace std; -//#define KEYBOARD_SUPPORT +//#define ALSA_MIDI +#ifdef ALSA_MIDI +#include +#endif class MidiEvent { @@ -88,12 +91,11 @@ private: pthread_t m_MidiReader; pthread_mutex_t* m_Mutex; - -#ifdef KEYBOARD_SUPPORT - void CheckKeyboard(); - char m_KeyVoice[256]; - int m_Oct; - int m_CurrentVoice; + +#ifdef ALSA_MIDI + int AlsaCallback(); + snd_seq_t *seq_handle; + snd_seq_t *AlsaOpen(); #endif };