Exemple #1
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;
}
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;
}
Exemple #3
0
bool
audio_set_volume(audio_t *audio, unsigned volume)
{
    struct mixer *mixer;
    bool res;

    mixer = mixer_open(audio->dev.card);
    if (! mixer) {
	fprintf(stderr, "Failed to open mixer\n");
	return false;
    }

    if (audio->dev.playback) {
        res = do_set_volume(mixer, "PCM Playback Volume", volume) ||
	      mixer_set(mixer, "PCM Playback Route", 1);
    } else {
        res = do_set_volume(mixer, "Mic Capture Volume", volume) ||
	      mixer_set(mixer, "Mic Capture Switch", 1) ||
	      mixer_set(mixer, "Speaker Playback Switch", 0) ||
	      mixer_set(mixer, "Mic Playback Switch", 0);
    }

    mixer_close(mixer);

    return res;
}
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
}
TinyAudioHardware::~TinyAudioHardware()
{
    closeOutputStream((AudioStreamOut *)mOutput);
    closeInputStream((AudioStreamIn *)mInput);
    if (mMixer)
	mixer_close(mMixer);
}
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;
}
Exemple #7
0
struct mixer *mixer_open(unsigned int card)
{
    struct mixer *mixer = NULL;
    int fd;
    char fn[256];

    snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
    fd = open(fn, O_RDWR);
    if (fd < 0)
        return 0;

    mixer = calloc(1, sizeof(*mixer));
    if (!mixer)
        goto fail;

    if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
        goto fail;

    mixer->fd = fd;

    if (add_controls(mixer) != 0)
        goto fail;

    return mixer;

fail:
    if (mixer)
        mixer_close(mixer);
    else if (fd >= 0)
        close(fd);
    return NULL;
}
TinyAlsaSubsystem::~TinyAlsaSubsystem()
{
    MixerMap::const_iterator it;

    for (it = mMixers.begin(); it != mMixers.end(); ++it) {
        mixer_close(it->second);
    }
}
void audio_route_free(struct audio_route *ar)
{
    free_mixer_state(ar);
    mixer_close(ar->mixer);
    path_free(ar);
    free(ar);
    ar = NULL;
}
TEST(pcmtest, CheckMixerDevices) {
    struct mixer *mixer;
    for (unsigned int i = 0; i < mixers; i++) {
         mixer = mixer_open(i);
         EXPECT_TRUE(mixer != NULL);
         if (mixer)
             mixer_close(mixer);
    }
}
Exemple #11
0
void audio_route_free(struct audio_route *ar)
{
    if (!ar) {
		ALOGE("%s: invalid audio_route", __func__);
        return;
    }
    free_mixer_state(ar);
    mixer_close(ar->mixer);
    free(ar);
}
/*
 * Parse the audio configuration file.
 * The file is named audio_conf.txt and must begin with the following header:
 *
 * card=<ALSA card number>
 * device=<ALSA device number>
 * period_size=<period size>
 * period_count=<period count>
 *
 * This header is followed by zero or more mixer settings, each with the format:
 * mixer "<name>" = <value list>
 * Since mixer names can contain spaces, the name must be enclosed in double quotes.
 * The values in the value list can be integers, booleans (represented by 0 or 1)
 * or strings for enum values.
 */
