Exemplo n.º 1
0
static char *ListAvailableDevices( demux_t *p_demux, bool b_probe )
{
    snd_ctl_card_info_t *p_info = NULL;
    snd_ctl_card_info_alloca( &p_info );

    snd_pcm_info_t *p_pcminfo = NULL;
    snd_pcm_info_alloca( &p_pcminfo );

    if( !b_probe )
        msg_Dbg( p_demux, "Available alsa capture devices:" );
    int i_card = -1;
    while( !snd_card_next( &i_card ) && i_card >= 0 )
    {
        char psz_devname[10];
        snprintf( psz_devname, 10, "hw:%d", i_card );

        snd_ctl_t *p_ctl = NULL;
        if( snd_ctl_open( &p_ctl, psz_devname, 0 ) < 0 ) continue;

        snd_ctl_card_info( p_ctl, p_info );
        if( !b_probe )
            msg_Dbg( p_demux, "  %s (%s)",
                     snd_ctl_card_info_get_id( p_info ),
                     snd_ctl_card_info_get_name( p_info ) );

        int i_dev = -1;
        while( !snd_ctl_pcm_next_device( p_ctl, &i_dev ) && i_dev >= 0 )
        {
            snd_pcm_info_set_device( p_pcminfo, i_dev );
            snd_pcm_info_set_subdevice( p_pcminfo, 0 );
            snd_pcm_info_set_stream( p_pcminfo, SND_PCM_STREAM_CAPTURE );
            if( snd_ctl_pcm_info( p_ctl, p_pcminfo ) < 0 ) continue;

            if( !b_probe )
                msg_Dbg( p_demux, "    hw:%d,%d : %s (%s)", i_card, i_dev,
                         snd_pcm_info_get_id( p_pcminfo ),
                         snd_pcm_info_get_name( p_pcminfo ) );
            else
            {
                char *psz_device;
                if( asprintf( &psz_device, "hw:%d,%d", i_card, i_dev ) > 0 )
                {
                    if( ProbeAudioDevAlsa( p_demux, psz_device ) )
                    {
                        snd_ctl_close( p_ctl );
                        return psz_device;
                    }
                    else
                        free( psz_device );
                }
            }
        }

        snd_ctl_close( p_ctl );
    }
    return NULL;
}
Exemplo n.º 2
0
bool MainWindowImpl::FindRadioshark(string& device)
{
	int card = -1;
	int dev = -1;
	
	snd_ctl_t *handle = NULL;
	snd_ctl_card_info_t *info = NULL;
	snd_pcm_info_t *pcminfo = NULL;
	snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE;
	char card_id[32];
	char *name = NULL;

	snd_ctl_card_info_alloca (&info);
	snd_pcm_info_alloca (&pcminfo);

	if (snd_card_next (&card) < 0 || card < 0)
	{
		return false;
	}
	while(card >= 0)
	{
		snprintf (card_id, 32, "hw:%d", card);
		if (snd_ctl_open (&handle, card_id, 0) == 0)
		{
			snd_ctl_card_info (handle, info);
			while (1)
			{
				snd_ctl_pcm_next_device (handle, &dev);
				if (dev < 0){
					break;
				}
				snd_pcm_info_set_device (pcminfo, dev);
				snd_pcm_info_set_subdevice (pcminfo, 0);
				snd_pcm_info_set_stream (pcminfo, stream);
	
				if (snd_ctl_pcm_info (handle, pcminfo) >= 0)
				{
					snd_card_get_name (card, &name);
					if(strncmp(name,"radioSHARK",32) == 0)
					{void PokeScreensaver(void);
						snd_ctl_close(handle);
						free (name);
						snprintf (card_id, 32, "hw:%d,%d", card,dev);
						device = string(card_id);
						return true;
					}
					free (name);
				}
			}
			snd_ctl_close(handle);
		}
		snd_card_next (&card);
	}
	return false;//didn't find the proper Radioshark card.
}
Exemplo n.º 3
0
void list_cards(void)
{
    snd_ctl_card_info_t *p_info = NULL;
    snd_ctl_card_info_alloca(&p_info);

    snd_pcm_info_t *p_pcminfo = NULL;
    snd_pcm_info_alloca(&p_pcminfo);

    printf("Availible alsa capture devices:\n");

    int i_card = -1;
    while (!snd_card_next(&i_card) && i_card >= 0)
    {
        char devname[10];
        snprintf( devname, 10, "hw:%d", i_card );

        snd_ctl_t *p_ctl = NULL;
        if ( snd_ctl_open( &p_ctl, devname, 0 ) < 0) continue;

        snd_ctl_card_info( p_ctl, p_info);
        printf("\t%s (%s)\n", snd_ctl_card_info_get_id(p_info), snd_ctl_card_info_get_name(p_info));

        int i_dev = -1;
        while (!snd_ctl_pcm_next_device(p_ctl, &i_dev) && i_dev >= 0)
        {
            snd_pcm_info_set_device(p_pcminfo, i_dev);
            snd_pcm_info_set_subdevice(p_pcminfo, 0);
            snd_pcm_info_set_stream(p_pcminfo, SND_PCM_STREAM_CAPTURE);

            if (snd_ctl_pcm_info(p_ctl, p_pcminfo) < 0) continue;

            printf("\t\thw:%d,%d : %s (%s)\n", i_card, i_dev, 
                    snd_pcm_info_get_id(p_pcminfo), 
                    snd_pcm_info_get_name(p_pcminfo));
        }

        snd_ctl_close(p_ctl);
    }

}
Exemplo n.º 4
0
static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count)
{
    const char *main_prefix = "plughw:";
    snd_ctl_t *handle;
    int card, err, dev, idx;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    DevMap *DevList;

    snd_ctl_card_info_malloc(&info);
    snd_pcm_info_malloc(&pcminfo);

    DevList = malloc(sizeof(DevMap) * 1);
    DevList[0].name = strdup(alsaDevice);
    DevList[0].device = strdup(GetConfigValue("alsa", (stream==SND_PCM_STREAM_PLAYBACK) ?
                                                      "device" : "capture", "default"));
    idx = 1;

    card = -1;
    if((err=snd_card_next(&card)) < 0)
        ERR("Failed to find a card: %s\n", snd_strerror(err));
    ConfigValueStr("alsa", prefix_name(stream), &main_prefix);
    while(card >= 0)
    {
        const char *card_prefix = main_prefix;
        const char *cardname, *cardid;
        char name[256];

        snprintf(name, sizeof(name), "hw:%d", card);
        if((err = snd_ctl_open(&handle, name, 0)) < 0)
        {
            ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
            goto next_card;
        }
        if((err = snd_ctl_card_info(handle, info)) < 0)
        {
            ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
            snd_ctl_close(handle);
            goto next_card;
        }

        cardname = snd_ctl_card_info_get_name(info);
        cardid = snd_ctl_card_info_get_id(info);

        snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid);
        ConfigValueStr("alsa", name, &card_prefix);

        dev = -1;
        while(1)
        {
            const char *devname;
            void *temp;

            if(snd_ctl_pcm_next_device(handle, &dev) < 0)
                ERR("snd_ctl_pcm_next_device failed\n");
            if(dev < 0)
                break;

            snd_pcm_info_set_device(pcminfo, dev);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);
            if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
                continue;
            }

            temp = realloc(DevList, sizeof(DevMap) * (idx+1));
            if(temp)
            {
                const char *device_prefix = card_prefix;
                char device[128];

                DevList = temp;
                devname = snd_pcm_info_get_name(pcminfo);

                snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev);
                ConfigValueStr("alsa", name, &device_prefix);

                snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
                         cardname, devname, cardid, dev);
                snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d",
                         device_prefix, cardid, dev);

                TRACE("Got device \"%s\", \"%s\"\n", name, device);
                DevList[idx].name = strdup(name);
                DevList[idx].device = strdup(device);
                idx++;
            }
        }
        snd_ctl_close(handle);
    next_card:
        if(snd_card_next(&card) < 0) {
            ERR("snd_card_next failed\n");
            break;
        }
    }

    snd_pcm_info_free(pcminfo);
    snd_ctl_card_info_free(info);

    *count = idx;
    return DevList;
}
Exemplo n.º 5
0
static GList *
gst_alsa_get_device_list (snd_pcm_stream_t stream)
{
  snd_ctl_t *handle;
  int card, dev;
  snd_ctl_card_info_t *info;
  snd_pcm_info_t *pcminfo;
  gboolean mixer = (stream == -1);
  GList *list = NULL;

  if (stream == -1)
    stream = 0;

  snd_ctl_card_info_malloc (&info);
  snd_pcm_info_malloc (&pcminfo);
  card = -1;

  if (snd_card_next (&card) < 0 || card < 0) {
    /* no soundcard found */
    GST_WARNING ("No soundcard found");
    goto beach;
  }

  while (card >= 0) {
    gchar name[32];

    g_snprintf (name, sizeof (name), "hw:%d", card);
    if (snd_ctl_open (&handle, name, 0) < 0) {
      goto next_card;
    }
    if (snd_ctl_card_info (handle, info) < 0) {
      snd_ctl_close (handle);
      goto next_card;
    }

    if (mixer) {
      list = g_list_append (list, g_strdup (name));
    } else {
      dev = -1;
      while (1) {
        gchar *gst_device;

        snd_ctl_pcm_next_device (handle, &dev);

        if (dev < 0)
          break;
        snd_pcm_info_set_device (pcminfo, dev);
        snd_pcm_info_set_subdevice (pcminfo, 0);
        snd_pcm_info_set_stream (pcminfo, stream);
        if (snd_ctl_pcm_info (handle, pcminfo) < 0) {
          continue;
        }

        gst_device = g_strdup_printf ("hw:%d,%d", card, dev);
        list = g_list_append (list, gst_device);
      }
    }
    snd_ctl_close (handle);
  next_card:
    if (snd_card_next (&card) < 0) {
      break;
    }
  }

beach:
  snd_ctl_card_info_free (info);
  snd_pcm_info_free (pcminfo);

  return list;
}
Exemplo n.º 6
0
static
jack_driver_param_constraint_desc_t *
enum_alsa_devices()
{
    snd_ctl_t * handle;
    snd_ctl_card_info_t * info;
    snd_pcm_info_t * pcminfo_capture;
    snd_pcm_info_t * pcminfo_playback;
    int card_no = -1;
    jack_driver_param_value_t card_id;
    jack_driver_param_value_t device_id;
    char description[64];
    int device_no;
    bool has_capture;
    bool has_playback;
    jack_driver_param_constraint_desc_t * constraint_ptr;
    uint32_t array_size = 0;

    snd_ctl_card_info_alloca(&info);
    snd_pcm_info_alloca(&pcminfo_capture);
    snd_pcm_info_alloca(&pcminfo_playback);

    constraint_ptr = NULL;

    while(snd_card_next(&card_no) >= 0 && card_no >= 0)
    {
        snprintf(card_id.str, sizeof(card_id.str), "hw:%d", card_no);

        if (snd_ctl_open(&handle, card_id.str, 0) >= 0 &&
                snd_ctl_card_info(handle, info) >= 0)
        {
            snprintf(card_id.str, sizeof(card_id.str), "hw:%s", snd_ctl_card_info_get_id(info));
            if (!jack_constraint_add_enum(
                        &constraint_ptr,
                        &array_size,
                        &card_id,
                        snd_ctl_card_info_get_name(info)))
                goto fail;

            device_no = -1;

            while (snd_ctl_pcm_next_device(handle, &device_no) >= 0 && device_no != -1)
            {
                snprintf(device_id.str, sizeof(device_id.str), "%s,%d", card_id.str, device_no);

                snd_pcm_info_set_device(pcminfo_capture, device_no);
                snd_pcm_info_set_subdevice(pcminfo_capture, 0);
                snd_pcm_info_set_stream(pcminfo_capture, SND_PCM_STREAM_CAPTURE);
                has_capture = snd_ctl_pcm_info(handle, pcminfo_capture) >= 0;

                snd_pcm_info_set_device(pcminfo_playback, device_no);
                snd_pcm_info_set_subdevice(pcminfo_playback, 0);
                snd_pcm_info_set_stream(pcminfo_playback, SND_PCM_STREAM_PLAYBACK);
                has_playback = snd_ctl_pcm_info(handle, pcminfo_playback) >= 0;

                if (has_capture && has_playback)
                {
                    snprintf(description, sizeof(description),"%s (duplex)", snd_pcm_info_get_name(pcminfo_capture));
                }
                else if (has_capture)
                {
                    snprintf(description, sizeof(description),"%s (capture)", snd_pcm_info_get_name(pcminfo_capture));
                }
                else if (has_playback)
                {
                    snprintf(description, sizeof(description),"%s (playback)", snd_pcm_info_get_name(pcminfo_playback));
                }
                else
                {
                    continue;
                }

                if (!jack_constraint_add_enum(
                            &constraint_ptr,
                            &array_size,
                            &device_id,
                            description))
                    goto fail;
            }

            snd_ctl_close(handle);
        }
    }

    return constraint_ptr;
fail:
    jack_constraint_free(constraint_ptr);
    return NULL;
}
Exemplo n.º 7
0
static int list_devices_for_card(int card, struct modlist *ml, const struct dmDrive *drive, const uint32_t parent, const char *mask, unsigned long opt)
{
	char dev[64];
	char *card_name;
	int err;
	int pcm_device=-1;
	int cards=0;
	snd_ctl_t *ctl;
	
	snprintf(dev, sizeof(dev), "hw:%i", card);
#ifdef ALSA_DEBUG
	fprintf(stderr, "ALSA snd_ctl_open(&ctl, \"%s\", 0) = ", dev);
#endif
	if ((err=snd_ctl_open(&ctl, dev, 0))<0)
	{
#ifdef ALSA_DEBUG
		fprintf(stderr, "failed: %s\n", snd_strerror(-err));
#endif
		return cards;
	}
#ifdef ALSA_DEBUG
	fprintf(stderr, "ok\n");
	fprintf(stderr, "ALSA snd_card_get_name(%i, &card_name) = ", card);
#endif
	if ((err=snd_card_get_name(card, &card_name))!=0)
	{
#ifdef ALSA_DEBUG
		fprintf(stderr, "failed: %s\n", snd_strerror(-err));
#endif
		card_name="Unknown card";
	}
#ifdef ALSA_DEBUG
	fprintf(stderr, "ok, %s name: %s\n", dev, card_name);
#endif

	while(1)
	{
#ifdef ALSA_DEBUG
		fprintf(stderr, "ALSA snd_ctl_pcm_next_device(ctl, &pcm_device (%i)) = ", pcm_device);
#endif
		if ((err=snd_ctl_pcm_next_device(ctl, &pcm_device))<0)
		{
#ifdef ALSA_DEBUG
			fprintf(stderr, " failed: %s\n", snd_strerror(-err));
#endif
			pcm_device=-1;
		}
#ifdef ALSA_DEBUG
		fprintf(stderr, "ok, pcm_device=%i\n", pcm_device);
#endif
		if (pcm_device<0)
			break;

#ifdef ALSA_DEBUG
		fprintf(stderr, "ALSA snd_pcm_info_set_device(pcm_info, %i)\n", pcm_device);
#endif
		snd_pcm_info_set_device(pcm_info, pcm_device);
#ifdef ALSA_DEBUG
		fprintf(stderr, "ALSA snd_pcm_info_set_subdevice(pcm_info, 0)\n");
#endif
		snd_pcm_info_set_subdevice(pcm_info, 0);
#ifdef ALSA_DEBUG
		fprintf(stderr, "ALSA snd_pcm_info_set_stream(pcm_info, SND_PCM_STREAM_PLAYBACK)\n");
#endif
		snd_pcm_info_set_stream(pcm_info, SND_PCM_STREAM_PLAYBACK);

#ifdef ALSA_DEBUG
		fprintf(stderr, "ALSA snd_ctl_pcm_info(ctl, pcm_info) = ");
#endif
		if ((err=snd_ctl_pcm_info(ctl, pcm_info))<0)
		{
#ifdef ALSA_DEBUG
			fprintf(stderr, "failed: %s\n", snd_strerror(-err));
#endif
			if (err!=-ENOENT)
				fprintf(stderr, "ALSA: snd_device_from_card(): snd_ctl_pcm_info(%d:%d) failed: %s\n", card, pcm_device, snd_strerror(-err));
			continue;
		}

#ifdef ALSA_DEBUG	
		fprintf(stderr, "ALSA: hw:%d,%d: name %s\n", card, pcm_device, snd_pcm_info_get_name(pcm_info));
#endif
		if (ml)
		{
			struct modlistentry entry;
			memset(&entry, 0, sizeof(entry));

			snprintf(entry.shortname, sizeof(entry.shortname), "hw:%d,%d.dev", card, pcm_device);
			strcpy(entry.name, entry.shortname);
			entry.drive=drive;
			entry.dirdbfullpath=dirdbFindAndRef(parent, entry.name);
			entry.flags=MODLIST_FLAG_FILE|MODLIST_FLAG_VIRTUAL;
			entry.fileref=mdbGetModuleReference(entry.name, 0);
			if (entry.fileref!=0xffffffff)
			{
				struct moduleinfostruct mi;
				mdbGetModuleInfo(&mi, entry.fileref);
				mi.flags1&=~MDB_VIRTUAL;
				mi.channels=2;
				snprintf(mi.modname, sizeof(mi.modname), "%s", snd_pcm_info_get_name(pcm_info));
				mi.modtype=mtUnRead;
				mdbWriteModuleInfo(entry.fileref, &mi);
			}
			entry.adb_ref=0xffffffff;
			entry.Read=0; entry.ReadHeader=0; entry.ReadHandle=alsaSelectPcmOut;
			modlist_append(ml, &entry);
			dirdbUnref(entry.dirdbfullpath);
		}
		cards++;
	}
#ifdef ALSA_DEBUG
	fprintf(stderr, "ALSA snd_ctl_close(ctl)\n");
#endif
	snd_ctl_close(ctl);
	return cards;
}
Exemplo n.º 8
0
bool AlsaBackend::ProbeDevice(DeviceInfo* device, StreamSpec& spec)
{
    char *name;

    if (devicesList.size() <= 1)
        UpdateDevicesList();

    size_t i = 1;
    // find device in device pool by given ID
    for (; i < devicesList.size(); ++i)
    {
        if ((device->guid[0] == 0 && device->id == devicesList.at(i).id) ||
           strncmp(devicesList.at(i).guid, device->guid, DEVICE_NAME_MAXLEN) == 0)
        {
            Log("found device");
            name = device->displayName;
            break;
        }
    }
    if (i >= devicesList.size())
    {
        Log("ProbeDevice failed!");
        return false;
    }

    // If device is BLUETOOTH type, don't waste time and start with 8KHz immediately. A2DP is not supported.
    if (device->type == DeviceInfo::TYPE_BLUETOOTH)
    {
        spec.rate = 8000;
        spec.channels = 1;
    }

    int result;
    char hwctl[8];
    snd_ctl_t *chandle = 0;
    int openMode = SND_PCM_ASYNC;
    snd_pcm_stream_t stream;
    snd_pcm_info_t *pcminfo;
    snd_pcm_info_alloca(&pcminfo);
    snd_pcm_t *phandle = 0;
    snd_pcm_hw_params_t *params;
    snd_pcm_hw_params_alloca(&params);

    // Probe mixer for device
    if (!device->mixer)
        device->mixer = new AlsaVolumeControl;
    static_cast<AlsaVolumeControl*>(device->mixer)->ProbeMixer(device);

    // First try for playback
    stream = SND_PCM_STREAM_PLAYBACK;

    bool skipPlayback = false;

    if (device->type == DeviceInfo::TYPE_HW)
    {
        snprintf(hwctl, 8, "hw:%d", device->id);
        Log("Trying to open ctl %s", hwctl);
        result = snd_ctl_open(&chandle, hwctl, SND_CTL_NONBLOCK);
        //@todo snd_ctl_card_info() call?
        if (result >= 0)
        {
            snd_pcm_info_set_device(pcminfo, device->id);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);

            result = snd_ctl_pcm_info(chandle, pcminfo);
            if (result < 0) 
            {
                Log("Device probably doesn't support playback (dev %d): %s", device->id, snd_strerror(result));
                skipPlayback = true;
            }
        }
        else
        {
            Log("Device probably doesn't have ctl interface.");
            chandle = 0;
        }
    }
    if (!skipPlayback)
    {
        result = snd_pcm_open(&phandle, device->guid, stream, openMode | SND_PCM_NONBLOCK);
        if (result >= 0)
        {
            // The device is open ... fill the parameter structure.
            result = snd_pcm_hw_params_any(phandle, params);
            if (result >= 0)
            {
                // Get output channel information.
                unsigned int value;
                result = snd_pcm_hw_params_get_channels_max(params, &value);
                if (result >= 0)
                {
                    device->outMaxChannels = value;
                    snd_pcm_close(phandle);
                }
                else
                {
                    snd_pcm_close(phandle); // @todo unify handle closing calls in case of errors
                    Log("error getting device %s output channels: %s", name, snd_strerror(result));
                }
            }
            else
            {
                snd_pcm_close(phandle); // @todo unify handle closing calls in case of errors (_EE_CALL)
                Log("snd_pcm_hw_params error for device %s: %s", name, snd_strerror(result));
            }
        }
        else
        {
            Log("snd_pcm_open error for playback on device %s: %s", name, snd_strerror(result));
        }
    }
    // Now try for capture
    stream = SND_PCM_STREAM_CAPTURE;
    snd_pcm_info_set_stream(pcminfo, stream);

    if (device->type == DeviceInfo::TYPE_HW && chandle)
    {
        result = snd_ctl_pcm_info(chandle, pcminfo);
        snd_ctl_close(chandle);
        if (result < 0) {
            Log("Device probably doesn't support capture: %s", snd_strerror(result));
            if (device->outMaxChannels == 0)  // cannot playback/capture at all
            {
                Log("ProbeDevice failed!");
                return false;
            }
            return ProbeParameters(device, spec, phandle, stream, pcminfo, name, params);
        }
    }

    result = snd_pcm_open(&phandle, device->guid, stream, openMode | SND_PCM_NONBLOCK);
    if (result < 0) {
        Log("snd_pcm_open error for capture on device %s: %s", name, snd_strerror(result));
        if (device->outMaxChannels == 0) 
        {
            Log("ProbeDevice failed!");
            return false;
        }
        return ProbeParameters(device, spec, phandle, stream, pcminfo, name, params);
    }

    // The device is open ... fill the parameter structure.
    result = snd_pcm_hw_params_any(phandle, params);
    if (result < 0) {
        snd_pcm_close(phandle);
        Log("snd_pcm_hw_params error for device %s: %s", name, snd_strerror(result));
        if (device->outMaxChannels == 0)
        {
            Log("ProbeDevice failed!");
            return false;
        }
        return ProbeParameters(device, spec, phandle, stream, pcminfo, name, params);
    }
    unsigned int value;
    result = snd_pcm_hw_params_get_channels_max(params, &value);
    if (result < 0) {
        snd_pcm_close(phandle);
        Log("error getting device %s input channels: %s", name, snd_strerror(result));
        if (device->outMaxChannels == 0)
        {
            Log("ProbeDevice failed!");
            return false;
        }
        return ProbeParameters(device, spec, phandle, stream, pcminfo, name, params);
    }
    device->inMaxChannels = value;
    snd_pcm_close(phandle);
    return ProbeParameters(device, spec, phandle, stream, pcminfo, name, params);
}
Exemplo n.º 9
0
void
ManglerAlsa::getDeviceList(std::vector<ManglerAudioDevice*>& inputDevices, std::vector<ManglerAudioDevice*>& outputDevices) {/*{{{*/
    snd_pcm_stream_t stream[2] = { SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_CAPTURE };
    int ctr;

    for (ctr = 0; ctr < 2; ctr++) { // the rest is just copypasta, with bad code from alsa
        snd_ctl_t *handle;
        int card, err, dev, idx_p = 0, idx_c = 0;
        snd_ctl_card_info_t *info;
        snd_pcm_info_t *pcminfo;

        card = -1;
        snd_ctl_card_info_alloca(&info);
        snd_pcm_info_alloca(&pcminfo);
        if (snd_card_next(&card) < 0 || card < 0) {
            fputs("alsa: no sound cards found!\n", stderr);
            return;
        }
        while (card >= 0) {
            char hw[256] = "";
            snprintf(hw, 255, "hw:%i", card);
            if ((err = snd_ctl_open(&handle, hw, 0)) < 0) {
                fprintf(stderr, "alsa: control open (%i): %s\n", card, snd_strerror(err));
                if (snd_card_next(&card) < 0) {
                    fprintf(stderr, "alsa: snd_ctl_open: snd_card_next\n");
                    break;
                }
                continue;
            }
            if ((err = snd_ctl_card_info(handle, info)) < 0) {
                fprintf(stderr, "alsa: control hardware info (%i): %s\n", card, snd_strerror(err));
                snd_ctl_close(handle);
                if (snd_card_next(&card) < 0) {
                    fprintf(stderr, "alsa: snd_ctl_card_info: snd_card_next\n");
                    break;
                }
                continue;
            }
            dev = -1;
            for (;;) {
                if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
                    fprintf(stderr, "alsa: snd_ctl_pcm_next_device\n");
                }
                if (dev < 0) {
                    break;
                }
                snd_pcm_info_set_device(pcminfo, dev);
                snd_pcm_info_set_subdevice(pcminfo, 0);
                snd_pcm_info_set_stream(pcminfo, stream[ctr]);
                if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                    if (err != -ENOENT) {
                        fprintf(stderr, "alsa: control digital audio info (%i): %s\n", card, snd_strerror(err));
                    }
                    continue;
                }
                char name[256] = "", desc[512] = "";
                snprintf(name, 255, "hw:%i,%i", card, dev);
                snprintf(desc, 511, "%s: %s (%s)",
                         snd_ctl_card_info_get_name(info),
                         snd_pcm_info_get_name(pcminfo),
                         name
                        );
                switch (stream[ctr]) {
                case SND_PCM_STREAM_PLAYBACK:
                    outputDevices.push_back(
                        new ManglerAudioDevice(
                            idx_p++,
                            name,
                            desc)
                    );
                    break;
                case SND_PCM_STREAM_CAPTURE:
                    inputDevices.push_back(
                        new ManglerAudioDevice(
                            idx_c++,
                            name,
                            desc)
                    );
                    break;
                }
            }
            snd_ctl_close(handle);
            if (snd_card_next(&card) < 0) {
                fprintf(stderr, "alsa: snd_card_next\n");
                break;
            }
        }
    }
}/*}}}*/
// for each ALSA device, call iterator. userData is passed to the iterator
// returns total number of iterations
int iteratePCMDevices(DeviceIteratorPtr iterator, void* userData) {
    int count = 0;
    int subdeviceCount;
    int card, dev, subDev;
    char devname[16];
    int err;
    snd_ctl_t *handle;
    snd_pcm_t *pcm;
    snd_pcm_info_t* pcminfo;
    snd_ctl_card_info_t *cardinfo, *defcardinfo = NULL;
    UINT32 deviceID;
    int doContinue = TRUE;

    snd_pcm_info_malloc(&pcminfo);
    snd_ctl_card_info_malloc(&cardinfo);

    // 1st try "default" device
    err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
                       SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
    if (err < 0) {
        // try with the other direction
        err = snd_pcm_open(&pcm, ALSA_DEFAULT_DEVICE_NAME,
                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
    }
    if (err < 0) {
        ERROR1("ERROR: snd_pcm_open (\"default\"): %s\n", snd_strerror(err));
    } else {
        err = snd_pcm_info(pcm, pcminfo);
        snd_pcm_close(pcm);
        if (err < 0) {
            ERROR1("ERROR: snd_pcm_info (\"default\"): %s\n",
                    snd_strerror(err));
        } else {
            // try to get card info
            card = snd_pcm_info_get_card(pcminfo);
            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, cardinfo) >= 0) {
                        defcardinfo = cardinfo;
                    }
                    snd_ctl_close(handle);
                }
            }
            // call callback function for the device
            if (iterator != NULL) {
                doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, pcminfo,
                                         defcardinfo, userData);
            }
            count++;
        }
    }

    // iterate cards
    card = -1;
    while (doContinue) {
        if (snd_card_next(&card) < 0) {
            break;
        }
        if (card < 0) {
            break;
        }
        sprintf(devname, ALSA_HARDWARE_CARD, card);
        TRACE1("Opening alsa 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 {
            err = snd_ctl_card_info(handle, cardinfo);
            if (err < 0) {
                ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n",
                        card, snd_strerror(err));
            } else {
                dev = -1;
                while (doContinue) {
                    if (snd_ctl_pcm_next_device(handle, &dev) < 0) {
                        ERROR0("snd_ctl_pcm_next_device\n");
                    }
                    if (dev < 0) {
                        break;
                    }
                    snd_pcm_info_set_device(pcminfo, dev);
                    snd_pcm_info_set_subdevice(pcminfo, 0);
                    snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
                    err = snd_ctl_pcm_info(handle, pcminfo);
                    if (err == -ENOENT) {
                        // try with the other direction
                        snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
                        err = snd_ctl_pcm_info(handle, pcminfo);
                    }
                    if (err < 0) {
                        if (err != -ENOENT) {
                            ERROR2("ERROR: snd_ctl_pcm_info, card=%d: %s",
                                    card, snd_strerror(err));
                        }
                    } else {
                        subdeviceCount = needEnumerateSubdevices(ALSA_PCM) ?
                            snd_pcm_info_get_subdevices_count(pcminfo) : 1;
                        if (iterator!=NULL) {
                            for (subDev = 0; subDev < subdeviceCount; subDev++) {
                                deviceID = encodeDeviceID(card, dev, subDev);
                                doContinue = (*iterator)(deviceID, pcminfo,
                                                         cardinfo, userData);
                                count++;
                                if (!doContinue) {
                                    break;
                                }
                            }
                        } else {
                            count += subdeviceCount;
                        }
                    }
                } // of while(doContinue)
            }
            snd_ctl_close(handle);
        }
    }
    snd_ctl_card_info_free(cardinfo);
    snd_pcm_info_free(pcminfo);
    return count;
}
Exemplo n.º 11
0
/* Try and find an IEC958 PCM device and mixer on card 0 and open it
 * This function is only used on older ALSA installs that don't have the
 * correct iec958 alias stuff set up, and relies on there being only
 * one IEC958 PCM device (relies IEC958 in the device name) and one IEC958
 * mixer control for doing the settings.
 */
