Esempio n. 1
0
static
void scan_card(scan_t *scan)
{
    int device = -1;
    int err;

    while ((err = snd_ctl_rawmidi_next_device(scan->ctl, &device))>=0 && device >=0) {
        snd_rawmidi_info_set_device(scan->info, device);

        snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_INPUT);
        snd_rawmidi_info_set_subdevice(scan->info, 0);
        if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0)
            scan_device(scan);
        else if (err != -ENOENT)
            alsa_error("scan: snd_ctl_rawmidi_info on device", err);

        snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_OUTPUT);
        snd_rawmidi_info_set_subdevice(scan->info, 0);
        if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0)
            scan_device(scan);
        else if (err != -ENOENT)
            alsa_error("scan: snd_ctl_rawmidi_info on device", err);
    }
}
Esempio n. 2
0
int is_output(snd_ctl_t *ctl, int card, int device, int sub) {
    snd_rawmidi_info_t *info;
    int status;

    snd_rawmidi_info_alloca(&info);
    snd_rawmidi_info_set_device(info, device);
    snd_rawmidi_info_set_subdevice(info, sub);
    snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT);

    if ((status = snd_ctl_rawmidi_info(ctl, info)) < 0 && status != -ENXIO) {
        return status;
    } else if (status == 0) {
        return 1;
    }

    return 0;
}
// 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;
}
Esempio n. 4
0
//list all the midi interfaces
void list_midi_interfaces(char* midi_dev, int bufsize)
{
    register int  err;
    int  cardNum;
    char devices[5][14];
    char user_midi[bufsize];

    // Start with first card
    cardNum = -1;

    for (;;)
    {
        snd_ctl_t *cardHandle;

        // Get next sound card's card number. When "cardNum" == -1, then ALSA
        // fetches the first card
        if ((err = snd_card_next(&cardNum)) < 0)
        {
            printf("Can't get the next card number: %s\n", snd_strerror(err));
            break;
        }

        // No more cards? ALSA sets "cardNum" to -1 if so
        if (cardNum < 0) break;

        // Open this card's control interface. We specify only the card number -- not
        // any device nor sub-device too
        {
            char   str[64];

            sprintf(str, "hw:%i", cardNum);
            if ((err = snd_ctl_open(&cardHandle, str, 0)) < 0)
            {
                printf("Can't open card %i: %s\n", cardNum, snd_strerror(err));
                continue;
            }
        }

        {
            int      devNum;

            // Start with the first MIDI device on this card
            devNum = -1;

            for (;;)
            {
                snd_rawmidi_info_t  *rawMidiInfo;
                register int        subDevCount, i;

                // Get the number of the next MIDI device on this card
                if ((err = snd_ctl_rawmidi_next_device(cardHandle, &devNum)) < 0)
                {
                    printf("Can't get next MIDI device number: %s\n", snd_strerror(err));
                    break;
                }

                // No more MIDI devices on this card? ALSA sets "devNum" to -1 if so.
                // NOTE: It's possible that this sound card may have no MIDI devices on it
                // at all, for example if it's only a digital audio card
                if (devNum < 0) break;

                // To get some info about the subdevices of this MIDI device (on the card), we need a
                // snd_rawmidi_info_t, so let's allocate one on the stack
                snd_rawmidi_info_alloca(&rawMidiInfo);
                memset(rawMidiInfo, 0, snd_rawmidi_info_sizeof());

                // Tell ALSA which device (number) we want info about
                snd_rawmidi_info_set_device(rawMidiInfo, devNum);

                // Get info on the MIDI outs of this device
                snd_rawmidi_info_set_stream(rawMidiInfo, SND_RAWMIDI_STREAM_INPUT);

                i = -1;
                subDevCount = 1;

                // More subdevices?
                while (++i < subDevCount)
                {
                    // Tell ALSA to fill in our snd_rawmidi_info_t with info on this subdevice
                    snd_rawmidi_info_set_subdevice(rawMidiInfo, i);
                    if ((err = snd_ctl_rawmidi_info(cardHandle, rawMidiInfo)) < 0)
                    {
                        printf("Can't get info for MIDI input subdevice hw:%i,%i,%i: %s\n", cardNum, devNum, i, snd_strerror(err));
                        continue;
                    }

                    // Print out how many subdevices (once only)
                    if (!i)
                    {
                        subDevCount = snd_rawmidi_info_get_subdevices_count(rawMidiInfo);
                        printf("\nFound %i MIDI input subdevices on card %i\n", subDevCount, cardNum);
                    }

                    // NOTE: If there's only one subdevice, then the subdevice number is immaterial,
                    // and can be omitted when you specify the hardware name
                    printf((subDevCount > 1 ? "[%i] -    hw:%i,%i,%i\n" : "[%i] -    hw:%i,%i\n"), i, cardNum, devNum, i);
                    sprintf(devices[i], (subDevCount > 1 ? "hw:%i,%i,%i\n":"hw:%i,%i\n"),cardNum, devNum, i);
                }
            }
        }

        // Close the card's control interface after we're done with it
        snd_ctl_close(cardHandle);


    }

    snd_config_update_free_global();

    printf("\nEnter the MIDI input to use (eg hw:1,0) > ");
    scanf("%s",user_midi);

    strncpy(midi_dev,user_midi,bufsize);
}
Esempio n. 5
0
void list_subdevice_info(snd_ctl_t *ctl, int card, int device) {
    snd_rawmidi_info_t *info;
    const char *name;
    const char *sub_name;
    int subs, subs_in, subs_out;
    int sub, in, out;
    int status;

    snd_rawmidi_info_alloca(&info);
    snd_rawmidi_info_set_device(info, device);

    snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
    snd_ctl_rawmidi_info(ctl, info);
    subs_in = snd_rawmidi_info_get_subdevices_count(info);
    snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT);
    snd_ctl_rawmidi_info(ctl, info);
    subs_out = snd_rawmidi_info_get_subdevices_count(info);
    subs = subs_in > subs_out ? subs_in : subs_out;

    sub = 0;
    in = out = 0;
    if ((status = is_output(ctl, card, device, sub)) < 0) {
        error("cannot get rawmidi information %d:%d: %s",
              card, device, snd_strerror(status));
        return;
    } else if (status)
        out = 1;

    if (status == 0) {
        if ((status = is_input(ctl, card, device, sub)) < 0) {
            error("cannot get rawmidi information %d:%d: %s",
                  card, device, snd_strerror(status));
            return;
        }
    } else if (status)
        in = 1;

    if (status == 0)
        return;

    name = snd_rawmidi_info_get_name(info);
    sub_name = snd_rawmidi_info_get_subdevice_name(info);
    if (sub_name[0] == '\0') {
        if (subs == 1) {
            printf("%c%c  hw:%d,%d    %s\n",
                   in  ? 'I' : ' ',
                   out ? 'O' : ' ',
                   card, device, name);
        } else
            printf("%c%c  hw:%d,%d    %s (%d subdevices)\n",
                   in  ? 'I' : ' ',
                   out ? 'O' : ' ',
                   card, device, name, subs);
    } else {
        sub = 0;
        for (;;) {
            printf("%c%c  hw:%d,%d,%d  %s\n",
                   in ? 'I' : ' ', out ? 'O' : ' ',
                   card, device, sub, sub_name);
            if (++sub >= subs)
                break;

            in = is_input(ctl, card, device, sub);
            out = is_output(ctl, card, device, sub);
            snd_rawmidi_info_set_subdevice(info, sub);
            if (out) {
                snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT);
                if ((status = snd_ctl_rawmidi_info(ctl, info)) < 0) {
                    error("cannot get rawmidi information %d:%d:%d: %s",
                          card, device, sub, snd_strerror(status));
                    break;
                }
            } else {
                snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
                if ((status = snd_ctl_rawmidi_info(ctl, info)) < 0) {
                    error("cannot get rawmidi information %d:%d:%d: %s",
                          card, device, sub, snd_strerror(status));
                    break;
                }
            }
            sub_name = snd_rawmidi_info_get_subdevice_name(info);
        }
    }
}