bool AudioPlayer::init(const char* config)
{
    int tempInt;
    struct mixer* mixer = NULL;
    char    name[MAX_LINE_LENGTH];

    for (;;) {
        const char* endl = strstr(config, "\n");
        if (!endl) break;
        String8 line(config, endl - config);
        if (line.length() >= MAX_LINE_LENGTH) {
            ALOGE("Line too long in audio_conf.txt");
            return false;
        }
        const char* l = line.string();

        if (sscanf(l, "card=%d", &tempInt) == 1) {
            ALOGD("card=%d", tempInt);
            mCard = tempInt;

            mixer = mixer_open(mCard);
            if (!mixer) {
                ALOGE("could not open mixer for card %d", mCard);
                return false;
            }
        } else if (sscanf(l, "device=%d", &tempInt) == 1) {
            ALOGD("device=%d", tempInt);
            mDevice = tempInt;
        } else if (sscanf(l, "period_size=%d", &tempInt) == 1) {
            ALOGD("period_size=%d", tempInt);
            mPeriodSize = tempInt;
        } else if (sscanf(l, "period_count=%d", &tempInt) == 1) {
            ALOGD("period_count=%d", tempInt);
            mPeriodCount = tempInt;
        } else if (sscanf(l, "mixer \"%[0-9a-zA-Z _]s\"", name) == 1) {
            const char* values = strchr(l, '=');
            if (values) {
                values++;   // skip '='
                ALOGD("name: \"%s\" = %s", name, values);
                setMixerValue(mixer, name, values);
            } else {
                ALOGE("values missing for name: \"%s\"", name);
            }
        }
        config = ++endl;
    }

    mixer_close(mixer);

    if (mCard >= 0 && mDevice >= 0) {
        return true;
    }

    return false;
}
int SetAudio_pga_parameter_eng(AUDIO_TOTAL_T *aud_params_ptr, unsigned int params_size, uint32_t vol_level)
{
    int ret = 0;
    int card_id;
    pga_gain_nv_t pga_gain_nv;
    struct mixer *mixer;
    struct audio_pga *pga;
    memset(&pga_gain_nv,0,sizeof(pga_gain_nv_t));

    if (sizeof(AUDIO_TOTAL_T) != params_size) {
        ALOGE("%s, Error: params_size = %d, total size = %d", __func__,params_size, sizeof(AUDIO_TOTAL_T));
        return -1;
    }
    ret = GetAudio_pga_nv(aud_params_ptr,&pga_gain_nv,vol_level);
    if(ret < 0){
        return -1;
    }
    card_id = get_snd_card_number(CARD_SPRDPHONE);
    ALOGW("%s card_id = %d", __func__,card_id);
    if (card_id < 0)
        return -1;
    mixer = mixer_open(card_id);
    if (!mixer) {
        ALOGE("%s Failed to open mixer",__func__);
        return -1;
    }
    pga = audio_pga_init(mixer);
    if (!pga) {
        mixer_close(mixer);
        ALOGE("%s Warning: Unable to locate PGA from XML.",__func__);
        return -1;
    }
    ret = SetAudio_gain_4eng(pga,&pga_gain_nv,aud_params_ptr);
    if(ret < 0){
        mixer_close(mixer);
        return -1;
    }
    mixer_close(mixer);
    return 0;
}
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;
}
int main(int argc, G_GNUC_UNUSED char **argv)
{
	GError *error = NULL;
	struct mixer *mixer;
	bool success;
	int volume;

	if (argc != 2) {
		g_printerr("Usage: read_mixer PLUGIN\n");
		return 1;
	}

	g_thread_init(NULL);

	mixer = mixer_new(&alsa_mixer_plugin, NULL, NULL, &error);
	if (mixer == NULL) {
		g_printerr("mixer_new() failed: %s\n", error->message);
		g_error_free(error);
		return 2;
	}

	success = mixer_open(mixer, &error);
	if (!success) {
		mixer_free(mixer);
		g_printerr("failed to open the mixer: %s\n", error->message);
		g_error_free(error);
		return 2;
	}

	volume = mixer_get_volume(mixer, &error);
	mixer_close(mixer);
	mixer_free(mixer);

	assert(volume >= -1 && volume <= 100);

	if (volume < 0) {
		if (error != NULL) {
			g_printerr("failed to read volume: %s\n",
				   error->message);
			g_error_free(error);
		} else
			g_printerr("failed to read volume\n");
		return 2;
	}

	g_print("%d\n", volume);
	return 0;
}
Exemple #16
0
size_t
alsavol(char *dest, size_t n)
{
	size_t ret;
	struct mixer *mx;

	if (!(mx = mixer_open(sndcrd)))
		die("couldn't open mixer for card %d\n", sndcrd);

	ret = actlstr(dest, n, (char*)swtchname, mx);
	if (strcmp(dest, "Off"))
		ret = actlstr(dest, n, (char*)volumname, mx);

	mixer_close(mx);
	return ret;
}
int audio_route_control_set_enum(unsigned int card_slot, char *control_name,
                                 char *string)
{
    struct mixer *control_mixer;
    struct mixer_ctl *ctl;
    const char *name;
    unsigned int num_ctls, num_values;
    unsigned int i, j;
    enum mixer_ctl_type type;
    int value;
    int ret, mixer_ret;

    control_mixer = mixer_open(card_slot);
    if (!control_mixer) {
        ALOGE("Unable to open the control mixer, aborting.");
        return -1;
    }
    ALOGV("Control mixer open successful.");

    num_ctls = mixer_get_num_ctls(control_mixer);

    ret = 0;
    for (i = 0; i < num_ctls; i++) {
        ctl = mixer_get_ctl(control_mixer, i);
        name = mixer_ctl_get_name(ctl);
        if (name && strcmp(name, control_name) == 0) {
            /* Found the control, update and exit */
            type = mixer_ctl_get_type(ctl);
            if (type == MIXER_CTL_TYPE_ENUM) {
                if (mixer_ctl_set_enum_by_string(ctl, string)) {
                    ALOGE("Error: invalid enum value");
                    ret = -1;
                } else {
                    ALOGV("Setting %s to string %s", name, string);
                }
            } else {
                ALOGV("Error: only enum types can be set with strings");
                ret = -1;
            }
            break;
        }
    }

    mixer_close(control_mixer);
    return ret;
}
int audio_route_control_set_number(unsigned int card_slot, char *control_name,
                                   char *string)
{
    struct mixer *control_mixer;
    struct mixer_ctl *ctl;
    const char *name;
    unsigned int num_ctls, num_values;
    unsigned int i, j;
    enum mixer_ctl_type type;
    int value;
    int ret, mixer_ret;

    control_mixer = mixer_open(card_slot);
    if (!control_mixer) {
        ALOGE("Unable to open the control mixer, aborting.");
        return -1;
    }
    ALOGV("Control mixer open successful.");

    num_ctls = mixer_get_num_ctls(control_mixer);

    ret = 0;
    for (i = 0; i < num_ctls; i++) {
        ctl = mixer_get_ctl(control_mixer, i);
        name = mixer_ctl_get_name(ctl);
        if (name && strcmp(name, control_name) == 0) {
            /* Found the control, update and exit */
            value = atoi(string);
            num_values = mixer_ctl_get_num_values(ctl);
            for (j = 0; j < num_values; j++) {
                mixer_ret = mixer_ctl_set_value(ctl, j, value);
                if (mixer_ret) {
                    ALOGE("Error: invalid value (%s to %d)", name, value);
                    mixer_close(control_mixer);
                    /* Add up the number of failed controller values */
                    ret += -1;
                }
            }
            if (ret == 0)
                ALOGV("Setting %s to int %d", name, value);
            break;
        }
    }

    return ret;
}
void send_channel_map_driver(struct pcm *pcm)
{
    int i, ret;
    struct mixer *mixer;
    const char* device = "/dev/snd/controlC0";

    mixer = mixer_open(device);
    if (!mixer) {
        fprintf(stderr,"oops: %s: %d\n", strerror(errno), __LINE__);
        return;
    }
    ret = pcm_set_channel_map(pcm, mixer, 8, channel_map);
    if (ret < 0)
        fprintf(stderr, "could not set channel mask\n");
    mixer_close(mixer);

    return;
}
TEST_F(MixerTest, tryTinyAlsaTest) {
    int hwId = AudioHardware::detectAudioHw();
    ASSERT_TRUE(hwId >= 0);
    struct mixer* mixerp = mixer_open(hwId);
    ASSERT_TRUE(mixerp != NULL);
    int num_ctls = mixer_get_num_ctls(mixerp);
    LOGI("Number of mixel control %d", num_ctls);
    for (int i = 0; i < num_ctls; i++) {
        struct mixer_ctl* control = mixer_get_ctl(mixerp, i);
        ASSERT_TRUE(control != NULL);
        LOGI("Mixer control %s type %s value %d", mixer_ctl_get_name(control),
                mixer_ctl_get_type_string(control), mixer_ctl_get_num_values(control));
        free(control);
    }
    // no mixer control for MobilePre. If this assumption fails,
    // mixer control should be added.
    ASSERT_TRUE(num_ctls == 0);
    mixer_close(mixerp);
}
static int loop_test(void)
{
	struct mixer *mixer;
	int card = 0;
	mixer = mixer_open(card);
	if (!mixer) {
		fprintf(stderr, "Failed to open mixer\n");
		return EXIT_FAILURE;
	}
	tinymix_set_value(mixer, 92, 1);
	tinymix_set_value(mixer, 93, 1);
	tinymix_set_value(mixer, 95, 1);
	tinymix_set_value(mixer, 100, 1);
	tinymix_set_value(mixer, 0, 60);
	tinymix_set_value(mixer, 34,7);
	tinymix_set_value(mixer, 18,7);
	mixer_close(mixer);
	return 0;
}
static int  exit_loop_mode()
{
	struct mixer *mixer;
	int card = 0;
	mixer = mixer_open(card);
	if (!mixer) {
		fprintf(stderr, "Failed to open mixer\n");
		return EXIT_FAILURE;
	}
	tinymix_set_value(mixer, 92, 0);
	tinymix_set_value(mixer, 93, 0);
	tinymix_set_value(mixer, 95, 0);
	tinymix_set_value(mixer, 100, 0);
	mixer_close(mixer);
	if(writeline("AT+ECHO1OFF")){
		return -1;
	}
	return 0;
}
Exemple #23
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;
}
static void do_mixer_settings(FILE *file) {

    struct mixer *mixer;
    char buf[256], *name, *value;

    mixer = mixer_open(0);
    if(!mixer) {
        log_info("cannot open mixer");
        return;
    }
    log_info("processing mixer settings from %s", alsa_config_file);
    while(fgets(buf, sizeof(buf),file)) {
	if(parse_config_line(buf, &name, &value)) {
	   log_info("%s -> %s", name, value);
           tinymix_set_value(mixer, name, value);
	}
    }
    mixer_close(mixer);
    log_info("mixer settings processed");
}
Exemple #25
0
int main(int argc, char **argv)
{
    struct mixer *mixer;
    int card = 0;

    if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
        argv++;
        if (argv[1]) {
            card = atoi(argv[1]);
            argv++;
            argc -= 2;
        } else {
            argc -= 1;
        }
    }

    mixer = mixer_open(card);
    if (!mixer) {
        fprintf(stderr, "Failed to open mixer\n");
        return EXIT_FAILURE;
    }


    if (argc == 1) {
        printf("Mixer name: '%s'\n", mixer_get_name(mixer));
        tinymix_list_controls(mixer);
    } else if (argc == 2) {
        tinymix_detail_control(mixer, argv[1], 1);
    } else if (argc >= 3) {
        tinymix_set_value(mixer, argv[1], &argv[2], argc - 2);
    } else {
        printf("Usage: tinymix [-D card] [control id] [value to set]\n");
    }

    mixer_close(mixer);

    return 0;
}
int main(int argc, char **argv)
{
    struct mixer *mixer;

    mixer = mixer_open(0);
    if (!mixer) {
        fprintf(stderr, "Failed to open mixer\n");
        return EXIT_FAILURE;
    }

    if (argc == 1)
        tinymix_list_controls(mixer);
    else if (argc == 2)
        tinymix_detail_control(mixer, atoi(argv[1]), 1);
    else if (argc == 3)
        tinymix_set_value(mixer, atoi(argv[1]), argv[2]);
    else
        printf("Usage: tinymix [control id] [value to set]\n");

    mixer_close(mixer);

    return 0;
}
Exemple #27
0
/** Opens a mixer for a given card.
 * @param card The card to open the mixer for.
 * @returns An initialized mixer handle.
 * @ingroup libtinyalsa-mixer
 */