static int
alsaspdifsink_find_pcm_device (AlsaSPDIFSink * sink)
{
  int err = -1, dev, idx, count;
  const gchar *ctl_name = "hw:0";
  const gchar *spdif_name = SND_CTL_NAME_IEC958 ("", PLAYBACK, NONE);
  int card = sink->card;
  gchar pcm_name[24];
  snd_pcm_t *pcm = NULL;
  snd_ctl_t *ctl = NULL;
  snd_ctl_card_info_t *info = NULL;
  snd_ctl_elem_list_t *clist = NULL;
  snd_ctl_elem_id_t *cid = NULL;
  snd_pcm_info_t *pinfo = NULL;

  GST_WARNING ("Opening IEC958 named device failed. Trying to autodetect");

  if ((err = snd_ctl_open (&ctl, ctl_name, card)) < 0)
    return err;

  snd_ctl_card_info_malloc (&info);
  snd_pcm_info_malloc (&pinfo);

  /* Find a mixer for IEC958 settings */
  snd_ctl_elem_list_malloc (&clist);
  if ((err = snd_ctl_elem_list (ctl, clist)) < 0)
    goto beach;

  if ((err =
          snd_ctl_elem_list_alloc_space (clist,
              snd_ctl_elem_list_get_count (clist))) < 0)
    goto beach;
  if ((err = snd_ctl_elem_list (ctl, clist)) < 0)
    goto beach;

  count = snd_ctl_elem_list_get_used (clist);
  for (idx = 0; idx < count; idx++) {
    if (strstr (snd_ctl_elem_list_get_name (clist, idx), spdif_name) != NULL)
      break;
  }
  if (idx == count) {
    /* No SPDIF mixer availble */
    err = 0;
    goto beach;
  }
  snd_ctl_elem_id_malloc (&cid);
  snd_ctl_elem_list_get_id (clist, idx, cid);

  /* Now find a PCM device for IEC 958 */
  if ((err = snd_ctl_card_info (ctl, info)) < 0)
    goto beach;
  dev = -1;
  do {
    if (snd_ctl_pcm_next_device (ctl, &dev) < 0)
      goto beach;
    if (dev < 0)
      break;                    /* No more devices */

    /* Filter for playback devices */
    snd_pcm_info_set_device (pinfo, dev);
    snd_pcm_info_set_subdevice (pinfo, 0);
    snd_pcm_info_set_stream (pinfo, SND_PCM_STREAM_PLAYBACK);
    if ((err = snd_ctl_pcm_info (ctl, pinfo)) < 0) {
      if (err != -ENOENT)
        goto beach;             /* Genuine error */

      /* Device has no playback streams */
      continue;
    }
    if (strstr (snd_pcm_info_get_name (pinfo), "IEC958") == NULL)
      continue;                 /* Not the device we are looking for */

    count = snd_pcm_info_get_subdevices_count (pinfo);
    GST_LOG_OBJECT (sink, "Device %d has %d subdevices\n", dev,
        snd_pcm_info_get_subdevices_count (pinfo));
    for (idx = 0; idx < count; idx++) {
      snd_pcm_info_set_subdevice (pinfo, idx);

      if ((err = snd_ctl_pcm_info (ctl, pinfo)) < 0)
        goto beach;

      g_assert (snd_pcm_info_get_stream (pinfo) == SND_PCM_STREAM_PLAYBACK);

      GST_LOG_OBJECT (sink, "Found playback stream on dev %d sub-d %d\n", dev,
          idx);

      /* Found a suitable PCM device, let's open it */
      g_snprintf (pcm_name, 24, "hw:%d,%d", card, dev);
      if ((err =
              snd_pcm_open (&(pcm), pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
        goto beach;

      break;
    }
  } while (pcm == NULL);

  if (pcm != NULL) {
    snd_ctl_elem_value_t *cval;
    snd_aes_iec958_t iec958;

    /* Have a PCM device and a mixer, set things up */
    snd_ctl_elem_value_malloc (&cval);
    snd_ctl_elem_value_set_id (cval, cid);
    snd_ctl_elem_value_get_iec958 (cval, &iec958);
    iec958.status[0] = IEC958_AES0_NONAUDIO;
    iec958.status[1] = IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER;
    iec958.status[2] = 0;
    iec958.status[3] = IEC958_AES3_CON_FS_48000;
    snd_ctl_elem_value_set_iec958 (cval, &iec958);
    snd_ctl_elem_value_free (cval);

    sink->pcm = pcm;
    pcm = NULL;
    err = 0;
  }

beach:
  if (pcm)
    snd_pcm_close (pcm);
  if (clist)
    snd_ctl_elem_list_clear (clist);
  if (ctl)
    snd_ctl_close (ctl);
  if (clist)
    snd_ctl_elem_list_free (clist);
  if (cid)
    snd_ctl_elem_id_free (cid);
  if (info)
    snd_ctl_card_info_free (info);
  if (pinfo)
    snd_pcm_info_free (pinfo);
  return err;
}
Exemplo n.º 12
0
void AudioALSA::list_devices(ArrayList<char*> *devices, int pcm_title, int mode)
{
	snd_ctl_t *handle;
	int card, err, dev, idx;
	snd_ctl_card_info_t *info;
	snd_pcm_info_t *pcminfo;
	char string[BCTEXTLEN];
	snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
	int error;
	switch(mode)
	{
		case MODERECORD:
			stream = SND_PCM_STREAM_CAPTURE;
			break;
		case MODEPLAY:
			stream = SND_PCM_STREAM_PLAYBACK;
			break;
	}

	snd_ctl_card_info_alloca(&info);
	snd_pcm_info_alloca(&pcminfo);

	card = -1;
#define DEFAULT_DEVICE "default"
	char *result = new char[strlen(DEFAULT_DEVICE) + 1];
	devices->append(result);
	devices->set_array_delete();     // since we are allocating by new[]
	strcpy(result, DEFAULT_DEVICE);

	while(snd_card_next(&card) >= 0)
	{
		char name[BCTEXTLEN];
		if(card < 0) break;
		sprintf(name, "hw:%i", card);

		if((err = snd_ctl_open(&handle, name, 0)) < 0)
		{
			printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err));
			continue;
		}

		if((err = snd_ctl_card_info(handle, info)) < 0)
		{
			printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err));
			snd_ctl_close(handle);
			continue;
		}

		dev = -1;

		while(1)
		{
			unsigned int count;
			if(snd_ctl_pcm_next_device(handle, &dev) < 0)
				printf("AudioALSA::list_devices: snd_ctl_pcm_next_device\n");

			if (dev < 0)
				break;

			snd_pcm_info_set_device(pcminfo, dev);
			snd_pcm_info_set_subdevice(pcminfo, 0);
			snd_pcm_info_set_stream(pcminfo, stream);

			if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) 
			{
				if(err != -ENOENT)
					printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err));
				continue;
			}

			if(pcm_title)
			{
				sprintf(string, "plughw:%d,%d", card, dev);
//				strcpy(string, "cards.pcm.front");
			}
			else
			{
				sprintf(string, "%s #%d", 
					snd_ctl_card_info_get_name(info), 
					dev);
			}

			char *result = devices->append(new char[strlen(string) + 1]);
			strcpy(result, string);
		}

		snd_ctl_close(handle);
	}

