Browse Source

add read/write handles for ALSA midi so MIDI plugin can control,

and change MIDI gui device range to 0 - 127
master
aj_genius 21 years ago
parent
commit
c4c867f05c
3 changed files with 114 additions and 66 deletions
  1. +99
    -60
      SpiralSound/Midi.C
  2. +11
    -2
      SpiralSound/Midi.h
  3. +4
    -4
      SpiralSound/Plugins/MidiPlugin/MidiPluginGUI.C

+ 99
- 60
SpiralSound/Midi.C View File

@@ -70,7 +70,7 @@ m_ClockCount (0)
AppleOpen();
#endif
#ifdef USE_ALSA_MIDI
seq_handle=AlsaOpen(t);
AlsaOpen();
#endif
#ifdef USE_OSS_MIDI
if (!OssOpen()) return;
@@ -122,30 +122,7 @@ MidiEvent MidiDevice::GetEvent(int Device)

void MidiDevice::SendEvent (int Device, const MidiEvent &Event) {
#ifdef USE_ALSA_MIDI
snd_seq_event_t ev;
snd_seq_ev_clear (&ev);
snd_seq_ev_set_direct (&ev);
snd_seq_ev_set_subs (&ev);
snd_seq_ev_set_source (&ev, 0);

switch (Event.GetType())
{
case MidiEvent::ON:
ev.type = SND_SEQ_EVENT_NOTEON;
break;
case MidiEvent::OFF:
ev.type = SND_SEQ_EVENT_NOTEOFF;
break;
default:
break;
}

ev.data.note.velocity = (char)Event.GetVolume()*127;
ev.data.control.channel = Device;
ev.data.note.note=Event.GetNote();

int ret=snd_seq_event_output(seq_handle, &ev);
snd_seq_drain_output(seq_handle);
AlsaSendEvent (Device, Event);
#else
if (Device<0 || Device>15)
{
@@ -367,17 +344,28 @@ void MidiDevice::OssAddEvent(unsigned char* midi)
// code taken and modified from jack_miniFMsynth

void MidiDevice::AlsaClose () {
snd_seq_close (seq_handle);

//Alsa requires two handles - one for read and one for write,
//so we make sure too close both here
snd_seq_close (seq_rhandle);
snd_seq_close (seq_whandle);
}

void MidiDevice::AlsaCollectEvents () {
//As Alsa only supports a read or write, we use the read handle here to poll our input
//for MIDI events
int seq_nfds, l1;
struct pollfd *pfds;
seq_nfds = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
// Andy Preston
// pfds = (struct pollfd *)alloca (sizeof(struct pollfd) * seq_nfds);

//get descriptors count to find out how many events are
//waiting to be processed
seq_nfds = snd_seq_poll_descriptors_count(seq_rhandle, POLLIN);
//poll the descriptors to be proccessed and loop through them
pfds = new struct pollfd[seq_nfds];
snd_seq_poll_descriptors(seq_handle, pfds, seq_nfds, POLLIN);
snd_seq_poll_descriptors(seq_rhandle, pfds, seq_nfds, POLLIN);
for (;;) {
if (poll (pfds, seq_nfds, 1000) > 0) {
for (l1 = 0; l1 < seq_nfds; l1++) {
@@ -388,7 +376,7 @@ void MidiDevice::AlsaCollectEvents () {
MidiEvent::type MessageType=MidiEvent::NONE;
int Volume=0, Note=0, EventDevice=0;
do {
snd_seq_event_input (seq_handle, &ev);
snd_seq_event_input (seq_rhandle, &ev);
if ((ev->type == SND_SEQ_EVENT_NOTEON) && (ev->data.note.velocity == 0)) {
ev->type = SND_SEQ_EVENT_NOTEOFF;
}
@@ -419,7 +407,7 @@ void MidiDevice::AlsaCollectEvents () {
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);
} while (snd_seq_event_input_pending(seq_rhandle, 0) > 0);
}
}
}
@@ -427,40 +415,91 @@ void MidiDevice::AlsaCollectEvents () {
delete [] pfds;
}

snd_seq_t *MidiDevice::AlsaOpen(Type t)
void MidiDevice::AlsaSendEvent (int Device, const MidiEvent &Event) {
//As Alsa only supports a read or write, we use the write handle here to send
//our MIDI events

snd_seq_event_t ev;
snd_seq_ev_clear (&ev);
snd_seq_ev_set_direct (&ev);
snd_seq_ev_set_subs (&ev);
snd_seq_ev_set_source (&ev, 0);

switch (Event.GetType())
{
case MidiEvent::ON:
ev.type = SND_SEQ_EVENT_NOTEON;
break;
case MidiEvent::OFF:
ev.type = SND_SEQ_EVENT_NOTEOFF;
break;
/* case MidiEvent::PARAMETER:
ev.type = SND_SEQ_EVENT_CONTROLLER;
ev.data.control.param = Event.GetNote();
ev.data.control.value =
break;
case MidiEvent::PITCHBEND:
ev.type = SND_SEQ_EVENT_PITCHBEND;
ev.data.control.param = Event.GetNote();
ev.data.control.value =
break;*/
default:
break;
}

ev.data.note.velocity = (char)Event.GetVolume()*127;
ev.data.control.channel = Device;
ev.data.note.note=Event.GetNote();

snd_seq_event_output(seq_whandle, &ev);
snd_seq_drain_output(seq_whandle);
}

void MidiDevice::AlsaOpen()
{
snd_seq_t *seq_handle;
int client_id, port_id;
int client_id, port_id;
//Alsa apears to require two handles, one for read and one for write
//so we try to open one first for input and then one for output
//open input handle
if (snd_seq_open(&seq_rhandle, "default", SND_SEQ_OPEN_INPUT, 0) < 0)
{
fprintf(stderr, "Error opening ALSA input sequencer.\n");
exit(1);
}

//setup our input name as seen by other apps, and get corresponding client id
snd_seq_set_client_name(seq_rhandle, m_AppName.c_str());
client_id = snd_seq_client_id(seq_rhandle);

if (t==WRITE)
//try and create our actual input port capable of being written to by MIDI outputs
if ((port_id = snd_seq_create_simple_port(seq_rhandle, m_AppName.c_str(),
SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION) < 0))
{
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");
}
fprintf(stderr, "Error creating input sequencer port.\n");
}
else

//open output handle
if (snd_seq_open(&seq_whandle, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0)
{
fprintf(stderr, "Error opening ALSA ouput sequencer.\n");
exit(1);
}

//setup our output name as seen by other apps, and get corresponding client id
snd_seq_set_client_name(seq_whandle, m_AppName.c_str());
client_id = snd_seq_client_id(seq_whandle);

//try and create our actual output port capable of being read from by MIDI inputs
if ((port_id = snd_seq_create_simple_port(seq_whandle, m_AppName.c_str(),
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_APPLICATION) < 0))
{
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");
}
fprintf(stderr, "Error creating output sequencer port.\n");
}
return(seq_handle);
}

#endif


+ 11
- 2
SpiralSound/Midi.h View File

@@ -98,9 +98,18 @@ private:
#ifdef USE_ALSA_MIDI
static void *MidiReaderCallback (void *o) { ((MidiDevice*)o)->AlsaCollectEvents(); return NULL; }
void AlsaCollectEvents();
void AlsaSendEvent(int Device, const MidiEvent &Event);

void AlsaClose ();
snd_seq_t *seq_handle;
snd_seq_t *AlsaOpen(Type t);

//snd_seq_t *seq_handle;

//I appears that ALsa does not support both a read and write handle
//so we must have two handle one for each mode
snd_seq_t *seq_rhandle;
snd_seq_t *seq_whandle;

void AlsaOpen();
#endif
#ifdef USE_OSS_MIDI
static void *MidiReaderCallback (void *o) { ((MidiDevice*)o)->OssCollectEvents(); return NULL; }


+ 4
- 4
SpiralSound/Plugins/MidiPlugin/MidiPluginGUI.C View File

@@ -80,7 +80,7 @@ SpiralPluginGUI(w,h,o,ch)
m_DeviceNum->box (FL_PLASTIC_UP_BOX);
m_DeviceNum->color (Info->GUI_COLOUR);
m_DeviceNum->step(1);
m_DeviceNum->value(1);
m_DeviceNum->value(0);
m_DeviceNum->callback((Fl_Callback*)cb_DeviceNum, NULL);

m_NoteCut = new Fl_Button (0, 52, 80, 20, "Note Cut");
@@ -123,10 +123,10 @@ void MidiPluginGUI::UpdateValues(SpiralPlugin *o)
//// Callbacks ////
inline void MidiPluginGUI::cb_DeviceNum_i(Fl_Counter* o, void* v)
{
if (o->value()<1) o->value(1);
if (o->value()>128) o->value(128);
if (o->value()<0) o->value(0);
if (o->value()>127) o->value(127);
m_GUICH->Set("DeviceNum",(int)o->value()-1);
m_GUICH->Set("DeviceNum",(int)o->value());
}
void MidiPluginGUI::cb_DeviceNum(Fl_Counter* o, void* v)
{ ((MidiPluginGUI*)(o->parent()))->cb_DeviceNum_i(o,v);}


Loading…
Cancel
Save