struct mixer *mixer_open(unsigned int card)
{
    struct snd_ctl_elem_list elist;
    struct snd_ctl_elem_id *eid = NULL;
    struct mixer *mixer = NULL;
    unsigned int n;
    int fd;
    char fn[256];

    snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
    fd = open(fn, O_RDWR);
    if (fd < 0)
        return 0;

    memset(&elist, 0, sizeof(elist));
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
        goto fail;

    mixer = calloc(1, sizeof(*mixer));
    if (!mixer)
        goto fail;

    mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
    if (!mixer->ctl)
        goto fail;

    if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
        goto fail;

    eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
    if (!eid)
        goto fail;

    mixer->count = elist.count;
    mixer->fd = fd;
    elist.space = mixer->count;
    elist.pids = eid;
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
        goto fail;

    for (n = 0; n < mixer->count; n++) {
        struct snd_ctl_elem_info *ei = &mixer->ctl[n].info;
        ei->id.numid = eid[n].numid;
        if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
            goto fail;
        mixer->ctl[n].mixer = mixer;
    }

    free(eid);
    return mixer;

fail:
    /* TODO: verify frees in failure case */
    if (eid)
        free(eid);
    if (mixer)
        mixer_close(mixer);
    else if (fd >= 0)
        close(fd);
    return 0;
}
Exemple #28
0
struct audio_route *audio_route_init(void)
{
    struct config_parse_state state;
    XML_Parser parser;
    FILE *file;
    int bytes_read;
    void *buf;
    int i;
    struct mixer_path *path;
    struct audio_route *ar;