//	snd_ctl_card_info_free(info);
//	snd_pcm_info_free(pcminfo);
}
Exemplo n.º 13
0
void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list)
{
  /* ensure that ALSA has been initialized */
  if(!snd_config)
    snd_config_update();

  snd_ctl_t *ctlhandle;
  snd_pcm_t *pcmhandle;

  snd_ctl_card_info_t *ctlinfo;
  snd_ctl_card_info_alloca(&ctlinfo);
  memset(ctlinfo, 0, snd_ctl_card_info_sizeof());

  snd_pcm_hw_params_t *hwparams;
  snd_pcm_hw_params_alloca(&hwparams);
  memset(hwparams, 0, snd_pcm_hw_params_sizeof());

  snd_pcm_info_t *pcminfo;
  snd_pcm_info_alloca(&pcminfo);
  memset(pcminfo, 0, snd_pcm_info_sizeof());

  /* get the sound config */
  snd_config_t *config;
  snd_config_copy(&config, snd_config);

  std::string strHwName;
  int n_cards = -1;
  while (snd_card_next(&n_cards) == 0 && n_cards != -1)
  {
    std::stringstream sstr;
    sstr << "hw:" << n_cards;
    std::string strHwName = sstr.str();

    if (snd_ctl_open_lconf(&ctlhandle, strHwName.c_str(), 0, config) != 0)
    {
      CLog::Log(LOGDEBUG, "CAESinkALSA::EnumerateDevicesEx - Unable to open control for device %s", strHwName.c_str());
      continue;
    }

    if (snd_ctl_card_info(ctlhandle, ctlinfo) != 0)
    {
      CLog::Log(LOGDEBUG, "CAESinkALSA::EnumerateDevicesEx - Unable to get card control info for device %s", strHwName.c_str());
      snd_ctl_close(ctlhandle);
      continue;
    }

    snd_hctl_t *hctl;
    if (snd_hctl_open_ctl(&hctl, ctlhandle) != 0)
      hctl = NULL;
    snd_hctl_load(hctl);

    int pcm_index    = 0;
    int iec958_index = 0;
    int hdmi_index   = 0;

    int dev = -1;
    while (snd_ctl_pcm_next_device(ctlhandle, &dev) == 0 && dev != -1)
    {
      snd_pcm_info_set_device   (pcminfo, dev);
      snd_pcm_info_set_subdevice(pcminfo, 0  );
      snd_pcm_info_set_stream   (pcminfo, SND_PCM_STREAM_PLAYBACK);

      if (snd_ctl_pcm_info(ctlhandle, pcminfo) < 0)
      {
        CLog::Log(LOGDEBUG, "CAESinkALSA::EnumerateDevicesEx - Skipping device %s,%d as it does not have PCM playback ability", strHwName.c_str(), dev);
        continue;
      }

      int dev_index;
      sstr.str(std::string());
      CAEDeviceInfo info;
      std::string devname = snd_pcm_info_get_name(pcminfo);

      bool maybeHDMI = false;

      /* detect HDMI */
      if (devname.find("HDMI") != std::string::npos)
      { 
        info.m_deviceType = AE_DEVTYPE_HDMI;
        dev_index = hdmi_index++;
        sstr << "hdmi";
      }
      else
      {
        /* detect IEC958 */

        /* some HDMI devices (intel) report Digital for HDMI also */
        if (devname.find("Digital") != std::string::npos)
          maybeHDMI = true;

        if (maybeHDMI || devname.find("IEC958" ) != std::string::npos)
        {
          info.m_deviceType = AE_DEVTYPE_IEC958;
          dev_index = iec958_index; /* dont increment, it might be HDMI */
          sstr << "iec958";
        }
        else
        {
          info.m_deviceType = AE_DEVTYPE_PCM;
          dev_index = pcm_index++;
          sstr << "hw";
        }
      }

      /* build the driver string to pass to ALSA */
      sstr << ":CARD=" << snd_ctl_card_info_get_id(ctlinfo) << ",DEV=" << dev_index;
      info.m_deviceName = sstr.str();

      /* get the friendly display name*/
      info.m_displayName      = snd_ctl_card_info_get_name(ctlinfo);
      info.m_displayNameExtra = devname;

      /* open the device for testing */
      int err = snd_pcm_open_lconf(&pcmhandle, info.m_deviceName.c_str(), SND_PCM_STREAM_PLAYBACK, 0, config);

      /* if open of possible IEC958 failed and it could be HDMI, try as HDMI */
      if (err < 0 && maybeHDMI)
      {
        /* check for HDMI if it failed */
        sstr.str(std::string());
        dev_index = hdmi_index;

        sstr << "hdmi";
        sstr << ":CARD=" << snd_ctl_card_info_get_id(ctlinfo) << ",DEV=" << dev_index;
        info.m_deviceName = sstr.str();
        err = snd_pcm_open_lconf(&pcmhandle, info.m_deviceName.c_str(), SND_PCM_STREAM_PLAYBACK, 0, config);

        /* if it was valid, increment the index and set the type */
        if (err >= 0)
        {
          ++hdmi_index;
          info.m_deviceType = AE_DEVTYPE_HDMI;
        }
      }

      /* if it's still IEC958, increment the index */
      if (info.m_deviceType == AE_DEVTYPE_IEC958)
        ++iec958_index;

      /* final error check */
      if (err < 0)
      {
        CLog::Log(LOGINFO, "CAESinkALSA::EnumerateDevicesEx - Unable to open %s for capability detection", strHwName.c_str());
        continue;
      }

      /* see if we can get ELD for this device */
      if (info.m_deviceType == AE_DEVTYPE_HDMI)
      {
        bool badHDMI = false;
        if (hctl && !GetELD(hctl, dev, info, badHDMI))
          CLog::Log(LOGDEBUG, "CAESinkALSA::EnumerateDevicesEx - Unable to obtain ELD information for device %s, make sure you have ALSA >= 1.0.25", info.m_deviceName.c_str());

        if (badHDMI)
        {
          CLog::Log(LOGDEBUG, "CAESinkALSA::EnumerateDevicesEx - Skipping HDMI device %s as it has no ELD data", info.m_deviceName.c_str());
          continue;
        }
      }

      /* ensure we can get a playback configuration for the device */
      if (snd_pcm_hw_params_any(pcmhandle, hwparams) < 0)
      {
        CLog::Log(LOGINFO, "CAESinkALSA::EnumerateDevicesEx - No playback configurations available for device %s", info.m_deviceName.c_str());
        snd_pcm_close(pcmhandle);
        continue;
      }

      /* detect the available sample rates */
      for (unsigned int *rate = ALSASampleRateList; *rate != 0; ++rate)
        if (snd_pcm_hw_params_test_rate(pcmhandle, hwparams, *rate, 0) >= 0)
          info.m_sampleRates.push_back(*rate);

      /* detect the channels available */
      int channels = 0;
      for (int i = 1; i <= ALSA_MAX_CHANNELS; ++i)
        if (snd_pcm_hw_params_test_channels(pcmhandle, hwparams, i) >= 0)
          channels = i;

      CAEChannelInfo alsaChannels;
      for (int i = 0; i < channels; ++i)
      {
        if (!info.m_channels.HasChannel(ALSAChannelMap[i]))
          info.m_channels += ALSAChannelMap[i];
        alsaChannels += ALSAChannelMap[i];
      }

      /* remove the channels from m_channels that we cant use */
      info.m_channels.ResolveChannels(alsaChannels);

      /* detect the PCM sample formats that are available */
      for (enum AEDataFormat i = AE_FMT_MAX; i > AE_FMT_INVALID; i = (enum AEDataFormat)((int)i - 1))
      {
        if (AE_IS_RAW(i) || i == AE_FMT_MAX)
          continue;
        snd_pcm_format_t fmt = AEFormatToALSAFormat(i);
        if (fmt == SND_PCM_FORMAT_UNKNOWN)
          continue;

        if (snd_pcm_hw_params_test_format(pcmhandle, hwparams, fmt) >= 0)
          info.m_dataFormats.push_back(i);
      }

      snd_pcm_close(pcmhandle);
      list.push_back(info);
    }

    /* snd_hctl_close also closes ctlhandle */
    if (hctl)
      snd_hctl_close(hctl);
    else
      snd_ctl_close(ctlhandle);
  }
}
Exemplo n.º 14
0
static void GetDevicesForCard( module_config_t *p_item, int i_card )
{
    int i_pcm_device = -1;
    int i_err = 0;
    snd_pcm_info_t *p_pcm_info;
    snd_ctl_t *p_ctl;
    char psz_dev[64];
    char *psz_card_name;

    sprintf( psz_dev, "hw:%i", i_card );

    if( ( i_err = snd_ctl_open( &p_ctl, psz_dev, 0 ) ) < 0 )
        return;

    if( ( i_err = snd_card_get_name( i_card, &psz_card_name ) ) != 0)
        psz_card_name = _("Unknown soundcard");

    snd_pcm_info_alloca( &p_pcm_info );

    for (;;)
    {
        char *psz_device, *psz_descr;
        if( ( i_err = snd_ctl_pcm_next_device( p_ctl, &i_pcm_device ) ) < 0 )
            i_pcm_device = -1;
        if( i_pcm_device < 0 )
            break;

        snd_pcm_info_set_device( p_pcm_info, i_pcm_device );
        snd_pcm_info_set_subdevice( p_pcm_info, 0 );
        snd_pcm_info_set_stream( p_pcm_info, SND_PCM_STREAM_PLAYBACK );

        if( ( i_err = snd_ctl_pcm_info( p_ctl, p_pcm_info ) ) < 0 )
        {
            if( i_err != -ENOENT )
            {
                /*printf( "get_devices_for_card(): "
                         "snd_ctl_pcm_info() "
                         "failed (%d:%d): %s.\n", i_card,
                         i_pcm_device, snd_strerror( -i_err ) );*/
            }
            continue;
        }

        if( asprintf( &psz_device, "hw:%d,%d", i_card, i_pcm_device ) == -1 )
            break;
        if( asprintf( &psz_descr, "%s: %s (%s)", psz_card_name,
                  snd_pcm_info_get_name(p_pcm_info), psz_device ) == -1 )
        {
            free( psz_device );
            break;
        }

        p_item->ppsz_list =
            (char **)realloc( p_item->ppsz_list,
                              (p_item->i_list + 2) * sizeof(char *) );
        p_item->ppsz_list_text =
            (char **)realloc( p_item->ppsz_list_text,
                              (p_item->i_list + 2) * sizeof(char *) );
        p_item->ppsz_list[ p_item->i_list ] = psz_device;
        p_item->ppsz_list_text[ p_item->i_list ] = psz_descr;
        p_item->i_list++;
        p_item->ppsz_list[ p_item->i_list ] = NULL;
        p_item->ppsz_list_text[ p_item->i_list ] = NULL;
    }

    snd_ctl_close( p_ctl );
}
Exemplo n.º 15
0
Arquivo: alsa.c Projeto: 9heart/DT3
static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count)
{
    snd_ctl_t *handle;
    int card, err, dev, idx;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    DevMap *DevList;
    char name[1024];

    snd_ctl_card_info_malloc(&info);
    snd_pcm_info_malloc(&pcminfo);

    card = -1;
    if((err=snd_card_next(&card)) < 0)
        ERR("Failed to find a card: %s\n", snd_strerror(err));

    DevList = malloc(sizeof(DevMap) * 1);
    DevList[0].name = strdup("ALSA Default");
    DevList[0].card = NULL;
    DevList[0].dev = 0;
    idx = 1;
    while(card >= 0)
    {
        sprintf(name, "hw:%d", card);
        if((err = snd_ctl_open(&handle, name, 0)) < 0)
        {
            ERR("control open (%i): %s\n", card, snd_strerror(err));
            goto next_card;
        }
        if((err = snd_ctl_card_info(handle, info)) < 0)
        {
            ERR("control hardware info (%i): %s\n", card, snd_strerror(err));
            snd_ctl_close(handle);
            goto next_card;
        }

        dev = -1;
        while(1)
        {
            const char *cname, *dname, *cid;
            void *temp;

            if(snd_ctl_pcm_next_device(handle, &dev) < 0)
                ERR("snd_ctl_pcm_next_device failed\n");
            if(dev < 0)
                break;

            snd_pcm_info_set_device(pcminfo, dev);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);
            if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    ERR("control digital audio info (%i): %s\n", card, snd_strerror(err));
                continue;
            }

            temp = realloc(DevList, sizeof(DevMap) * (idx+1));
            if(temp)
            {
                DevList = temp;
                cname = snd_ctl_card_info_get_name(info);
                dname = snd_pcm_info_get_name(pcminfo);
                cid = snd_ctl_card_info_get_id(info);
                snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
                         cname, dname, cid, dev);
                DevList[idx].name = strdup(name);
                DevList[idx].card = strdup(cid);
                DevList[idx].dev = dev;
                idx++;
            }
        }
        snd_ctl_close(handle);
    next_card:
        if(snd_card_next(&card) < 0) {
            ERR("snd_card_next failed\n");
            break;
        }
    }

    snd_pcm_info_free(pcminfo);
    snd_ctl_card_info_free(info);

    *count = idx;
    return DevList;
}
Exemplo n.º 16
0
void ALSAAudioCaptureDevice::enumerateDevices(std::vector<AudioCaptureDevice::DeviceIdPtr>& devices)
	{
	/* Enumerate all ALSA cards and devices: */
	int cardIndex=-1; // Start with first card
	while(true)
		{
		/* Get the index of the next card: */
		if(snd_card_next(&cardIndex)!=0||cardIndex<0)
			{
			/* There was an error, or there are no more cards: */
			break;
			}
		
		/* Open the card's control interface: */
		char cardName[20];
		snprintf(cardName,sizeof(cardName),"hw:%d",cardIndex);
		snd_ctl_t* cardHandle;
		if(snd_ctl_open(&cardHandle,cardName,0)!=0)
			break;
		
		/* Enumerate all PCM devices on this card: */
		int numCardDevices=0;
		int pcmIndex=-1;
		while(true)
			{
			/* Get the index of the next PCM device: */
			if(snd_ctl_pcm_next_device(cardHandle,&pcmIndex)!=0||pcmIndex<0)
				{
				/* There was an error, or there are no more PCM devices: */
				break;
				}
			
			/* Create an info structure for the PCM device: */
			snd_pcm_info_t* pcmInfo;
			snd_pcm_info_alloca(&pcmInfo);
			snd_pcm_info_set_device(pcmInfo,pcmIndex);
			snd_pcm_info_set_stream(pcmInfo,SND_PCM_STREAM_CAPTURE);
			
			/* Get the number of capture subdevices for the device: */
			if(snd_ctl_pcm_info(cardHandle,pcmInfo)!=0)
				break;
			int numSubDevices=snd_pcm_info_get_subdevices_count(pcmInfo);
			for(int subDeviceIndex=0;subDeviceIndex<numSubDevices;++subDeviceIndex)
				{
				/* Query information about the subdevice: */
				snd_pcm_info_set_subdevice(pcmInfo,subDeviceIndex);
				if(snd_ctl_pcm_info(cardHandle,pcmInfo)==0)
					{
					/* Query the card's name: */
					char* cardName;
					if(snd_card_get_name(cardIndex,&cardName)==0)
						{
						/* Create a device ID: */
						std::string deviceName=cardName;
						free(cardName);
						if(numCardDevices>0)
							{
							char suffix[10];
							snprintf(suffix,sizeof(suffix),":%d",numCardDevices);
							deviceName.append(suffix);
							}
						DeviceId* newDeviceId=new DeviceId(deviceName);
						
						/* Set the PCM device name: */
						char pcmDeviceName[20];
						if(numSubDevices>1)
							snprintf(pcmDeviceName,sizeof(pcmDeviceName),"plughw:%d,%d,%d",snd_pcm_info_get_card(pcmInfo),snd_pcm_info_get_device(pcmInfo),snd_pcm_info_get_subdevice(pcmInfo));
						else
							snprintf(pcmDeviceName,sizeof(pcmDeviceName),"plughw:%d,%d",snd_pcm_info_get_card(pcmInfo),snd_pcm_info_get_device(pcmInfo));
						newDeviceId->pcmDeviceName=pcmDeviceName;
						
						/* Store the device ID: */
						devices.push_back(newDeviceId);
						
						++numCardDevices;
						}
					}
				}
			}
		
		/* Close the card's control interface: */
		snd_ctl_close(cardHandle);
		}
	}
