summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2012-10-26 15:47:01 +0200
committerPaul Kocialkowski <contact@paulk.fr>2012-10-26 15:47:01 +0200
commitf6e1b0eae63dfd937213e0b0fdb01f106621421c (patch)
tree8c8b018a2461c7096f203f0ea6ba091fda1ab22c
parent7751e9ab8b411d69fab1e455ef4ff75b883ab4d6 (diff)
downloadhardware_tinyalsa-audio-f6e1b0eae63dfd937213e0b0fdb01f106621421c.zip
hardware_tinyalsa-audio-f6e1b0eae63dfd937213e0b0fdb01f106621421c.tar.gz
hardware_tinyalsa-audio-f6e1b0eae63dfd937213e0b0fdb01f106621421c.tar.bz2
Mixer: Avoid mode and use directions logic instead, introducing modem support
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rw-r--r--audio_hw.c24
-rw-r--r--audio_in.c27
-rw-r--r--audio_out.c28
-rw-r--r--mixer.c410
-rw-r--r--mixer.h45
5 files changed, 361 insertions, 173 deletions
diff --git a/audio_hw.c b/audio_hw.c
index 38acef4..7dee074 100644
--- a/audio_hw.c
+++ b/audio_hw.c
@@ -89,7 +89,7 @@ static int audio_hw_set_voice_volume(struct audio_hw_device *dev, float volume)
if(device->mode == AUDIO_MODE_IN_CALL) {
// FIXME: Select the device from ril interface
tinyalsa_mixer_set_voice_volume(device->mixer,
- AUDIO_DEVICE_IN_DEFAULT, device->mode, volume);
+ AUDIO_DEVICE_OUT_DEFAULT, volume);
}
return 0;
@@ -126,16 +126,17 @@ static int audio_hw_set_mode(struct audio_hw_device *dev, int mode)
device = (struct tinyalsa_audio_device *) dev;
if(mode != device->mode) {
- device->mode = mode;
+ if(mode == AUDIO_MODE_IN_CALL) {
+ tinyalsa_mixer_set_modem_state(device->mixer, 1);
- if(device->stream_out != NULL) {
- audio_out_set_route(device->stream_out,
- device->stream_out->device_current);
- // TODO: audio_input_set_route
+ if(device->stream_out != NULL)
+ tinyalsa_mixer_set_device(device->mixer, device->stream_out->device_current);
+ } else if(device->mode == AUDIO_MODE_IN_CALL) {
+ tinyalsa_mixer_set_modem_state(device->mixer, 0);
}
- }
- device->mode = mode;
+ device->mode = mode;
+ }
return 0;
}
@@ -160,7 +161,7 @@ static int audio_hw_set_mic_mute(struct audio_hw_device *dev, bool 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, device->mode, state);
+ AUDIO_DEVICE_IN_DEFAULT, state);
}
return 0;
@@ -307,11 +308,6 @@ int audio_hw_open(const hw_module_t *module, const char *name,
goto error_device;
}
- rc = tinyalsa_mixer_set_route(tinyalsa_mixer, AUDIO_DEVICE_OUT_DEFAULT, AUDIO_MODE_NORMAL);
- if(rc < 0) {
- LOGE("Failed to set default mixer route");
- }
-
tinyalsa_audio_device->mixer = tinyalsa_mixer;
*device = &(dev->common);
diff --git a/audio_in.c b/audio_in.c
index 8e83478..29cda6e 100644
--- a/audio_in.c
+++ b/audio_in.c
@@ -95,22 +95,11 @@ int audio_in_set_route(struct tinyalsa_audio_stream_in *stream_in,
stream_in->device_current = device;
- if(device == 0) {
- tinyalsa_mixer_set_route(stream_in->device->mixer,
- AUDIO_DEVICE_IN_DEFAULT, stream_in->device->mode);
+ if(device == 0)
+ return stream_in->stream.common.standby((struct audio_stream *) stream_in);
- rc = yamaha_mc1n2_audio_input_stop(stream_in->device->mc1n2_pdata);
- if(rc < 0) {
- LOGE("Failed to set Yamaha-MC1N2-Audio route");
- }
-
- stream_in->standby = 1;
-
- return 0;
- }
- tinyalsa_mixer_set_route(stream_in->device->mixer,
- stream_in->device_current, stream_in->device->mode);
+ 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,
@@ -308,7 +297,7 @@ static int audio_in_set_gain(struct audio_stream_in *stream, float gain)
return -1;
tinyalsa_mixer_set_input_gain(stream_in->device->mixer,
- stream_in->device_current, stream_in->device->mode, gain);
+ stream_in->device_current, gain);
return 0;
}
@@ -396,6 +385,8 @@ void audio_hw_close_input_stream(struct audio_hw_device *dev,
tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev;
+ tinyalsa_mixer_set_input_state(tinyalsa_audio_device->mixer, 0);
+
tinyalsa_audio_device->stream_in = NULL;
}
@@ -459,6 +450,12 @@ int audio_hw_open_input_stream(struct audio_hw_device *dev,
*channels = (uint32_t) tinyalsa_audio_stream_in->channels;
*format = (uint32_t) tinyalsa_audio_stream_in->format;
+ rc = tinyalsa_mixer_set_input_state(tinyalsa_audio_device->mixer, 1);
+ if(rc < 0) {
+ LOGE("Unable to set input state");
+ goto error_stream;
+ }
+
audio_in_set_route(tinyalsa_audio_stream_in, devices);
rc = audio_in_pcm_open(tinyalsa_audio_stream_in);
diff --git a/audio_out.c b/audio_out.c
index 4bfd9b3..a347eaa 100644
--- a/audio_out.c
+++ b/audio_out.c
@@ -99,22 +99,10 @@ int audio_out_set_route(struct tinyalsa_audio_stream_out *stream_out,
stream_out->device_current = device;
- if(device == 0) {
- tinyalsa_mixer_set_route(stream_out->device->mixer,
- AUDIO_DEVICE_OUT_DEFAULT, stream_out->device->mode);
+ if(device == 0)
+ return stream_out->stream.common.standby((struct audio_stream *) stream_out);
- rc = yamaha_mc1n2_audio_output_stop(stream_out->device->mc1n2_pdata);
- if(rc < 0) {
- LOGE("Failed to set Yamaha-MC1N2-Audio route");
- }
-
- stream_out->standby = 1;
-
- return 0;
- }
-
- tinyalsa_mixer_set_route(stream_out->device->mixer,
- stream_out->device_current, stream_out->device->mode);
+ 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,
@@ -322,7 +310,7 @@ static int audio_out_set_volume(struct audio_stream_out *stream, float left,
volume = (left + right) / 2;
tinyalsa_mixer_set_output_volume(stream_out->device->mixer,
- stream_out->device_current, stream_out->device->mode, volume);
+ stream_out->device_current, volume);
return 0;
}
@@ -418,6 +406,8 @@ void audio_hw_close_output_stream(struct audio_hw_device *dev,
tinyalsa_audio_device = (struct tinyalsa_audio_device *) dev;
+ tinyalsa_mixer_set_output_state(tinyalsa_audio_device->mixer, 0);
+
tinyalsa_audio_device->stream_out = NULL;
}
@@ -482,6 +472,12 @@ int audio_hw_open_output_stream(struct audio_hw_device *dev,
*channels = (uint32_t) tinyalsa_audio_stream_out->channels;
*format = (uint32_t) tinyalsa_audio_stream_out->format;
+ rc = tinyalsa_mixer_set_output_state(tinyalsa_audio_device->mixer, 1);
+ if(rc < 0) {
+ LOGE("Unable to set output state");
+ goto error_stream;
+ }
+
audio_out_set_route(tinyalsa_audio_stream_out, devices);
rc = audio_out_pcm_open(tinyalsa_audio_stream_out);
diff --git a/mixer.c b/mixer.c
index 6848dc8..e18d1da 100644
--- a/mixer.c
+++ b/mixer.c
@@ -176,7 +176,7 @@ void tinyalsa_mixer_device_free(struct tinyalsa_mixer_device *mixer_device)
}
struct tinyalsa_mixer_device *tinyalsa_mixer_get_device(struct tinyalsa_mixer_io *mixer_io,
- audio_devices_t device, audio_mode_t mode)
+ audio_devices_t device)
{
struct tinyalsa_mixer_device *mixer_device = NULL;
struct list_head *list = NULL;
@@ -188,8 +188,7 @@ struct tinyalsa_mixer_device *tinyalsa_mixer_get_device(struct tinyalsa_mixer_io
while(list != NULL) {
mixer_device = (struct tinyalsa_mixer_device *) list->data;
- if(mixer_device != NULL && mixer_device->props.type == device &&
- mixer_device->props.mode == mode) {
+ if(mixer_device != NULL && mixer_device->props.type == device) {
break;
} else {
mixer_device = NULL;
@@ -254,7 +253,7 @@ void tinyalsa_mixer_config_start(void *data, const XML_Char *elem,
}
}
} else if(strcmp(elem, "output") == 0) {
- config_data->direction = AUDIO_DEVICE_OUT_ALL;
+ config_data->direction = TINYALSA_MIXER_DIRECTION_OUTPUT;
for(i=0 ; attr[i] != NULL && attr[i+1] ; i++) {
if(strcmp(attr[i], "card") == 0) {
@@ -312,7 +311,7 @@ void tinyalsa_mixer_config_start(void *data, const XML_Char *elem,
}
}
} else if(strcmp(elem, "input") == 0) {
- config_data->direction = AUDIO_DEVICE_IN_ALL;
+ config_data->direction = TINYALSA_MIXER_DIRECTION_INPUT;
for(i=0 ; attr[i] != NULL && attr[i+1] ; i++) {
if(strcmp(attr[i], "card") == 0) {
@@ -360,28 +359,26 @@ void tinyalsa_mixer_config_start(void *data, const XML_Char *elem,
LOGE("Unknown input attr: %s", attr[i]);
}
}
- } else if(strcmp(elem, "mode") == 0) {
- for(i=0 ; attr[i] != NULL && attr[i+1] != NULL ; i++) {
- if(strcmp(attr[i], "type") == 0) {
+ } 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++;
- if(strcmp(attr[i], "normal") == 0) {
- config_data->device_props.mode = AUDIO_MODE_NORMAL;
- } else if(strcmp(attr[i], "ringtone") == 0) {
- config_data->device_props.mode = AUDIO_MODE_RINGTONE;
- } else if(strcmp(attr[i], "in-call") == 0) {
- config_data->device_props.mode = AUDIO_MODE_IN_CALL;
- } else if(strcmp(attr[i], "in-communication") == 0) {
- config_data->device_props.mode = AUDIO_MODE_IN_COMMUNICATION;
- } else {
- LOGE("Unknown mode attr: %s", attr[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 {
+ LOGE("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 & (~AUDIO_DEVICE_OUT_ALL)) == 0) {
+ 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) {
@@ -415,8 +412,10 @@ void tinyalsa_mixer_config_start(void *data, const XML_Char *elem,
} else {
LOGE("Unknown device attr: %s", attr[i]);
}
- } else if((config_data->direction & (~AUDIO_DEVICE_IN_ALL)) == 0) {
- if(strcmp(attr[i], "communication") == 0) {
+ } 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;
@@ -436,19 +435,6 @@ void tinyalsa_mixer_config_start(void *data, const XML_Char *elem,
LOGE("Unknown device attr: %s", attr[i]);
}
}
- } else if(strcmp(attr[i], "mode") == 0) {
- i++;
- if(strcmp(attr[i], "normal") == 0) {
- config_data->device_props.mode = AUDIO_MODE_NORMAL;
- } else if(strcmp(attr[i], "ringtone") == 0) {
- config_data->device_props.mode = AUDIO_MODE_RINGTONE;
- } else if(strcmp(attr[i], "in-call") == 0) {
- config_data->device_props.mode = AUDIO_MODE_IN_CALL;
- } else if(strcmp(attr[i], "in-communication") == 0) {
- config_data->device_props.mode = AUDIO_MODE_IN_COMMUNICATION;
- } else {
- LOGE("Unknown mode attr: %s", attr[i]);
- }
} else {
LOGE("Unknown device attr: %s", attr[i]);
}
@@ -537,9 +523,13 @@ void tinyalsa_mixer_config_end(void *data, const XML_Char *elem)
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 & (~AUDIO_DEVICE_OUT_ALL)) == 0) {
+ if(config_data->direction == TINYALSA_MIXER_DIRECTION_OUTPUT) {
list = list_head_alloc();
list->data = (void *) config_data->device;
@@ -554,7 +544,7 @@ void tinyalsa_mixer_config_end(void *data, const XML_Char *elem)
list_prev->next = list;
list->prev = list_prev;
}
- } else if((config_data->direction & (~AUDIO_DEVICE_IN_ALL)) == 0) {
+ } else if(config_data->direction == TINYALSA_MIXER_DIRECTION_INPUT) {
list = list_head_alloc();
list->data = (void *) config_data->device;
@@ -569,6 +559,21 @@ void tinyalsa_mixer_config_end(void *data, const XML_Char *elem)
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;
@@ -642,7 +647,7 @@ error_file:
}
/*
- * Route
+ * Route/Directions
*/
int tinyalsa_mixer_set_route_ctrl(struct tinyalsa_mixer *mixer,
@@ -724,8 +729,60 @@ int tinyalsa_mixer_set_route_list(struct tinyalsa_mixer *mixer, struct list_head
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;
+
+ mixer->mixer = mixer_open(mixer_io->props.card);
+ if(mixer->mixer == NULL) {
+ LOGE("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) {
+ LOGE("Unable to find a matching device: 0x%x", device);
+ goto error_mixer;
+ }
+
+ if(mixer_io->device_current != NULL) {
+ rc = tinyalsa_mixer_set_route_list(mixer, mixer_io->device_current->disable);
+ if(rc < 0) {
+ LOGE("Unable to disable current device controls");
+ goto error_mixer;
+ }
+ }
+
+ rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->enable);
+ if(rc < 0) {
+ LOGE("Unable to enable device controls");
+ goto error_mixer;
+ }
+
+ mixer_io->device_current = mixer_device;
+
+ mixer_close(mixer->mixer);
+ mixer->mixer = NULL;
+
+ return 0;
+
+error_mixer:
+ mixer_close(mixer->mixer);
+ mixer->mixer = NULL;
+
+ return -1;
+}
+
int tinyalsa_mixer_set_device_volume_with_attr(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, char *attr, float volume)
+ 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;
@@ -738,12 +795,23 @@ int tinyalsa_mixer_set_device_volume_with_attr(struct tinyalsa_mixer *mixer,
if(mixer == NULL || attr == NULL)
return -1;
- if(audio_is_output_device(device)) {
- mixer_io = &mixer->output;
- } else if(audio_is_input_device(device)) {
- mixer_io = &mixer->input;
- } else {
- LOGE("Invalid device: 0x%x", device);
+ 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:
+ LOGE("Invalid diretion: 0x%x", direction);
+ return -1;
+ }
+
+ if(!mixer_io->state) {
+ LOGE("Unable to set device for the asked direction: state is %d", mixer_io->state);
return -1;
}
@@ -753,10 +821,9 @@ int tinyalsa_mixer_set_device_volume_with_attr(struct tinyalsa_mixer *mixer,
return -1;
}
- mixer_device = tinyalsa_mixer_get_device(mixer_io, device, mode);
+ mixer_device = tinyalsa_mixer_get_device(mixer_io, device);
if(mixer_device == NULL) {
- LOGE("Unable to find a matching device: 0x%x with mode: 0x%x",
- device, mode);
+ LOGE("Unable to find a matching device: 0x%x", device);
goto error_mixer;
}
@@ -811,7 +878,8 @@ error_mixer:
}
int tinyalsa_mixer_set_device_state_with_attr(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, char *attr, int state)
+ 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;
@@ -822,12 +890,25 @@ int tinyalsa_mixer_set_device_state_with_attr(struct tinyalsa_mixer *mixer,
if(mixer == NULL || attr == NULL)
return -1;
- if(audio_is_output_device(device)) {
- mixer_io = &mixer->output;
- } else if(audio_is_input_device(device)) {
- mixer_io = &mixer->input;
- } else {
- LOGE("Invalid device: 0x%x", device);
+ state = state >= 1 ? 1 : 0;
+
+ 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:
+ LOGE("Invalid diretion: 0x%x", direction);
+ return -1;
+ }
+
+ if(!mixer_io->state) {
+ LOGE("Unable to set device for the asked direction: state is %d", mixer_io->state);
return -1;
}
@@ -837,10 +918,9 @@ int tinyalsa_mixer_set_device_state_with_attr(struct tinyalsa_mixer *mixer,
return -1;
}
- mixer_device = tinyalsa_mixer_get_device(mixer_io, device, mode);
+ mixer_device = tinyalsa_mixer_get_device(mixer_io, device);
if(mixer_device == NULL) {
- LOGE("Unable to find a matching device: 0x%x with mode: 0x%x",
- device, mode);
+ LOGE("Unable to find a matching device: 0x%x", device);
goto error_mixer;
}
@@ -873,34 +953,41 @@ error_mixer:
return -1;
}
-/*
- * Interface
- */
-
-int tinyalsa_mixer_set_route(struct tinyalsa_mixer *mixer, audio_devices_t device, audio_mode_t mode)
+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 = NULL;
- int device_default = 0;
+ struct list_head *list;
+ audio_devices_t default_device;
int rc;
- LOGD("%s(%x, %x)", __func__, device, mode);
-
if(mixer == NULL)
return -1;
- if(audio_is_output_device(device)) {
- mixer_io = &mixer->output;
- if(device == AUDIO_DEVICE_OUT_DEFAULT)
- device_default = 1;
- } else if(audio_is_input_device(device)) {
- mixer_io = &mixer->input;
- if(device == AUDIO_DEVICE_IN_DEFAULT)
- device_default = 1;
- } else {
- LOGE("Invalid device: 0x%x", device);
- return -1;
+ state = state >= 1 ? 1 : 0;
+
+ 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:
+ LOGE("Invalid diretion: 0x%x", direction);
+ return -1;
+ }
+
+ if(mixer_io->state == state) {
+ LOGD("Current state is already: %d", state);
+ return 0;
}
mixer->mixer = mixer_open(mixer_io->props.card);
@@ -909,40 +996,37 @@ int tinyalsa_mixer_set_route(struct tinyalsa_mixer *mixer, audio_devices_t devic
return -1;
}
- if(device_default && mixer_io->device_current != NULL) {
+ 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) {
LOGE("Unable to disable current device controls");
goto error_mixer;
}
-
- mixer_io->device_current = NULL;
-
- goto exit_mixer;
}
- mixer_device = tinyalsa_mixer_get_device(mixer_io, device, mode);
+ mixer_device = tinyalsa_mixer_get_device(mixer_io, default_device);
if(mixer_device == NULL) {
- LOGE("Unable to find a matching device: 0x%x with mode: 0x%x",
- device, mode);
- goto error_mixer;
+ LOGD("Unable to find default device");
+ // This is not really an issue
}
- if(mixer_io->device_current != NULL) {
- rc = tinyalsa_mixer_set_route_list(mixer, mixer_io->device_current->disable);
+ if(state && mixer_device != NULL && mixer_device->enable != NULL) {
+ rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->enable);
if(rc < 0) {
- LOGE("Unable to disable current device controls");
+ LOGE("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) {
+ LOGE("Unable to disable default device controls");
goto error_mixer;
}
}
- rc = tinyalsa_mixer_set_route_list(mixer, mixer_device->enable);
- if(rc < 0) {
- LOGE("Unable to enable device controls");
- goto error_mixer;
- }
-
- mixer_io->device_current = mixer_device;
+ mixer_io->device_current = NULL;
+ mixer_io->state = state;
exit_mixer:
mixer_close(mixer->mixer);
@@ -957,12 +1041,80 @@ error_mixer:
return -1;
}
+/*
+ * Interface
+ */
+
+int tinyalsa_mixer_set_output_state(struct tinyalsa_mixer *mixer, int state)
+{
+ LOGD("%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)
+{
+ LOGD("%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)
+{
+ LOGD("%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;
+
+ LOGD("%s(%x)", __func__, device);
+
+ if(mixer == NULL)
+ return -1;
+
+ if(!audio_is_output_device(device) && !audio_is_input_device(device)) {
+ LOGE("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) {
+ LOGE("Unable to set route for device: %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) {
+ LOGE("Unable to set route for device: %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) {
+ LOGE("Unable to set route for device: %x", device);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int tinyalsa_mixer_set_output_volume(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, float volume)
+ audio_devices_t device, float volume)
{
- LOGD("%s(%p, %x, %x, %f)", __func__, mixer, device, mode, volume);
+ LOGD("%s(%p, %x, %f)", __func__, mixer, device, volume);
- return tinyalsa_mixer_set_device_volume_with_attr(mixer, device, mode,
+ return tinyalsa_mixer_set_device_volume_with_attr(mixer,
+ TINYALSA_MIXER_DIRECTION_OUTPUT, device,
"output-volume", volume);
}
@@ -971,34 +1123,46 @@ int tinyalsa_mixer_set_master_volume(struct tinyalsa_mixer *mixer, float volume)
LOGD("%s(%p, %f)", __func__, mixer, volume);
return tinyalsa_mixer_set_device_volume_with_attr(mixer,
- AUDIO_DEVICE_OUT_DEFAULT, AUDIO_MODE_NORMAL,
+ 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, audio_mode_t mode, int mute)
+ audio_devices_t device, int mute)
{
- LOGD("%s(%p, %x, %x, %d)", __func__, mixer, device, mode, mute);
-
- return tinyalsa_mixer_set_device_state_with_attr(mixer, device, mode,
- "mic-mute", mute ? 0 : 1);
+ LOGD("%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, audio_mode_t mode, float gain)
+ audio_devices_t device, float gain)
{
- LOGD("%s(%p, %x, %x, %f)", __func__, mixer, device, mode, gain);
+ LOGD("%s(%p, %x, %f)", __func__, mixer, device, gain);
- return tinyalsa_mixer_set_device_volume_with_attr(mixer, device, mode,
+ 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, audio_mode_t mode, float volume)
+ audio_devices_t device, float volume)
{
- LOGD("%s(%p, %x, %x, %f)", __func__, mixer, device, mode, volume);
+ LOGD("%s(%p, %x, %f)", __func__, mixer, device, volume);
- return tinyalsa_mixer_set_device_volume_with_attr(mixer, device, mode,
+ return tinyalsa_mixer_set_device_volume_with_attr(mixer,
+ TINYALSA_MIXER_DIRECTION_MODEM, device,
"voice-volume", volume);
}
@@ -1033,6 +1197,16 @@ audio_devices_t tinyalsa_mixer_get_supported_devices(struct tinyalsa_mixer *mixe
list = list->next;
}
+ list = mixer->modem.devices;
+ while(list != NULL) {
+ if(list->data != NULL) {
+ mixer_device = (struct tinyalsa_mixer_device *) list->data;
+ devices |= mixer_device->props.type;
+ }
+
+ list = list->next;
+ }
+
return devices;
}
@@ -1050,6 +1224,13 @@ struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_input_props(struct tinyalsa_m
return &(mixer->input.props);
}
+struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_modem_props(struct tinyalsa_mixer *mixer)
+{
+ LOGD("%s(%p)", __func__, mixer);
+
+ return &(mixer->modem.props);
+}
+
void tinyalsa_mixer_close(struct tinyalsa_mixer *mixer)
{
LOGD("%s(%p)", __func__, mixer);
@@ -1057,8 +1238,13 @@ void tinyalsa_mixer_close(struct tinyalsa_mixer *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);
}
diff --git a/mixer.h b/mixer.h
index 3b1e19b..a6f7cca 100644
--- a/mixer.h
+++ b/mixer.h
@@ -47,7 +47,6 @@ struct tinyalsa_mixer_data {
struct tinyalsa_mixer_device_props {
audio_devices_t type;
- audio_mode_t mode;
};
struct tinyalsa_mixer_device {
@@ -72,42 +71,56 @@ 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;
- int direction;
+ enum tinyalsa_mixer_direction direction;
struct tinyalsa_mixer_device *device;
struct list_head **list_start;
struct list_head *list;
};
-int tinyalsa_mixer_open(struct tinyalsa_mixer **mixer_p, char *config_file);
-void tinyalsa_mixer_close(struct tinyalsa_mixer *mixer);
+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);
-struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_input_props(struct tinyalsa_mixer *mixer);
-struct tinyalsa_mixer_io_props *tinyalsa_mixer_get_output_props(struct tinyalsa_mixer *mixer);
-audio_devices_t tinyalsa_mixer_get_supported_devices(struct tinyalsa_mixer *mixer);
+int tinyalsa_mixer_set_device(struct tinyalsa_mixer *mixer, audio_devices_t device);
-int tinyalsa_mixer_set_voice_volume(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, float volume);
-int tinyalsa_mixer_set_input_gain(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, float gain);
-int tinyalsa_mixer_set_mic_mute(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, int mute);
-int tinyalsa_mixer_set_master_volume(struct tinyalsa_mixer *mixer, float volume);
int tinyalsa_mixer_set_output_volume(struct tinyalsa_mixer *mixer,
- audio_devices_t device, audio_mode_t mode, float volume);
+ 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);
+
+audio_devices_t tinyalsa_mixer_get_supported_devices(struct tinyalsa_mixer *mixer);
+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);
-int tinyalsa_mixer_set_route(struct tinyalsa_mixer *mixer, audio_devices_t device, audio_mode_t mode);
+void tinyalsa_mixer_close(struct tinyalsa_mixer *mixer);
+int tinyalsa_mixer_open(struct tinyalsa_mixer **mixer_p, char *config_file);
#endif