Exemplo n.º 1
0
static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
{
#if 0 //TARGET_AUDIO_PRIMARY
    struct mixer *mixer;
    struct mixer_ctl *ctl;
    struct audio_device * adev = (struct audio_device *)dev;

    if ((0 > volume) || (1 < volume) || (NULL == adev))
      return -EINVAL;

    pthread_mutex_lock(&adev->lock);
    adev->master_volume = (int)(volume*100);

    if (!(mixer = mixer_open(0))) {
      pthread_mutex_unlock(&adev->lock);
      return -ENOSYS;
    }

    ctl = mixer_get_ctl_by_name(mixer, "HP Playback Volume");
    mixer_ctl_set_value(ctl,0,adjust_volume(adev->master_volume));
    mixer_ctl_set_value(ctl,1,adjust_volume(adev->master_volume));

    mixer_close(mixer);
    pthread_mutex_unlock(&adev->lock);
    return 0;
#else
    return -ENOSYS;
#endif
}
bool AudioALSAPlaybackHandlerNormal::SetLowJitterMode(bool bEnable,uint32_t SampleRate)
{
    ALOGD("%s() bEanble = %d SampleRate = %u", __FUNCTION__, bEnable,SampleRate);

    enum mixer_ctl_type type;
    struct mixer_ctl *ctl;
    int retval = 0;

    // check need open low jitter mode
    if(SampleRate < GetLowJitterModeSampleRate() && (AudioALSADriverUtility::getInstance()->GetPropertyValue(PROPERTY_KEY_EXTDAC)) == false)
    {
        ALOGD("%s(), bEanble = %d", __FUNCTION__, bEnable);
        return false;
    }

    ctl = mixer_get_ctl_by_name(mMixer, "Audio_I2S0dl1_hd_Switch");

    if (ctl == NULL)
    {
        ALOGE("Audio_I2S0dl1_hd_Switch not support");
        return false;
    }

    if (bEnable == true)
    {
        retval = mixer_ctl_set_enum_by_string(ctl, "On");
        ASSERT(retval == 0);
    }
    else
    {
        retval = mixer_ctl_set_enum_by_string(ctl, "Off");
        ASSERT(retval == 0);
    }
    return true;
}
Exemplo n.º 3
0
void mixer_ctl_set(struct mixer *mixer, const char *name, const char *val)
{
    struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name);
    int ret = mixer_ctl_set_enum_by_string(ctl, val);
    if (ret != 0)
	LOGE("Failed to set %s to %s\n", name, val);
}
Exemplo n.º 4
0
int offload_update_mixer_and_effects_ctl(int card, int device_id,
                                         struct mixer *mixer,
                                         struct mixer_ctl *ctl)
{
    char mixer_string[128];

    snprintf(mixer_string, sizeof(mixer_string),
             "%s %d", "Audio Effects Config", device_id);
    ALOGV("%s: mixer_string: %s", __func__, mixer_string);
    mixer = mixer_open(card);
    if (!mixer) {
        ALOGE("Failed to open mixer");
        ctl = NULL;
        return -EINVAL;
    } else {
        ctl = mixer_get_ctl_by_name(mixer, mixer_string);
        if (!ctl) {
            ALOGE("mixer_get_ctl_by_name failed");
            mixer_close(mixer);
            mixer = NULL;
            return -EINVAL;
        }
    }
    ALOGV("mixer: %p, ctl: %p", mixer, ctl);
    return 0;
}
int platform_listen_connect_mad
(
   void *platform,
   bool en,
   audio_listen_session_t *p_ses
)
{
#ifndef PLATFORM_APQ8084
    return 0;
#else
    /* This mixer control is only valid for CPE supported codec */
    struct platform_data *my_data = (struct platform_data *)platform;
    audio_listen_hardware_t *listen_hal = my_data->listen_hal;
    int status = 0;
    struct mixer_ctl *ctl = NULL;
    const char *mixer_ctl_name = "MAD_SEL MUX";

    ctl = mixer_get_ctl_by_name(listen_hal->mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
        __func__, mixer_ctl_name);
        return -EINVAL;
    }
    if(p_ses->exec_mode == LISTEN_EXEC_MODE_CPE)
        status = mixer_ctl_set_enum_by_string(ctl, "SPE");
    else
        status = mixer_ctl_set_enum_by_string(ctl, "MSM");

    if (status)
        ALOGE("%s: ERROR. Mixer ctl set failed", __func__);

    return status;
