summaryrefslogtreecommitdiffstats
path: root/modules/usbaudio/audio_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/usbaudio/audio_hw.c')
-rw-r--r--modules/usbaudio/audio_hw.c49
1 files changed, 19 insertions, 30 deletions
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 664a753..0346408 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -104,9 +104,11 @@ struct stream_in {
alsa_device_profile * profile;
alsa_device_proxy proxy; /* state of the stream */
- // not used?
- // struct audio_config hal_pcm_config;
-
+ unsigned hal_channel_count; /* channel count exposed to AudioFlinger.
+ * This may differ from the device channel count when
+ * the device is not compatible with AudioFlinger
+ * capabilities, e.g. exposes too many channels or
+ * too few channels. */
/* We may need to read more data from the device in order to data reduce to 16bit, 4chan */
void * conversion_buffer; /* any conversions are put into here
* they could come from here too if
@@ -623,25 +625,13 @@ static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
const struct stream_in * in = ((const struct stream_in*)stream);
- size_t buffer_size =
- proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(in->stream));
- ALOGV("in_get_buffer_size() = %zd", buffer_size);
-
- return buffer_size;
+ return proxy_get_period_size(&in->proxy) * audio_stream_in_frame_size(&(in->stream));
}
static uint32_t in_get_channels(const struct audio_stream *stream)
{
- /* TODO Here is the code we need when we support arbitrary channel counts
- * alsa_device_proxy * proxy = ((struct stream_in*)stream)->proxy;
- * unsigned channel_count = proxy_get_channel_count(proxy);
- * uint32_t channel_mask = audio_channel_in_mask_from_count(channel_count);
- * ALOGV("in_get_channels() = 0x%X count:%d", channel_mask, channel_count);
- * return channel_mask;
- */
- /* TODO When AudioPolicyManager & AudioFlinger supports arbitrary channels
- rewrite this to return the ACTUAL channel format */
- return AUDIO_CHANNEL_IN_STEREO;
+ const struct stream_in *in = (const struct stream_in*)stream;
+ return audio_channel_in_mask_from_count(in->hal_channel_count);
}
static audio_format_t in_get_format(const struct audio_stream *stream)
@@ -808,7 +798,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte
*/
num_read_buff_bytes = bytes;
int num_device_channels = proxy_get_channel_count(&in->proxy);
- int num_req_channels = 2; /* always, for now */
+ int num_req_channels = in->hal_channel_count;
if (num_device_channels != num_req_channels) {
num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
@@ -960,19 +950,18 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
ret = -EINVAL;
}
- if (config->channel_mask == AUDIO_CHANNEL_NONE) {
- /* just return AUDIO_CHANNEL_IN_STEREO until the framework supports other input
- * formats */
- config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
-
- } else if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
- /* allow only stereo capture for now */
- config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
- ret = -EINVAL;
+ /* Channels */
+ unsigned proposed_channel_count = profile_get_default_channel_count(in->profile);
+ if (k_force_channels) {
+ proposed_channel_count = k_force_channels;
+ } else if (config->channel_mask != AUDIO_CHANNEL_NONE) {
+ proposed_channel_count = audio_channel_count_from_in_mask(config->channel_mask);
}
- // proxy_config.channels = 0; /* don't change */
- proxy_config.channels = profile_get_default_channel_count(in->profile);
+ /* we can expose any channel count mask, and emulate internally. */
+ config->channel_mask = audio_channel_in_mask_from_count(proposed_channel_count);
+ in->hal_channel_count = proposed_channel_count;
+ proxy_config.channels = profile_get_default_channel_count(in->profile);
proxy_prepare(&in->proxy, in->profile, &proxy_config);
in->standby = true;