diff options
Diffstat (limited to 'audio_hw.c')
-rw-r--r-- | audio_hw.c | 122 |
1 files changed, 109 insertions, 13 deletions
@@ -1,6 +1,6 @@ /* * 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 * @@ -20,11 +20,13 @@ #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 @@ -75,6 +77,7 @@ static int audio_hw_init_check(const struct audio_hw_device *dev) static int audio_hw_set_voice_volume(struct audio_hw_device *dev, float volume) { struct tinyalsa_audio_device *device; + audio_devices_t device_modem; LOGD("%s(%p, %f)", __func__, dev, volume); @@ -86,10 +89,23 @@ static int audio_hw_set_voice_volume(struct audio_hw_device *dev, float volume) if(device->mixer == NULL) return -1; - if(device->mode == AUDIO_MODE_IN_CALL) { - // FIXME: Select the device from ril interface - tinyalsa_mixer_set_voice_volume(device->mixer, - AUDIO_DEVICE_OUT_DEFAULT, volume); + if(volume != device->voice_volume) { + 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; } return 0; @@ -116,7 +132,9 @@ static int audio_hw_set_master_volume(struct audio_hw_device *dev, float volume) 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; LOGD("%s(%p, %d)", __func__, dev, mode); @@ -131,7 +149,11 @@ static int audio_hw_set_mode(struct audio_hw_device *dev, int mode) tinyalsa_mixer_set_modem_state(device->mixer, 1); if(device->stream_out != NULL) - tinyalsa_mixer_set_device(device->mixer, device->stream_out->device_current); + 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); @@ -139,6 +161,17 @@ static int audio_hw_set_mode(struct audio_hw_device *dev, int mode) LOGE("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) { + LOGE("Failed to open RIL interface"); + device->ril_interface = NULL; + } else { + device->ril_interface = ril_interface; + + 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); @@ -148,6 +181,9 @@ static int audio_hw_set_mode(struct audio_hw_device *dev, int mode) LOGE("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; @@ -159,6 +195,7 @@ static int audio_hw_set_mode(struct audio_hw_device *dev, int mode) static int audio_hw_set_mic_mute(struct audio_hw_device *dev, bool state) { struct tinyalsa_audio_device *device; + audio_devices_t device_modem; LOGD("%s(%p, %d)", __func__, dev, state); @@ -171,12 +208,27 @@ static int audio_hw_set_mic_mute(struct audio_hw_device *dev, bool state) return -1; if(device->mic_mute != state) { - device->mic_mute = state; + 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); + } + } - // FIXME: Select the device from input if mode isn't in-call, - // select it from ril interface if mode is in-call - tinyalsa_mixer_set_mic_mute(device->mixer, - AUDIO_DEVICE_IN_DEFAULT, state); + device->mic_mute = state; } return 0; @@ -201,9 +253,50 @@ static int audio_hw_get_mic_mute(const struct audio_hw_device *dev, bool *state) 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; + LOGD("%s(%p, %s)", __func__, dev, kvpairs); - return -ENOSYS; + 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); + + if(audio_is_output_device((audio_devices_t) value)) { + if(device->stream_out != NULL && device->stream_out->device_current != (audio_devices_t) value) + audio_out_set_route(device->stream_out, (audio_devices_t) value); + 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) + audio_in_set_route(device->stream_in, (audio_devices_t) value); + } + + str_parms_destroy(parms); + + return 0; + +error_params: + str_parms_destroy(parms); + + return -1; } static char *audio_hw_get_parameters(const struct audio_hw_device *dev, @@ -211,7 +304,7 @@ static char *audio_hw_get_parameters(const struct audio_hw_device *dev, { LOGD("%s(%p, %s)", __func__, dev, keys); - return NULL; + return strdup(""); } static size_t audio_hw_get_input_buffer_size(const struct audio_hw_device *dev, @@ -270,6 +363,9 @@ int audio_hw_open(const hw_module_t *module, const char *name, LOGD("%s(%p, %s, %p)", __func__, module, name, device); + if(device == NULL) + return -EINVAL; + if(strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; |