#endif
}
static void tinymix_set_value(struct mixer *mixer, const char *control,
                              char **values, unsigned int num_values)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_ctl_values;
    unsigned int i;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_ctl_values = mixer_ctl_get_num_values(ctl);

    if (isdigit(values[0][0])) {
        if (num_values == 1) {
            /* Set all values the same */
            int value = atoi(values[0]);

            for (i = 0; i < num_ctl_values; i++) {
                if (mixer_ctl_set_value(ctl, i, value)) {
                    fprintf(stderr, "Error: invalid value\n");
                    return;
                }
            }
        } else {
            /* Set multiple values */
            if (num_values > num_ctl_values) {
                fprintf(stderr,
                        "Error: %d values given, but control only takes %d\n",
                        num_values, num_ctl_values);
                return;
            }
            for (i = 0; i < num_values; i++) {
                if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
                    fprintf(stderr, "Error: invalid value for index %d\n", i);
                    return;
                }
            }
        }
    } else {
        if (type == MIXER_CTL_TYPE_ENUM) {
            if (num_values != 1) {
                fprintf(stderr, "Enclose strings in quotes and try again\n");
                return;
            }
            if (mixer_ctl_set_enum_by_string(ctl, values[0]))
                fprintf(stderr, "Error: invalid enum value\n");
        } else {
            fprintf(stderr, "Error: only enum types can be set with strings\n");
        }
    }
}
Exemplo n.º 7
0
static void tinymix_set_value(struct mixer *mixer, char *name, char *value)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int i, num_values;

    ctl = mixer_get_ctl_by_name(mixer, name);
    if(!ctl) {
        log_err("cannot find control \'%s\'", name);
        return;
    }
    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if(isdigit(value[0])) {
        int val = atoi(value);
        for(i = 0; i < num_values; i++) {
            if(mixer_ctl_set_value(ctl, i, val)) {
		log_err("value %d not accepted for %s", val, name);
		return;
            }
        }
    } else if(type == MIXER_CTL_TYPE_ENUM) {
        if(mixer_ctl_set_enum_by_string(ctl, value))
            log_err("value %s not accepted for %s", value, name);
    } else if(type == MIXER_CTL_TYPE_BOOL) {
        if(strcasecmp(value,"on") == 0) i = 1;
        else if(strcasecmp(value, "off") == 0) i = 0;
        else {
            log_err("cannot set %s to \'%s\', on/off or 1/0 expected", name, value);
            return;
        }
        if(mixer_ctl_set_value(ctl, 0, i)) log_err("value %d not accepted for %s", i, name);
    } else log_err("type mismatch for %s, ignored", name);
}
static int set_clocks_enabled(bool enable)
{
    enum mixer_ctl_type type;
    struct mixer_ctl *ctl;
    struct mixer *mixer = mixer_open(0);

    if (mixer == NULL) {
        ALOGE("Error opening mixer 0");
        return -1;
    }

    ctl = mixer_get_ctl_by_name(mixer, AMP_MIXER_CTL);
    if (ctl == NULL) {
        mixer_close(mixer);
        ALOGE("%s: Could not find %s\n", __func__, AMP_MIXER_CTL);
        return -ENODEV;
    }

    type = mixer_ctl_get_type(ctl);
    if (type != MIXER_CTL_TYPE_ENUM) {
        ALOGE("%s: %s is not supported\n", __func__, AMP_MIXER_CTL);
        mixer_close(mixer);
        return -ENOTTY;
    }

    mixer_ctl_set_value(ctl, 0, enable);
    mixer_close(mixer);
    return 0;
}
Exemplo n.º 9
0
size_t
actlstr(char *buf, size_t n, char *ch, struct mixer *mx) {
	size_t ret;
	char *status;
	struct mixer_ctl *ctl;

	if (!(ctl = mixer_get_ctl_by_name(mx, ch))) {
		mixer_close(mx);
		die("couldn't find mixer ctl '%s'\n", ch);
	}

	switch (mixer_ctl_get_type(ctl)) {
	case MIXER_CTL_TYPE_INT:
		if ((ret = snprintf(buf, n, "%d%%",
				mixer_ctl_get_percent(ctl, 0))) > n)
			ret = n;
		break;
	case MIXER_CTL_TYPE_BOOL:
		status = mixer_ctl_get_value(ctl, 0) ? "On" : "Off";
		ret = stpncpy(buf, status, n) - buf;
		break;
	default:
		mixer_close(mx);
		die("unsupported ctl type '%s'\n",
			mixer_ctl_get_type_string(ctl));
	};

	return ret;
}
Exemplo n.º 10
0
void mixer_ctl_set(struct mixer *mixer, const char *name, int val)
{
    struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name);
    int ret = mixer_ctl_set_value(ctl, 0, val);
    if (ret != 0)
	LOGE("Failed to set %s to %d\n", name, val);
    mixer_ctl_set_value(ctl, 1, val);
}
Exemplo n.º 11
0
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
         case MIXER_CTL_TYPE_BYTE:
            printf(" 0x%02x", mixer_ctl_get_value(ctl, i));
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }
    printf("\n");
}
static bool setMixerValue(struct mixer* mixer, const char* name, const char* values)
{
    if (!mixer) {
        ALOGE("no mixer in setMixerValue");
        return false;
    }
    struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name);
    if (!ctl) {
        ALOGE("mixer_get_ctl_by_name failed for %s", name);
        return false;
    }

    enum mixer_ctl_type type = mixer_ctl_get_type(ctl);
    int numValues = mixer_ctl_get_num_values(ctl);
    int intValue;
    char stringValue[MAX_LINE_LENGTH];

    for (int i = 0; i < numValues && values; i++) {
        // strip leading space
        while (*values == ' ') values++;
        if (*values == 0) break;

        switch (type) {
            case MIXER_CTL_TYPE_BOOL:
            case MIXER_CTL_TYPE_INT:
                if (sscanf(values, "%d", &intValue) == 1) {
                    if (mixer_ctl_set_value(ctl, i, intValue) != 0) {
                        ALOGE("mixer_ctl_set_value failed for %s %d", name, intValue);
                    }
                } else {
                    ALOGE("Could not parse %s as int for %s", values, name);
                }
                break;
            case MIXER_CTL_TYPE_ENUM:
                if (sscanf(values, "%s", stringValue) == 1) {
                    if (mixer_ctl_set_enum_by_string(ctl, stringValue) != 0) {
                        ALOGE("mixer_ctl_set_enum_by_string failed for %s %s", name, stringValue);
                    }
                } else {
                    ALOGE("Could not parse %s as enum for %s", values, name);
                }
                break;
            default:
                ALOGE("unsupported mixer type %d for %s", type, name);
                break;
        }

        values = strchr(values, ' ');
    }

    return true;
}
static int SetAudio_gain_4eng(struct audio_pga *pga, pga_gain_nv_t *pga_gain_nv, AUDIO_TOTAL_T *aud_params_ptr)
{
    int card_id = 0;
    int32_t lmode = 0;
    struct mixer *mixer = NULL;
    struct mixer_ctl *pa_config_ctl = NULL;
    ALOGD("vb_pga.c  %s", __func__);
    if((NULL == aud_params_ptr) || (NULL == pga_gain_nv) || (NULL == pga)){
        ALOGE("%s aud_params_ptr or pga_gain_nv or audio_pga is NULL",__func__);
        return -1;
    }
    card_id = get_snd_card_number(CARD_SPRDPHONE);
    if (card_id < 0){
        ALOGE("%s get_snd_card_number error(%d)",__func__,card_id);
        return -1;
    }
    mixer = mixer_open(card_id);
    if (!mixer) {
        ALOGE("%s Unable to open the mixer, aborting.",__func__);
        return -1;
    }
    pa_config_ctl = mixer_get_ctl_by_name(mixer, MIXER_CTL_INNER_PA_CONFIG);
    lmode = GetAudio_mode_number_from_nv(aud_params_ptr);
    ALOGD("vb_pga.c  %s, mode: %d", __func__, lmode);
    if(0 == lmode){ //Headset
        audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_l,"linein-hp-l");
        audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_r,"linein-hp-r");
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"headphone-l");
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"headphone-r");
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l");
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r");
    }else if(1 == lmode){   //Headfree
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"headphone-spk-l");
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"headphone-spk-r");
        mixer_ctl_set_value(pa_config_ctl, 0, pga_gain_nv->pa_config);
    }else if(2 == lmode){   //Handset
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"earpiece");
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l");
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r");
    }else if(3 == lmode){   //Handsfree
        audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_l,"linein-spk-l");
        audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_r,"linein-spk-r");
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"speaker-l");
        audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"speaker-r");
        mixer_ctl_set_value(pa_config_ctl, 0, pga_gain_nv->pa_config);
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l");
        audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r");
    }
    mixer_close(mixer);
    ALOGW("%s, set cp mode(0x%x) ",__func__,lmode);
    return 0;
}
Exemplo n.º 14
0
/// Speaker over current test
int AudioFtm::Audio_READ_SPK_OC_STA(void)
{
    ALOGD("%s()", __FUNCTION__);
    struct mixer_ctl *ctl;
    int retval, dValue;
    ctl = mixer_get_ctl_by_name(mMixer, "Audio_Speaker_OC_Falg");
    if (NULL == ctl)
    {
        ALOGD("[%s] [%d]", __FUNCTION__, __LINE__);
        return true; //true means SPK OC fail
    }
    dValue = mixer_ctl_get_value(ctl, 0);
    ALOGD("-%s() value [0x%x]", __FUNCTION__, dValue);
    return dValue;
}
Exemplo n.º 15
0
static void send_app_type_cfg(void *platform, struct mixer *mixer,
                              struct listnode *streams_output_cfg_list)
{
    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1};
    int length = 0, i, num_app_types = 0;
    struct listnode *node;
    bool update;
    struct mixer_ctl *ctl = NULL;
    const char *mixer_ctl_name = "App Type Config";
    struct streams_output_cfg *so_info;

    if (!mixer) {
        ALOGE("%s: mixer is null",__func__);
        return;
    }
    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
        return;
    }
    if (streams_output_cfg_list == NULL) {
        app_type_cfg[length++] = 1;
        app_type_cfg[length++] = platform_get_default_app_type(platform);
        app_type_cfg[length++] = 48000;
        app_type_cfg[length++] = 16;
        mixer_ctl_set_array(ctl, app_type_cfg, length);
        return;
    }

    app_type_cfg[length++] = num_app_types;
    list_for_each(node, streams_output_cfg_list) {
        so_info = node_to_item(node, struct streams_output_cfg, list);
        update = true;
        for (i=0; i<length; i=i+3) {
            if (app_type_cfg[i+1] == -1)
                break;
            else if (app_type_cfg[i+1] == so_info->app_type_cfg.app_type) {
                update = false;
                break;
            }
        }
        if (update && ((length + 3) <= MAX_LENGTH_MIXER_CONTROL_IN_INT)) {
            num_app_types += 1 ;
            app_type_cfg[length++] = so_info->app_type_cfg.app_type;
            app_type_cfg[length++] = so_info->app_type_cfg.sample_rate;
            app_type_cfg[length++] = so_info->app_type_cfg.bit_width;
        }
    }
