23 #include <alsa/asoundlib.h>
30 class ALSAMIDIDevice:
public MIDIDevice
34 snd_rawmidi_t *mHandleIn;
35 snd_rawmidi_t *mHandleOut;
36 snd_rawmidi_status_t *mStatusIn;
38 ALSAMIDIDevice(
const std::string& name,
const std::string& device);
41 void ConcreteStart(
void) throw(Err);
42 void ConcreteStop(
void) throw(Err);
44 void Read(
void) throw(Err);
45 void Write(
unsigned char* msg,
int size) throw(Err);
48 ALSAMIDIDevice::ALSAMIDIDevice(const std::
string& name,const std::
string& device):
57 void ALSAMIDIDevice::ConcreteStart(
void) throw(Err)
59 snd_rawmidi_t** handleInRef =
NULL;
60 snd_rawmidi_t** handleOutRef =
NULL;
62 if (
mInputs.size()) handleInRef = &mHandleIn;
63 if (
mOutputs.size()) handleOutRef = &mHandleOut;
65 int err = snd_rawmidi_open(handleInRef,handleOutRef,mDevice.c_str(),
66 SND_RAWMIDI_NONBLOCK);
69 std::string str(
"Could not open ALSAMIDIDevice ");
71 throw Err(str.c_str());
73 snd_rawmidi_status_malloc(&mStatusIn);
77 void ALSAMIDIDevice::ConcreteStop(
void) throw(Err)
80 snd_rawmidi_drain(mHandleIn);
81 snd_rawmidi_close(mHandleIn);
82 snd_rawmidi_status_free(mStatusIn);
86 snd_rawmidi_drain(mHandleOut);
87 snd_rawmidi_close(mHandleOut);
91 void ALSAMIDIDevice::Write(
unsigned char* msg,
int size)
throw(Err)
93 snd_rawmidi_write(mHandleOut,msg,size);
94 snd_rawmidi_drain(mHandleOut);
97 void ALSAMIDIDevice::Read(
void) throw(Err)
103 int err = snd_rawmidi_read(mHandleIn,&ch,1);
108 snd_rawmidi_status(mHandleIn,mStatusIn);
109 n = snd_rawmidi_status_get_avail(mStatusIn);
113 ALSAMIDIDevice::~ALSAMIDIDevice()
118 class ALSAMIDIDeviceList:
public MIDIDeviceList
120 static ALSAMIDIDeviceList sDevices;
123 :MIDIDeviceList(std::string(
"alsa"))
127 snd_ctl_card_info_t *info;
129 snd_ctl_card_info_alloca(&info);
131 if (snd_card_next(&card) < 0 || card < 0)
134 std::stringstream namestr;
135 namestr <<
"hw:" << card;
136 std::string name(namestr.str());
137 if (snd_ctl_open(&handle, name.c_str(), 0) < 0)
140 if (snd_ctl_card_info(handle, info) < 0) {
141 snd_ctl_close(handle);
146 snd_ctl_rawmidi_next_device(handle, &dev);
149 std::stringstream dname;
150 dname << name <<
"," << dev;
151 mAvailableDevices.push_back(dname.str());
153 snd_ctl_close(handle);
154 if (snd_card_next(&card) < 0)
162 std::string DefaultDevice(
void)
168 const std::string& name,
const std::string& device)
170 return new ALSAMIDIDevice(name,device);
174 ALSAMIDIDeviceList ALSAMIDIDeviceList::sDevices;