Exemplo n.º 17
0
static void probe_devices(snd_pcm_stream_t stream, vector_DevMap *DeviceList)
{
    const char *main_prefix = "plughw:";
    snd_ctl_t *handle;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    int card, err, dev;
    DevMap entry;

    clear_devlist(DeviceList);

    snd_ctl_card_info_malloc(&info);
    snd_pcm_info_malloc(&pcminfo);

    AL_STRING_INIT(entry.name);
    AL_STRING_INIT(entry.device_name);
    al_string_copy_cstr(&entry.name, alsaDevice);
    al_string_copy_cstr(&entry.device_name, GetConfigValue(NULL, "alsa", (stream==SND_PCM_STREAM_PLAYBACK) ?
                                                           "device" : "capture", "default"));
    VECTOR_PUSH_BACK(*DeviceList, entry);

    card = -1;
    if((err=snd_card_next(&card)) < 0)
        ERR("Failed to find a card: %s\n", snd_strerror(err));
    ConfigValueStr(NULL, "alsa", prefix_name(stream), &main_prefix);
    while(card >= 0)
    {
        const char *card_prefix = main_prefix;
        const char *cardname, *cardid;
        char name[256];

        snprintf(name, sizeof(name), "hw:%d", card);
        if((err = snd_ctl_open(&handle, name, 0)) < 0)
        {
            ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
            goto next_card;
        }
        if((err = snd_ctl_card_info(handle, info)) < 0)
        {
            ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
            snd_ctl_close(handle);
            goto next_card;
        }

        cardname = snd_ctl_card_info_get_name(info);
        cardid = snd_ctl_card_info_get_id(info);

        snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid);
        ConfigValueStr(NULL, "alsa", name, &card_prefix);

        dev = -1;
        while(1)
        {
            const char *device_prefix = card_prefix;
            const char *devname;
            char device[128];

            if(snd_ctl_pcm_next_device(handle, &dev) < 0)
                ERR("snd_ctl_pcm_next_device failed\n");
            if(dev < 0)
                break;

            snd_pcm_info_set_device(pcminfo, dev);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);
            if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
                continue;
            }

            devname = snd_pcm_info_get_name(pcminfo);

            snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev);
            ConfigValueStr(NULL, "alsa", name, &device_prefix);

            snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
                        cardname, devname, cardid, dev);
            snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d",
                        device_prefix, cardid, dev);

            TRACE("Got device \"%s\", \"%s\"\n", name, device);
            AL_STRING_INIT(entry.name);
            AL_STRING_INIT(entry.device_name);
            al_string_copy_cstr(&entry.name, name);
            al_string_copy_cstr(&entry.device_name, device);
            VECTOR_PUSH_BACK(*DeviceList, entry);
        }
        snd_ctl_close(handle);
    next_card:
        if(snd_card_next(&card) < 0) {
            ERR("snd_card_next failed\n");
            break;
        }
    }

    snd_pcm_info_free(pcminfo);
    snd_ctl_card_info_free(info);
}
void qjackctlInterfaceComboBox::populateModel (void)
{
	bool bBlockSignals = QComboBox::blockSignals(true);

	QComboBox::setUpdatesEnabled(false);
	QComboBox::setDuplicatesEnabled(false);

	QLineEdit *pLineEdit = QComboBox::lineEdit();

	// FIXME: Only valid for ALSA, Sun and OSS devices,
	// for the time being... and also CoreAudio ones too.
	const QString& sDriver = m_pDriverComboBox->currentText();
	bool bAlsa      = (sDriver == "alsa");
	bool bSun       = (sDriver == "sun");
	bool bOss       = (sDriver == "oss");
#ifdef CONFIG_COREAUDIO
	bool bCoreaudio = (sDriver == "coreaudio");
	std::map<QString, AudioDeviceID> coreaudioIdMap;
#endif
#ifdef CONFIG_PORTAUDIO
	bool bPortaudio = (sDriver == "portaudio");
#endif
	QString sCurName = pLineEdit->text();
	QString sName, sSubName;
	
	int iCards = 0;

	clearCards();

	int iCurCard = -1;

	if (bAlsa) {
#ifdef CONFIG_ALSA_SEQ
		// Enumerate the ALSA cards and PCM harfware devices...
		snd_ctl_t *handle;
		snd_ctl_card_info_t *info;
		snd_pcm_info_t *pcminfo;
		snd_ctl_card_info_alloca(&info);
		snd_pcm_info_alloca(&pcminfo);
		const QString sPrefix("hw:%1");
		const QString sSuffix(" (%1)");
		const QString sSubSuffix("%1,%2");
		QString sName2, sSubName2;
		bool bCapture, bPlayback;
		int iCard = -1;
		while (snd_card_next(&iCard) >= 0 && iCard >= 0) {
			sName = sPrefix.arg(iCard);
			if (snd_ctl_open(&handle, sName.toUtf8().constData(), 0) >= 0
				&& snd_ctl_card_info(handle, info) >= 0) {
				sName2 = sPrefix.arg(snd_ctl_card_info_get_id(info));
				addCard(sName2, snd_ctl_card_info_get_name(info) + sSuffix.arg(sName));
				if (sCurName == sName || sCurName == sName2)
					iCurCard = iCards;
				++iCards;
				int iDevice = -1;
				while (snd_ctl_pcm_next_device(handle, &iDevice) >= 0
					&& iDevice >= 0) {
					// Capture devices..
					bCapture = false;
					if (m_iAudio == QJACKCTL_CAPTURE ||
						m_iAudio == QJACKCTL_DUPLEX) {
						snd_pcm_info_set_device(pcminfo, iDevice);
						snd_pcm_info_set_subdevice(pcminfo, 0);
						snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
						bCapture = (snd_ctl_pcm_info(handle, pcminfo) >= 0);
					}
					// Playback devices..
					bPlayback = false;
					if (m_iAudio == QJACKCTL_PLAYBACK ||
						m_iAudio == QJACKCTL_DUPLEX) {
						snd_pcm_info_set_device(pcminfo, iDevice);
						snd_pcm_info_set_subdevice(pcminfo, 0);
						snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
						bPlayback = (snd_ctl_pcm_info(handle, pcminfo) >= 0);
					}
					// List iif compliant with the audio mode criteria...
					if ((m_iAudio == QJACKCTL_CAPTURE && bCapture && !bPlayback) ||
						(m_iAudio == QJACKCTL_PLAYBACK && !bCapture && bPlayback) ||
						(m_iAudio == QJACKCTL_DUPLEX && bCapture && bPlayback)) {
						sSubName  = sSubSuffix.arg(sName).arg(iDevice);
						sSubName2 = sSubSuffix.arg(sName2).arg(iDevice);
						addCard(sSubName2, snd_pcm_info_get_name(pcminfo) + sSuffix.arg(sSubName));
						if (sCurName == sSubName || sCurName == sSubName2)
							iCurCard = iCards;
						++iCards;
					}
				}
				snd_ctl_close(handle);
			}
		}
#endif 	// CONFIG_ALSA_SEQ
	}
	else
	if (bSun) {
		QFile file("/var/run/dmesg.boot");
		if (file.open(QIODevice::ReadOnly)) {
			QTextStream stream(&file);
			QString sLine;
			QRegExp rxDevice("audio([0-9]) at (.*)");
			while (!stream.atEnd()) {
				sLine = stream.readLine();
				if (rxDevice.exactMatch(sLine)) {
					sName = "/dev/audio" + rxDevice.cap(1);
					addCard(sName, rxDevice.cap(2));
					if (sCurName == sName)
						iCurCard = iCards;
					++iCards;
				}
			}
			file.close();
		}
	}
	else
	if (bOss) {
		// Enumerate the OSS Audio devices...
		QFile file("/dev/sndstat");
		if (file.open(QIODevice::ReadOnly)) {
			QTextStream stream(&file);
			QString sLine;
			bool bAudioDevices = false;
			QRegExp rxHeader("Audio devices.*", Qt::CaseInsensitive);
			QRegExp rxDevice("([0-9]+):[ ]+(.*)");
			while (!stream.atEnd()) {
				sLine = stream.readLine();
				if (bAudioDevices) {
					if (rxDevice.exactMatch(sLine)) {
						sName = "/dev/dsp" + rxDevice.cap(1);
						addCard(sName, rxDevice.cap(2));
						if (sCurName == sName)
							iCurCard = iCards;
						++iCards;
					}
					else break;
				}
				else if (rxHeader.exactMatch(sLine))
					bAudioDevices = true;
			}
			file.close();
		}
	}
#ifdef CONFIG_COREAUDIO
	else if (bCoreaudio) {
		// Find out how many Core Audio devices are there, if any...
		// (code snippet gently "borrowed" from Stephane Letz jackdmp;)
		OSStatus err;
		Boolean isWritable;
		UInt32 outSize = sizeof(isWritable);
		err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
				&outSize, &isWritable);
		if (err == noErr) {
			// Calculate the number of device available...
			int numCoreDevices = outSize / sizeof(AudioDeviceID);
			// Make space for the devices we are about to get...
			AudioDeviceID *coreDeviceIDs = new AudioDeviceID [numCoreDevices];
			err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
					&outSize, (void *) coreDeviceIDs);
			if (err == noErr) {
				// Look for the CoreAudio device name...
				char coreDeviceName[256];
				UInt32 nameSize = 256;
				for (int i = 0; i < numCoreDevices; i++) {
					err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
							0, true, kAudioDevicePropertyDeviceName,
							&outSize, &isWritable);
					if (err == noErr) {
						err = AudioDeviceGetProperty(coreDeviceIDs[i],
								0, true, kAudioDevicePropertyDeviceName,
								&nameSize, (void *) coreDeviceName);
						if (err == noErr) {
							char drivername[128];
							UInt32 dnsize = 128;
							// this returns the unique id for the device
							// that must be used on the commandline for jack
							if (getDeviceUIDFromID(coreDeviceIDs[i],
								drivername, dnsize) == noErr) {
								sName = drivername;
							} else {
								sName = "Error";
							}
							coreaudioIdMap[sName] = coreDeviceIDs[i];
							// TODO: hide this ugly ID from the user,
							// only show human readable name
							// humanreadable \t UID
							sSubName = QString(coreDeviceName);
							addCard(sSubName, sName);
							if (sCurName == sName || sCurName == sSubName)
								iCurCard = iCards;
							++iCards;
						}
					}
				}
			}
			delete [] coreDeviceIDs;
		}
	}