status_t AudioALSACodecDeviceOutSpeakerEarphonePMIC::close()
{
    ALOGD("+%s(), mClientCount = %d", __FUNCTION__, mClientCount);

    mClientCount--;

    if (mClientCount == 0)
    {
        if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Headset_Speaker_Amp_Switch"), "Off"))
        {
            ALOGE("Error: Audio_Amp_R_Switch invalid value");
        }
    }

    ALOGD("-%s(), mClientCount = %d", __FUNCTION__, mClientCount);
    return NO_ERROR;
}
Exemplo n.º 17
0
static bool
do_set_volume(struct mixer *mixer, const char *name, unsigned volume)
{
    struct mixer_ctl *ctl;
    unsigned i;

    ctl = mixer_get_ctl_by_name(mixer, name);
    if (! ctl) {
	fprintf(stderr, "Failed to find control: %s\n", name);
	mixer_close(mixer);
	return false;
    }

    for (i = 0; i < mixer_ctl_get_num_values(ctl); i++) {
        mixer_ctl_set_percent(ctl, i, volume);
    }

    return true;
}
Exemplo n.º 18
0
bool AudioFtm::ReadAuxadcData(int channel, int *value)
{
    struct mixer_ctl *ctl;
    int retval, dValue;
    channel = 0x001B; //AUX_SPK_THR_I_AP include mt_pmic.h
    ALOGD("+%s() channel [0x%x] (force to replace)", __FUNCTION__, channel);
    ctl = mixer_get_ctl_by_name(mMixer, "Audio AUXADC Data");
    if (NULL == ctl || NULL == value)
    {
        ALOGD("[%s] [%d]", __FUNCTION__, __LINE__);
        return false;
    }
    retval = mixer_ctl_set_value(ctl, 0, channel);
    usleep(1000);
    dValue = mixer_ctl_get_value(ctl, 0);
    *value = dValue;
    ALOGD("-%s() value [0x%x]", __FUNCTION__, dValue);
    return false;
}
Exemplo n.º 19
0
static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
                                          int pcm_device_id, int app_type,
                                          int acdb_dev_id, int sample_rate,
                                          int stream_type,
                                          snd_device_t snd_device)
{

    char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
    struct mixer_ctl *ctl;
    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
    int snd_device_be_idx = -1;

    if (stream_type == PCM_PLAYBACK) {
        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
             "Audio Stream %d App Type Cfg", pcm_device_id);
    } else if (stream_type == PCM_CAPTURE) {
        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
             "Audio Stream Capture %d App Type Cfg", pcm_device_id);
    }

    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",
             __func__, mixer_ctl_name);
        rc = -EINVAL;
        goto exit;
    }
    app_type_cfg[len++] = app_type;
    app_type_cfg[len++] = acdb_dev_id;
    app_type_cfg[len++] = sample_rate;

    snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
    if (snd_device_be_idx > 0)
        app_type_cfg[len++] = snd_device_be_idx;
    ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
          "sample rate %d, snd_device_be_idx %d",
          __func__, stream_type, app_type, acdb_dev_id, sample_rate,
          snd_device_be_idx);
    mixer_ctl_set_array(ctl, app_type_cfg, len);