    ar = calloc(1, sizeof(struct audio_route));
    if (!ar)
        goto err_calloc;

    ar->mixer = mixer_open(MIXER_CARD);
    if (!ar->mixer) {
        ALOGE("Unable to open the mixer, aborting.");
        goto err_mixer_open;
    }

    ar->mixer_path = NULL;
    ar->mixer_path_size = 0;
    ar->num_mixer_paths = 0;

    /* allocate space for and read current mixer settings */
    if (alloc_mixer_state(ar) < 0)
        goto err_mixer_state;

    file = fopen(MIXER_XML_PATH, "r");
    if (!file) {
        ALOGE("Failed to open %s", MIXER_XML_PATH);
        goto err_fopen;
    }

    parser = XML_ParserCreate(NULL);
    if (!parser) {
        ALOGE("Failed to create XML parser");
        goto err_parser_create;
    }

    memset(&state, 0, sizeof(state));
    state.ar = ar;
    XML_SetUserData(parser, &state);
    XML_SetElementHandler(parser, start_tag, end_tag);

    for (;;) {
        buf = XML_GetBuffer(parser, BUF_SIZE);
        if (buf == NULL)
            goto err_parse;

        bytes_read = fread(buf, 1, BUF_SIZE, file);
        if (bytes_read < 0)
            goto err_parse;

        if (XML_ParseBuffer(parser, bytes_read,
                            bytes_read == 0) == XML_STATUS_ERROR) {
            ALOGE("Error in mixer xml (%s)", MIXER_XML_PATH);
            goto err_parse;
        }

        if (bytes_read == 0)
            break;
    }

