audio: capture modifications - WIP

Capture is always mono at audio HAL.
Capture from kernel is always stereo at 44.1kHz.
One channel is stripped before resampling and forwarding to audio HAL.

Fixed several problems in mixer_paths.xml:
 - PGA input config to single ended
 - various inversions between INxL and INxR.

Change-Id: I74f437ba61eda313b7ba2251d8b9225fe6f87173
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index d44e2d5..373cfa6 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -394,6 +394,7 @@
                                    struct resampler_buffer* buffer)
 {
     struct stream_in *in;
+    size_t i;
 
     if (buffer_provider == NULL || buffer == NULL)
         return -EINVAL;
@@ -411,21 +412,24 @@
     if (in->frames_in == 0) {
         in->read_status = pcm_read(in->pcm,
                                    (void*)in->buffer,
-                                   pcm_config.period_size *
-                                       audio_stream_frame_size(&in->stream.common));
+                                   pcm_frames_to_bytes(in->pcm, pcm_config.period_size));
         if (in->read_status != 0) {
             ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
             buffer->raw = NULL;
             buffer->frame_count = 0;
             return in->read_status;
         }
+
         in->frames_in = pcm_config.period_size;
+
+        /* Do stereo to mono conversion in place by discarding right channel */
+        for (i = 1; i < in->frames_in; i++)
+            in->buffer[i] = in->buffer[i * 2];
     }
 
     buffer->frame_count = (buffer->frame_count > in->frames_in) ?
                                 in->frames_in : buffer->frame_count;
-    buffer->i16 = in->buffer + (pcm_config.period_size - in->frames_in) *
-                                                pcm_config.channels;
+    buffer->i16 = in->buffer + (pcm_config.period_size - in->frames_in);
 
     return in->read_status;
 