exit:
    return rc;
}
status_t AudioALSACodecDeviceOutSpeakerPMIC::close()
{
    ALOGD("+%s(), mClientCount = %d", __FUNCTION__, mClientCount);

    mClientCount--;

    if (mClientCount == 0)
    {
        if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Speaker_Amp_Switch"), "Off"))
        {
            ALOGE("Error: Speaker_Amp_Switch invalid value");
        }
#if defined(MTK_SPEAKER_MONITOR_SUPPORT)
        //AudioALSASpeakerMonitor::getInstance()->EnableSpeakerMonitorThread(false);
        AudioALSASpeakerMonitor::getInstance()->Deactivate();
#endif
    }

    ALOGD("-%s(), mClientCount = %d", __FUNCTION__, mClientCount);
    return NO_ERROR;
}
Exemplo n.º 21
0
void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer)
{
    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1};
    int length = 0, app_type = 0,rc = 0;
    struct mixer_ctl *ctl = NULL;
    const char *mixer_ctl_name = "App Type Config";

    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
        return;
    }
    rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type);
    if (rc == 0) {
        app_type_cfg[length++] = 1;
        app_type_cfg[length++] = app_type;
        app_type_cfg[length++] = 48000;
        app_type_cfg[length++] = 16;
        mixer_ctl_set_array(ctl, app_type_cfg, length);
    }
    return;
}
status_t AudioALSAPlaybackHandlerSphDL::close()
{
    ALOGD("+%s()", __FUNCTION__);

    // close codec driver
    // Don't stopoutputDevice here, let speech driver to open.
    mHardwareResourceManager->stopOutputDevice();

    //Echo reference path
    if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Audio_Dl1_MD_Echo_Ref_Switch"), "Off"))
    {
        ALOGE("Error: Audio_Dl1_MD_Echo_Ref_Switch invalid value");
    }

    // close pcm driver
    closePcmDriver();


    // bit conversion
    deinitBitConverter();


    // SRC
    deinitBliSrc();


    // post processing
    deinitPostProcessing();


    // debug pcm dump
    ClosePCMDump();


    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
status_t AudioALSAPlaybackHandlerSphDL::open()
{
    ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices);
    // debug pcm dump
    OpenPCMDump(LOG_TAG);
    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmI2S0Dl1Playback);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmI2S0Dl1Playback);
    ALOGD("AudioALSAPlaybackHandlerSphDL::open() pcmindex = %d", pcmindex);
    ListPcmDriver(cardindex, pcmindex);

    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    ALOGD("buffersizemax = %d", mStreamAttributeTarget.buffer_size);
    pcm_params_free(params);


    // HW attribute config // TODO(Harvey): query this
    mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_16_BIT;
    mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_MONO;
    mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask);
    mStreamAttributeTarget.sample_rate = mStreamAttributeSource->sample_rate; // same as source stream


    // HW pcm config
    mConfig.channels = mStreamAttributeTarget.num_channels;
    mConfig.rate = mStreamAttributeTarget.sample_rate;

    // Buffer size: 1536(period_size) * 2(ch) * 4(byte) * 2(period_count) = 24 kb

    mConfig.period_count = 4;
    //mConfig.period_size = (0x4000/(mConfig.channels*mConfig.period_count))/((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4);
    mConfig.period_size = 512;

    mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format);

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;
    ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format);


    // post processing
    initPostProcessing();

