Example #1
0
 snd_config_for_each(i, next, conf) {
     snd_config_t *n = snd_config_iterator_entry(i);
     const char *id;
     if (snd_config_get_id(n, &id) < 0)
         continue;
     if (strcmp(id, "comment") == 0)
         continue;
     if (strcmp(id, "type") == 0)
         continue;
     if (strcmp(id, "card") == 0) {
         err = snd_config_get_integer(n, &card);
         if (err < 0) {
             err = snd_config_get_string(n, &str);
             if (err < 0)
                 return -EINVAL;
             card = snd_card_get_index(str);
             if (card < 0)
                 return card;
         }
         continue;
     }
     if (strcmp(id, "device") == 0) {
         err = snd_config_get_integer(n, &device);
         if (err < 0)
             return err;
         continue;
     }
     SNDERR("Unexpected field %s", id);
     return -EINVAL;
 }
Example #2
0
/* very simple device name parsing; only limited prefix are allowed:
 * "hw" and "default"
 */
int _snd_dev_get_device(const char *name, int *cardp, int *devp, int *subdevp)
{
    int card;
    *cardp = 0;
    if (devp)
        *devp = 0;
    if (subdevp)
        *subdevp = -1;
    if (!strcmp(name, "hw") || !strcmp(name, "default") ||
            !strcmp(name, "sysdefault"))
        return 0;
    if (!strncmp(name, "hw:", 3))
        name += 3;
    else if (!strncmp(name, "default:", 8))
        name += 8;
    else if (!strncmp(name, "sysdefault:", 11))
        name += 11;
    else
        return -EINVAL;
    card = snd_card_get_index(name);
    if (card < 0)
        return card;
    *cardp = card;
    if (devp && subdevp) {
        /* parse the secondary and third arguments (if any) */
        name = strchr(name, ',');
        if (name) {
            sscanf(name, ",%d,%d",  devp, subdevp);
            if (*devp < 0 || *devp >= SALSA_MAX_DEVICES)
                return -EINVAL;
        }
    }
    return 0;
}
mixerVolume::mixerVolume(const char *name, const char *card, long volume) {
	snd_mixer_selem_id_t *sid = NULL;
	elem = NULL;
	handle = NULL;
	min = 0;
	max = 100;
	char cardId[10];

	if (!name || !card)
		return;

	int cx = snd_card_get_index(card);
	if (cx < 0 || cx > 31)
		return;
	snprintf(cardId, sizeof(cardId), "hw:%i", cx);

	if (0 > snd_mixer_open(&handle, 0))
		return;
	if (0 > snd_mixer_attach(handle, cardId))
		return;
	if (0 > snd_mixer_selem_register(handle, NULL, NULL))
		return;
	if (0 > snd_mixer_load(handle))
		return;
	snd_mixer_selem_id_alloca(&sid);
	if (!sid)
		return;
	snd_mixer_selem_id_set_index(sid, 0);
	snd_mixer_selem_id_set_name(sid, name);
	elem = snd_mixer_find_selem(handle, sid);
	if (elem) {
		snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
		setVolume(volume);
	}
}
Example #4
0
static void amixer_card(t_amixer *x, t_symbol *s, int argc, t_atom *argv)
{
  if(1==argc){
    int id=-1;
    if(A_FLOAT==argv->a_type)id=atom_getint(argv);
    else id=snd_card_get_index(atom_getsymbol(argv)->s_name);
    if (id >= 0 && id < 32)
      sprintf(x->card, "hw:%i", id);
    else {
      pd_error(x, "invalid card %d", id);
      return;
    }


  } else error("amixer: can only be integer of symbol");
}
Example #5
0
bool QAudioDeviceInfoInternal::open()
{
    int err = 0;
    QString dev = device;
    if(!dev.contains(QLatin1String("default"))) {
        int idx = snd_card_get_index(dev.toLocal8Bit().constData());
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
    }
    if(mode == QAudio::AudioOutput) {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
    } else {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
    }
    if(err < 0) {
        handle = 0;
        return false;
    }
    return true;
}
Example #6
0
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const
{
    // Set nearest to closest settings that do work.
    // See if what is in settings will work (return value).
    int err = 0;
    snd_pcm_t* handle;
    snd_pcm_hw_params_t *params;
    QString dev = device;

    // open()
    if(!dev.contains(QLatin1String("default"))) {
        int idx = snd_card_get_index(dev.toLocal8Bit().constData());
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
    }
    if(mode == QAudio::AudioOutput) {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
    } else {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
    }
    if(err < 0) {
        handle = 0;
        return false;
    }

    bool testChannel = false;
    bool testCodec = false;
    bool testFreq = false;
    bool testType = false;
    bool testSize = false;

    int  dir = 0;

    snd_pcm_nonblock( handle, 0 );
    snd_pcm_hw_params_alloca( &params );
    snd_pcm_hw_params_any( handle, params );

    // set the values!
    snd_pcm_hw_params_set_channels(handle,params,format.channels());
    snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
    switch(format.sampleSize()) {
        case 8:
            if(format.sampleType() == QAudioFormat::SignedInt)
                snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
            else if(format.sampleType() == QAudioFormat::UnSignedInt)
                snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
            break;
        case 16:
            if(format.sampleType() == QAudioFormat::SignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
            } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
            }
            break;
        case 32:
            if(format.sampleType() == QAudioFormat::SignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
            } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
            }
    }

    // For now, just accept only audio/pcm codec
    if(!format.codec().startsWith(QLatin1String("audio/pcm"))) {
        err=-1;
    } else
        testCodec = true;

    if(err>=0 && format.channels() != -1) {
        err = snd_pcm_hw_params_test_channels(handle,params,format.channels());
        if(err>=0)
            err = snd_pcm_hw_params_set_channels(handle,params,format.channels());
        if(err>=0)
            testChannel = true;
    }

    if(err>=0 && format.frequency() != -1) {
        err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0);
        if(err>=0)
            err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
        if(err>=0)
            testFreq = true;
    }

    if((err>=0 && format.sampleSize() != -1) &&
            (format.sampleType() != QAudioFormat::Unknown)) {
        switch(format.sampleSize()) {
            case 8:
                if(format.sampleType() == QAudioFormat::SignedInt)
                    err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
                else if(format.sampleType() == QAudioFormat::UnSignedInt)
                    err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
                break;
            case 16:
                if(format.sampleType() == QAudioFormat::SignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
                } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
                }
                break;
            case 32:
                if(format.sampleType() == QAudioFormat::SignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
                } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
                }
        }
        if(err>=0) {
            testSize = true;
            testType = true;
        }
    }
    if(err>=0)
        err = snd_pcm_hw_params(handle, params);

    if(err == 0) {
        // settings work
        // close()
        if(handle)
            snd_pcm_close(handle);
        return true;
    }
    if(handle)
        snd_pcm_close(handle);

    return false;
}
/**
 * \brief Parse control element id from the config
 * \param conf the config tree to parse
 * \param ctl_id the pointer to store the resultant control element id
 * \param cardp the pointer to store the card index
 * \param cchannelsp the pointer to store the number of channels (optional)
 * \param hwctlp the pointer to store the h/w control flag (optional)
 * \return 0 if successful, or a negative error code
 *
 * This function parses the given config tree to retrieve the control element id
 * and the card index.  It's used by softvol.  External PCM plugins can use this
 * function for creating or assigining their controls.
 *
 * cchannelsp and hwctlp arguments are optional.  Set NULL if not necessary.
 */
