diff options
-rw-r--r-- | tinyalsa_audio/Android.mk | 59 | ||||
-rw-r--r-- | tinyalsa_audio/audio_hw.c | 516 | ||||
-rw-r--r-- | tinyalsa_audio/audio_hw.h | 119 | ||||
-rw-r--r-- | tinyalsa_audio/audio_in.c | 812 | ||||
-rw-r--r-- | tinyalsa_audio/audio_out.c | 747 | ||||
-rw-r--r-- | tinyalsa_audio/audio_ril_interface.c | 375 | ||||
-rw-r--r-- | tinyalsa_audio/audio_ril_interface.h | 102 | ||||
-rw-r--r-- | tinyalsa_audio/mixer.c | 1349 | ||||
-rw-r--r-- | tinyalsa_audio/mixer.h | 125 |
9 files changed, 0 insertions, 4204 deletions
diff --git a/tinyalsa_audio/Android.mk b/tinyalsa_audio/Android.mk deleted file mode 100644 index 55b4bda..0000000 --- a/tinyalsa_audio/Android.mk +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -LOCAL_PATH := $(call my-dir) - -ifeq ($(strip $(BOARD_USE_TINYALSA_AUDIO)),true) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - audio_hw.c \ - audio_out.c \ - audio_in.c \ - audio_ril_interface.c \ - mixer.c - -LOCAL_C_INCLUDES += \ - external/tinyalsa/include \ - external/expat/lib \ - system/media/audio_utils/include \ - system/media/audio_effects/include \ - hardware/tinyalsa-audio/include - -LOCAL_SHARED_LIBRARIES := \ - libc \ - libcutils \ - libutils \ - libexpat \ - libtinyalsa \ - libaudioutils \ - libdl - -ifeq ($(strip $(BOARD_USE_YAMAHA_MC1N2_AUDIO)),true) - LOCAL_CFLAGS += -DYAMAHA_MC1N2_AUDIO -DYAMAHA_MC1N2_AUDIO_DEVICE=\"galaxys2\" - LOCAL_C_INCLUDES += $(LOCAL_PATH)/../yamaha-mc1n2-audio/include - LOCAL_SHARED_LIBRARIES += libyamaha-mc1n2-audio -endif - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM) -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw - -include $(BUILD_SHARED_LIBRARY) - -endif diff --git a/tinyalsa_audio/audio_hw.c b/tinyalsa_audio/audio_hw.c deleted file mode 100644 index bb219e1..0000000 --- a/tinyalsa_audio/audio_hw.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This is based on Galaxy Nexus audio.primary.tuna implementation: - * Copyright 2011, The Android Open-Source Project - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define LOG_TAG "TinyALSA-Audio Hardware" - -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <sys/time.h> - -#include <cutils/str_parms.h> -#include <cutils/log.h> - -#ifdef YAMAHA_MC1N2_AUDIO -#include <yamaha-mc1n2-audio.h> -#endif - -#include "audio_hw.h" -#include "mixer.h" - -/* - * Functions - */ - -static int audio_hw_init_check(const struct audio_hw_device *dev) -{ - struct tinyalsa_audio_device *device; - - ALOGD("%s(%p)", __func__, dev); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - return 0; -} - -static int audio_hw_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - struct tinyalsa_audio_device *device; - audio_devices_t device_modem; - - ALOGD("%s(%p, %f)++", __func__, dev, volume); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - if(volume != device->voice_volume) { - pthread_mutex_lock(&device->lock); - - if(device->mode == AUDIO_MODE_IN_CALL) { - if(device->ril_interface != NULL) - device_modem = device->ril_interface->device_current; - else if(device->stream_out != NULL) - device_modem = device->stream_out->device_current; - else - device_modem = AUDIO_DEVICE_OUT_EARPIECE; - - tinyalsa_mixer_set_voice_volume(device->mixer, - device_modem, volume); - - if(device->ril_interface != NULL) - audio_ril_interface_set_voice_volume(device->ril_interface, device_modem, volume); - } - - device->voice_volume = volume; - - pthread_mutex_unlock(&device->lock); - } - - ALOGD("%s(%p, %f)--", __func__, dev, volume); - - return 0; -} - -static int audio_hw_set_master_volume(struct audio_hw_device *dev, float volume) -{ - struct tinyalsa_audio_device *device; - - ALOGD("%s(%p, %f)++", __func__, dev, volume); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - pthread_mutex_lock(&device->lock); - tinyalsa_mixer_set_master_volume(device->mixer, volume); - pthread_mutex_unlock(&device->lock); - - ALOGD("%s(%p, %f)--", __func__, dev, volume); - - return 0; -} - -static int audio_hw_set_mode(struct audio_hw_device *dev, int mode) -{ - struct tinyalsa_audio_ril_interface *ril_interface; - struct tinyalsa_audio_device *device; - audio_devices_t device_modem; - int rc; - - ALOGD("%s(%p, %d)++", __func__, dev, mode); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(mode != device->mode) { - pthread_mutex_lock(&device->lock); - - if(mode == AUDIO_MODE_IN_CALL) { - tinyalsa_mixer_set_modem_state(device->mixer, 1); - - if(device->stream_out != NULL) - device_modem = device->stream_out->device_current; - else - device_modem = AUDIO_DEVICE_OUT_EARPIECE; - - tinyalsa_mixer_set_device(device->mixer, device_modem); - -#ifdef YAMAHA_MC1N2_AUDIO - rc = yamaha_mc1n2_audio_modem_start(device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } -#endif - - rc = audio_ril_interface_open((struct audio_hw_device *) device, device_modem, &ril_interface); - if(rc < 0 || ril_interface == NULL) { - ALOGE("Failed to open RIL interface"); - device->ril_interface = NULL; - } else { - device->ril_interface = ril_interface; - - //Only enable dualmic for earpiece. - if(device_modem == AUDIO_DEVICE_OUT_EARPIECE) - audio_ril_interface_set_twomic(ril_interface,TWO_MIC_SOLUTION_ON); - - if(device->voice_volume) - audio_ril_interface_set_voice_volume(ril_interface, device_modem, device->voice_volume); - } - } else if(device->mode == AUDIO_MODE_IN_CALL) { - tinyalsa_mixer_set_modem_state(device->mixer, 0); - - /* - * Should be safe to ALWAYS disable it on exit - * But we should instrument secril-client to be sure - * when this is/isn't controlled - FIXME - */ - if(device->ril_interface != NULL) { - audio_ril_interface_set_twomic(device->ril_interface,TWO_MIC_SOLUTION_OFF); - } - -#ifdef YAMAHA_MC1N2_AUDIO - rc = yamaha_mc1n2_audio_modem_stop(device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } -#endif - - if(device->ril_interface != NULL) { - audio_ril_interface_close((struct audio_hw_device *) device, device->ril_interface); - } - } - - device->mode = mode; - - pthread_mutex_unlock(&device->lock); - } - - ALOGD("%s(%p, %d)--", __func__, dev, mode); - - return 0; -} - -static int audio_hw_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - struct tinyalsa_audio_device *device; - audio_devices_t device_modem; - - ALOGD("%s(%p, %d)++", __func__, dev, state); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - if(device->mic_mute != state) { - pthread_mutex_lock(&device->lock); - - if(device->mode == AUDIO_MODE_IN_CALL) { - if(device->ril_interface != NULL) - device_modem = device->ril_interface->device_current; - else if(device->stream_out != NULL) - device_modem = device->stream_out->device_current; - else - device_modem = AUDIO_DEVICE_OUT_EARPIECE; - - tinyalsa_mixer_set_mic_mute(device->mixer, - device_modem, state); - - if(device->ril_interface != NULL) - audio_ril_interface_set_mic_mute(device->ril_interface, state); - } else { - if(device->stream_in != NULL) { - tinyalsa_mixer_set_mic_mute(device->mixer, - device->stream_in->device_current, state); - } - } - - device->mic_mute = state; - - pthread_mutex_unlock(&device->lock); - } - - ALOGD("%s(%p, %d)--", __func__, dev, state); - - return 0; -} - -static int audio_hw_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - struct tinyalsa_audio_device *device; - - ALOGD("%s(%p, %p)", __func__, dev, state); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - *state = device->mic_mute; - - return 0; -} - -static int audio_hw_set_parameters(struct audio_hw_device *dev, - const char *kvpairs) -{ - struct tinyalsa_audio_device *device; - struct str_parms *parms; - char value_string[32] = { 0 }; - int value; - int rc; - - ALOGD("%s(%p, %s)++", __func__, dev, kvpairs); - - if(dev == NULL || kvpairs == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - parms = str_parms_create_str(kvpairs); - if(parms == NULL) - return -1; - - rc = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value_string, sizeof(value_string)); - if(rc < 0) - goto error_params; - - value = atoi(value_string); - - pthread_mutex_lock(&device->lock); - - if(audio_is_output_device((audio_devices_t) value)) { - if(device->stream_out != NULL && device->stream_out->device_current != (audio_devices_t) value) { - pthread_mutex_lock(&device->stream_out->lock); - audio_out_set_route(device->stream_out, (audio_devices_t) value); - pthread_mutex_unlock(&device->stream_out->lock); - } - if(device->ril_interface != NULL && device->ril_interface->device_current != (audio_devices_t) value) { - audio_ril_interface_set_route(device->ril_interface, (audio_devices_t) value); - } - } else if(audio_is_input_device((audio_devices_t) value)) { - if(device->stream_in != NULL && device->stream_in->device_current != (audio_devices_t) value) { - pthread_mutex_lock(&device->stream_in->lock); - audio_in_set_route(device->stream_in, (audio_devices_t) value); - pthread_mutex_unlock(&device->stream_in->lock); - } - } - - pthread_mutex_unlock(&device->lock); - - str_parms_destroy(parms); - - ALOGD("%s(%p, %s)--", __func__, dev, kvpairs); - - return 0; - -error_params: - str_parms_destroy(parms); - - ALOGD("%s(%p, %s)-- (PARAMETER ERROR)", __func__, dev, kvpairs); - - return -1; -} - -static char *audio_hw_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - ALOGD("%s(%p, %s)", __func__, dev, keys); - - return strdup(""); -} - -static size_t audio_hw_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - struct tinyalsa_audio_device *device; - struct tinyalsa_mixer_io_props *mixer_props; - size_t size; - - int channel_count = popcount(config->channel_mask); - - ALOGD("%s(%p, %d, %d, %d)++", __func__, dev, config->sample_rate, config->format, channel_count); - - if(dev == NULL) - return -1; - - device = (struct tinyalsa_audio_device *) dev; - - if(device->mixer == NULL) - return -1; - - mixer_props = tinyalsa_mixer_get_input_props(device->mixer); - if(mixer_props == NULL) - return -1; - - // Default value - if(mixer_props->rate == 0) - mixer_props->rate = 44100; - - size = (mixer_props->period_size * config->sample_rate) / mixer_props->rate; - size = ((size + 15) / 16) * 16; - size = size * channel_count * audio_bytes_per_sample(config->format); - - ALOGD("%s(%p, %d, %d, %d)--", __func__, dev, config->sample_rate, config->format, channel_count); - - return size; -} - -static int audio_hw_dump(const audio_hw_device_t *device, int fd) -{ - ALOGD("%s(%p, %d)", __func__, device, fd); - - return 0; -} - -/* - * Interface - */ - -int audio_hw_close(hw_device_t *device) -{ - struct tinyalsa_audio_device *tinyalsa_audio_device; - - ALOGD("%s(%p)++", __func__, device); - - if(device != NULL) { - tinyalsa_audio_device = (struct tinyalsa_audio_device *) device; - - if(tinyalsa_audio_device->mixer != NULL) { - tinyalsa_mixer_close(tinyalsa_audio_device->mixer); - tinyalsa_audio_device->mixer = NULL; - } - -#ifdef YAMAHA_MC1N2_AUDIO - if(tinyalsa_audio_device->mc1n2_pdata != NULL) { - yamaha_mc1n2_audio_stop(tinyalsa_audio_device->mc1n2_pdata); - tinyalsa_audio_device->mc1n2_pdata = NULL; - } -#endif - - free(device); - } - - ALOGD("%s(%p)--", __func__, device); - - return 0; -} - -int audio_hw_open(const hw_module_t *module, const char *name, - hw_device_t **device) -{ - struct tinyalsa_audio_device *tinyalsa_audio_device = NULL; - struct tinyalsa_mixer *tinyalsa_mixer = NULL; - struct audio_hw_device *dev; - int rc; - - ALOGD("%s(%p, %s, %p)++", __func__, module, name, device); - - if(device == NULL) - return -EINVAL; - - if(strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) - return -EINVAL; - - tinyalsa_audio_device = calloc(1, sizeof(struct tinyalsa_audio_device)); - if(tinyalsa_audio_device == NULL) - return -ENOMEM; - - dev = &(tinyalsa_audio_device->device); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = AUDIO_DEVICE_API_VERSION_2_0; - dev->common.module = (struct hw_module_t *) module; - dev->common.close = audio_hw_close; - - dev->init_check = audio_hw_init_check; - dev->set_voice_volume = audio_hw_set_voice_volume; - dev->set_master_volume = audio_hw_set_master_volume; - dev->set_mode = audio_hw_set_mode; - dev->set_mic_mute = audio_hw_set_mic_mute; - dev->get_mic_mute = audio_hw_get_mic_mute; - dev->set_parameters = audio_hw_set_parameters; - dev->get_parameters = audio_hw_get_parameters; - dev->get_input_buffer_size = audio_hw_get_input_buffer_size; - - dev->open_output_stream = audio_hw_open_output_stream; - dev->close_output_stream = audio_hw_close_output_stream; - - dev->open_input_stream = audio_hw_open_input_stream; - dev->close_input_stream = audio_hw_close_input_stream; - - dev->dump = audio_hw_dump; - -#ifdef YAMAHA_MC1N2_AUDIO - rc = yamaha_mc1n2_audio_start(&tinyalsa_audio_device->mc1n2_pdata, - YAMAHA_MC1N2_AUDIO_DEVICE); - if(rc < 0) { - ALOGE("Failed to open Yamaha-MC1N2-Audio"); - goto error_device; - } - - rc = yamaha_mc1n2_audio_init(tinyalsa_audio_device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to init Yamaha-MC1N2-Audio"); - } -#endif - - rc = tinyalsa_mixer_open(&tinyalsa_mixer, TINYALSA_MIXER_CONFIG_FILE); - if(rc < 0 || tinyalsa_mixer == NULL) { - ALOGE("Failed to open mixer!"); - goto error_device; - } - - tinyalsa_audio_device->mixer = tinyalsa_mixer; - - *device = &(dev->common); - - ALOGD("%s(%p, %s, %p)--", __func__, module, name, device); - - return 0; - -error_device: - *device = NULL; - free(tinyalsa_audio_device); - - ALOGD("%s(%p, %s, %p)-- (DEVICE ERROR)", __func__, module, name, device); - - return -1; -} - -struct hw_module_methods_t audio_hw_module_methods = { - .open = audio_hw_open, -}; - -struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = AUDIO_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "TinyALSA-Audio", - .author = "Paul Kocialkowski", - .methods = &audio_hw_module_methods, - }, -}; diff --git a/tinyalsa_audio/audio_hw.h b/tinyalsa_audio/audio_hw.h deleted file mode 100644 index 903d202..0000000 --- a/tinyalsa_audio/audio_hw.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TINYALSA_AUDIO_HW_H -#define TINYALSA_AUDIO_HW_H - -#include <hardware/hardware.h> -#include <hardware/audio.h> -#include <system/audio.h> - -#include <audio_utils/resampler.h> - -#ifdef YAMAHA_MC1N2_AUDIO -#include <yamaha-mc1n2-audio.h> -#endif - -#include "mixer.h" -#include "audio_ril_interface.h" - -struct tinyalsa_audio_stream_out { - struct audio_stream_out stream; - struct tinyalsa_audio_device *device; - - struct tinyalsa_mixer_io_props *mixer_props; - int rate; - audio_channel_mask_t channel_mask; - audio_format_t format; - - audio_devices_t device_current; - - struct resampler_itfe *resampler; - - struct pcm *pcm; - int standby; - - pthread_mutex_t lock; -}; - -struct tinyalsa_audio_stream_in { - struct audio_stream_in stream; - struct tinyalsa_audio_device *device; - - struct tinyalsa_mixer_io_props *mixer_props; - int rate; - - audio_channel_mask_t channel_mask; - audio_format_t format; - - audio_devices_t device_current; - - struct resampler_itfe *resampler; - struct resampler_buffer_provider buffer_provider; - void *buffer; - int frames_left; - - struct pcm *pcm; - int standby; - - pthread_mutex_t lock; -}; - -struct tinyalsa_audio_device { - struct audio_hw_device device; - - struct tinyalsa_audio_stream_out *stream_out; - struct tinyalsa_audio_stream_in *stream_in; - struct tinyalsa_audio_ril_interface *ril_interface; - -#ifdef YAMAHA_MC1N2_AUDIO - struct yamaha_mc1n2_audio_pdata *mc1n2_pdata; -#endif - - struct tinyalsa_mixer *mixer; - audio_mode_t mode; - - float voice_volume; - int mic_mute; - - pthread_mutex_t lock; -}; - -int audio_out_set_route(struct tinyalsa_audio_stream_out *stream_out, - audio_devices_t device); - -void audio_hw_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream); -int audio_hw_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out); - -int audio_in_set_route(struct tinyalsa_audio_stream_in *stream_in, - audio_devices_t device); - -void audio_hw_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream); -int audio_hw_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in); - -#endif diff --git a/tinyalsa_audio/audio_in.c b/tinyalsa_audio/audio_in.c deleted file mode 100644 index 0bafbb0..0000000 --- a/tinyalsa_audio/audio_in.c +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This is based on Galaxy Nexus audio.primary.tuna implementation: - * Copyright 2011, The Android Open-Source Project - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define LOG_TAG "TinyALSA-Audio Input" - -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <sys/time.h> - -#include <cutils/str_parms.h> -#include <cutils/log.h> - -#define EFFECT_UUID_NULL EFFECT_UUID_NULL_IN -#define EFFECT_UUID_NULL_STR EFFECT_UUID_NULL_STR_IN -#include <audio_utils/resampler.h> -#include "audio_hw.h" -#include "mixer.h" - -/* - * Functions - */ - -int audio_in_pcm_open(struct tinyalsa_audio_stream_in *stream_in) -{ - struct pcm *pcm = NULL; - struct pcm_config pcm_config; - - if(stream_in == NULL) - return -1; - - memset(&pcm_config, 0, sizeof(pcm_config)); - pcm_config.channels = popcount(stream_in->mixer_props->channel_mask); - pcm_config.rate = stream_in->mixer_props->rate; - switch(stream_in->mixer_props->format) { - case AUDIO_FORMAT_PCM_16_BIT: - pcm_config.format = PCM_FORMAT_S16_LE; - break; - case AUDIO_FORMAT_PCM_32_BIT: - pcm_config.format = PCM_FORMAT_S32_LE; - break; - default: - ALOGE("Invalid format: 0x%x", stream_in->mixer_props->format); - return -1; - } - pcm_config.period_size = stream_in->mixer_props->period_size; - pcm_config.period_count = stream_in->mixer_props->period_count; - - pcm = pcm_open(stream_in->mixer_props->card, - stream_in->mixer_props->device, PCM_IN, &pcm_config); - - if(pcm == NULL || !pcm_is_ready(pcm)) { - ALOGE("Unable to open pcm device: %s", pcm_get_error(pcm)); - return -1; - } - - stream_in->pcm = pcm; - - if(stream_in->resampler != NULL) - stream_in->resampler->reset(stream_in->resampler); - - return 0; -} - -void audio_in_pcm_close(struct tinyalsa_audio_stream_in *stream_in) -{ - if(stream_in->pcm == NULL) - return; - - pcm_close(stream_in->pcm); - stream_in->pcm = NULL; -} - -int audio_in_set_route(struct tinyalsa_audio_stream_in *stream_in, - audio_devices_t device) -{ - int rc; - - if(stream_in == NULL) - return -1; - - stream_in->device_current = device; - - if(device == 0) { - pthread_mutex_unlock(&stream_in->lock); - return stream_in->stream.common.standby((struct audio_stream *) stream_in); - } - - tinyalsa_mixer_set_device(stream_in->device->mixer, stream_in->device_current); - -#ifdef YAMAHA_MC1N2_AUDIO - yamaha_mc1n2_audio_set_route(stream_in->device->mc1n2_pdata, device); -#endif - - return 0; -} - -int audio_in_resampler_open(struct tinyalsa_audio_stream_in *stream_in) -{ - int rc; - - if(stream_in == NULL) - return -1; - - rc = create_resampler(stream_in->mixer_props->rate, - stream_in->rate, - popcount(stream_in->mixer_props->channel_mask), - RESAMPLER_QUALITY_DEFAULT, - &stream_in->buffer_provider, - &stream_in->resampler); - if(rc < 0 || stream_in->resampler == NULL) { - ALOGE("Failed to create resampler"); - return -1; - } - - stream_in->buffer = malloc(stream_in->mixer_props->period_size * - popcount(stream_in->mixer_props->channel_mask) * - audio_bytes_per_sample(stream_in->mixer_props->format)); - - return 0; -} - -void audio_in_resampler_close(struct tinyalsa_audio_stream_in *stream_in) -{ - if(stream_in == NULL) - return; - - if(stream_in->resampler != NULL) { - release_resampler(stream_in->resampler); - stream_in->resampler = NULL; - } - - if(stream_in->buffer != NULL) { - free(stream_in->buffer); - stream_in->buffer = NULL; - } -} - -int audio_in_get_next_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer *buffer) -{ - struct tinyalsa_audio_stream_in *stream_in; - int rc; - - if(buffer_provider == NULL || buffer == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) ((void *) buffer_provider - - offsetof(struct tinyalsa_audio_stream_in, buffer_provider)); - - if(stream_in->frames_left == 0) { - if(stream_in->pcm == NULL || !pcm_is_ready(stream_in->pcm)) { - ALOGE("pcm device is not ready"); - goto error_pcm; - } - - rc = pcm_read(stream_in->pcm, stream_in->buffer, - stream_in->mixer_props->period_size * - popcount(stream_in->mixer_props->channel_mask) * - audio_bytes_per_sample(stream_in->mixer_props->format)); - if(rc != 0) { - ALOGE("pcm read failed!"); - goto error_pcm; - } - - stream_in->frames_left = stream_in->mixer_props->period_size; - } - - buffer->frame_count = (buffer->frame_count > stream_in->frames_left) ? - stream_in->frames_left : buffer->frame_count; - - buffer->raw = stream_in->buffer + - (stream_in->mixer_props->period_size - stream_in->frames_left) * - popcount(stream_in->mixer_props->channel_mask) * - audio_bytes_per_sample(stream_in->mixer_props->format); - - return 0; - -error_pcm: - buffer->raw = NULL; - buffer->frame_count = 0; - return -1; -} - -void audio_in_release_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer *buffer) -{ - struct tinyalsa_audio_stream_in *stream_in; - - if(buffer_provider == NULL || buffer == NULL) - return; - - stream_in = (struct tinyalsa_audio_stream_in *) ((void *) buffer_provider - - offsetof(struct tinyalsa_audio_stream_in, buffer_provider)); - - stream_in->frames_left -= buffer->frame_count; -} - -int audio_in_read_process(struct tinyalsa_audio_stream_in *stream_in, void *buffer, int size) -{ - size_t frames_out; - - size_t frames_in; - int size_in; - void *buffer_in = NULL; - - int frames_out_resampler; - int size_out_resampler; - void *buffer_out_resampler = NULL; - - int frames_out_read; - int size_out_read; - void *buffer_out_read = NULL; - - int frames_out_channels; - int size_out_channels; - void *buffer_out_channels = NULL; - - int i, j; - int rc; - - if(stream_in == NULL || buffer == NULL || size <= 0) - return -1; - - frames_in = size / audio_stream_frame_size((struct audio_stream *) stream_in); - - if(stream_in->resampler != NULL) { - frames_out_resampler = frames_in; - size_out_resampler = frames_out_resampler * popcount(stream_in->mixer_props->channel_mask) * audio_bytes_per_sample(stream_in->mixer_props->format); - buffer_out_resampler = calloc(1, size_out_resampler); - - frames_out = 0; - while(frames_out < frames_out_resampler) { - frames_in = frames_out_resampler - frames_out; - stream_in->resampler->resample_from_provider(stream_in->resampler, - buffer_out_resampler + (size_out_resampler / frames_out_resampler) * frames_out, - &frames_in); - - frames_out += frames_in; - } - - frames_in = frames_out_resampler; - size_in = size_out_resampler; - buffer_in = buffer_out_resampler; - } else { - frames_out_read = frames_in; - size_out_read = frames_out_read * popcount(stream_in->mixer_props->channel_mask) * audio_bytes_per_sample(stream_in->mixer_props->format); - buffer_out_read = calloc(1, size_out_read); - - if(stream_in->pcm == NULL || !pcm_is_ready(stream_in->pcm)) { - ALOGE("pcm device is not ready"); - goto error; - } - - rc = pcm_read(stream_in->pcm, buffer_out_read, size_out_read); - if(rc != 0) { - ALOGE("pcm read failed!"); - goto error; - } - - frames_in = frames_out_read; - size_in = size_out_read; - buffer_in = buffer_out_read; - } - - if(buffer_in == NULL) - goto error; - - //FIXME: This is only for PCM 16 - if(popcount(stream_in->channel_mask) < popcount(stream_in->mixer_props->channel_mask)) { - frames_out_channels = frames_in; - size_out_channels = frames_out_channels * audio_stream_frame_size((struct audio_stream *) stream_in); - buffer_out_channels = calloc(1, size_out_channels); - - int channels_count_in = popcount(stream_in->mixer_props->channel_mask); - int channels_count_out = popcount(stream_in->channel_mask); - int ratio = channels_count_in / channels_count_out; - - int16_t *byte_in = (int16_t *) buffer_in; - int16_t *byte_out = (int16_t *) buffer_out_channels; - int16_t byte; - - for(i=0 ; i < frames_out_channels * channels_count_out; i++) { - byte = 0; - for(j=0 ; j < ratio ; j++) { - byte += *byte_in / ratio; - byte_in++; - } - - *byte_out = byte; - byte_out++; - } - - frames_in = frames_out_channels; - size_in = size_out_channels; - buffer_in = buffer_out_channels; - } else if(popcount(stream_in->channel_mask) != popcount(stream_in->mixer_props->channel_mask)) { - ALOGE("Asked for more channels than hardware can provide!"); - goto error; - } - - if(buffer_in != NULL) - memcpy(buffer, buffer_in, size); - - if(buffer_out_resampler != NULL) - free(buffer_out_resampler); - if(buffer_out_read != NULL) - free(buffer_out_read); - if(buffer_out_channels != NULL) - free(buffer_out_channels); - - return 0; - -error: - if(buffer_out_resampler != NULL) - free(buffer_out_resampler); - if(buffer_out_read != NULL) - free(buffer_out_read); - if(buffer_out_channels != NULL) - free(buffer_out_channels); - - return -1; -} - -static uint32_t audio_in_get_sample_rate(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - - if(stream == NULL) - return 0; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - return stream_in->rate; -} - -static int audio_in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct tinyalsa_audio_stream_in *stream_in; - - ALOGD("%s(%p, %d)", __func__, stream, rate); - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in->rate != (int) rate) { - pthread_mutex_lock(&stream_in->lock); - - stream_in->rate = rate; - - if(stream_in->rate != stream_in->mixer_props->rate) { - audio_in_resampler_close(stream_in); - audio_in_resampler_open(stream_in); - - stream_in->standby = 1; - } - - pthread_mutex_unlock(&stream_in->lock); - } - - return 0; -} - -static size_t audio_in_get_buffer_size(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - size_t size; - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - size = (stream_in->mixer_props->period_size * stream_in->rate) / - stream_in->mixer_props->rate; - size = ((size + 15) / 16) * 16; - size = size * audio_stream_frame_size((struct audio_stream *) stream); - - return size; -} - -static audio_channel_mask_t audio_in_get_channels(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - return stream_in->channel_mask; -} - -static audio_format_t audio_in_get_format(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - return stream_in->format; -} - -static int audio_in_set_format(struct audio_stream *stream, audio_format_t format) -{ - struct tinyalsa_audio_stream_in *stream_in; - - //ALOGD("%s(%p, %d)", __func__, stream, format); - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in->format != (audio_format_t) format) { - pthread_mutex_lock(&stream_in->lock); - - stream_in->format = format; - - if(stream_in->format != stream_in->mixer_props->format) - stream_in->standby = 1; - - pthread_mutex_unlock(&stream_in->lock); - } - - return 0; -} - -static int audio_in_standby(struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - int rc; - - //ALOGD("%s(%p)", __func__, stream); - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - pthread_mutex_lock(&stream_in->lock); - - if(stream_in->pcm != NULL) - audio_in_pcm_close(stream_in); - -#ifdef YAMAHA_MC1N2_AUDIO - if(!stream_in->standby) { - rc = yamaha_mc1n2_audio_input_stop(stream_in->device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } - } -#endif - - stream_in->standby = 1; - - pthread_mutex_unlock(&stream_in->lock); - - return 0; -} - -static int audio_in_dump(const struct audio_stream *stream, int fd) -{ - //ALOGD("%s(%p, %d)", __func__, stream, fd); - - return 0; -} - -static int audio_in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct tinyalsa_audio_stream_in *stream_in; - struct str_parms *parms; - char value_string[32] = { 0 }; - int value; - int rc; - - //ALOGD("%s(%p, %s)", __func__, stream, kvpairs); - - if(stream == NULL || kvpairs == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in->device == NULL || stream_in->device->mixer == NULL) - return -1; - - parms = str_parms_create_str(kvpairs); - if(parms == NULL) - return -1; - - rc = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value_string, sizeof(value_string)); - if(rc < 0) - goto error_params; - - value = atoi(value_string); - - pthread_mutex_lock(&stream_in->device->lock); - - if(stream_in->device_current != (audio_devices_t) value) { - pthread_mutex_lock(&stream_in->lock); - audio_in_set_route(stream_in, (audio_devices_t) value); - pthread_mutex_unlock(&stream_in->lock); - } - - pthread_mutex_unlock(&stream_in->device->lock); - - str_parms_destroy(parms); - - return 0; - -error_params: - str_parms_destroy(parms); - - return -1; -} - -static char *audio_in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - //ALOGD("%s(%p, %s)", __func__, stream, keys); - - return strdup(""); -} - -static int audio_in_set_gain(struct audio_stream_in *stream, float gain) -{ - struct tinyalsa_audio_stream_in *stream_in; - - ALOGD("%s(%p, %f)", __func__, stream, gain); - - if(stream == NULL) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in->device == NULL || stream_in->device->mixer == NULL) - return -1; - - pthread_mutex_lock(&stream_in->device->lock); - tinyalsa_mixer_set_input_gain(stream_in->device->mixer, - stream_in->device_current, gain); - pthread_mutex_unlock(&stream_in->device->lock); - - return 0; -} - -static ssize_t audio_in_read(struct audio_stream_in *stream, - void *buffer, size_t bytes) -{ - struct tinyalsa_audio_stream_in *stream_in; - int rc; - - if(stream == NULL || buffer == NULL || bytes <= 0) - return -1; - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in->device == NULL) - return -1; - - pthread_mutex_lock(&stream_in->lock); - - if(stream_in->standby) { -#ifdef YAMAHA_MC1N2_AUDIO - rc = yamaha_mc1n2_audio_input_start(stream_in->device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } -#endif - - rc = audio_in_pcm_open(stream_in); - if(rc < 0) { - ALOGE("Unable to open pcm device"); - goto error; - } - - stream_in->standby = 0; - } - - rc = audio_in_read_process(stream_in, buffer, (int) bytes); - if(rc < 0) { - ALOGE("Read and process failed!"); - goto error; - } - - if(stream_in->device != NULL && stream_in->device->mic_mute) - memset(buffer, 0, bytes); - - pthread_mutex_unlock(&stream_in->lock); - - return bytes; - -error: - pthread_mutex_unlock(&stream_in->lock); - - return -1; -} - -static uint32_t audio_in_get_input_frames_lost(struct audio_stream_in *stream) -{ - return 0; -} - -static int audio_in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - //ALOGD("%s(%p, %p)", __func__, stream, effect); - - return 0; -} - -static int audio_in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - //ALOGD("%s(%p, %p)", __func__, stream, effect); - - return 0; -} - -/* - * Interface - */ - -void audio_hw_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) -{ - struct tinyalsa_audio_stream_in *stream_in; - struct tinyalsa_audio_device *tinyalsa_audio_device; - - ALOGD("%s(%p)", __func__, stream); - - stream_in = (struct tinyalsa_audio_stream_in *) stream; - - if(stream_in != NULL && stream_in->resampler != NULL) - audio_in_resampler_close(stream_in); - -#ifdef YAMAHA_MC1N2_AUDIO - if(stream_in != NULL && !stream_in->standby) - yamaha_mc1n2_audio_input_stop(stream_in->device->mc1n2_pdata); -#endif - - if(stream != NULL) - free(stream); - - if(dev == NULL) - return; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - - pthread_mutex_lock(&tinyalsa_audio_device->lock); - - tinyalsa_mixer_set_input_state(tinyalsa_audio_device->mixer, 0); - tinyalsa_audio_device->stream_in = NULL; - - pthread_mutex_unlock(&tinyalsa_audio_device->lock); -} - -int audio_hw_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) -{ - struct tinyalsa_audio_device *tinyalsa_audio_device; - struct tinyalsa_audio_stream_in *tinyalsa_audio_stream_in; - struct audio_stream_in *stream; - int rc; - - ALOGD("%s(%p, %d, %p, %p)", - __func__, dev, devices, config, stream_in); - - if(dev == NULL || config == NULL || stream_in == NULL) - return -EINVAL; - - *stream_in = NULL; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - tinyalsa_audio_stream_in = calloc(1, sizeof(struct tinyalsa_audio_stream_in)); - - if(tinyalsa_audio_stream_in == NULL) - return -ENOMEM; - - tinyalsa_audio_stream_in->device = tinyalsa_audio_device; - tinyalsa_audio_device->stream_in = tinyalsa_audio_stream_in; - stream = &(tinyalsa_audio_stream_in->stream); - - stream->common.get_sample_rate = audio_in_get_sample_rate; - stream->common.set_sample_rate = audio_in_set_sample_rate; - stream->common.get_buffer_size = audio_in_get_buffer_size; - stream->common.get_channels = audio_in_get_channels; - stream->common.get_format = audio_in_get_format; - stream->common.set_format = audio_in_set_format; - stream->common.standby = audio_in_standby; - stream->common.dump = audio_in_dump; - stream->common.set_parameters = audio_in_set_parameters; - stream->common.get_parameters = audio_in_get_parameters; - stream->common.add_audio_effect = audio_in_add_audio_effect; - stream->common.remove_audio_effect = audio_in_remove_audio_effect; - stream->set_gain = audio_in_set_gain; - stream->read = audio_in_read; - stream->get_input_frames_lost = audio_in_get_input_frames_lost; - - if(tinyalsa_audio_device->mixer == NULL) - goto error_stream; - - tinyalsa_audio_stream_in->mixer_props = - tinyalsa_mixer_get_input_props(tinyalsa_audio_device->mixer); - - if(tinyalsa_audio_stream_in->mixer_props == NULL) - goto error_stream; - - // Default values - if(tinyalsa_audio_stream_in->mixer_props->rate == 0) - tinyalsa_audio_stream_in->mixer_props->rate = 44100; - if(tinyalsa_audio_stream_in->mixer_props->channel_mask == 0) - tinyalsa_audio_stream_in->mixer_props->channel_mask = AUDIO_CHANNEL_IN_STEREO; - if(tinyalsa_audio_stream_in->mixer_props->format == 0) - tinyalsa_audio_stream_in->mixer_props->format = AUDIO_FORMAT_PCM_16_BIT; - - if(config->sample_rate == 0) - tinyalsa_audio_stream_in->rate = - tinyalsa_audio_stream_in->mixer_props->rate; - else - tinyalsa_audio_stream_in->rate = config->sample_rate; - if(config->channel_mask == 0) - tinyalsa_audio_stream_in->channel_mask = - tinyalsa_audio_stream_in->mixer_props->channel_mask; - else - tinyalsa_audio_stream_in->channel_mask = config->channel_mask; - if(config->format == 0) - tinyalsa_audio_stream_in->format = - tinyalsa_audio_stream_in->mixer_props->format; - else - tinyalsa_audio_stream_in->format = config->format; - - tinyalsa_audio_stream_in->buffer_provider.get_next_buffer = - audio_in_get_next_buffer; - tinyalsa_audio_stream_in->buffer_provider.release_buffer = - audio_in_release_buffer; - - if(tinyalsa_audio_stream_in->rate != tinyalsa_audio_stream_in->mixer_props->rate) { - rc = audio_in_resampler_open(tinyalsa_audio_stream_in); - if(rc < 0) { - ALOGE("Unable to open resampler!"); - goto error_stream; - } - } - - config->sample_rate = tinyalsa_audio_stream_in->rate; - config->channel_mask = tinyalsa_audio_stream_in->channel_mask; - config->format = tinyalsa_audio_stream_in->format; - - pthread_mutex_lock(&tinyalsa_audio_device->lock); - - rc = tinyalsa_mixer_set_input_state(tinyalsa_audio_device->mixer, 1); - if(rc < 0) { - ALOGE("Unable to set input state"); - pthread_mutex_unlock(&tinyalsa_audio_device->lock); - goto error_stream; - } - - pthread_mutex_lock(&tinyalsa_audio_stream_in->lock); - - audio_in_set_route(tinyalsa_audio_stream_in, devices); - - pthread_mutex_unlock(&tinyalsa_audio_device->lock); - - rc = audio_in_pcm_open(tinyalsa_audio_stream_in); - if(rc < 0) { - ALOGE("Unable to open pcm device"); - pthread_mutex_unlock(&tinyalsa_audio_stream_in->lock); - goto error_stream; - } - - audio_in_pcm_close(tinyalsa_audio_stream_in); - - tinyalsa_audio_stream_in->standby = 1; - - pthread_mutex_unlock(&tinyalsa_audio_stream_in->lock); - - *stream_in = stream; - - return 0; - -error_stream: - if(tinyalsa_audio_stream_in->resampler != NULL) - audio_in_resampler_close(tinyalsa_audio_stream_in); - free(tinyalsa_audio_stream_in); - tinyalsa_audio_device->stream_in = NULL; - - return -1; -} diff --git a/tinyalsa_audio/audio_out.c b/tinyalsa_audio/audio_out.c deleted file mode 100644 index 3055c07..0000000 --- a/tinyalsa_audio/audio_out.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This is based on Galaxy Nexus audio.primary.tuna implementation: - * Copyright 2011, The Android Open-Source Project - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define LOG_TAG "TinyALSA-Audio Output" - -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <sys/time.h> - -#include <cutils/str_parms.h> -#include <cutils/log.h> - -#ifdef YAMAHA_MC1N2_AUDIO -#include <yamaha-mc1n2-audio.h> -#endif - -#define EFFECT_UUID_NULL EFFECT_UUID_NULL_OUT -#define EFFECT_UUID_NULL_STR EFFECT_UUID_NULL_STR_OUT -#include <audio_utils/resampler.h> -#include "audio_hw.h" -#include "mixer.h" - -/* - * Functions - */ - -int audio_out_pcm_open(struct tinyalsa_audio_stream_out *stream_out) -{ - struct pcm *pcm = NULL; - struct pcm_config pcm_config; - - if(stream_out == NULL) - return -1; - - memset(&pcm_config, 0, sizeof(pcm_config)); - pcm_config.channels = popcount(stream_out->mixer_props->channel_mask); - pcm_config.rate = stream_out->mixer_props->rate; - switch(stream_out->mixer_props->format) { - case AUDIO_FORMAT_PCM_16_BIT: - pcm_config.format = PCM_FORMAT_S16_LE; - break; - case AUDIO_FORMAT_PCM_32_BIT: - pcm_config.format = PCM_FORMAT_S32_LE; - break; - default: - ALOGE("Invalid format: 0x%x", stream_out->mixer_props->format); - return -1; - } - pcm_config.period_size = stream_out->mixer_props->period_size; - pcm_config.period_count = stream_out->mixer_props->period_count; - - pcm = pcm_open(stream_out->mixer_props->card, - stream_out->mixer_props->device, PCM_OUT, &pcm_config); - - if(pcm == NULL || !pcm_is_ready(pcm)) { - ALOGE("Unable to open pcm device: %s", pcm_get_error(pcm)); - return -1; - } - - stream_out->pcm = pcm; - - if(stream_out->resampler != NULL) - stream_out->resampler->reset(stream_out->resampler); - - return 0; -} - -void audio_out_pcm_close(struct tinyalsa_audio_stream_out *stream_out) -{ - if(stream_out->pcm == NULL) - return; - - pcm_close(stream_out->pcm); - stream_out->pcm = NULL; -} - -int audio_out_set_route(struct tinyalsa_audio_stream_out *stream_out, - audio_devices_t device) -{ - int rc; - - if(stream_out == NULL) - return -1; - - stream_out->device_current = device; - - if(device == 0) { - pthread_mutex_unlock(&stream_out->lock); - return stream_out->stream.common.standby((struct audio_stream *) stream_out); - } - - tinyalsa_mixer_set_device(stream_out->device->mixer, stream_out->device_current); - -#ifdef YAMAHA_MC1N2_AUDIO - yamaha_mc1n2_audio_set_route(stream_out->device->mc1n2_pdata, device); -#endif - - return 0; -} - -int audio_out_resampler_open(struct tinyalsa_audio_stream_out *stream_out) -{ - int rc; - - if(stream_out == NULL) - return -1; - - rc = create_resampler(stream_out->rate, - stream_out->mixer_props->rate, - popcount(stream_out->channel_mask), - RESAMPLER_QUALITY_DEFAULT, - NULL, - &stream_out->resampler); - if(rc < 0 || stream_out->resampler == NULL) { - ALOGE("Failed to create resampler"); - return -1; - } - - return 0; -} - -void audio_out_resampler_close(struct tinyalsa_audio_stream_out *stream_out) -{ - if(stream_out == NULL) - return; - - if(stream_out->resampler != NULL) { - release_resampler(stream_out->resampler); - stream_out->resampler = NULL; - } -} - -int audio_out_write_process(struct tinyalsa_audio_stream_out *stream_out, void *buffer, int size) -{ - size_t frames_out; - - size_t frames_in; - int size_in; - void *buffer_in = NULL; - - int frames_out_resampler; - int size_out_resampler; - void *buffer_out_resampler = NULL; - - int frames_out_channels; - int size_out_channels; - void *buffer_out_channels = NULL; - - int i, j; - int rc; - - if(stream_out == NULL || buffer == NULL || size <= 0) - return -1; - - frames_in = size / audio_stream_frame_size((struct audio_stream *) stream_out); - size_in = size; - buffer_in = buffer; - - if(stream_out->resampler != NULL) { - frames_out_resampler = (frames_in * stream_out->mixer_props->rate) / - stream_out->rate; - frames_out_resampler = ((frames_out_resampler + 15) / 16) * 16; - size_out_resampler = frames_out_resampler * audio_stream_frame_size((struct audio_stream *) stream_out); - buffer_out_resampler = calloc(1, size_out_resampler); - - frames_out = frames_out_resampler; - stream_out->resampler->resample_from_input(stream_out->resampler, - buffer_in, &frames_in, buffer_out_resampler, &frames_out); - - frames_in = frames_out; - size_in = frames_out * audio_stream_frame_size((struct audio_stream *) stream_out); - buffer_in = buffer_out_resampler; - } - - if(buffer_in == NULL) - goto error; - - //FIXME: This is only for PCM 16 - if(popcount(stream_out->mixer_props->channel_mask) < popcount(stream_out->channel_mask)) { - frames_out_channels = frames_in; - size_out_channels = frames_out_channels * popcount(stream_out->mixer_props->channel_mask) * audio_bytes_per_sample(stream_out->mixer_props->format); - buffer_out_channels = calloc(1, size_out_channels); - - int channels_count_in = popcount(stream_out->channel_mask); - int channels_count_out = popcount(stream_out->mixer_props->channel_mask); - int ratio = channels_count_in / channels_count_out; - - int16_t *byte_in = (int16_t *) buffer_in; - int16_t *byte_out = (int16_t *) buffer_out_channels; - int16_t byte; - - for(i=0 ; i < frames_out_channels * channels_count_out; i++) { - byte = 0; - for(j=0 ; j < ratio ; j++) { - byte += *byte_in / ratio; - byte_in++; - } - - *byte_out = byte; - byte_out++; - } - - frames_in = frames_out_channels; - size_in = size_out_channels; - buffer_in = buffer_out_channels; - } else if(popcount(stream_out->channel_mask) != popcount(stream_out->mixer_props->channel_mask)) { - ALOGE("Asked for more channels than software can provide!"); - goto error; - } - - if(buffer_in != NULL) { - if(stream_out->pcm == NULL || !pcm_is_ready(stream_out->pcm)) { - ALOGE("pcm device is not ready"); - goto error; - } - - rc = pcm_write(stream_out->pcm, buffer_in, size_in); - if(rc != 0) { - ALOGE("pcm write failed!"); - goto error; - } - } - - if(buffer_out_resampler != NULL) - free(buffer_out_resampler); - if(buffer_out_channels != NULL) - free(buffer_out_channels); - - return 0; - -error: - if(buffer_out_resampler != NULL) - free(buffer_out_resampler); - if(buffer_out_channels != NULL) - free(buffer_out_channels); - - return -1; -} - -static uint32_t audio_out_get_sample_rate(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - - if(stream == NULL) - return 0; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - return stream_out->rate; -} - -static int audio_out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct tinyalsa_audio_stream_out *stream_out; - - ALOGD("%s(%p, %d)", __func__, stream, rate); - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out->rate != (int) rate) { - pthread_mutex_lock(&stream_out->lock); - - stream_out->rate = rate; - - if(stream_out->rate != stream_out->mixer_props->rate) { - audio_out_resampler_close(stream_out); - audio_out_resampler_open(stream_out); - - stream_out->standby = 1; - } - - pthread_mutex_unlock(&stream_out->lock); - } - - return 0; -} - -static size_t audio_out_get_buffer_size(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - size_t size; - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - size = (stream_out->mixer_props->period_size * stream_out->rate) / - stream_out->mixer_props->rate; - size = ((size + 15) / 16) * 16; - size = size * audio_stream_frame_size((struct audio_stream *) stream); - - return size; -} - -static audio_channel_mask_t audio_out_get_channels(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - return stream_out->channel_mask; -} - -static audio_format_t audio_out_get_format(const struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - return stream_out->format; -} - -static int audio_out_set_format(struct audio_stream *stream, audio_format_t format) -{ - struct tinyalsa_audio_stream_out *stream_out; - - //ALOGD("%s(%p, %d)", __func__, stream, format); - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out->format != (audio_format_t) format) { - pthread_mutex_lock(&stream_out->lock); - - stream_out->format = format; - - if(stream_out->format != stream_out->mixer_props->format) - stream_out->standby = 1; - - pthread_mutex_unlock(&stream_out->lock); - } - - return 0; -} - -static int audio_out_standby(struct audio_stream *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - int rc; - - //ALOGD("%s(%p)", __func__, stream); - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - pthread_mutex_lock(&stream_out->lock); - - if(stream_out->pcm != NULL) - audio_out_pcm_close(stream_out); - -#ifdef YAMAHA_MC1N2_AUDIO - if(!stream_out->standby) { - rc = yamaha_mc1n2_audio_output_stop(stream_out->device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } - } -#endif - - stream_out->standby = 1; - - pthread_mutex_unlock(&stream_out->lock); - - return 0; -} - -static int audio_out_dump(const struct audio_stream *stream, int fd) -{ - //ALOGD("%s(%p, %d)", __func__, stream, fd); - - return 0; -} - -static int audio_out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct tinyalsa_audio_stream_out *stream_out; - struct str_parms *parms; - char value_string[32] = { 0 }; - int value; - int rc; - - //ALOGD("%s(%p, %s)", __func__, stream, kvpairs); - - if(stream == NULL || kvpairs == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out->device == NULL || stream_out->device->mixer == NULL) - return -1; - - parms = str_parms_create_str(kvpairs); - if(parms == NULL) - return -1; - - rc = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value_string, sizeof(value_string)); - if(rc < 0) - goto error_params; - - value = atoi(value_string); - - pthread_mutex_lock(&stream_out->device->lock); - - if(stream_out->device_current != (audio_devices_t) value) { - pthread_mutex_lock(&stream_out->lock); - audio_out_set_route(stream_out, (audio_devices_t) value); - pthread_mutex_unlock(&stream_out->lock); - } - if(stream_out->device->ril_interface != NULL && stream_out->device->ril_interface->device_current != (audio_devices_t) value) { - audio_ril_interface_set_route(stream_out->device->ril_interface, (audio_devices_t) value); - } - - pthread_mutex_unlock(&stream_out->device->lock); - - str_parms_destroy(parms); - - return 0; - -error_params: - str_parms_destroy(parms); - - return -1; -} - -static char *audio_out_get_parameters(const struct audio_stream *stream, const char *keys) -{ - //ALOGD("%s(%p, %s)", __func__, stream, keys); - - return strdup(""); -} - -static uint32_t audio_out_get_latency(const struct audio_stream_out *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - uint32_t latency; - - //ALOGD("%s(%p)", __func__, stream); - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - latency = (stream_out->mixer_props->period_size * - stream_out->mixer_props->period_count * 1000) / - stream_out->mixer_props->rate; - - return latency; -} - -static int audio_out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - struct tinyalsa_audio_stream_out *stream_out; - float volume; - - ALOGD("%s(%p, %f, %f)", __func__, stream, left, right); - - if(stream == NULL) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out->device == NULL || stream_out->device->mixer == NULL) - return -1; - - volume = (left + right) / 2; - - pthread_mutex_lock(&stream_out->device->lock); - tinyalsa_mixer_set_output_volume(stream_out->device->mixer, - stream_out->device_current, volume); - pthread_mutex_unlock(&stream_out->device->lock); - - return 0; -} - -static ssize_t audio_out_write(struct audio_stream_out *stream, - const void *buffer, size_t bytes) -{ - struct tinyalsa_audio_stream_out *stream_out; - int rc; - - if(stream == NULL || buffer == NULL || bytes <= 0) - return -1; - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out->device == NULL) - return -1; - - pthread_mutex_lock(&stream_out->lock); - - if(stream_out->standby) { -#ifdef YAMAHA_MC1N2_AUDIO - rc = yamaha_mc1n2_audio_output_start(stream_out->device->mc1n2_pdata); - if(rc < 0) { - ALOGE("Failed to set Yamaha-MC1N2-Audio route"); - } -#endif - - rc = audio_out_pcm_open(stream_out); - if(rc < 0) { - ALOGE("Unable to open pcm device"); - goto error; - } - - stream_out->standby = 0; - } - - rc = audio_out_write_process(stream_out, (void *) buffer, (int) bytes); - if(rc < 0) { - ALOGE("Process and write failed!"); - goto error; - } - - pthread_mutex_unlock(&stream_out->lock); - - return bytes; - -error: - pthread_mutex_unlock(&stream_out->lock); - - return -1; -} - -static int audio_out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - //ALOGD("%s(%p, %p)", __func__, stream, dsp_frames); - - return -EINVAL; -} - -static int audio_out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - //ALOGD("%s(%p, %p)", __func__, stream, effect); - - return 0; -} - -static int audio_out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - //ALOGD("%s(%p, %p)", __func__, stream, effect); - - return 0; -} - -/* - * Interface - */ - -void audio_hw_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) -{ - struct tinyalsa_audio_stream_out *stream_out; - struct tinyalsa_audio_device *tinyalsa_audio_device; - - ALOGD("%s(%p)", __func__, stream); - - stream_out = (struct tinyalsa_audio_stream_out *) stream; - - if(stream_out != NULL && stream_out->resampler != NULL) - audio_out_resampler_close(stream_out); - -#ifdef YAMAHA_MC1N2_AUDIO - if(stream_out != NULL && !stream_out->standby) - yamaha_mc1n2_audio_output_stop(stream_out->device->mc1n2_pdata); -#endif - - if(stream != NULL) - free(stream); - - if(dev == NULL) - return; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - - pthread_mutex_lock(&tinyalsa_audio_device->lock); - - tinyalsa_mixer_set_output_state(tinyalsa_audio_device->mixer, 0); - tinyalsa_audio_device->stream_out = NULL; - - pthread_mutex_unlock(&tinyalsa_audio_device->lock); -} - -int audio_hw_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) -{ - struct tinyalsa_audio_device *tinyalsa_audio_device; - struct tinyalsa_audio_stream_out *tinyalsa_audio_stream_out; - struct audio_stream_out *stream; - int rc; - - ALOGD("%s(%p, %d, %p, %p)", - __func__, dev, devices, config, stream_out); - - if(dev == NULL || config == NULL || stream_out == NULL) - return -EINVAL; - - //tuna added this for JB... but does it apply to us? - *stream_out = NULL; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - tinyalsa_audio_stream_out = calloc(1, sizeof(struct tinyalsa_audio_stream_out)); - - if(tinyalsa_audio_stream_out == NULL) - return -ENOMEM; - - tinyalsa_audio_stream_out->device = tinyalsa_audio_device; - tinyalsa_audio_device->stream_out = tinyalsa_audio_stream_out; - stream = &(tinyalsa_audio_stream_out->stream); - - stream->common.get_sample_rate = audio_out_get_sample_rate; - stream->common.set_sample_rate = audio_out_set_sample_rate; - stream->common.get_buffer_size = audio_out_get_buffer_size; - stream->common.get_channels = audio_out_get_channels; - stream->common.get_format = audio_out_get_format; - stream->common.set_format = audio_out_set_format; - stream->common.standby = audio_out_standby; - stream->common.dump = audio_out_dump; - stream->common.set_parameters = audio_out_set_parameters; - stream->common.get_parameters = audio_out_get_parameters; - stream->common.add_audio_effect = audio_out_add_audio_effect; - stream->common.remove_audio_effect = audio_out_remove_audio_effect; - stream->get_latency = audio_out_get_latency; - stream->set_volume = audio_out_set_volume; - stream->write = audio_out_write; - stream->get_render_position = audio_out_get_render_position; - - if(tinyalsa_audio_device->mixer == NULL) - goto error_stream; - - tinyalsa_audio_stream_out->mixer_props = - tinyalsa_mixer_get_output_props(tinyalsa_audio_device->mixer); - - if(tinyalsa_audio_stream_out->mixer_props == NULL) - goto error_stream; - - // Default values - if(tinyalsa_audio_stream_out->mixer_props->rate == 0) - tinyalsa_audio_stream_out->mixer_props->rate = 44100; - if(tinyalsa_audio_stream_out->mixer_props->channel_mask == 0) - tinyalsa_audio_stream_out->mixer_props->channel_mask = AUDIO_CHANNEL_OUT_STEREO; - if(tinyalsa_audio_stream_out->mixer_props->format == 0) - tinyalsa_audio_stream_out->mixer_props->format = AUDIO_FORMAT_PCM_16_BIT; - - //Default incoming data will always be 44100Hz, stereo, PCM 16 - if(config->sample_rate == 0) - tinyalsa_audio_stream_out->rate = 44100; - else - tinyalsa_audio_stream_out->rate = config->sample_rate; - if(config->channel_mask == 0) - tinyalsa_audio_stream_out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; - else - tinyalsa_audio_stream_out->channel_mask = config->channel_mask; - if(config->format == 0) - tinyalsa_audio_stream_out->format = AUDIO_FORMAT_PCM_16_BIT; - else - tinyalsa_audio_stream_out->format = config->format; - - if(tinyalsa_audio_stream_out->rate != tinyalsa_audio_stream_out->mixer_props->rate) { - rc = audio_out_resampler_open(tinyalsa_audio_stream_out); - if(rc < 0) { - ALOGE("Unable to open resampler!"); - goto error_stream; - } - } - - config->sample_rate = (uint32_t) tinyalsa_audio_stream_out->rate; - config->channel_mask = (uint32_t) tinyalsa_audio_stream_out->channel_mask; - config->format = (uint32_t) tinyalsa_audio_stream_out->format; - - pthread_mutex_lock(&tinyalsa_audio_device->lock); - - rc = tinyalsa_mixer_set_output_state(tinyalsa_audio_device->mixer, 1); - if(rc < 0) { - ALOGE("Unable to set output state"); - pthread_mutex_unlock(&tinyalsa_audio_device->lock); - goto error_stream; - } - - pthread_mutex_lock(&tinyalsa_audio_stream_out->lock); - - audio_out_set_route(tinyalsa_audio_stream_out, devices); - - pthread_mutex_unlock(&tinyalsa_audio_device->lock); - - rc = audio_out_pcm_open(tinyalsa_audio_stream_out); - if(rc < 0) { - ALOGE("Unable to open pcm device"); - pthread_mutex_unlock(&tinyalsa_audio_stream_out->lock); - goto error_stream; - } - - audio_out_pcm_close(tinyalsa_audio_stream_out); - - tinyalsa_audio_stream_out->standby = 1; - - pthread_mutex_unlock(&tinyalsa_audio_stream_out->lock); - - *stream_out = stream; - - return 0; - -error_stream: - free(tinyalsa_audio_stream_out); - tinyalsa_audio_device->stream_out = NULL; - - return -1; -} diff --git a/tinyalsa_audio/audio_ril_interface.c b/tinyalsa_audio/audio_ril_interface.c deleted file mode 100644 index 2f88d14..0000000 --- a/tinyalsa_audio/audio_ril_interface.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define LOG_TAG "TinyALSA-Audio RIL Interface" - -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <dlfcn.h> -#include <sys/time.h> - -#include <cutils/log.h> - -#include <cutils/properties.h> - -#define EFFECT_UUID_NULL EFFECT_UUID_NULL_RIL -#define EFFECT_UUID_NULL_STR EFFECT_UUID_NULL_STR_RIL -#include "audio_hw.h" - -#include "audio_ril_interface.h" - -/* Function pointers */ -void *(*_ril_open_client)(void); -int (*_ril_close_client)(void *); -int (*_ril_connect)(void *); -int (*_ril_is_connected)(void *); -int (*_ril_disconnect)(void *); -int (*_ril_set_call_volume)(void *, enum ril_sound_type, int); -int (*_ril_set_call_audio_path)(void *, enum ril_audio_path); -int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state); -int (*_ril_set_call_twomic)(void *, enum ril_twomic_device, enum ril_twomic_enable); -int (*_ril_set_mic_mute)(void *, enum ril_mic_mute); -int (*_ril_register_unsolicited_handler)(void *, int, void *); -int (*_ril_get_wb_amr)(void *, void *); - -#define VOLUME_STEPS_DEFAULT "5" -#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps" - -static int audio_ril_interface_connect_if_required(struct tinyalsa_audio_ril_interface *ril_interface) -{ - if (_ril_is_connected(ril_interface->interface)) - return 0; - - if (_ril_connect(ril_interface->interface) != RIL_CLIENT_ERR_SUCCESS) { - ALOGE("ril_connect() failed"); - return -1; - } - - /* get wb amr status to set pcm samplerate depending on - wb amr status when ril is connected. */ - /* FIXME: AMR */ -#if 0 - if(_ril_get_wb_amr) - _ril_get_wb_amr(ril_interface->client, ril_set_wb_amr_callback); -#endif - - return 0; -} - - -int audio_ril_interface_set_voice_volume(struct tinyalsa_audio_ril_interface *ril_interface, - audio_devices_t device, float volume) -{ - int rc; - - enum ril_sound_type sound_type; - - if(ril_interface == NULL) - return -1; - - ALOGD("%s(%d, %f)", __func__, device, volume); - - pthread_mutex_lock(&ril_interface->lock); - - /* Should this be returning -1 when a failure occurs? */ - if (audio_ril_interface_connect_if_required(ril_interface)) - return 0; - - if(_ril_set_call_volume == NULL) - goto error; - - switch((int) device) { - case AUDIO_DEVICE_OUT_EARPIECE: - sound_type = SOUND_TYPE_VOICE; - break; - case AUDIO_DEVICE_OUT_SPEAKER: - sound_type = SOUND_TYPE_SPEAKER; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADSET: - case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: - sound_type = SOUND_TYPE_HEADSET; - break; - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: - sound_type = SOUND_TYPE_BTVOICE; - break; - default: - sound_type = SOUND_TYPE_VOICE; - break; - } - - rc = _ril_set_call_volume(ril_interface->interface, sound_type, - (int)(volume * ril_interface->volume_steps_max)); - - if(rc < 0) { - ALOGE("Failed to set RIL interface voice volume"); - goto error; - } - - pthread_mutex_unlock(&ril_interface->lock); - - return 0; - -error: - pthread_mutex_unlock(&ril_interface->lock); - - return -1; -} - -int audio_ril_interface_set_route(struct tinyalsa_audio_ril_interface *ril_interface, audio_devices_t device) -{ - int rc; - - enum ril_audio_path path; - - ALOGD("%s(%d)", __func__, device); - - if(ril_interface == NULL) - return -1; - - pthread_mutex_lock(&ril_interface->lock); - - /* Should this be returning -1 when a failure occurs? */ - if (audio_ril_interface_connect_if_required(ril_interface)) - return 0; - - ril_interface->device_current = device; - - if(_ril_set_call_audio_path == NULL) - goto error; - - switch((int) device) { - case AUDIO_DEVICE_OUT_EARPIECE: - path = SOUND_AUDIO_PATH_HANDSET; - break; - case AUDIO_DEVICE_OUT_SPEAKER: - path = SOUND_AUDIO_PATH_SPEAKER; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADSET: - path = SOUND_AUDIO_PATH_HEADSET; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: - path = SOUND_AUDIO_PATH_HEADPHONE; - break; - // FIXME: Bluetooth values/path relation - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: - path = SOUND_AUDIO_PATH_BLUETOOTH; - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: - path = SOUND_AUDIO_PATH_BLUETOOTH_NO_NR; - break; - default: - path = SOUND_AUDIO_PATH_HANDSET; - break; - } - - rc = _ril_set_call_audio_path(ril_interface->interface,path); - - if(rc < 0) { - ALOGE("Failed to set RIL interface route"); - goto error; - } - - pthread_mutex_unlock(&ril_interface->lock); - - return 0; - -error: - pthread_mutex_unlock(&ril_interface->lock); - - return -1; -} - -int audio_ril_interface_set_mic_mute(struct tinyalsa_audio_ril_interface *ril_interface, enum ril_mic_mute state) -{ - if (audio_ril_interface_connect_if_required(ril_interface)) - return 0; - - return _ril_set_mic_mute(ril_interface->interface, state); -} - - -int audio_ril_interface_set_twomic(struct tinyalsa_audio_ril_interface *ril_interface, enum ril_twomic_enable twomic) -{ - int rc; - - ALOGD("%s(%d)", __func__, twomic); - - if(ril_interface == NULL) - return -1; - - pthread_mutex_lock(&ril_interface->lock); - - /* Should this be returning -1 when a failure occurs? */ - if (audio_ril_interface_connect_if_required(ril_interface)) - return 0; - - if(_ril_set_call_twomic == NULL) - goto error; - - rc = _ril_set_call_twomic(ril_interface->interface,AUDIENCE,twomic); - - if(rc < 0) { - ALOGE("Failed to set RIL interface route"); - goto error; - } - - pthread_mutex_unlock(&ril_interface->lock); - - return 0; - -error: - pthread_mutex_unlock(&ril_interface->lock); - - return -1; -} - -/* - * Interface - */ - -void audio_ril_interface_close(struct audio_hw_device *dev, - struct tinyalsa_audio_ril_interface *ril_interface) -{ - struct tinyalsa_audio_device *tinyalsa_audio_device; - - ALOGD("%s(%p)", __func__, ril_interface); - - if(ril_interface->dl_handle != NULL) { - if ((_ril_disconnect(ril_interface->interface) != RIL_CLIENT_ERR_SUCCESS) || - (_ril_close_client(ril_interface->interface) != RIL_CLIENT_ERR_SUCCESS)) { - ALOGE("ril_disconnect() or ril_close_client() failed"); - return; - } - - dlclose(ril_interface->dl_handle); - ril_interface->dl_handle = NULL; - } - - if(ril_interface != NULL) - free(ril_interface); - - if(dev == NULL) - return; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - - tinyalsa_audio_device->ril_interface = NULL; -} - -int audio_ril_interface_open(struct audio_hw_device *dev, audio_devices_t device, - struct tinyalsa_audio_ril_interface **ril_interface) -{ - struct audio_ril_interface *(*audio_ril_interface_open)(void); - - struct tinyalsa_audio_device *tinyalsa_audio_device; - struct tinyalsa_audio_ril_interface *tinyalsa_audio_ril_interface; - struct audio_ril_interface *interface; - void *dl_handle; - int rc; - - char property[PROPERTY_VALUE_MAX]; - - ALOGD("%s(%p, %d, %p)", __func__, dev, device, ril_interface); - - if(dev == NULL || ril_interface == NULL) - return -EINVAL; - - tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev; - tinyalsa_audio_ril_interface = calloc(1, sizeof(struct tinyalsa_audio_ril_interface)); - - if(tinyalsa_audio_ril_interface == NULL) - return -ENOMEM; - - tinyalsa_audio_ril_interface->device = tinyalsa_audio_device; - tinyalsa_audio_device->ril_interface = tinyalsa_audio_ril_interface; - - dl_handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW); - if(dl_handle == NULL) { - ALOGE("Unable to dlopen lib: %s", RIL_CLIENT_LIBPATH); - goto error_interface; - } - - _ril_open_client = dlsym(dl_handle, "OpenClient_RILD"); - _ril_close_client = dlsym(dl_handle, "CloseClient_RILD"); - _ril_connect = dlsym(dl_handle, "Connect_RILD"); - _ril_is_connected = dlsym(dl_handle, "isConnected_RILD"); - _ril_disconnect = dlsym(dl_handle, "Disconnect_RILD"); - _ril_set_call_volume = dlsym(dl_handle, "SetCallVolume"); - _ril_set_call_audio_path = dlsym(dl_handle, "SetCallAudioPath"); - _ril_set_call_clock_sync = dlsym(dl_handle, "SetCallClockSync"); - _ril_set_call_twomic = dlsym(dl_handle, "SetTwoMicControl"); - _ril_set_mic_mute = dlsym(dl_handle, "SetMute"); - _ril_register_unsolicited_handler = dlsym(dl_handle, - "RegisterUnsolicitedHandler"); - /* since this function is not supported in all RILs, don't require it */ - _ril_get_wb_amr = dlsym(dl_handle, "GetWB_AMR"); - - if (!_ril_open_client || !_ril_close_client || !_ril_connect || - !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume || - !_ril_set_call_audio_path || !_ril_set_mic_mute || - !_ril_set_call_clock_sync || - !_ril_register_unsolicited_handler || !_ril_set_call_twomic) { - ALOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH); - dlclose(dl_handle); - goto error_interface; - } - - interface = _ril_open_client(); - if(interface == NULL) { - ALOGE("Unable to open audio ril interface"); - goto error_interface; - } - - tinyalsa_audio_ril_interface->interface = interface; - tinyalsa_audio_ril_interface->dl_handle = dl_handle; - - property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT); - tinyalsa_audio_ril_interface->volume_steps_max = atoi(property); - /* this catches the case where VOLUME_STEPS_PROPERTY does not contain - an integer */ - if (tinyalsa_audio_ril_interface->volume_steps_max == 0) - tinyalsa_audio_ril_interface->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT); - - if(device) { - tinyalsa_audio_ril_interface->device_current = device; - audio_ril_interface_set_route(tinyalsa_audio_ril_interface, device); - } - - *ril_interface = tinyalsa_audio_ril_interface; - - return 0; - -error_interface: - *ril_interface = NULL; - free(tinyalsa_audio_ril_interface); - tinyalsa_audio_device->ril_interface = NULL; - - if(dl_handle != NULL) - dlclose(dl_handle); - - return -1; -} diff --git a/tinyalsa_audio/audio_ril_interface.h b/tinyalsa_audio/audio_ril_interface.h deleted file mode 100644 index 66d806f..0000000 --- a/tinyalsa_audio/audio_ril_interface.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "audio_hw.h" - -#ifndef TINYALSA_AUDIO_RIL_INTERFACE_H -#define TINYALSA_AUDIO_RIL_INTERFACE_H - -struct tinyalsa_audio_ril_interface { - void *interface; - struct tinyalsa_audio_device *device; - - int volume_steps_max; - - void *dl_handle; - - audio_devices_t device_current; - - pthread_mutex_t lock; -}; - -#define RIL_CLIENT_LIBPATH "libsecril-client.so" - -#define RIL_CLIENT_ERR_SUCCESS 0 -#define RIL_CLIENT_ERR_AGAIN 1 -#define RIL_CLIENT_ERR_INIT 2 // Client is not initialized -#define RIL_CLIENT_ERR_INVAL 3 // Invalid value -#define RIL_CLIENT_ERR_CONNECT 4 // Connection error -#define RIL_CLIENT_ERR_IO 5 // IO error -#define RIL_CLIENT_ERR_RESOURCE 6 // Resource not available -#define RIL_CLIENT_ERR_UNKNOWN 7 - -enum ril_sound_type { - SOUND_TYPE_VOICE, - SOUND_TYPE_SPEAKER, - SOUND_TYPE_HEADSET, - SOUND_TYPE_BTVOICE -}; - -enum ril_audio_path { - SOUND_AUDIO_PATH_HANDSET, - SOUND_AUDIO_PATH_HEADSET, - SOUND_AUDIO_PATH_SPEAKER, - SOUND_AUDIO_PATH_BLUETOOTH, - SOUND_AUDIO_PATH_BLUETOOTH_NO_NR, - SOUND_AUDIO_PATH_HEADPHONE -}; - -enum ril_clock_state { - SOUND_CLOCK_STOP, - SOUND_CLOCK_START -}; - -/** - * Two mic Solution control - * Two MIC Solution Device - */ -enum ril_twomic_device { - AUDIENCE, - FORTEMEDIA -}; - -/** - * Two MIC Solution Report - */ -enum ril_twomic_enable { - TWO_MIC_SOLUTION_OFF, - TWO_MIC_SOLUTION_ON -}; - - -enum ril_mic_mute { - MIC_UNMUTE, - MIC_MUTE -}; - - -int audio_ril_interface_set_mic_mute(struct tinyalsa_audio_ril_interface *ril_interface, enum ril_mic_mute); -int audio_ril_interface_set_voice_volume(struct tinyalsa_audio_ril_interface *ril_interface, audio_devices_t device, float volume); -int audio_ril_interface_set_route(struct tinyalsa_audio_ril_interface *ril_interface, audio_devices_t device); -int audio_ril_interface_set_twomic(struct tinyalsa_audio_ril_interface *ril_interface, enum ril_twomic_enable); - -void audio_ril_interface_close(struct audio_hw_device *dev, - struct tinyalsa_audio_ril_interface *interface); -int audio_ril_interface_open(struct audio_hw_device *dev, audio_devices_t device, - struct tinyalsa_audio_ril_interface **ril_interface); - -#endif diff --git a/tinyalsa_audio/mixer.c b/tinyalsa_audio/mixer.c deleted file mode 100644 index cda890e..0000000 --- a/tinyalsa_audio/mixer.c +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This is based on Galaxy Nexus audio.primary.tuna implementation: - * Copyright 2011, The Android Open-Source Project - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define LOG_TAG "TinyALSA-Audio Mixer" - -#include <fcntl.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <sys/time.h> - -#include <cutils/log.h> - -#include <expat.h> - -#define EFFECT_UUID_NULL EFFECT_UUID_NULL_MIXER -#define EFFECT_UUID_NULL_STR EFFECT_UUID_NULL_STR_MIXER -#include "audio_hw.h" -#include "mixer.h" - -/* - * List - */ - -struct list_head *list_head_alloc(void) -{ - struct list_head *list = (struct list_head *) - calloc(1, sizeof(struct list_head)); - - return list; -} - -void list_head_free(struct list_head *list) -{ - struct list_head *list_prev; - - while(list != NULL) { - list_prev = list; - list = list->next; - - free(list_prev); - } -} - -/* - * Mixer data - */ - -struct tinyalsa_mixer_data *tinyalsa_mixer_data_alloc(void) -{ - struct tinyalsa_mixer_data *mixer_data = (struct tinyalsa_mixer_data *) - calloc(1, sizeof(struct tinyalsa_mixer_data)); - - return mixer_data; -} - -void tinyalsa_mixer_data_free(struct tinyalsa_mixer_data *mixer_data) -{ - if(mixer_data == NULL) - return; - - if(mixer_data->name != NULL) { - free(mixer_data->name); - mixer_data->name = NULL; - } - - if(mixer_data->value != NULL) { - free(mixer_data->value); - mixer_data->value = NULL; - } - - if(mixer_data->attr != NULL) { - free(mixer_data->attr); - mixer_data->attr = NULL; - } - - free(mixer_data); -} - -struct tinyalsa_mixer_data *tinyalsa_mixer_get_data_with_attr( - struct list_head *list_data, char *attr) -{ - struct tinyalsa_mixer_data *mixer_data = NULL; - - while(list_data != NULL) { - mixer_data = (struct tinyalsa_mixer_data *) list_data->data; - - if(mixer_data->type == MIXER_DATA_TYPE_CTRL) { - if(mixer_data->attr != NULL && - strcmp(mixer_data->attr, attr) == 0) { - break; - } else { - mixer_data = NULL; - } - - } - - if(list_data->next != NULL) - list_data = list_data->next; - else - break; - } - - return mixer_data; -} - -/* - * Mixer device - */ - -struct tinyalsa_mixer_device *tinyalsa_mixer_device_alloc(void) -{ - struct tinyalsa_mixer_device *mixer_device = (struct tinyalsa_mixer_device *) - calloc(1, sizeof(struct tinyalsa_mixer_device)); - - return mixer_device; -} - -void tinyalsa_mixer_device_free(struct tinyalsa_mixer_device *mixer_device) -{ - struct tinyalsa_mixer_data *mixer_data; - struct list_head *list_data; - struct list_head *list_prev; - - if(mixer_device == NULL) - return; - - list_data = mixer_device->enable; - - while(list_data != NULL) { - mixer_data = (struct tinyalsa_mixer_data *) list_data->data; - - tinyalsa_mixer_data_free(mixer_data); - list_data->data = NULL; - - list_prev = list_data; - list_data = list_data->next; - - list_head_free(list_prev); - } - - list_data = mixer_device->disable; - - while(list_data != NULL) { - mixer_data = (struct tinyalsa_mixer_data *) list_data->data; - - tinyalsa_mixer_data_free(mixer_data); - list_data->data = NULL; - - list_prev = list_data; - list_data = list_data->next; - - list_head_free(list_prev); - } - - mixer_device->enable = NULL; - mixer_device->disable = NULL; - - free(mixer_device); -} - -struct tinyalsa_mixer_device *tinyalsa_mixer_get_device(struct tinyalsa_mixer_io *mixer_io, - audio_devices_t device) -{ - struct tinyalsa_mixer_device *mixer_device = NULL; - struct list_head *list = NULL; - - if(mixer_io == NULL) - return NULL; - - list = mixer_io->devices; - - while(list != NULL) { - mixer_device = (struct tinyalsa_mixer_device *) list->data; - if(mixer_device != NULL && mixer_device->props.type == device) { - break; - } else { - mixer_device = NULL; - } - - list = list->next; - } - - return mixer_device; -} - -/* - * Mixer I/O - */ - -void tinyalsa_mixer_io_free_devices(struct tinyalsa_mixer_io *mixer_io) -{ - struct tinyalsa_mixer_device *mixer_device; - struct list_head *list_device; - struct list_head *list_prev; - - if(mixer_io == NULL) - return; - - list_device = mixer_io->devices; - - while(list_device != NULL) { - mixer_device = (struct tinyalsa_mixer_device *) list_device->data; - - tinyalsa_mixer_device_free(mixer_device); - list_device->data = NULL; - - list_prev = list_device; - list_device = list_device->next; - - list_head_free(list_prev); - } -} - -/* - * Mixer config - */ - -void tinyalsa_mixer_config_start(void *data, const XML_Char *elem, - const XML_Char **attr) -{ - struct tinyalsa_mixer_config_data *config_data; - struct tinyalsa_mixer_data *mixer_data; - struct list_head *list; - int i; - - if(data == NULL || elem == NULL || attr == NULL) - return; - - config_data = (struct tinyalsa_mixer_config_data *) data; - - if(strcmp(elem, "tinyalsa-audio") == 0) { - for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) { - if(strcmp(attr[i], "device") == 0) { - i++; - ALOGD("Parsing config for device: %s", attr[i]); - } - } - } else if(strcmp(elem, "output") == 0) { - config_data->direction = TINYALSA_MIXER_DIRECTION_OUTPUT; - - for(i=0 ; attr[i] != NULL && attr[i+1] ; i++) { - if(strcmp(attr[i], "card") == 0) { - i++; - config_data->io_props.card = atoi(attr[i]); - } else if(strcmp(attr[i], "device") == 0) { - i++; - config_data->io_props.device = atoi(attr[i]); - } else if(strcmp(attr[i], "rate") == 0) { - i++; - config_data->io_props.rate = atoi(attr[i]); - } else if(strcmp(attr[i], "channels") == 0) { - i++; - switch(atoi(attr[i])) { - case 1: - config_data->io_props.channel_mask = AUDIO_CHANNEL_OUT_MONO; - break; - case 2: - config_data->io_props.channel_mask = AUDIO_CHANNEL_OUT_STEREO; - break; - case 4: - config_data->io_props.channel_mask = AUDIO_CHANNEL_OUT_QUAD_SIDE; - break; - case 6: - config_data->io_props.channel_mask = AUDIO_CHANNEL_OUT_5POINT1; - break; - case 8: - config_data->io_props.channel_mask = AUDIO_CHANNEL_OUT_7POINT1; - break; - default: - ALOGE("Unknown channel attr: %s", attr[i]); - break; - } - } else if(strcmp(attr[i], "format") == 0) { - i++; - if(strcmp(attr[i], "PCM_8") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_8_BIT; - } else if(strcmp(attr[i], "PCM_16") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_16_BIT; - } else if(strcmp(attr[i], "PCM_32") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_32_BIT; - } else if(strcmp(attr[i], "PCM_8_24") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_8_24_BIT; - } else { - ALOGE("Unknown format attr: %s", attr[i]); - } - } else if(strcmp(attr[i], "period_size") == 0) { - i++; - config_data->io_props.period_size = atoi(attr[i]); - } else if(strcmp(attr[i], "period_count") == 0) { - i++; - config_data->io_props.period_count = atoi(attr[i]); - } else { - ALOGE("Unknown output attr: %s", attr[i]); - } - } - } else if(strcmp(elem, "input") == 0) { - config_data->direction = TINYALSA_MIXER_DIRECTION_INPUT; - - for(i=0 ; attr[i] != NULL && attr[i+1] ; i++) { - if(strcmp(attr[i], "card") == 0) { - i++; - config_data->io_props.card = atoi(attr[i]); - } else if(strcmp(attr[i], "device") == 0) { - i++; - config_data->io_props.device = atoi(attr[i]); - } else if(strcmp(attr[i], "rate") == 0) { - i++; - config_data->io_props.rate = atoi(attr[i]); - } else if(strcmp(attr[i], "channels") == 0) { - i++; - switch(atoi(attr[i])) { - case 1: - config_data->io_props.channel_mask = AUDIO_CHANNEL_IN_MONO; - break; - case 2: - config_data->io_props.channel_mask = AUDIO_CHANNEL_IN_STEREO; - break; - default: - ALOGE("Unknown channel attr: %s", attr[i]); - break; - } - } else if(strcmp(attr[i], "format") == 0) { - i++; - if(strcmp(attr[i], "PCM_8") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_8_BIT; - } else if(strcmp(attr[i], "PCM_16") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_16_BIT; - } else if(strcmp(attr[i], "PCM_32") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_32_BIT; - } else if(strcmp(attr[i], "PCM_8_24") == 0) { - config_data->io_props.format = AUDIO_FORMAT_PCM_8_24_BIT; - } else { - ALOGE("Unknown format attr: %s", attr[i]); - } - } else if(strcmp(attr[i], "period_size") == 0) { - i++; - config_data->io_props.period_size = atoi(attr[i]); - } else if(strcmp(attr[i], "period_count") == 0) { - i++; - config_data->io_props.period_count = atoi(attr[i]); - } else { - ALOGE("Unknown input attr: %s", attr[i]); - } - } - } else if(strcmp(elem, "modem") == 0) { - config_data->direction = TINYALSA_MIXER_DIRECTION_MODEM; - - for(i=0 ; attr[i] != NULL && attr[i+1] ; i++) { - if(strcmp(attr[i], "card") == 0) { - i++; - config_data->io_props.card = atoi(attr[i]); - } else if(strcmp(attr[i], "device") == 0) { - i++; - config_data->io_props.device = atoi(attr[i]); - } else { - ALOGE("Unknown modem attr: %s", attr[i]); - } - } - } else if(strcmp(elem, "device") == 0) { - for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) { - if(strcmp(attr[i], "type") == 0) { - i++; - if(config_data->direction == TINYALSA_MIXER_DIRECTION_OUTPUT || - config_data->direction == TINYALSA_MIXER_DIRECTION_MODEM) { - if(strcmp(attr[i], "default") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_DEFAULT; - } else if(strcmp(attr[i], "earpiece") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_EARPIECE; - } else if(strcmp(attr[i], "speaker") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_SPEAKER; - } else if(strcmp(attr[i], "wired-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_WIRED_HEADSET; - } else if(strcmp(attr[i], "wired-headphone") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - } else if(strcmp(attr[i], "bt-sco") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_SCO; - } else if(strcmp(attr[i], "bt-sco-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - } else if(strcmp(attr[i], "bt-sco-carkit") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - } else if(strcmp(attr[i], "bt-a2dp") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - } else if(strcmp(attr[i], "bt-a2dp-headphones") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - } else if(strcmp(attr[i], "bt-a2dp-speaker") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - } else if(strcmp(attr[i], "aux-digital") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_AUX_DIGITAL; - } else if(strcmp(attr[i], "analog-dock-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - } else if(strcmp(attr[i], "digital-dock-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; -/* - * There is now FM support for Qcom devices. Now that Qcom FM is working, - * it may be possible to get Samsung FM working... SAMSUNG_FM_ENABLED - * is a temp placeholder for the ifdef. See QCOM_FM_ENABLED for an example - * in system/core/include/system/audio.h - */ -#ifdef SAMSUNG_FM_ENABLED - } else if(strcmp(attr[i], "fm") == 0) { - config_data->device_props.type = AUDIO_DEVICE_OUT_FM; -#endif - } else { - ALOGE("Unknown device attr: %s", attr[i]); - } - } else if(config_data->direction == TINYALSA_MIXER_DIRECTION_INPUT) { - if(strcmp(attr[i], "default") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_DEFAULT; - } else if(strcmp(attr[i], "communication") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_COMMUNICATION; - } else if(strcmp(attr[i], "ambient") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_AMBIENT; - } else if(strcmp(attr[i], "builtin-mic") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_BUILTIN_MIC; - } else if(strcmp(attr[i], "bt-sco-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if(strcmp(attr[i], "wired-headset") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if(strcmp(attr[i], "aux-digital") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_AUX_DIGITAL; - } else if(strcmp(attr[i], "voice-call") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_VOICE_CALL; - } else if(strcmp(attr[i], "back-mic") == 0) { - config_data->device_props.type = AUDIO_DEVICE_IN_BACK_MIC; - } else { - ALOGE("Unknown device attr: %s", attr[i]); - } - } - } else { - ALOGE("Unknown device attr: %s", attr[i]); - } - - if(config_data->device_props.type != 0) { - config_data->device = tinyalsa_mixer_device_alloc(); - memcpy(&config_data->device->props, &config_data->device_props, sizeof(config_data->device_props)); - } else { - ALOGE("Missing attrs for elem: %s", elem); - } - } - } else if(strcmp(elem, "path") == 0) { - for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) { - if(strcmp(attr[i], "type") == 0) { - i++; - if(strcmp(attr[i], "enable") == 0) { - config_data->list_start = &config_data->device->enable; - } else if(strcmp(attr[i], "disable") == 0) { - config_data->list_start = &config_data->device->disable; - } else { - ALOGE("Unknown path attr: %s", attr[i]); - } - } else { - ALOGE("Unknown path attr: %s", attr[i]); - } - } - } else if(strcmp(elem, "ctrl") == 0) { - if(config_data->device != NULL && config_data->list_start != NULL) { - list = list_head_alloc(); - mixer_data = tinyalsa_mixer_data_alloc(); - - mixer_data->type = MIXER_DATA_TYPE_CTRL; - list->data = (void *) mixer_data; - } else { - ALOGE("Missing device/path for elem: %s", elem); - return; - } - - for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) { - if(strcmp(attr[i], "name") == 0) { - i++; - mixer_data->name = strdup((char *) attr[i]); - } else if(strcmp(attr[i], "attr") == 0) { - i++; - mixer_data->attr = strdup((char *) attr[i]); - } else if(strcmp(attr[i], "value") == 0) { - i++; - mixer_data->value = strdup((char *) attr[i]); - } else { - ALOGE("Unknown ctrl attr: %s", attr[i]); - } - } - - if(mixer_data->name != NULL && mixer_data->value != NULL) { - if(*config_data->list_start == NULL) { - *config_data->list_start = list; - } else { - config_data->list->next = list; - list->prev = config_data->list; - } - - config_data->list = list; - } else { - tinyalsa_mixer_data_free(mixer_data); - list_head_free(list); - } - } else if(strcmp(elem, "write") == 0) { - if(config_data->device != NULL && config_data->list_start != NULL) { - list = list_head_alloc(); - mixer_data = tinyalsa_mixer_data_alloc(); - - mixer_data->type = MIXER_DATA_TYPE_WRITE; - list->data = (void *) mixer_data; - } else { - ALOGE("Missing device/path for elem: %s", elem); - return; - } - - for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) { - if(strcmp(attr[i], "name") == 0) { - i++; - mixer_data->name = strdup((char *) attr[i]); - } else if(strcmp(attr[i], "value") == 0) { - i++; - mixer_data->value = strdup((char *) attr[i]); - } else { - ALOGE("Unknown write attr: %s", attr[i]); - } - } - - if(mixer_data->name != NULL && mixer_data->value != NULL) { - if(*config_data->list_start == NULL) { - *config_data->list_start = list; - } else { - config_data->list->next = list; - list->prev = config_data->list; - } - - config_data->list = list; - } else { - tinyalsa_mixer_data_free(mixer_data); - list_head_free(list); - } - } -} - -void tinyalsa_mixer_config_end(void *data, const XML_Char *elem) -{ - struct tinyalsa_mixer_config_data *config_data; - struct list_head *list_prev; - struct list_head *list; - - if(data == NULL || elem == NULL) - return; - - config_data = (struct tinyalsa_mixer_config_data *) data; - - if(strcmp(elem, "output") == 0) { - memcpy(&config_data->mixer->output.props, &config_data->io_props, sizeof(config_data->io_props)); - memset(&config_data->io_props, 0, sizeof(config_data->io_props)); - config_data->direction = 0; - } else if(strcmp(elem, "input") == 0) { - memcpy(&config_data->mixer->input.props, &config_data->io_props, sizeof(config_data->io_props)); - memset(&config_data->io_props, 0, sizeof(config_data->io_props)); - config_data->direction = 0; - } else if(strcmp(elem, "modem") == 0) { - memcpy(&config_data->mixer->modem.props, &config_data->io_props, sizeof(config_data->io_props)); - memset(&config_data->io_props, 0, sizeof(config_data->io_props)); - config_data->direction = 0; - } else if(strcmp(elem, "device") == 0) { - // direction == 0 will fallback to out - if(config_data->direction == TINYALSA_MIXER_DIRECTION_OUTPUT) { - list = list_head_alloc(); - list->data = (void *) config_data->device; - - if(config_data->mixer->output.devices == NULL) { - config_data->mixer->output.devices = list; - } else { - list_prev = config_data->mixer->output.devices; - - while(list_prev->next != NULL) - list_prev = list_prev->next; - - list_prev->next = list; - list->prev = list_prev; - } - } else if(config_data->direction == TINYALSA_MIXER_DIRECTION_INPUT) { - list = list_head_alloc(); - list->data = (void *) config_data->device; - - if(config_data->mixer->input.devices == NULL) { - config_data->mixer->input.devices = list; - } else { - list_prev = config_data->mixer->input.devices; - - while(list_prev->next != NULL) - list_prev = list_prev->next; - - list_prev->next = list; - list->prev = list_prev; - } - } else if(config_data->direction == TINYALSA_MIXER_DIRECTION_MODEM) { - list = list_head_alloc(); - list->data = (void *) config_data->device; - - if(config_data->mixer->modem.devices == NULL) { - config_data->mixer->modem.devices = list; - } else { - list_prev = config_data->mixer->modem.devices; - - while(list_prev->next != NULL) - list_prev = list_prev->next; - - list_prev->next = list; - list->prev = list_prev; - } - } - - config_data->device = NULL; - config_data->list = NULL; - } else if(strcmp(elem, "path") == 0) { - config_data->list_start = 0; - config_data->list = 0; - } -} - -int tinyalsa_mixer_config_parse(struct tinyalsa_mixer *mixer, char *config_file) -{ - struct tinyalsa_mixer_config_data config_data; - char buf[80]; - XML_Parser p; - FILE *f; - - int eof = 0; - int len = 0; - - if(mixer == NULL || config_file == NULL) - return -1; - - f = fopen(config_file, "r"); - if(!f) { - ALOGE("Failed to open tinyalsa-audio config file!"); - return -1; - } - - p = XML_ParserCreate(NULL); - if(!p) { - ALOGE("Failed to create XML parser!"); - goto error_file; - } - - memset(&config_data, 0, sizeof(config_data)); - config_data.mixer = mixer; - - XML_SetUserData(p, &config_data); - XML_SetElementHandler(p, tinyalsa_mixer_config_start, tinyalsa_mixer_config_end); - - while(!eof) { - len = fread(buf, 1, sizeof(buf), f); - if(ferror(f)) { - ALOGE("Failed to read config file!"); - goto error_xml_parser; - } - - eof = feof(f); - - if(XML_Parse(p, buf, len, eof) == XML_STATUS_ERROR) { - ALOGE("Failed to parse line %d: %s", - (int) XML_GetCurrentLineNumber(p), - (char *) XML_ErrorString(XML_GetErrorCode(p))); - goto error_xml_parser; - } - } - - XML_ParserFree(p); - fclose(f); - - return 0; - -error_xml_parser: - XML_ParserFree(p); - -error_file: - fclose(f); - - return -1; -} - -/* - * Route/Directions - */ - -int tinyalsa_mixer_set_route_ctrl(struct tinyalsa_mixer *mixer, - struct tinyalsa_mixer_data *mixer_data) -{ - struct mixer_ctl *ctl; - int value = 0; - int type; - int rc; - int i; - - if(mixer_data->type != MIXER_DATA_TYPE_CTRL) - return -1; - - ctl = mixer_get_ctl_by_name(mixer->mixer, mixer_data->name); - type = mixer_ctl_get_type(ctl); - - ALOGD("Setting %s to %s", mixer_data->name, mixer_data->value); - - switch(type) { - case MIXER_CTL_TYPE_BOOL: - value = strcmp(mixer_data->value, "on") == 0 ? - 1 : 0; - break; - case MIXER_CTL_TYPE_INT: - value = atoi(mixer_data->value); - break; - case MIXER_CTL_TYPE_BYTE: - value = atoi(mixer_data->value) & 0xff; - break; - } - - if(type == MIXER_CTL_TYPE_BOOL || type == MIXER_CTL_TYPE_INT || - type == MIXER_CTL_TYPE_BYTE) { - for(i=0 ; i < mixer_ctl_get_num_values(ctl) ; i++) { - rc = mixer_ctl_set_value(ctl, i, value); - if(rc < 0) - return -1; - } - } else if(type == MIXER_CTL_TYPE_ENUM || type == MIXER_CTL_TYPE_UNKNOWN) { - rc = mixer_ctl_set_enum_by_string(ctl, mixer_data->value); - if(rc < 0) - return -1; - } - - return 0; -} - -int tinyalsa_mixer_set_route_write(struct tinyalsa_mixer *mixer, - struct tinyalsa_mixer_data *mixer_data) -{ - char *buffer = NULL; - int fd; - - if(mixer_data->type != MIXER_DATA_TYPE_WRITE) - return -1; - - ALOGD("Writing %s to %s", mixer_data->value, mixer_data->name); - - asprintf(&buffer, "%s\n", mixer_data->value); - if(buffer == NULL) - return -1; - - fd = open(mixer_data->name, O_WRONLY); - if(fd < 0) { - free(buffer); - return -1; - } - - write(fd, buffer, strlen(buffer) + 1); - - free(buffer); - - close(fd); - - return 0; -} - -int tinyalsa_mixer_set_route_list(struct tinyalsa_mixer *mixer, struct list_head *list) -{ - struct tinyalsa_mixer_data *mixer_data = NULL; - int rc; - - if(mixer == NULL || mixer->mixer == NULL) - return -1; - - while(list != NULL) { - mixer_data = (struct tinyalsa_mixer_data *) list->data; - - if(mixer_data->type == MIXER_DATA_TYPE_CTRL) { - if(mixer_data->attr != NULL && - strcmp(mixer_data->attr, "voice-volume") == 0) { - ALOGD("Skipping voice volume control"); - } else { - rc = tinyalsa_mixer_set_route_ctrl(mixer, mixer_data); - if(rc < 0) { - ALOGE("Unable to set control!"); - goto list_continue; - } - } - } else if(mixer_data->type == MIXER_DATA_TYPE_WRITE) { - rc = tinyalsa_mixer_set_route_write(mixer, mixer_data); - if(rc < 0) { - ALOGE("Unable to write!"); - goto list_continue; - } - } - -list_continue: - if(list->next != NULL) - list = list->next; - else - break; - } - - return 0; -} - -int tinyalsa_mixer_set_route(struct tinyalsa_mixer *mixer, - struct tinyalsa_mixer_io *mixer_io, audio_devices_t device) -{ - struct tinyalsa_mixer_device *mixer_device = NULL; - struct list_head *list = NULL; - int rc; - - if(mixer == NULL || mixer_io == NULL) - return -1; - - ALOGD("%s(card=%d,device=%d)++",__func__,mixer_io->props.card,device); - - mixer->mixer = mixer_open(mixer_io->props.card); - if(mixer->mixer == NULL) { - ALOGE("Unable to open mixer for card: %d", mixer_io->props.card); - return -1; - } - - - mixer_device = tinyalsa_mixer_get_device(mixer_io, device); - if(mixer_device == NULL) { - ALOGE("Unable to find a matching device: 0x%x", device); - goto error_mixer; - } - - // No need to disable and enable the same route - if(mixer_device == mixer_io->device_current) - goto exit_mixer; - - if(mixer_io->device_current != NULL) { - rc = tinyalsa_mixer_set_route_list(mixer, mixer_io->device_current->disable); - if(rc < 0) { - ALOGE("Unable to disable current device controls"); - goto error_mixer; - } - } - - rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->enable); - if(rc < 0) { - ALOGE("Unable to enable device controls"); - goto error_mixer; - } - - mixer_io->device_current = mixer_device; - -exit_mixer: - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(card=%d,device=%d)--",__func__,mixer_io->props.card,device); - - return 0; - -error_mixer: - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(card=%d,device=%d)-- (MIXER ERROR)",__func__,mixer_io->props.card,device); - - return -1; -} - -int tinyalsa_mixer_set_device_volume_with_attr(struct tinyalsa_mixer *mixer, - enum tinyalsa_mixer_direction direction, audio_devices_t device, - char *attr, float volume) -{ - struct tinyalsa_mixer_io *mixer_io = NULL; - struct tinyalsa_mixer_device *mixer_device = NULL; - struct tinyalsa_mixer_data *mixer_data = NULL; - struct list_head *list = NULL; - int value, value_min, value_max, values_count; - char *value_string = NULL; - int rc; - - if(mixer == NULL || attr == NULL) - return -1; - - ALOGD("%s(direction=%d, device=%d, attr=%s, volume=%f)++",__func__,direction,device,attr,volume); - - switch(direction) { - case TINYALSA_MIXER_DIRECTION_OUTPUT: - mixer_io = &mixer->output; - break; - case TINYALSA_MIXER_DIRECTION_INPUT: - mixer_io = &mixer->input; - break; - case TINYALSA_MIXER_DIRECTION_MODEM: - mixer_io = &mixer->modem; - break; - default: - ALOGE("Invalid diretion: 0x%x", direction); - return -1; - } - - if(!mixer_io->state) { - ALOGE("Unable to set device for the asked direction: state is %d", mixer_io->state); - return -1; - } - - mixer->mixer = mixer_open(mixer_io->props.card); - if(mixer->mixer == NULL) { - ALOGE("Unable to open mixer for card: %d", mixer_io->props.card); - return -1; - } - - mixer_device = tinyalsa_mixer_get_device(mixer_io, device); - if(mixer_device == NULL) { - ALOGE("Unable to find a matching device: 0x%x", device); - goto error_mixer; - } - - list = mixer_device->enable; - - mixer_data = tinyalsa_mixer_get_data_with_attr(list, attr); - if(mixer_data == NULL) { - ALOGE("Unable to find a matching ctrl with attr: %s", attr); - goto error_mixer; - } - - if(mixer_data->value == NULL) { - ALOGE("Missing mixer data value!"); - goto error_mixer; - } - - values_count = sscanf(mixer_data->value, "%d-%d", &value_min, &value_max); - if(values_count != 2) { - ALOGE("Failed to get mixer data value!"); - goto error_mixer; - } - - value = (value_max - value_min) * volume + value_min; - - // Ugly workaround because a string value is needed - value_string = mixer_data->value; - asprintf(&mixer_data->value, "%d", value); - - rc = tinyalsa_mixer_set_route_ctrl(mixer, mixer_data); - if(rc < 0) { - ALOGE("Unable to set ctrl!"); - goto error_data; - } - - free(mixer_data->value); - mixer_data->value = value_string; - - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, device=%d, attr=%s, volume=%f)--",__func__,direction,device,attr,volume); - - return 0; - -error_data: - free(mixer_data->value); - mixer_data->value = value_string; - - ALOGD("%s(direction=%d, device=%d, attr=%s, volume=%f)-- (DATA ERROR)",__func__,direction,device,attr,volume); - -error_mixer: - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, device=%d, attr=%s, volume=%f)-- (MIXER ERROR)",__func__,direction,device,attr,volume); - - return -1; -} - -int tinyalsa_mixer_set_device_state_with_attr(struct tinyalsa_mixer *mixer, - enum tinyalsa_mixer_direction direction, audio_devices_t device, - char *attr, int state) -{ - struct tinyalsa_mixer_io *mixer_io = NULL; - struct tinyalsa_mixer_device *mixer_device = NULL; - struct tinyalsa_mixer_data *mixer_data = NULL; - struct list_head *list = NULL; - int rc; - - if(mixer == NULL || attr == NULL) - return -1; - - state = state >= 1 ? 1 : 0; - - ALOGD("%s(direction=%d, device=%d, attr=%s, state=%d)++",__func__,direction,device,attr,state); - - switch(direction) { - case TINYALSA_MIXER_DIRECTION_OUTPUT: - mixer_io = &mixer->output; - break; - case TINYALSA_MIXER_DIRECTION_INPUT: - mixer_io = &mixer->input; - break; - case TINYALSA_MIXER_DIRECTION_MODEM: - mixer_io = &mixer->modem; - break; - default: - ALOGE("Invalid diretion: 0x%x", direction); - return -1; - } - - if(!mixer_io->state) { - ALOGE("Unable to set device for the asked direction: state is %d", mixer_io->state); - return -1; - } - - mixer->mixer = mixer_open(mixer_io->props.card); - if(mixer->mixer == NULL) { - ALOGE("Unable to open mixer for card: %d", mixer_io->props.card); - return -1; - } - - mixer_device = tinyalsa_mixer_get_device(mixer_io, device); - if(mixer_device == NULL) { - ALOGE("Unable to find a matching device: 0x%x", device); - goto error_mixer; - } - - if(state) - list = mixer_device->enable; - else - list = mixer_device->disable; - - mixer_data = tinyalsa_mixer_get_data_with_attr(list, attr); - if(mixer_data == NULL) { - ALOGE("Unable to find a matching ctrl with attr: %s", attr); - goto error_mixer; - } - - rc = tinyalsa_mixer_set_route_ctrl(mixer, mixer_data); - if(rc < 0) { - ALOGE("Unable to set ctrl!"); - goto error_mixer; - } - - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, device=%d, attr=%s, state=%d)--",__func__,direction,device,attr,state); - - return 0; - -error_mixer: - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, device=%d, attr=%s, state=%d)-- (MIXER ERROR)",__func__,direction,device,attr,state); - - return -1; -} - -int tinyalsa_mixer_set_state(struct tinyalsa_mixer *mixer, - enum tinyalsa_mixer_direction direction, int state) -{ - struct tinyalsa_mixer_io *mixer_io = NULL; - struct tinyalsa_mixer_device *mixer_device = NULL; - struct list_head *list; - audio_devices_t default_device; - int rc; - - if(mixer == NULL) - return -1; - - state = state >= 1 ? 1 : 0; - - ALOGD("%s(direction=%d, state=%d)++",__func__,direction,state); - - switch(direction) { - case TINYALSA_MIXER_DIRECTION_OUTPUT: - mixer_io = &mixer->output; - default_device = AUDIO_DEVICE_OUT_DEFAULT; - break; - case TINYALSA_MIXER_DIRECTION_INPUT: - mixer_io = &mixer->input; - default_device = AUDIO_DEVICE_IN_DEFAULT; - break; - case TINYALSA_MIXER_DIRECTION_MODEM: - mixer_io = &mixer->modem; - default_device = AUDIO_DEVICE_OUT_DEFAULT; - break; - default: - ALOGE("Invalid diretion: 0x%x", direction); - return -1; - } - - if(mixer_io->state == state) { - ALOGD("Current state is already: %d", state); - return 0; - } - - mixer->mixer = mixer_open(mixer_io->props.card); - if(mixer->mixer == NULL) { - ALOGE("Unable to open mixer for card: %d", mixer_io->props.card); - return -1; - } - - if(!state && mixer_io->device_current != NULL && - mixer_io->device_current->disable != NULL) { - rc = tinyalsa_mixer_set_route_list(mixer, mixer_io->device_current->disable); - if(rc < 0) { - ALOGE("Unable to disable current device controls"); - goto error_mixer; - } - } - - mixer_device = tinyalsa_mixer_get_device(mixer_io, default_device); - if(mixer_device == NULL) { - ALOGD("Unable to find default device"); - // This is not really an issue - } - - if(state && mixer_device != NULL && mixer_device->enable != NULL) { - rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->enable); - if(rc < 0) { - ALOGE("Unable to enable default device controls"); - goto error_mixer; - } - } else if(!state && mixer_device != NULL) { - rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->disable); - if(rc < 0) { - ALOGE("Unable to disable default device controls"); - goto error_mixer; - } - } - - mixer_io->device_current = NULL; - mixer_io->state = state; - - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, state=%d)--",__func__,direction,state); - - return 0; - -error_mixer: - mixer_close(mixer->mixer); - mixer->mixer = NULL; - - ALOGD("%s(direction=%d, state=%d)-- (MIXER ERROR)",__func__,direction,state); - - return -1; -} - -/* - * Interface - */ - -int tinyalsa_mixer_set_output_state(struct tinyalsa_mixer *mixer, int state) -{ - ALOGD("%s(%d)", __func__, state); - - return tinyalsa_mixer_set_state(mixer, TINYALSA_MIXER_DIRECTION_OUTPUT, state); -} - -int tinyalsa_mixer_set_input_state(struct tinyalsa_mixer *mixer, int state) -{ - ALOGD("%s(%d)", __func__, state); - - return tinyalsa_mixer_set_state(mixer, TINYALSA_MIXER_DIRECTION_INPUT, state); -} - -int tinyalsa_mixer_set_modem_state(struct tinyalsa_mixer *mixer, int state) -{ - ALOGD("%s(%d)", __func__, state); - - return tinyalsa_mixer_set_state(mixer, TINYALSA_MIXER_DIRECTION_MODEM, state); -} - -int tinyalsa_mixer_set_device(struct tinyalsa_mixer *mixer, audio_devices_t device) -{ - int rc; - - ALOGD("%s(%x)", __func__, device); - - if(mixer == NULL) - return -1; - - if(!audio_is_output_device(device) && !audio_is_input_device(device)) { - ALOGE("Invalid device: 0x%x", device); - return -1; - } - - - if(audio_is_output_device(device) && mixer->output.state) { - rc = tinyalsa_mixer_set_route(mixer, &mixer->output, device); - if(rc < 0) { - ALOGE("Unable to set route for output device: 0x%x", device); - return -1; - } - } - - if(audio_is_input_device(device) && mixer->input.state) { - rc = tinyalsa_mixer_set_route(mixer, &mixer->input, device); - if(rc < 0) { - ALOGE("Unable to set route for input device: 0x%x", device); - return -1; - } - } - - if(audio_is_output_device(device) && mixer->modem.state) { - rc = tinyalsa_mixer_set_route(mixer, &mixer->modem, device); - if(rc < 0) { - ALOGE("Unable to set route for modem device: 0x%x", device); - return -1; - } - } - - return 0; -} - -int tinyalsa_mixer_set_output_volume(struct tinyalsa_mixer *mixer, - audio_devices_t device, float volume) -{ - ALOGD("%s(%p, %x, %f)", __func__, mixer, device, volume); - - return tinyalsa_mixer_set_device_volume_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_OUTPUT, device, - "output-volume", volume); -} - -int tinyalsa_mixer_set_master_volume(struct tinyalsa_mixer *mixer, float volume) -{ - ALOGD("%s(%p, %f)", __func__, mixer, volume); - - return tinyalsa_mixer_set_device_volume_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_OUTPUT, AUDIO_DEVICE_OUT_DEFAULT, - "master-volume", volume); -} - -int tinyalsa_mixer_set_mic_mute(struct tinyalsa_mixer *mixer, - audio_devices_t device, int mute) -{ - ALOGD("%s(%p, %x, %d)", __func__, mixer, device, mute); - - // Mic mute can be set for both input and modem directions - if(audio_is_input_device(device)) { - return tinyalsa_mixer_set_device_state_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_INPUT, device, - "mic-mute", mute); - } else if(audio_is_output_device(device)) { - return tinyalsa_mixer_set_device_state_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_MODEM, device, - "mic-mute", mute); - } else { - return -1; - } -} - -int tinyalsa_mixer_set_input_gain(struct tinyalsa_mixer *mixer, - audio_devices_t device, float gain) -{ - ALOGD("%s(%p, %x, %f)", __func__, mixer, device, gain); - - return tinyalsa_mixer_set_device_volume_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_INPUT, device, - "input-gain", gain); -} - -int tinyalsa_mixer_set_voice_volume(struct tinyalsa_mixer *mixer, - audio_devices_t device, float volume) -{ - ALOGD("%s(%p, %x, %f)", __func__, mixer, device, volume); - - return tinyalsa_mixer_set_device_volume_with_attr(mixer, - TINYALSA_MIXER_DIRECTION_MODEM, device, - "voice-volume", volume); -} - -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_output_props(struct tinyalsa_mixer *mixer) -{ - ALOGD("%s(%p)", __func__, mixer); - - return &(mixer->output.props); -} - -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_input_props(struct tinyalsa_mixer *mixer) -{ - ALOGD("%s(%p)", __func__, mixer); - - return &(mixer->input.props); -} - -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_modem_props(struct tinyalsa_mixer *mixer) -{ - ALOGD("%s(%p)", __func__, mixer); - - return &(mixer->modem.props); -} - -void tinyalsa_mixer_close(struct tinyalsa_mixer *mixer) -{ - ALOGD("%s(%p)", __func__, mixer); - - if(mixer == NULL) - return; - - tinyalsa_mixer_set_output_state(mixer, 0); - tinyalsa_mixer_set_input_state(mixer, 0); - tinyalsa_mixer_set_modem_state(mixer, 0); - - tinyalsa_mixer_io_free_devices(&mixer->output); - tinyalsa_mixer_io_free_devices(&mixer->input); - tinyalsa_mixer_io_free_devices(&mixer->modem); - - free(mixer); -} - -int tinyalsa_mixer_open(struct tinyalsa_mixer **mixer_p, char *config_file) -{ - struct tinyalsa_mixer *mixer = NULL; - int rc; - - ALOGD("%s(%p, %s)", __func__, mixer_p, config_file); - - if(mixer_p == NULL || config_file == NULL) - return -1; - - mixer = calloc(1, sizeof(struct tinyalsa_mixer)); - - rc = tinyalsa_mixer_config_parse(mixer, config_file); - if(rc < 0) { - ALOGE("Unable to parse mixer config!"); - goto error_mixer; - } - - *mixer_p = mixer; - - return 0; - -error_mixer: - *mixer_p = NULL; - - free(mixer); - - return -1; -} diff --git a/tinyalsa_audio/mixer.h b/tinyalsa_audio/mixer.h deleted file mode 100644 index 5301b7c..0000000 --- a/tinyalsa_audio/mixer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TINYALSA_AUDIO_MIXER_H -#define TINYALSA_AUDIO_MIXER_H - -#include <tinyalsa/asoundlib.h> - -#include <hardware/audio.h> -#include <system/audio.h> - -#define TINYALSA_MIXER_CONFIG_FILE "/system/etc/tinyalsa-audio.xml" - -struct list_head { - struct list_head *prev; - struct list_head *next; - - void *data; -}; - -enum tinyalsa_mixer_data_type { - MIXER_DATA_TYPE_CTRL, - MIXER_DATA_TYPE_WRITE, - MIXER_DATA_TYPE_MAX -}; - -struct tinyalsa_mixer_data { - enum tinyalsa_mixer_data_type type; - char *name; - char *value; - char *attr; -}; - -struct tinyalsa_mixer_device_props { - audio_devices_t type; -}; - -struct tinyalsa_mixer_device { - struct tinyalsa_mixer_device_props props; - struct list_head *enable; - struct list_head *disable; -}; - -struct tinyalsa_mixer_io_props { - int card; - int device; - - int rate; - audio_channel_mask_t channel_mask; - audio_format_t format; - - int period_size; - int period_count; -}; - -struct tinyalsa_mixer_io { - struct tinyalsa_mixer_io_props props; - struct tinyalsa_mixer_device *device_current; - struct list_head *devices; - int state; -}; - -struct tinyalsa_mixer { - struct tinyalsa_mixer_io output; - struct tinyalsa_mixer_io input; - struct tinyalsa_mixer_io modem; - struct mixer *mixer; -}; - -enum tinyalsa_mixer_direction { - TINYALSA_MIXER_DIRECTION_OUTPUT, - TINYALSA_MIXER_DIRECTION_INPUT, - TINYALSA_MIXER_DIRECTION_MODEM, - TINYALSA_MIXER_DIRECTION_MAX -}; - -struct tinyalsa_mixer_config_data { - struct tinyalsa_mixer *mixer; - struct tinyalsa_mixer_io_props io_props; - struct tinyalsa_mixer_device_props device_props; - enum tinyalsa_mixer_direction direction; - - struct tinyalsa_mixer_device *device; - struct list_head **list_start; - struct list_head *list; -}; - -int tinyalsa_mixer_set_output_state(struct tinyalsa_mixer *mixer, int state); -int tinyalsa_mixer_set_input_state(struct tinyalsa_mixer *mixer, int state); -int tinyalsa_mixer_set_modem_state(struct tinyalsa_mixer *mixer, int state); - -int tinyalsa_mixer_set_device(struct tinyalsa_mixer *mixer, audio_devices_t device); - -int tinyalsa_mixer_set_output_volume(struct tinyalsa_mixer *mixer, - audio_devices_t device, float volume); -int tinyalsa_mixer_set_master_volume(struct tinyalsa_mixer *mixer, float volume); -int tinyalsa_mixer_set_mic_mute(struct tinyalsa_mixer *mixer, - audio_devices_t device, int mute); -int tinyalsa_mixer_set_input_gain(struct tinyalsa_mixer *mixer, - audio_devices_t device, float gain); -int tinyalsa_mixer_set_voice_volume(struct tinyalsa_mixer *mixer, - audio_devices_t device, float volume); - -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_output_props(struct tinyalsa_mixer *mixer); -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_input_props(struct tinyalsa_mixer *mixer); -struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_modem_props(struct tinyalsa_mixer *mixer); - -void tinyalsa_mixer_close(struct tinyalsa_mixer *mixer); -int tinyalsa_mixer_open(struct tinyalsa_mixer **mixer_p, char *config_file); - -#endif |