#if defined(MTK_SPEAKER_MONITOR_SUPPORT)
    unsigned int fc, bw;
    int th;
    if (mAudioFilterManagerHandler)
    {
        AudioALSASpeakerMonitor::getInstance()->GetFilterParam(&fc, &bw, &th);
        ALOGD("%s(), fc %d bw %d, th %d", __FUNCTION__, fc, bw, th);
        mAudioFilterManagerHandler->setSpkFilterParam(fc, bw, th);
    }
#endif

    // SRC
    initBliSrc();


    // bit conversion
    initBitConverter();


    // open pcm driver
    openPcmDriver(pcmindex);

    //Echo reference path
    if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Audio_Dl1_MD_Echo_Ref_Switch"), "On"))
    {
        ALOGE("Error: Audio_Dl1_MD_Echo_Ref_Switch invalid value");
    }

    // open codec driver
    // Don't startoutputDevice here, let speech driver to open.
    mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate);

    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
Exemplo n.º 24
0
static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
{
#if 0 //TARGET_AUDIO_PRIMARY
    struct mixer *mixer;
    struct mixer_ctl *ctl;
#endif
    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
        return -EINVAL;

    struct audio_device *adev = calloc(1, sizeof(struct audio_device));
    if (!adev)
        return -ENOMEM;

    profile_init(&adev->out_profile, PCM_OUT);
    profile_init(&adev->in_profile, PCM_IN);

    adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
    adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
    adev->hw_device.common.module = (struct hw_module_t *)module;
    adev->hw_device.common.close = adev_close;

    adev->hw_device.init_check = adev_init_check;
    adev->hw_device.set_voice_volume = adev_set_voice_volume;
    adev->hw_device.set_master_volume = adev_set_master_volume;
    adev->hw_device.set_mode = adev_set_mode;
    adev->hw_device.set_mic_mute = adev_set_mic_mute;
    adev->hw_device.get_mic_mute = adev_get_mic_mute;
    adev->hw_device.set_parameters = adev_set_parameters;
    adev->hw_device.get_parameters = adev_get_parameters;
    adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
    adev->hw_device.open_output_stream = adev_open_output_stream;
    adev->hw_device.close_output_stream = adev_close_output_stream;
    adev->hw_device.open_input_stream = adev_open_input_stream;
    adev->hw_device.close_input_stream = adev_close_input_stream;
    adev->hw_device.dump = adev_dump;

    *device = &adev->hw_device.common;
#if 0 //TARGET_AUDIO_PRIMARY
    mixer = mixer_open(0);

    if (mixer) {
        /* setting master volume to value 50 */
        adev->master_volume = 50;

	int ret = 0;
        ctl = mixer_get_ctl_by_name(mixer, "HP Playback Switch");
        ret = mixer_ctl_set_value(ctl,0,1);
        ret = mixer_ctl_set_value(ctl,1,1);
        ctl = mixer_get_ctl_by_name(mixer, "HP Playback Volume");
        mixer_ctl_set_value(ctl,0,adjust_volume(adev->master_volume));
        mixer_ctl_set_value(ctl,1,adjust_volume(adev->master_volume));
        ctl = mixer_get_ctl_by_name(mixer, "HPO MIX DAC1 Switch");
        mixer_ctl_set_value(ctl,0,1);
        ctl = mixer_get_ctl_by_name(mixer, "HPO MIX DAC1 Switch");
        mixer_ctl_set_value(ctl,0,1);
        ctl = mixer_get_ctl_by_name(mixer, "OUT MIXR DAC R1 Switch");
        mixer_ctl_set_value(ctl,0,1);
        ctl = mixer_get_ctl_by_name(mixer, "OUT MIXL DAC L1 Switch");
        mixer_ctl_set_value(ctl,0,1);
        ctl = mixer_get_ctl_by_name(mixer, "Stereo DAC MIXR DAC R1 Switch");
        mixer_ctl_set_value(ctl,0,1);
        ctl = mixer_get_ctl_by_name(mixer, "Stereo DAC MIXL DAC L1 Switch");
        mixer_ctl_set_value(ctl,0,1);

        mixer_close(mixer);
    }
#endif
    return 0;
}
Exemplo n.º 25
0
bool HDMIAudioCaps::loadCaps(int ALSADeviceID) {
    bool ret = false;
    struct mixer* mixer = NULL;
    struct mixer_ctl* ctrls[kCtrlCount] = {NULL};
    int tmp, mode_cnt;
    Mutex::Autolock _l(mLock);

    ALOGE("%s: start", __func__);

    reset_l();

    // Open the mixer for the chosen ALSA device
    if (NULL == (mixer = mixer_open(ALSADeviceID))) {
        ALOGE("%s: mixer_open(%d) failed", __func__, ALSADeviceID);
        goto bailout;
    }

    // Gather handles to all of the controls we will need in order to enumerate
    // the audio capabilities of this HDMI link.  No need to free/release these
    // later, they are just pointers into the tinyalsa mixer structure itself.
    for (size_t i = 0; i < kCtrlCount; ++i) {
        ctrls[i] = mixer_get_ctl_by_name(mixer, kCtrlNames[i]);
        if (NULL == ctrls[i]) {
            ALOGE("%s: mixer_get_ctrl_by_name(%s) failed", __func__, kCtrlNames[i]);
            goto bailout;
	}
    }

    // Start by checking to see if this HDMI connection supports even basic
    // audio.  If it does not, there is no point in proceeding.
    if ((tmp = mixer_ctl_get_value(ctrls[kBasicAudNdx], 0)) <= 0) {
        ALOGI("%s: Basic audio not supported by attached device", __func__);
        goto bailout;
    }

    // Looks like we support basic audio.  Get a count of the available
    // non-basic modes.
    mBasicAudioSupported = true;
    if ((mode_cnt = mixer_ctl_get_value(ctrls[kModeCntNdx], 0)) < 0)
        goto bailout;

    // Fetch the speaker allocation data block, if available.
    if ((tmp = mixer_ctl_get_value(ctrls[kSpeakerAlloc], 0)) < 0)
        goto bailout;
    mSpeakerAlloc = static_cast<uint16_t>(tmp);
    ALOGI("%s: Speaker Allocation Map for attached device is: 0x%hx", __func__, mSpeakerAlloc);

    // If there are no non-basic modes available, then we are done.  Be sure to
    // flag this as a successful operation.
    if (!mode_cnt) {
        ret = true;
        goto bailout;
    }

    // Now enumerate the non-basic modes.  Any errors at this point in time
    // should indicate that the HDMI cable was unplugged and we should just
    // abort with an empty set of audio capabilities.
    for (int i = 0; i < mode_cnt; ++i) {
        Mode m;

        // Pick the mode we want to fetch info for.
        if (mixer_ctl_set_value(ctrls[kModeSelNdx], 0, i) < 0)
            goto bailout;

        // Now fetch the common fields.
        if ((tmp = mixer_ctl_get_value(ctrls[kFmtNdx], 0)) < 0)
            goto bailout;
        m.fmt = static_cast<AudFormat>(tmp);
        ALOGI("Got mode %d from ALSA driver.", m.fmt);

        if ((tmp = mixer_ctl_get_value(ctrls[kMaxChCntNdx], 0)) < 0)
            goto bailout;
        m.max_ch = static_cast<uint32_t>(tmp);

        if ((tmp = mixer_ctl_get_value(ctrls[kSampRateNdx], 0)) < 0)
            goto bailout;
        m.sr_bitmask = static_cast<uint32_t>(tmp);

        // Now for the mode dependent fields.  Only LPCM has the bits-per-sample
        // mask.  Only AC3 through ATRAC have the compressed bitrate field.
        m.bps_bitmask = 0;
        m.comp_bitrate = 0;

        if (m.fmt == kFmtLPCM) {
            if ((tmp = mixer_ctl_get_value(ctrls[kBPSNdx], 0)) < 0)
                goto bailout;
            m.bps_bitmask = static_cast<uint32_t>(tmp);
        } else if ((m.fmt >= kFmtAC3) && (m.fmt <= kFmtATRAC)) { // FIXME ATRAC is not last format!?
            if ((tmp = mixer_ctl_get_value(ctrls[kMaxCompBRNdx], 0)) < 0)
                goto bailout;
            m.comp_bitrate = static_cast<uint32_t>(tmp);
        }

        // Finally, sanity check the info.  If it passes, add it to the vector
        // of available modes.
        if (sanityCheckMode(m))  {
            ALOGI("Passed sanity check for mode %d from ALSA driver.", m.fmt);
            mModes.add(m);
        }
    }

    // Looks like we managed to enumerate all of the modes before someone
    // unplugged the HDMI cable.  Signal success and get out.
    ret = true;

bailout:
    if (NULL != mixer)
        mixer_close(mixer);

    if (!ret)
        reset_l();

    return ret;
}
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int ctl_index;
    struct mixer_ctl *ctl;
    int value;
    unsigned int id;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(ar, state->path, sub_path);
            }
        }
    }

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        if (ctl == NULL) {
            ALOGE("Control '%s' doesn't exist - skipping", attr_name);
            goto done;
        }

        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
            value = atoi((char *)attr_value);
            break;
        case MIXER_CTL_TYPE_ENUM:
            value = mixer_enum_string_to_value(ctl, (char *)attr_value);
            break;
        default:
            value = 0;
            break;
        }

        /* locate the mixer ctl in the list */
        for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) {
            if (ar->mixer_state[ctl_index].ctl == ctl)
                break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* apply the new value */
            if (attr_id) {
                /* set only one value */
                id = atoi((char *)attr_id);
                if (id < ar->mixer_state[ctl_index].num_values)
                    ar->mixer_state[ctl_index].new_value[id] = value;
                else
                    ALOGE("value id out of range for mixer ctl '%s'",
                          mixer_ctl_get_name(ctl));
            } else {
                /* set all values the same */
                for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++)
                    ar->mixer_state[ctl_index].new_value[i] = value;
            }
        } else {
            /* nested ctl (within a path) */
            mixer_value.ctl_index = ctl_index;
            mixer_value.value = value;
            if (attr_id)
                mixer_value.index = atoi((char *)attr_id);
            else
                mixer_value.index = -1;
            path_add_value(ar, state->path, &mixer_value);
        }
    }