	audio_route_apply_path(ar, "init");

    /* apply the initial mixer values, and save them so we can reset the
       mixer to the original values */
    update_mixer_state(ar);
    save_mixer_state(ar);

    XML_ParserFree(parser);
    fclose(file);
    return ar;

err_parse:
    XML_ParserFree(parser);
err_parser_create:
    fclose(file);
err_fopen:
    free_mixer_state(ar);
err_mixer_state:
    mixer_close(ar->mixer);
err_mixer_open:
    free(ar);
    ar = NULL;
err_calloc:
    return NULL;
}
struct mixer *mixer_open(const char *device)
{
    struct snd_ctl_elem_list elist;
    struct snd_ctl_elem_info tmp;
    struct snd_ctl_elem_id *eid = NULL;
    struct mixer *mixer = NULL;
    unsigned n, m;
    int fd;

    fd = open(device, O_RDWR);
    if (fd < 0) {
        ALOGE("Control open failed\n");
        return 0;
    }

    memset(&elist, 0, sizeof(elist));
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0) {
        ALOGE("SNDRV_CTL_IOCTL_ELEM_LIST failed\n");
        goto fail;
    }

    mixer = calloc(1, sizeof(*mixer));
    if (!mixer)
        goto fail;

    mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
    mixer->info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
    if (!mixer->ctl || !mixer->info)
        goto fail;

    eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
    if (!eid)
        goto fail;

    mixer->count = elist.count;
    mixer->fd = fd;
    elist.space = mixer->count;
    elist.pids = eid;
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
        goto fail;

    for (n = 0; n < mixer->count; n++) {
        struct snd_ctl_elem_info *ei = mixer->info + n;
        ei->id.numid = eid[n].numid;
        if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
            goto fail;
        mixer->ctl[n].info = ei;
        mixer->ctl[n].mixer = mixer;
        if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
            char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
            if (!enames)
                goto fail;
            mixer->ctl[n].ename = enames;
            for (m = 0; m < ei->value.enumerated.items; m++) {
                memset(&tmp, 0, sizeof(tmp));
                tmp.id.numid = ei->id.numid;
                tmp.value.enumerated.item = m;
                if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
                    goto fail;
                enames[m] = strdup(tmp.value.enumerated.name);
                if (!enames[m])
                    goto fail;
            }
        }
    }

    free(eid);
    return mixer;