#endif 	// CONFIG_COREAUDIO
#ifdef CONFIG_PORTAUDIO
	else if (bPortaudio) {
		if (Pa_Initialize() == paNoError) {
			// Fill hostapi info...
			PaHostApiIndex iNumHostApi = Pa_GetHostApiCount();
			QString *pHostName = new QString[iNumHostApi];
			for (PaHostApiIndex i = 0; i < iNumHostApi; ++i)
				pHostName[i] = QString(Pa_GetHostApiInfo(i)->name);
			// Fill device info...
			PaDeviceIndex iNumDevice = Pa_GetDeviceCount();
			PaDeviceInfo **ppDeviceInfo = new PaDeviceInfo * [iNumDevice];
			for (PaDeviceIndex i = 0; i < iNumDevice; ++i) {
				ppDeviceInfo[i] = const_cast<PaDeviceInfo *> (Pa_GetDeviceInfo(i));
				sName = pHostName[ppDeviceInfo[i]->hostApi] + "::" + QString(ppDeviceInfo[i]->name);
				addCard(sName, QString());
				if (sCurName == sName)
					iCurCard = iCards;
				++iCards;
			}
			Pa_Terminate();
		}
	}
#endif  // CONFIG_PORTAUDIO

	addCard(m_sDefName, QString());
	if (sCurName == m_sDefName || sCurName.isEmpty())
		iCurCard = iCards;
	++iCards;

	QTreeView *pTreeView = static_cast<QTreeView *> (QComboBox::view());
	pTreeView->setMinimumWidth(
		pTreeView->sizeHint().width() + QComboBox::iconSize().width());

	QComboBox::setCurrentIndex(iCurCard);

	pLineEdit->setText(sCurName);

	QComboBox::setUpdatesEnabled(true);
	QComboBox::blockSignals(bBlockSignals);
}
Exemplo n.º 19
0
static
jack_driver_param_constraint_desc_t *
enum_alsa_devices()
{
    snd_ctl_t * handle;
    snd_ctl_card_info_t * info;
    snd_pcm_info_t * pcminfo_capture;
    snd_pcm_info_t * pcminfo_playback;
    int card_no = -1;
    char card_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
    char device_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
    char description[64];
    int device_no;
    bool has_capture;
    bool has_playback;
    jack_driver_param_constraint_desc_t * constraint_ptr;
    uint32_t array_size = 0;

    snd_ctl_card_info_alloca(&info);
    snd_pcm_info_alloca(&pcminfo_capture);
    snd_pcm_info_alloca(&pcminfo_playback);

    constraint_ptr = NULL;

    while(snd_card_next(&card_no) >= 0 && card_no >= 0)
    {
        snprintf(card_id, sizeof(card_id), "hw:%d", card_no);

        if (snd_ctl_open(&handle, card_id, 0) >= 0 &&
            snd_ctl_card_info(handle, info) >= 0)
        {
            fill_device(&constraint_ptr, &array_size, card_id, snd_ctl_card_info_get_name(info));

            device_no = -1;

            while (snd_ctl_pcm_next_device(handle, &device_no) >= 0 && device_no != -1)
            {
                snprintf(device_id, sizeof(device_id), "%s,%d", card_id, device_no);

                snd_pcm_info_set_device(pcminfo_capture, device_no);
                snd_pcm_info_set_subdevice(pcminfo_capture, 0);
                snd_pcm_info_set_stream(pcminfo_capture, SND_PCM_STREAM_CAPTURE);
                has_capture = snd_ctl_pcm_info(handle, pcminfo_capture) >= 0;

                snd_pcm_info_set_device(pcminfo_playback, device_no);
                snd_pcm_info_set_subdevice(pcminfo_playback, 0);
                snd_pcm_info_set_stream(pcminfo_playback, SND_PCM_STREAM_PLAYBACK);
                has_playback = snd_ctl_pcm_info(handle, pcminfo_playback) >= 0;

                if (has_capture && has_playback)
                {
                    snprintf(description, sizeof(description),"%s (duplex)", snd_pcm_info_get_name(pcminfo_capture));
                }
                else if (has_capture)
                {
                    snprintf(description, sizeof(description),"%s (capture)", snd_pcm_info_get_name(pcminfo_capture));
                }
                else if (has_playback)
                {
                    snprintf(description, sizeof(description),"%s (playback)", snd_pcm_info_get_name(pcminfo_playback));
                }
                else
                {
                    continue;
                }

                fill_device(&constraint_ptr, &array_size, device_id, description);
            }

            snd_ctl_close(handle);
        }
    }

    return constraint_ptr;
}
Exemplo n.º 20
0
static void device_list(snd_pcm_stream_t stream)
{
      snd_ctl_t *handle;
      int card, err, dev, idx;
      snd_ctl_card_info_t *info;
      snd_pcm_info_t *pcminfo;
      snd_ctl_card_info_alloca(&info);
      snd_pcm_info_alloca(&pcminfo);

      card = -1;
      if (snd_card_next(&card) < 0 || card < 0) {
            error(_("no soundcards found..."));
            return;
      }
      printf(_("**** List of %s Hardware Devices ****\n"),
             snd_pcm_stream_name(stream));
      while (card >= 0) {
            char name[32];
            sprintf(name, "hw:%d", card);
            if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
                  error("control open (%i): %s", card, snd_strerror(err));
                  goto next_card;
            }
            if ((err = snd_ctl_card_info(handle, info)) < 0) {
                  error("control hardware info (%i): %s", card, snd_strerror(err));
                  snd_ctl_close(handle);
                  goto next_card;
            }
            dev = -1;
            while (1) {
                  unsigned int count;
                  if (snd_ctl_pcm_next_device(handle, &dev)<0)
                        error("snd_ctl_pcm_next_device");
                  if (dev < 0)
                        break;
                  snd_pcm_info_set_device(pcminfo, dev);
                  snd_pcm_info_set_subdevice(pcminfo, 0);
                  snd_pcm_info_set_stream(pcminfo, stream);
                  if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                        if (err != -ENOENT)
                              error("control digital audio info (%i): %s", card, snd_strerror(err));
                        continue;
                  }
                  printf(_("card %i: [%s,%i] %s [%s], device %i: %s [%s]\n"),
			 card, name, dev, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
                        dev,
                        snd_pcm_info_get_id(pcminfo),
                        snd_pcm_info_get_name(pcminfo));
                  count = snd_pcm_info_get_subdevices_count(pcminfo);
                  printf( _("  Subdevices: %i/%i\n"),
                        snd_pcm_info_get_subdevices_avail(pcminfo), count);
                  for (idx = 0; idx < (int)count; idx++) {
                        snd_pcm_info_set_subdevice(pcminfo, idx);
                        if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                              error("control digital audio playback info (%i): %s", card, snd_strerror(err));
                        } else {
                              printf(_("  Subdevice #%i: %s\n"),
                                    idx, snd_pcm_info_get_subdevice_name(pcminfo));
                        }
                  }
            }
            snd_ctl_close(handle);
      next_card:
            if (snd_card_next(&card) < 0) {
                  error("snd_card_next");
                  break;
            }
      }
}
Exemplo n.º 21
0
void bg_alsa_create_card_parameters(bg_parameter_info_t * ret,
                                    int record)
  {
  snd_ctl_card_info_t *info;
  snd_ctl_t *handle;
  snd_pcm_info_t *pcminfo;
  snd_pcm_stream_t stream;
  int err;
  int card, dev;

  stream = record ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK;
  
  ret->name      = gavl_strdup("card");
  ret->long_name = gavl_strdup(TRS("Card"));
  ret->type = BG_PARAMETER_STRINGLIST;

  snd_ctl_card_info_malloc(&info);

  card = -1;
  if (snd_card_next(&card) < 0 || card < 0)
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN, "No soundcards found");
    return;
    }
  
  /* Default is always supported */
  ret->val_default.val_str = gavl_strdup("default");
  append_card(ret, gavl_strdup("default"),
              gavl_strdup(TRS("Default")));
  
  while (card >= 0)
    {
    char name[32];
    sprintf(name, "hw:%d", card);
    if ((err = snd_ctl_open(&handle, name, 0)) < 0)
      {
      bg_log(BG_LOG_ERROR, LOG_DOMAIN,
             "control open failed (%i): %s",
             card, snd_strerror(err));
      goto next_card;
      }
    if ((err = snd_ctl_card_info(handle, info)) < 0)
      {
      bg_log(BG_LOG_ERROR, LOG_DOMAIN,
             "control hardware info failed (%i): %s",
             card, snd_strerror(err));
      snd_ctl_close(handle);
      goto next_card;
      }
    dev = -1;

    while (1)
      {
      char * name, *label;
      snd_pcm_info_malloc(&pcminfo);
      if (snd_ctl_pcm_next_device(handle, &dev)<0)
        {
        bg_log(BG_LOG_ERROR, LOG_DOMAIN, "snd_ctl_pcm_next_device failed");
        snd_pcm_info_free(pcminfo);
        break;
        }
      if (dev < 0)
        {
        snd_pcm_info_free(pcminfo);
        break;
        }
      snd_pcm_info_set_device(pcminfo, dev);
      snd_pcm_info_set_subdevice(pcminfo, 0);
      snd_pcm_info_set_stream(pcminfo, stream);
      if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0)
        {
        if (err != -ENOENT)
          bg_log(BG_LOG_ERROR, LOG_DOMAIN,
                 "control digital audio info failed (%i): %s",
                 card, snd_strerror(err));
        snd_pcm_info_free(pcminfo);
        continue;
        }
      name = bg_sprintf("hw:%d,%d", card, dev);
      label = gavl_strdup(snd_pcm_info_get_name(pcminfo));
      append_card(ret, name, label);
      snd_pcm_info_free(pcminfo);
      }
    snd_ctl_close(handle);
    
    next_card:
    if (snd_card_next(&card) < 0)
      break;
    }
  snd_ctl_card_info_free(info);
  
  }