done:
    state->level++;
}
Exemplo n.º 27
0
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;
    int ret;
    char *buf = NULL;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
        buf = calloc(1, num_values);
        if (buf == NULL) {
            fprintf(stderr, "Failed to alloc mem for bytes %d\n", num_values);
            return;
        }

        ret = mixer_ctl_get_array(ctl, buf, num_values);
        if (ret < 0) {
            fprintf(stderr, "Failed to mixer_ctl_get_array\n");
            free(buf);
            return;
        }
    }

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
        case MIXER_CTL_TYPE_BYTE:
            printf("%02x", buf[i]);
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }

    free(buf);

    printf("\n");
}
bool TinyAmixerControl::accessHW(bool receive, std::string &error)
{
    CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled());

    // Mixer handle
    struct mixer *mixer;
    // Mixer control handle
    struct mixer_ctl *mixerControl;
    uint32_t elementCount;
    std::string controlName = getControlName();

    // Debug conditionnaly enabled in XML
    logControlInfo(receive);

    // Check parameter type is ok (deferred error, no exceptions available :-()
    if (!isTypeSupported()) {

        error = "Parameter type not supported.";
        return false;
    }

    // Check card number
    int32_t cardIndex = getCardNumber();
    if (cardIndex < 0) {

        error = "Card " + getCardName() + " not found. Error: " + strerror(-cardIndex);
        return false;
    }

    // Open alsa mixer
    // getMixerHandle is non-const; we need to forcefully remove the constness
    // then, we need to cast the generic subsystem into a TinyAlsaSubsystem.
    mixer = static_cast<TinyAlsaSubsystem *>(
        const_cast<CSubsystem *>(getSubsystem()))->getMixerHandle(cardIndex);

    if (!mixer) {

        error = "Failed to open mixer for card: " + getCardName();
        return false;
    }

    // Get control handle
    if (isdigit(controlName[0])) {

        mixerControl = mixer_get_ctl(mixer, asInteger(controlName));
    } else {

        mixerControl = mixer_get_ctl_by_name(mixer, controlName.c_str());
    }

    // Check control has been found
    if (!mixerControl) {
        error = "Failed to open mixer control: " + controlName;

        return false;
    }

    // Get element count
    elementCount = getNumValues(mixerControl);

    uint32_t scalarSize = getScalarSize();

    // Check available size
    if (elementCount * scalarSize != getSize()) {

        error = "ALSA: Control element count (" + asString(elementCount) +
                ") and configurable scalar element count (" +
                asString(getSize() / scalarSize) + ") mismatch";

        return false;
    }

    // Read/Write element
    bool success;
    if (receive) {

        success = readControl(mixerControl, elementCount, error);

    } else {

        success = writeControl(mixerControl, elementCount, error);

    }

    return success;
}
Exemplo n.º 29
0
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_value = NULL;
    const XML_Char *attr_ignore = NULL;
	char *sub_attr_value;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int j;
    unsigned int k;
    struct mixer_ctl *ctl;
    int values[MAX_CTL_VALS];
	unsigned int num_values;
	unsigned int num_ctl_vals;
    struct mixer_setting mixer_setting;
	unsigned ignored = 0;

    /* Get name, type and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
        else if (strcmp(attr[i], "ignore") == 0)
            attr_ignore = attr[i + 1];
    }

	if (attr_ignore && strcmp(attr_ignore, "1") == 0) {
		ignored = 1;
	}

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(state->path, sub_path);
            }
        }
    }

	else if (strcmp(tag_name, "ctl") == 0 && state->level == 1 && ignored) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);

		/* locate the mixer ctl in the list */
		for (i = 0; i < ar->num_mixer_ctls; i++) {
			if (ar->mixer_state[i].ctl == ctl)
				break;
		}
        ar->mixer_state[i].ignored = 1;
	}

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
			/* TODO */
			num_values = 1;
			char *sub_attr_value;
			for (j = 0; j < strlen((char*)attr_value); j++) {
				if (attr_value[j] == ',') num_values++;
			}
			sub_attr_value = (char*)attr_value;
			k = strlen((char*)attr_value);
			for (j = 0; j < k; j++) {
				if (sub_attr_value[j] == ',') sub_attr_value[j] = '\0';
			}
			sub_attr_value = (char*)attr_value;
			for (j = 0; j < num_values; j++) {
            	values[j] = atoi(sub_attr_value);
#if 1
				ALOGV("attr='%s' idx=%u str='%s' val=%d", attr_name, j,
						sub_attr_value, values[j]);
#endif
				sub_attr_value += (strlen(sub_attr_value) + 1);
			}
            break;
        case MIXER_CTL_TYPE_ENUM:
			num_values = 1;
            values[0] = mixer_enum_string_to_value(ctl, (char *)attr_value);
			ALOGV("attr='%s' attr_val='%s' val=%d", attr_name, attr_value, values[0]);
            break;
        default:
			num_values = 1;
            values[0] = 0;
			ALOGV("attr='%s' UNKNOWN CTL TYPE", attr_name);
            break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* locate the mixer ctl in the list */
            for (i = 0; i < ar->num_mixer_ctls; i++) {
                if (ar->mixer_state[i].ctl == ctl)
                    break;
            }

            /* apply the new value */
            ar->mixer_state[i].ignored = 0;
            ar->mixer_state[i].ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	ar->mixer_state[i].new_value[j] = values[j];
			}
        } else {
            /* nested ctl (within a path) */
            mixer_setting.ctl = ctl;
            mixer_setting.ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	mixer_setting.value[j] = values[j];
			}
            path_add_setting(state->path, &mixer_setting);
        }
    }

    state->level++;
}
Exemplo n.º 30
0
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;
    int ret;
    char buf[512] = { 0 };
    size_t len;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (type == MIXER_CTL_TYPE_BYTE) {
        len = num_values;
        if (len > sizeof(buf)) {
            fprintf(stderr, "Truncating get to %zu bytes\n", sizeof(buf));
            len = sizeof(buf);
        }
        ret = mixer_ctl_get_array(ctl, buf, len);
        if (ret < 0) {
            fprintf(stderr, "Failed to mixer_ctl_get_array\n");
            return;
        }
    }

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
        case MIXER_CTL_TYPE_BYTE:
            printf("%02x", buf[i]);
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }
    printf("\n");
}