/* alsa_rawmidi_init: * Inits the ALSA RawMIDI interface. */ static int alsa_rawmidi_init(int input, int voices) { int ret = -1, err; char tmp1[128], tmp2[128], temp[256]; #if ALLEGRO_ALSA_VERSION == 9 snd_rawmidi_info_t *info; const char *device = NULL; #else /* ALLEGRO_ALSA_VERSION == 5 */ snd_rawmidi_info_t info; int card = -1; int device = -1; #endif if (input) { ret = -1; } else { #if ALLEGRO_ALSA_VERSION == 9 device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), "default"); err = snd_rawmidi_open(NULL, &rawmidi_handle, device, 0); #else /* ALLEGRO_ALSA_VERSION == 5 */ card = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_card", tmp2), snd_defaults_rawmidi_card()); device = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), snd_defaults_rawmidi_device()); err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND); #endif if (err) { snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err)); ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp)); ret = -1; } ret = 0; } if (rawmidi_handle) { #if ALLEGRO_ALSA_VERSION == 9 snd_rawmidi_nonblock(rawmidi_handle, 0); snd_rawmidi_info_malloc(&info); snd_rawmidi_info(rawmidi_handle, info); _al_sane_strncpy(alsa_rawmidi_desc, snd_rawmidi_info_get_name(info), sizeof(alsa_rawmidi_desc)); #else /* ALLEGRO_ALSA_VERSION == 5 */ snd_rawmidi_block_mode(rawmidi_handle, 1); snd_rawmidi_info(rawmidi_handle, &info); _al_sane_strncpy(alsa_rawmidi_desc, info.name, sizeof(alsa_rawmidi_desc)); #endif midi_alsa.desc = alsa_rawmidi_desc; alsa_rawmidi_errors = 0; } return ret; }
char *mus_midi_describe(void) { int i, err; snd_rawmidi_t *line; snd_rawmidi_info_t *info; char *buf = NULL; char one[256]; snd_rawmidi_info_malloc(&info); buf = (char *)CALLOC(1024, sizeof(char)); for (i = 0; i < 8; i++) { /* presumably this should use the card|device from the info struct, not a blind loop */ err = snd_rawmidi_open(&line, NULL, mus_midi_device_name(i << 16), SND_RAWMIDI_NONBLOCK); /* do the "devices" matter here? */ if (err < 0) continue; err = snd_rawmidi_info(line, info); if (err < 0) break; sprintf(one, "%s: card: %d, device: %d, stream: %d, flags: %x, id: %s, name: %s[%s; %d]\n", mus_midi_device_name(i << 16), snd_rawmidi_info_get_card(info), /* card number */ snd_rawmidi_info_get_device(info), /* device number */ snd_rawmidi_info_get_stream(info), /* snd_rawmidi_stream_t */ snd_rawmidi_info_get_flags(info), /* 1=out 2=in 4=dupex */ snd_rawmidi_info_get_id(info), /* hardware id (out in?) */ snd_rawmidi_info_get_name(info), snd_rawmidi_info_get_subdevice_name(info), snd_rawmidi_info_get_subdevices_count(info)); strcat(buf, one); } snd_rawmidi_info_free(info); return(buf); }
// for each ALSA device, call iterator. userData is passed to the iterator // returns total number of iterations static int iterateRawmidiDevices(snd_rawmidi_stream_t direction, DeviceIteratorPtr iterator, void* userData) { int count = 0; int subdeviceCount; int card, dev, subDev; char devname[16]; int err; snd_ctl_t *handle; snd_rawmidi_t *rawmidi; snd_rawmidi_info_t *rawmidi_info; snd_ctl_card_info_t *card_info, *defcardinfo = NULL; UINT32 deviceID; int doContinue = TRUE; snd_rawmidi_info_malloc(&rawmidi_info); snd_ctl_card_info_malloc(&card_info); // 1st try "default" device if (direction == SND_RAWMIDI_STREAM_INPUT) { err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME, SND_RAWMIDI_NONBLOCK); } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) { err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME, SND_RAWMIDI_NONBLOCK); } else { ERROR0("ERROR: iterateRawmidiDevices(): direction is neither" " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n"); err = MIDI_INVALID_ARGUMENT; } if (err < 0) { ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n", snd_strerror(err)); } else { err = snd_rawmidi_info(rawmidi, rawmidi_info); snd_rawmidi_close(rawmidi); if (err < 0) { ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n", snd_strerror(err)); } else { // try to get card info card = snd_rawmidi_info_get_card(rawmidi_info); if (card >= 0) { sprintf(devname, ALSA_HARDWARE_CARD, card); if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) { if (snd_ctl_card_info(handle, card_info) >= 0) { defcardinfo = card_info; } snd_ctl_close(handle); } } // call calback function for the device if (iterator != NULL) { doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info, defcardinfo, userData); } count++; } } // iterate cards card = -1; TRACE0("testing for cards...\n"); if (snd_card_next(&card) >= 0) { TRACE1("Found card %d\n", card); while (doContinue && (card >= 0)) { sprintf(devname, ALSA_HARDWARE_CARD, card); TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK); if (err < 0) { ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err)); } else { TRACE0("snd_ctl_open() SUCCESS\n"); err = snd_ctl_card_info(handle, card_info); if (err < 0) { ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err)); } else { TRACE0("snd_ctl_card_info() SUCCESS\n"); dev = -1; while (doContinue) { if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) { ERROR0("snd_ctl_rawmidi_next_device\n"); } TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n"); if (dev < 0) { break; } snd_rawmidi_info_set_device(rawmidi_info, dev); snd_rawmidi_info_set_subdevice(rawmidi_info, 0); snd_rawmidi_info_set_stream(rawmidi_info, direction); err = snd_ctl_rawmidi_info(handle, rawmidi_info); TRACE0("after snd_ctl_rawmidi_info()\n"); if (err < 0) { if (err != -ENOENT) { ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err)); } } else { TRACE0("snd_ctl_rawmidi_info() SUCCESS\n"); subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI) ? snd_rawmidi_info_get_subdevices_count(rawmidi_info) : 1; if (iterator!=NULL) { for (subDev = 0; subDev < subdeviceCount; subDev++) { TRACE3(" Iterating %d,%d,%d\n", card, dev, subDev); deviceID = encodeDeviceID(card, dev, subDev); doContinue = (*iterator)(deviceID, rawmidi_info, card_info, userData); count++; TRACE0("returned from iterator\n"); if (!doContinue) { break; } } } else { count += subdeviceCount; } } } // of while(doContinue) } snd_ctl_close(handle); } if (snd_card_next(&card) < 0) { break; } } } else { ERROR0("No cards found!\n"); } snd_ctl_card_info_free(card_info); snd_rawmidi_info_free(rawmidi_info); return count; }