fail:
    if (eid)
        free(eid);
    if (mixer)
        mixer_close(mixer);
    else if (fd >= 0)
        close(fd);
    return 0;
}
Exemple #30
0
struct mixer *mixer_open(unsigned int card)
{
    struct snd_ctl_elem_list elist;
    struct snd_ctl_elem_info tmp;
    struct snd_ctl_elem_id *eid = NULL;
    struct mixer *mixer = NULL;
    unsigned int n, m;
    int fd;
    char fn[256];

    snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
    fd = open(fn, O_RDWR);
    if (fd < 0)
        return 0;

    memset(&elist, 0, sizeof(elist));
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
        goto fail;

    mixer = calloc(1, sizeof(*mixer));
    if (!mixer)
        goto fail;

    mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
    mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
    if (!mixer->ctl || !mixer->elem_info)
        goto fail;

    if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
        goto fail;

    eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
    if (!eid)
        goto fail;

    mixer->count = elist.count;
    mixer->fd = fd;
    elist.space = mixer->count;
    elist.pids = eid;
    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
        goto fail;

    for (n = 0; n < mixer->count; n++) {
        struct snd_ctl_elem_info *ei = mixer->elem_info + n;
        ei->id.numid = eid[n].numid;
        if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
            goto fail;
        mixer->ctl[n].info = ei;
        mixer->ctl[n].mixer = mixer;
        if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
            char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
            if (!enames)
                goto fail;
            mixer->ctl[n].ename = enames;
            for (m = 0; m < ei->value.enumerated.items; m++) {
                memset(&tmp, 0, sizeof(tmp));
                tmp.id.numid = ei->id.numid;
                tmp.value.enumerated.item = m;
                if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
                    goto fail;
                enames[m] = strdup(tmp.value.enumerated.name);
                if (!enames[m])
                    goto fail;
            }
        }
    }

    free(eid);
    return mixer;

fail:
    /* TODO: verify frees in failure case */
    if (eid)
        free(eid);
    if (mixer)
        mixer_close(mixer);
    else if (fd >= 0)
        close(fd);
    return 0;
}