24 #include "JackALSARawMidiPort.h"    25 #include "JackALSARawMidiUtil.h"    26 #include "JackError.h"    30 JackALSARawMidiPort::JackALSARawMidiPort(snd_rawmidi_info_t *info,
    31                                          size_t index, 
unsigned short io_mask)
    33     int card = snd_rawmidi_info_get_card(info);
    34     unsigned int device = snd_rawmidi_info_get_device(info);
    35     unsigned int subdevice = snd_rawmidi_info_get_subdevice(info);
    37     snprintf(device_id, 
sizeof(device_id), 
"hw:%d,%d,%d", card, device,
    39     const char *alias_suffix;
    40     const char *error_message;
    42     const char *name_prefix;
    44     if (snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT) {
    47         name_prefix = 
"system:midi_playback_";
    52         name_prefix = 
"system:midi_capture_";
    56     int code = snd_rawmidi_open(in, out, device_id, SND_RAWMIDI_NONBLOCK);
    58         error_message = snd_strerror(code);
    59         func = 
"snd_rawmidi_open";
    62     snd_rawmidi_params_t *params;
    63     code = snd_rawmidi_params_malloc(¶ms);
    65         error_message = snd_strerror(code);
    66         func = 
"snd_rawmidi_params_malloc";
    69     code = snd_rawmidi_params_current(rawmidi, params);
    71         error_message = snd_strerror(code);
    72         func = 
"snd_rawmidi_params_current";
    75     code = snd_rawmidi_params_set_avail_min(rawmidi, params, 1);
    77         error_message = snd_strerror(code);
    78         func = 
"snd_rawmidi_params_set_avail_min";
    83     code = snd_rawmidi_params_set_buffer_size(rawmidi, params, 32);
    85         error_message = snd_strerror(code);
    86         func = 
"snd_rawmidi_params_set_buffer_size";
    90     code = snd_rawmidi_params_set_no_active_sensing(rawmidi, params, 1);
    92         error_message = snd_strerror(code);
    93         func = 
"snd_rawmidi_params_set_no_active_sensing";
    96     code = snd_rawmidi_params(rawmidi, params);
    98         error_message = snd_strerror(code);
    99         func = 
"snd_rawmidi_params";
   102     snd_rawmidi_params_free(params);
   103     alsa_poll_fd_count = snd_rawmidi_poll_descriptors_count(rawmidi);
   104     if (! alsa_poll_fd_count) {
   105         error_message = 
"returned '0' count for poll descriptors";
   106         func = 
"snd_rawmidi_poll_descriptors_count";
   110         CreateNonBlockingPipe(fds);
   111     } 
catch (std::exception e) {
   112         error_message = e.what();
   113         func = 
"CreateNonBlockingPipe";
   116     snprintf(alias, 
sizeof(alias), 
"system:%d-%d %s %d %s", card + 1,
   117              device + 1, snd_rawmidi_info_get_name(info), subdevice + 1,
   119     snprintf(name, 
sizeof(name), 
"%s%zu", name_prefix, index + 1);
   120     this->io_mask = io_mask;
   123     snd_rawmidi_params_free(params);
   125     snd_rawmidi_close(rawmidi);
   127     throw std::runtime_error(std::string(func) + 
": " + error_message);
   130 JackALSARawMidiPort::~JackALSARawMidiPort()
   132     DestroyNonBlockingPipe(fds);
   134         int code = snd_rawmidi_close(rawmidi);
   136             jack_error(
"JackALSARawMidiPort::~JackALSARawMidiPort - "   137                        "snd_rawmidi_close: %s", snd_strerror(code));
   144 JackALSARawMidiPort::GetAlias()
   150 JackALSARawMidiPort::GetIOPollEvent()
   152     unsigned short events;
   153     int code = snd_rawmidi_poll_descriptors_revents(rawmidi, alsa_poll_fds,
   157         jack_error(
"JackALSARawMidiPort::GetIOPollEvents - "   158                    "snd_rawmidi_poll_descriptors_revents: %s",
   162     if (events & POLLNVAL) {
   163         jack_error(
"JackALSARawMidiPort::GetIOPollEvents - the file "   164                    "descriptor is invalid.");
   167     if (events & POLLERR) {
   168         jack_error(
"JackALSARawMidiPort::GetIOPollEvents - an error has "   169                    "occurred on the device or stream.");
   172     return (events & io_mask) ? 1 : 0;
   176 JackALSARawMidiPort::GetName()
   182 JackALSARawMidiPort::GetPollDescriptorCount()
   184     return alsa_poll_fd_count + 1;
   188 JackALSARawMidiPort::GetQueuePollEvent()
   190     unsigned short events = queue_poll_fd->revents;
   191     if (events & POLLNVAL) {
   192         jack_error(
"JackALSARawMidiPort::GetQueuePollEvents - the file "   193                    "descriptor is invalid.");
   196     if (events & POLLERR) {
   197         jack_error(
"JackALSARawMidiPort::GetQueuePollEvents - an error has "   198                    "occurred on the device or stream.");
   201     int event = events & POLLIN ? 1 : 0;
   204         ssize_t result = read(fds[0], &c, 1);
   207             jack_error(
"JackALSARawMidiPort::GetQueuePollEvents - error "   208                        "reading a byte from the pipe file descriptor: %s",
   217 JackALSARawMidiPort::PopulatePollDescriptors(
struct pollfd *poll_fd)
   219     alsa_poll_fds = poll_fd + 1;
   220     assert(snd_rawmidi_poll_descriptors(rawmidi, alsa_poll_fds,
   221                                         alsa_poll_fd_count) ==
   223     queue_poll_fd = poll_fd;
   224     queue_poll_fd->events = POLLERR | POLLIN | POLLNVAL;
   225     queue_poll_fd->fd = fds[0];
   226     SetIOEventsEnabled(
true);
   230 JackALSARawMidiPort::SetIOEventsEnabled(
bool enabled)
   232     unsigned short mask = POLLNVAL | POLLERR | (enabled ? io_mask : 0);
   233     for (
int i = 0; i < alsa_poll_fd_count; i++) {
   234         (alsa_poll_fds + i)->events = mask;
   239 JackALSARawMidiPort::TriggerQueueEvent()
   242     ssize_t result = write(fds[1], &c, 1);
   248         jack_error(
"JackALSARawMidiPort::TriggerQueueEvent - error writing a "   249                    "byte to the pipe file descriptor: %s", strerror(errno));
   252         jack_error(
"JackALSARawMidiPort::TriggerQueueEvent - couldn't write a "   253                    "byte to the pipe file descriptor.");
 SERVER_EXPORT void jack_error(const char *fmt,...)