Exemplo n.º 22
0
/* returns the card name when the device number is unknown or -1 */
static gchar *
gst_alsa_find_device_name_no_handle (GstObject * obj, const gchar * devcard,
    gint device_num, snd_pcm_stream_t stream)
{
  snd_ctl_card_info_t *info = NULL;
  snd_ctl_t *ctl = NULL;
  gchar *ret = NULL;
  gint dev = -1;

  GST_LOG_OBJECT (obj, "[%s] device=%d", devcard, device_num);

  if (snd_ctl_open (&ctl, devcard, 0) < 0)
    return NULL;

  snd_ctl_card_info_malloc (&info);
  if (snd_ctl_card_info (ctl, info) < 0)
    goto done;

  if (device_num != -1) {
    while (snd_ctl_pcm_next_device (ctl, &dev) == 0 && dev >= 0) {
      if (dev == device_num) {
        snd_pcm_info_t *pcminfo;

        snd_pcm_info_malloc (&pcminfo);
        snd_pcm_info_set_device (pcminfo, dev);
        snd_pcm_info_set_subdevice (pcminfo, 0);
        snd_pcm_info_set_stream (pcminfo, stream);
        if (snd_ctl_pcm_info (ctl, pcminfo) < 0) {
          snd_pcm_info_free (pcminfo);
          break;
        }

        ret = (gchar *) snd_pcm_info_get_name (pcminfo);
        if (ret) {
          ret = g_strdup (ret);
          GST_LOG_OBJECT (obj, "name from pcminfo: %s", ret);
        }
        snd_pcm_info_free (pcminfo);
        if (ret)
          break;
      }
    }
  }

  if (ret == NULL) {
    char *name = NULL;
    gint card;

    GST_LOG_OBJECT (obj, "trying card name");
    card = snd_ctl_card_info_get_card (info);
    snd_card_get_name (card, &name);
    ret = g_strdup (name);
    free (name);
  }

done:
  snd_ctl_card_info_free (info);
  snd_ctl_close (ctl);

  return ret;
}