@@ -450,13 +454,14 @@
 static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
 {
     ssize_t frames_wr = 0;
+    size_t frame_size = audio_stream_frame_size(&in->stream.common);
 
     while (frames_wr < frames) {
         size_t frames_rd = frames - frames_wr;
         if (in->resampler != NULL) {
             in->resampler->resample_from_provider(in->resampler,
                     (int16_t *)((char *)buffer +
-                            frames_wr * audio_stream_frame_size(&in->stream.common)),
+                            frames_wr * frame_size),
                     &frames_rd);
         } else {
             struct resampler_buffer buf = {
@@ -466,9 +471,9 @@
             get_next_buffer(&in->buf_provider, &buf);
             if (buf.raw != NULL) {
                 memcpy((char *)buffer +
-                           frames_wr * audio_stream_frame_size(&in->stream.common),
+                           frames_wr * frame_size,
                         buf.raw,
-                        buf.frame_count * audio_stream_frame_size(&in->stream.common));
+                        buf.frame_count * frame_size);
                 frames_rd = buf.frame_count;
             }
             release_buffer(&in->buf_provider, &buf);
@@ -667,20 +672,19 @@
     return 0;
 }
 
+static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
+{
+    return AUDIO_CHANNEL_IN_MONO;
+}
+
+
 static size_t in_get_buffer_size(const struct audio_stream *stream)
 {
     struct stream_in *in = (struct stream_in *)stream;
 
     return get_input_buffer_size(in->requested_rate,
                                  AUDIO_FORMAT_PCM_16_BIT,
-                                 pcm_config.channels);
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
-{
-    struct stream_in *in = (struct stream_in *)stream;
-
-    return audio_channel_in_mask_from_count(pcm_config.channels);
+                                 popcount(in_get_channels(stream)));
 }
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
@@ -809,10 +813,8 @@
 
     /*if (in->num_preprocessors != 0)
         ret = process_frames(in, buffer, frames_rq);
-    else */if (in->resampler != NULL)
-        ret = read_frames(in, buffer, frames_rq);
-    else
-        ret = pcm_read(in->pcm, buffer, bytes);
+      else */
+    ret = read_frames(in, buffer, frames_rq);
 
     if (ret > 0)
         ret = 0;
@@ -977,9 +979,9 @@
 
     *stream_in = NULL;
 
-    /* Respond with a request for stereo if a different format is given. */
-    if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
-        config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+    /* Respond with a request for mono if a different format is given. */
+    if (config->channel_mask != AUDIO_CHANNEL_IN_MONO) {
+        config->channel_mask = AUDIO_CHANNEL_IN_MONO;
         return -EINVAL;
     }
 
@@ -1008,8 +1010,9 @@
     in->requested_rate = config->sample_rate;
     in->input_source = AUDIO_SOURCE_DEFAULT;
 
-    in->buffer = malloc(pcm_config.period_size *
-                        audio_stream_frame_size(&in->stream.common));
+    in->buffer = malloc(pcm_config.period_size * pcm_config.channels
+                                               * audio_stream_frame_size(&in->stream.common));
+
     if (!in->buffer) {
         ret = -ENOMEM;
         goto err_malloc;
@@ -1021,7 +1024,7 @@
 
         ret = create_resampler(pcm_config.rate,
                                in->requested_rate,
-                               pcm_config.channels,
+                               1,
                                RESAMPLER_QUALITY_DEFAULT,
                                &in->buf_provider,
                                &in->resampler);
diff --git a/mixer_paths.xml b/mixer_paths.xml
index 45c57cd..6f89450 100644
--- a/mixer_paths.xml
+++ b/mixer_paths.xml
@@ -14,26 +14,24 @@
 
   <ctl name="MIXINL IN1L Switch" value="0" />
   <ctl name="IN1L Switch" value="0" />
-  <ctl name="IN1L PGA IN1LP Switch" value="1" />
+  <ctl name="IN1L PGA IN1LP Switch" value="0" />
   <ctl name="IN1L PGA IN1LN Switch" value="1" />
 
   <ctl name="MIXINL IN2L Switch" value="0" />
   <ctl name="IN2L Switch" value="0" />
-  <ctl name="IN2L PGA IN2LP Switch" value="1" />
+  <ctl name="IN2L PGA IN2LP Switch" value="0" />
   <ctl name="IN2L PGA IN2LN Switch" value="1" />
 
   <ctl name="MIXINR IN1R Switch" value="0" />
   <ctl name="IN1R Switch" value="0" />
-  <ctl name="IN1R PGA IN1RP Switch" value="1" />
+  <ctl name="IN1R PGA IN1RP Switch" value="0" />
   <ctl name="IN1R PGA IN1RN Switch" value="1" />
 
   <ctl name="MIXINR IN2R Switch" value="0" />
   <ctl name="IN2R Switch" value="0" />
-  <ctl name="IN2R PGA IN2RP Switch" value="1" />
+  <ctl name="IN2R PGA IN2RP Switch" value="0" />
   <ctl name="IN2R PGA IN2RN Switch" value="1" />
 
-  <ctl name="AIF1ADC1 HPF Switch" value="on" />
-
   <ctl name="AIF2DACL Mux" value="AIF3" />
   <ctl name="AIF2DACR Mux" value="AIF3" />
   <ctl name="AIF3ADC Mux" value="Mono PCM" />
@@ -112,29 +110,33 @@
     <ctl name="MIXINR IN2R Switch" value="1" />
     <ctl name="MIXINR IN2R Volume" value="1" />
     <ctl name="IN2R Switch" value="1" />
-    <ctl name="AIF1ADCL Source" value="right" />
-    <ctl name="AIF1ADCR Source" value="right" />
+    <ctl name="AIF1ADCL Source" value="Right" />
     <path name="adc-to-aif1adc" />
   </path>
 
   <path name="main-mic-off">
-    <ctl name="MIXINL IN2R Switch" value="0" />
-    <ctl name="MIXINL IN2R Volume" value="0" />
+    <ctl name="MIXINR IN2R Switch" value="0" />
     <ctl name="IN2R Switch" value="0" />
   </path>
 
-  <path name="second-mic-on">
+  <path name="second-mic-on-left">
     <ctl name="MIXINL IN2L Switch" value="1" />
     <ctl name="MIXINL IN2L Volume" value="1" />
     <ctl name="IN2L Switch" value="1" />
-    <ctl name="AIF1ADCL Source" value="left" />
-    <ctl name="AIF1ADCR Source" value="left" />
+    <ctl name="AIF1ADCL Source" value="Left" />
+    <path name="adc-to-aif1adc" />
+  </path>
+
+  <path name="second-mic-on-right">
+    <ctl name="MIXINL IN2L Switch" value="1" />
+    <ctl name="MIXINL IN2L Volume" value="1" />
+    <ctl name="IN2L Switch" value="1" />
+    <ctl name="AIF1ADCR Source" value="Left" />
     <path name="adc-to-aif1adc" />
   </path>
 
   <path name="second-mic-off">
     <ctl name="MIXINL IN2L Switch" value="0" />
-    <ctl name="MIXINL IN2L Volume" value="0" />
     <ctl name="IN2L Switch" value="0" />
   </path>
 
@@ -142,48 +144,44 @@
     <ctl name="MIXINL IN1L Switch" value="1" />
     <ctl name="MIXINL IN1L Volume" value="1" />
     <ctl name="IN1L Switch" value="1" />
-    <ctl name="AIF1ADCL Source" value="left" />
-    <ctl name="AIF1ADCR Source" value="left" />
+    <ctl name="AIF1ADCR Source" value="Left" />
     <path name="adc-to-aif1adc" />
   </path>
 
   <path name="third-mic-off">
     <ctl name="MIXINL IN1L Switch" value="0" />
-    <ctl name="MIXINL IN1L Volume" value="0" />
     <ctl name="IN1L Switch" value="0" />
   </path>
 
   <path name="headset-mic-on">
-    <ctl name="MIXINL IN1R Switch" value="1" />
-    <ctl name="MIXINL IN1R Volume" value="1" />
+    <ctl name="MIXINR IN1R Switch" value="1" />
+    <ctl name="MIXINR IN1R Volume" value="1" />
     <ctl name="IN1R Switch" value="1" />
-    <ctl name="AIF1ADCL Source" value="right" />
-    <ctl name="AIF1ADCR Source" value="right" />
+    <ctl name="AIF1ADCL Source" value="Right" />
     <path name="adc-to-aif1adc" />
   </path>
 
   <path name="headset-mic-off">
-    <ctl name="MIXINL IN1R Switch" value="0" />
-    <ctl name="MIXINL IN1R Volume" value="0" />
+    <ctl name="MIXINR IN1R Switch" value="0" />
     <ctl name="IN1R Switch" value="0" />
   </path>
 
   <path name="main-mic">
-    <path name="main-mic-on" />
     <path name="second-mic-off" />
     <path name="headset-mic-off" />
+    <path name="main-mic-on" />
   </path>
 
   <path name="second-mic">
-    <path name="second-mic-on" />
     <path name="main-mic-off" />
     <path name="headset-mic-off" />
+    <path name="second-mic-on-left" />
   </path>
 
   <path name="headset-mic">
-    <path name="headset-mic-on" />
     <path name="main-mic-off" />
     <path name="second-mic-off" />
+    <path name="headset-mic-on" />
   </path>
 
   <!-- These are useful named paths -->
@@ -256,43 +254,56 @@
 
   <path name="media-main-mic">
     <path name="main-mic" />
-    <ctl name="IN2R Volume" value="20" />
+    <ctl name="IN2R Volume" value="16" />
+    <ctl name="AIF1ADC1 HPF Switch" value="1" />
     <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
   <path name="voice-rec-main-mic">
-    <path name="main-mic" />
-    <ctl name="IN2R Volume" value="20" />
+    <path name="headset-mic-off" />
+    <path name="main-mic-on" />
+    <path name="second-mic-on-right" />
+    <ctl name="IN2R Volume" value="16" />
+    <ctl name="IN2L Volume" value="16" />
+    <ctl name="AIF1ADC1 HPF Switch" value="1" />
     <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
   <path name="communication-main-mic">
-    <path name="main-mic" />
-    <ctl name="IN2R Volume" value="20" />
-    <ctl name="AIF1ADC1 HPF Mode" value="Voice 1" />
+    <path name="headset-mic-off" />
+    <path name="main-mic-on" />
+    <path name="second-mic-on-right" />
+    <ctl name="IN2R Volume" value="16" />
+    <ctl name="IN2L Volume" value="16" />
+    <ctl name="AIF1ADC1 HPF Switch" value="1" />
+    <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
   <path name="media-second-mic">
-    <path name="second-mic" />
-    <ctl name="IN2L Volume" value="20" />
+    <path name="main-mic-off" />
+    <path name="headset-mic-off" />
+    <path name="second-mic-on-left" />
+    <ctl name="IN2L Volume" value="16" />
+    <ctl name="AIF1ADC1 HPF Switch" value="1" />
     <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
   <path name="media-headset-mic">
     <path name="headset-mic" />
-    <ctl name="IN1R Volume" value="20" />
+    <ctl name="IN1R Volume" value="16" />
     <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
+  <!-- TODO headset paths not properly configured yet -->
   <path name="voice-rec-headset-mic">
     <path name="headset-mic" />
-    <ctl name="IN1R Volume" value="20" />
+    <ctl name="IN1R Volume" value="16" />
     <ctl name="AIF1ADC1 HPF Mode" value="HiFi" />
   </path>
 
   <path name="communication-headset-mic">
     <path name="headset-mic" />
-    <ctl name="IN1R Volume" value="20" />
+    <ctl name="IN1R Volume" value="16" />
     <ctl name="AIF1ADC1 HPF Mode" value="Voice 1" />
   </path>