int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp,
			     int *cchannelsp, int *hwctlp)
{
	snd_config_iterator_t i, next;
	int iface = SND_CTL_ELEM_IFACE_MIXER;
	const char *name = NULL;
	long index = 0;
	long device = -1;
	long subdevice = -1;
	int err;

	assert(ctl_id && cardp);

	*cardp = -1;
	if (cchannelsp)
		*cchannelsp = 2;
	snd_config_for_each(i, next, conf) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (strcmp(id, "comment") == 0)
			continue;
		if (strcmp(id, "card") == 0) {
			const char *str;
			long v;
			if ((err = snd_config_get_integer(n, &v)) < 0) {
				if ((err = snd_config_get_string(n, &str)) < 0) {
					SNDERR("Invalid field %s", id);
					goto _err;
				}
				*cardp = snd_card_get_index(str);
				if (*cardp < 0) {
					SNDERR("Cannot get index for %s", str);
					err = *cardp;
					goto _err;
				}
			} else
				*cardp = v;
			continue;
		}
		if (strcmp(id, "iface") == 0 || strcmp(id, "interface") == 0) {
			const char *ptr;
			if ((err = snd_config_get_string(n, &ptr)) < 0) {
				SNDERR("field %s is not a string", id);
				goto _err;
			}
			if ((err = snd_config_get_ctl_iface_ascii(ptr)) < 0) {
				SNDERR("Invalid value for '%s'", id);
				goto _err;
			}
			iface = err;
			continue;
		}
		if (strcmp(id, "name") == 0) {
			if ((err = snd_config_get_string(n, &name)) < 0) {
				SNDERR("field %s is not a string", id);
				goto _err;
			}
			continue;
		}
		if (strcmp(id, "index") == 0) {
			if ((err = snd_config_get_integer(n, &index)) < 0) {
				SNDERR("field %s is not an integer", id);
				goto _err;
			}
			continue;
		}
		if (strcmp(id, "device") == 0) {
			if ((err = snd_config_get_integer(n, &device)) < 0) {
				SNDERR("field %s is not an integer", id);
				goto _err;
			}
			continue;
		}
		if (strcmp(id, "subdevice") == 0) {
			if ((err = snd_config_get_integer(n, &subdevice)) < 0) {
				SNDERR("field %s is not an integer", id);
				goto _err;
			}
			continue;
		}
		if (cchannelsp && strcmp(id, "count") == 0) {
			long v;
			if ((err = snd_config_get_integer(n, &v)) < 0) {
				SNDERR("field %s is not an integer", id);
				goto _err;
			}
			if (v < 1 || v > 2) {
				SNDERR("Invalid count %ld", v);
				goto _err;
			}
			*cchannelsp = v;
			continue;
		}
		if (hwctlp && strcmp(id, "hwctl") == 0) {
			if ((err = snd_config_get_bool(n)) < 0) {
				SNDERR("The field %s must be a boolean type", id);
				return err;
			}
			*hwctlp = err;
			continue;
		}
		SNDERR("Unknown field %s", id);
		return -EINVAL;
	}