blob: b2005c62f197d6261f552304f13725ca81c8dd4f [file] [log] [blame]
Simon Wilson19957a32012-04-06 16:17:12 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "usb_audio_hw"
Paul McLeancf611912014-04-28 13:03:18 -070018/*#define LOG_NDEBUG 0*/
Paul McLeanf62d75e2014-07-11 15:14:19 -070019/*#define LOG_PCM_PARAMS 0*/
Simon Wilson19957a32012-04-06 16:17:12 -070020
21#include <errno.h>
Mark Salyzyn88e458a2014-04-28 12:30:44 -070022#include <inttypes.h>
Simon Wilson19957a32012-04-06 16:17:12 -070023#include <pthread.h>
24#include <stdint.h>
Simon Wilson19957a32012-04-06 16:17:12 -070025#include <stdlib.h>
Mark Salyzyn88e458a2014-04-28 12:30:44 -070026#include <sys/time.h>
Simon Wilson19957a32012-04-06 16:17:12 -070027
Mark Salyzyn88e458a2014-04-28 12:30:44 -070028#include <log/log.h>
Simon Wilson19957a32012-04-06 16:17:12 -070029#include <cutils/str_parms.h>
30#include <cutils/properties.h>
31
Simon Wilson19957a32012-04-06 16:17:12 -070032#include <hardware/audio.h>
Paul McLeane32cbc12014-06-25 10:42:07 -070033#include <hardware/audio_alsaops.h>
34#include <hardware/hardware.h>
35
36#include <system/audio.h>
Simon Wilson19957a32012-04-06 16:17:12 -070037
38#include <tinyalsa/asoundlib.h>
39
Paul McLeanf62d75e2014-07-11 15:14:19 -070040#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
41
Paul McLeaneedc92e2013-12-19 15:46:15 -080042/* This is the default configuration to hand to The Framework on the initial
43 * adev_open_output_stream(). Actual device attributes will be used on the subsequent
44 * adev_open_output_stream() after the card and device number have been set in out_set_parameters()
45 */
46#define OUT_PERIOD_SIZE 1024
47#define OUT_PERIOD_COUNT 4
48#define OUT_SAMPLING_RATE 44100
49
50struct pcm_config default_alsa_out_config = {
Simon Wilson19957a32012-04-06 16:17:12 -070051 .channels = 2,
Paul McLeaneedc92e2013-12-19 15:46:15 -080052 .rate = OUT_SAMPLING_RATE,
53 .period_size = OUT_PERIOD_SIZE,
54 .period_count = OUT_PERIOD_COUNT,
Simon Wilson19957a32012-04-06 16:17:12 -070055 .format = PCM_FORMAT_S16_LE,
56};
57
Paul McLeaneedc92e2013-12-19 15:46:15 -080058/*
59 * Input defaults. See comment above.
60 */
61#define IN_PERIOD_SIZE 1024
62#define IN_PERIOD_COUNT 4
63#define IN_SAMPLING_RATE 44100
64
65struct pcm_config default_alsa_in_config = {
66 .channels = 2,
67 .rate = IN_SAMPLING_RATE,
68 .period_size = IN_PERIOD_SIZE,
69 .period_count = IN_PERIOD_COUNT,
70 .format = PCM_FORMAT_S16_LE,
71 .start_threshold = 1,
72 .stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
73};
74
Paul McLeanf62d75e2014-07-11 15:14:19 -070075struct audio_device_profile {
76 int card;
77 int device;
78 int direction; /* PCM_OUT or PCM_IN */
79};
80
Simon Wilson19957a32012-04-06 16:17:12 -070081struct audio_device {
82 struct audio_hw_device hw_device;
83
84 pthread_mutex_t lock; /* see note below on mutex acquisition order */
Paul McLeaneedc92e2013-12-19 15:46:15 -080085
86 /* output */
Paul McLeanf62d75e2014-07-11 15:14:19 -070087 struct audio_device_profile out_profile;
Paul McLeaneedc92e2013-12-19 15:46:15 -080088
89 /* input */
Paul McLeanf62d75e2014-07-11 15:14:19 -070090 struct audio_device_profile in_profile;
Paul McLeaneedc92e2013-12-19 15:46:15 -080091
Simon Wilson19957a32012-04-06 16:17:12 -070092 bool standby;
93};
94
95struct stream_out {
96 struct audio_stream_out stream;
97
Paul McLeaneedc92e2013-12-19 15:46:15 -080098 pthread_mutex_t lock; /* see note below on mutex acquisition order */
99 struct pcm *pcm; /* state of the stream */
100 bool standby;
101
102 struct audio_device *dev; /* hardware information */
Paul McLeanf62d75e2014-07-11 15:14:19 -0700103 struct audio_device_profile * profile;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800104
105 void * conversion_buffer; /* any conversions are put into here
106 * they could come from here too if
107 * there was a previous conversion */
108 size_t conversion_buffer_size; /* in bytes */
109};
110
111/*
112 * Output Configuration Cache
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700113 * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure.
Paul McLeaneedc92e2013-12-19 15:46:15 -0800114 */
115static struct pcm_config cached_output_hardware_config;
116static bool output_hardware_config_is_cached = false;
117
118struct stream_in {
119 struct audio_stream_in stream;
120
Simon Wilson19957a32012-04-06 16:17:12 -0700121 pthread_mutex_t lock; /* see note below on mutex acquisition order */
122 struct pcm *pcm;
123 bool standby;
124
125 struct audio_device *dev;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800126
Paul McLeanf62d75e2014-07-11 15:14:19 -0700127 struct audio_device_profile * profile;
128
Paul McLeaneedc92e2013-12-19 15:46:15 -0800129 struct audio_config hal_pcm_config;
130
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700131 /* this is the format the framework thinks it's using. We may need to convert from the actual
132 * (24-bit, 32-bit?) format to this theoretical (framework, probably 16-bit)
133 * format in in_read() */
134 enum pcm_format input_framework_format;
135
Paul McLeaneedc92e2013-12-19 15:46:15 -0800136// struct resampler_itfe *resampler;
137// struct resampler_buffer_provider buf_provider;
Paul McLean30f41852014-04-16 15:44:20 -0700138
Paul McLeaneedc92e2013-12-19 15:46:15 -0800139 int read_status;
Paul McLean30f41852014-04-16 15:44:20 -0700140
141 // We may need to read more data from the device in order to data reduce to 16bit, 4chan */
142 void * conversion_buffer; /* any conversions are put into here
143 * they could come from here too if
144 * there was a previous conversion */
145 size_t conversion_buffer_size; /* in bytes */
Simon Wilson19957a32012-04-06 16:17:12 -0700146};
147
Paul McLeaneedc92e2013-12-19 15:46:15 -0800148/*
Paul McLean30f41852014-04-16 15:44:20 -0700149 * Input Configuration Cache
150 * FIXME(pmclean) This is not reentrant. Should probably be moved into the stream structure
151 * but that will involve changes in The Framework.
152 */
153static struct pcm_config cached_input_hardware_config;
154static bool input_hardware_config_is_cached = false;
155
156/*
Paul McLeaneedc92e2013-12-19 15:46:15 -0800157 * Utility
158 */
159/*
Paul McLeaneedc92e2013-12-19 15:46:15 -0800160 * Data Conversions
161 */
162/*
Paul McLean30f41852014-04-16 15:44:20 -0700163 * Convert a buffer of packed (3-byte) PCM24LE samples to PCM16LE samples.
164 * in_buff points to the buffer of PCM24LE samples
Paul McLeaneedc92e2013-12-19 15:46:15 -0800165 * num_in_samples size of input buffer in SAMPLES
Paul McLean30f41852014-04-16 15:44:20 -0700166 * out_buff points to the buffer to receive converted PCM16LE LE samples.
167 * returns
168 * the number of BYTES of output data.
169 * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
170 * support PCM24_3LE (24-bit, packed).
171 * NOTE:
Paul McLean30f41852014-04-16 15:44:20 -0700172 * This conversion is safe to do in-place (in_buff == out_buff).
Paul McLeane32cbc12014-06-25 10:42:07 -0700173 * TODO Move this to a utilities module.
Paul McLean30f41852014-04-16 15:44:20 -0700174 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700175static size_t convert_24_3_to_16(const unsigned char * in_buff, size_t num_in_samples,
176 short * out_buff)
177{
Paul McLean30f41852014-04-16 15:44:20 -0700178 /*
179 * Move from front to back so that the conversion can be done in-place
180 * i.e. in_buff == out_buff
181 */
182 /* we need 2 bytes in the output for every 3 bytes in the input */
183 unsigned char* dst_ptr = (unsigned char*)out_buff;
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700184 const unsigned char* src_ptr = in_buff;
Paul McLean30f41852014-04-16 15:44:20 -0700185 size_t src_smpl_index;
186 for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
187 src_ptr++; /* lowest-(skip)-byte */
188 *dst_ptr++ = *src_ptr++; /* low-byte */
189 *dst_ptr++ = *src_ptr++; /* high-byte */
190 }
191
192 /* return number of *bytes* generated: */
193 return num_in_samples * 2;
194}
195
196/*
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700197 * Convert a buffer of packed (3-byte) PCM32 samples to PCM16LE samples.
198 * in_buff points to the buffer of PCM32 samples
199 * num_in_samples size of input buffer in SAMPLES
200 * out_buff points to the buffer to receive converted PCM16LE LE samples.
201 * returns
202 * the number of BYTES of output data.
203 * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
204 * support PCM_FORMAT_S32_LE (32-bit).
205 * NOTE:
206 * This conversion is safe to do in-place (in_buff == out_buff).
207 * TODO Move this to a utilities module.
208 */
209static size_t convert_32_to_16(const int32_t * in_buff, size_t num_in_samples, short * out_buff)
210{
211 /*
212 * Move from front to back so that the conversion can be done in-place
213 * i.e. in_buff == out_buff
214 */
215
216 short * dst_ptr = out_buff;
217 const int32_t* src_ptr = in_buff;
218 size_t src_smpl_index;
219 for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
220 *dst_ptr++ = *src_ptr++ >> 16;
221 }
222
223 /* return number of *bytes* generated: */
224 return num_in_samples * 2;
225}
226
227/*
Paul McLean30f41852014-04-16 15:44:20 -0700228 * Convert a buffer of N-channel, interleaved PCM16 samples to M-channel PCM16 channels
229 * (where N < M).
230 * in_buff points to the buffer of PCM16 samples
231 * in_buff_channels Specifies the number of channels in the input buffer.
Paul McLeaneedc92e2013-12-19 15:46:15 -0800232 * out_buff points to the buffer to receive converted PCM16 samples.
Paul McLean30f41852014-04-16 15:44:20 -0700233 * out_buff_channels Specifies the number of channels in the output buffer.
234 * num_in_samples size of input buffer in SAMPLES
235 * returns
236 * the number of BYTES of output data.
237 * NOTE
238 * channels > N are filled with silence.
239 * This conversion is safe to do in-place (in_buff == out_buff)
Paul McLeaneedc92e2013-12-19 15:46:15 -0800240 * We are doing this since we *always* present to The Framework as STEREO device, but need to
241 * support 4-channel devices.
Paul McLeane32cbc12014-06-25 10:42:07 -0700242 * TODO Move this to a utilities module.
Paul McLeaneedc92e2013-12-19 15:46:15 -0800243 */
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700244static size_t expand_channels_16(const short* in_buff, int in_buff_chans,
Paul McLean30f41852014-04-16 15:44:20 -0700245 short* out_buff, int out_buff_chans,
Paul McLeane32cbc12014-06-25 10:42:07 -0700246 size_t num_in_samples)
247{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800248 /*
249 * Move from back to front so that the conversion can be done in-place
250 * i.e. in_buff == out_buff
Paul McLean30f41852014-04-16 15:44:20 -0700251 * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
Paul McLeaneedc92e2013-12-19 15:46:15 -0800252 */
Paul McLean30f41852014-04-16 15:44:20 -0700253 int num_out_samples = (num_in_samples * out_buff_chans)/in_buff_chans;
254
255 short* dst_ptr = out_buff + num_out_samples - 1;
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700256 size_t src_index;
257 const short* src_ptr = in_buff + num_in_samples - 1;
Paul McLean30f41852014-04-16 15:44:20 -0700258 int num_zero_chans = out_buff_chans - in_buff_chans;
259 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
260 int dst_offset;
Paul McLeane32cbc12014-06-25 10:42:07 -0700261 for (dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700262 *dst_ptr-- = 0;
263 }
Paul McLeane32cbc12014-06-25 10:42:07 -0700264 for (; dst_offset < out_buff_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700265 *dst_ptr-- = *src_ptr--;
266 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800267 }
268
269 /* return number of *bytes* generated */
Paul McLean30f41852014-04-16 15:44:20 -0700270 return num_out_samples * sizeof(short);
271}
272
273/*
274 * Convert a buffer of N-channel, interleaved PCM16 samples to M-channel PCM16 channels
275 * (where N > M).
276 * in_buff points to the buffer of PCM16 samples
277 * in_buff_channels Specifies the number of channels in the input buffer.
278 * out_buff points to the buffer to receive converted PCM16 samples.
279 * out_buff_channels Specifies the number of channels in the output buffer.
280 * num_in_samples size of input buffer in SAMPLES
281 * returns
282 * the number of BYTES of output data.
283 * NOTE
284 * channels > N are thrown away.
285 * This conversion is safe to do in-place (in_buff == out_buff)
286 * We are doing this since we *always* present to The Framework as STEREO device, but need to
287 * support 4-channel devices.
Paul McLeane32cbc12014-06-25 10:42:07 -0700288 * TODO Move this to a utilities module.
Paul McLean30f41852014-04-16 15:44:20 -0700289 */
290static size_t contract_channels_16(short* in_buff, int in_buff_chans,
291 short* out_buff, int out_buff_chans,
Paul McLeane32cbc12014-06-25 10:42:07 -0700292 size_t num_in_samples)
293{
Paul McLean30f41852014-04-16 15:44:20 -0700294 /*
295 * Move from front to back so that the conversion can be done in-place
296 * i.e. in_buff == out_buff
297 * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
298 */
299 int num_out_samples = (num_in_samples * out_buff_chans)/in_buff_chans;
300
301 int num_skip_samples = in_buff_chans - out_buff_chans;
302
303 short* dst_ptr = out_buff;
304 short* src_ptr = in_buff;
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700305 size_t src_index;
Paul McLean30f41852014-04-16 15:44:20 -0700306 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
307 int dst_offset;
Paul McLeane32cbc12014-06-25 10:42:07 -0700308 for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700309 *dst_ptr++ = *src_ptr++;
310 }
311 src_ptr += num_skip_samples;
312 }
313
314 /* return number of *bytes* generated */
315 return num_out_samples * sizeof(short);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800316}
317
318/*
319 * ALSA Utilities
320 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700321/*TODO This table and the function that uses it should be moved to a utilities module (probably) */
Paul McLeaneedc92e2013-12-19 15:46:15 -0800322/*
Paul McLeane32cbc12014-06-25 10:42:07 -0700323 * Maps bit-positions in a pcm_mask to the corresponding AUDIO_ format string.
Paul McLeaneedc92e2013-12-19 15:46:15 -0800324 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700325static const char * const format_string_map[] = {
326 "AUDIO_FORMAT_PCM_8_BIT", /* 00 - SNDRV_PCM_FORMAT_S8 */
327 "AUDIO_FORMAT_PCM_8_BIT", /* 01 - SNDRV_PCM_FORMAT_U8 */
328 "AUDIO_FORMAT_PCM_16_BIT", /* 02 - SNDRV_PCM_FORMAT_S16_LE */
329 NULL, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
330 NULL, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
331 NULL, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
332 "AUDIO_FORMAT_PCM_24_BIT_PACKED", /* 06 - SNDRV_PCM_FORMAT_S24_LE */
333 NULL, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
334 NULL, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
335 NULL, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
336 "AUDIO_FORMAT_PCM_32_BIT", /* 10 - SNDRV_PCM_FORMAT_S32_LE */
337 NULL, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
338 NULL, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
339 NULL, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
340 "AUDIO_FORMAT_PCM_FLOAT", /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
341 NULL, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
342 NULL, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
343 NULL, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
344 NULL, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
345 NULL, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
346 NULL, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
347 NULL, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
348 NULL, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
349 NULL, /* 23 - SNDRV_PCM_FORMAT_MPEG */
350 NULL, /* 24 - SNDRV_PCM_FORMAT_GSM */
351 NULL, NULL, NULL, NULL, NULL, NULL, /* 25 -> 30 (not assigned) */
352 NULL, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
353 "AUDIO_FORMAT_PCM_24_BIT_PACKED", /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
354 NULL, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
355 NULL, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
356 NULL, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
357 NULL, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
358 NULL, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
359 NULL, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
360 NULL, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
361 NULL, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
362 NULL, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
363 NULL, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
364 NULL, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
365 NULL, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
366 NULL, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
367 NULL, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
368 NULL, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
369 NULL, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
370 NULL /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
371};
372
373/*
374 * Generate string containing a bar ("|") delimited list of AUDIO_ formats specified in
375 * the mask parameter.
376 *
377 */
378static char* get_format_str_for_mask(struct pcm_mask* mask)
Paul McLeaneedc92e2013-12-19 15:46:15 -0800379{
Paul McLeane32cbc12014-06-25 10:42:07 -0700380 char buffer[256];
381 int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
382 buffer[0] = '\0';
383
384 int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
385 int bits_per_slot = sizeof(mask->bits[0]) * 8;
386
387 const char* format_str = NULL;
388 int table_size = sizeof(format_string_map)/sizeof(format_string_map[0]);
389
390 int slot_index, bit_index, table_index;
391 table_index = 0;
392 int num_written = 0;
393 for (slot_index = 0; slot_index < num_slots; slot_index++) {
394 unsigned bit_mask = 1;
395 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
396 if ((mask->bits[slot_index] & bit_mask) != 0) {
397 format_str = table_index < table_size
398 ? format_string_map[table_index]
399 : NULL;
400 if (format_str != NULL) {
401 if (num_written != 0) {
402 num_written += snprintf(buffer + num_written,
403 buffer_size - num_written, "|");
404 }
405 num_written += snprintf(buffer + num_written, buffer_size - num_written,
406 "%s", format_str);
407 }
408 }
409 bit_mask <<= 1;
410 table_index++;
Paul McLean30f41852014-04-16 15:44:20 -0700411 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800412 }
Paul McLeane32cbc12014-06-25 10:42:07 -0700413
414 return strdup(buffer);
415}
416
417/*
418 * Maps from bit position in pcm_mask to AUDIO_ format constants.
419 */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700420static audio_format_t const format_value_map[] = {
Paul McLeane32cbc12014-06-25 10:42:07 -0700421 AUDIO_FORMAT_PCM_8_BIT, /* 00 - SNDRV_PCM_FORMAT_S8 */
422 AUDIO_FORMAT_PCM_8_BIT, /* 01 - SNDRV_PCM_FORMAT_U8 */
423 AUDIO_FORMAT_PCM_16_BIT, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
424 AUDIO_FORMAT_INVALID, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
425 AUDIO_FORMAT_INVALID, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
426 AUDIO_FORMAT_INVALID, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700427 AUDIO_FORMAT_INVALID, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
Paul McLeane32cbc12014-06-25 10:42:07 -0700428 AUDIO_FORMAT_INVALID, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
429 AUDIO_FORMAT_INVALID, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
430 AUDIO_FORMAT_INVALID, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
431 AUDIO_FORMAT_PCM_32_BIT, /* 10 - SNDRV_PCM_FORMAT_S32_LE */
432 AUDIO_FORMAT_INVALID, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
433 AUDIO_FORMAT_INVALID, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
434 AUDIO_FORMAT_INVALID, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
435 AUDIO_FORMAT_PCM_FLOAT, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
436 AUDIO_FORMAT_INVALID, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
437 AUDIO_FORMAT_INVALID, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
438 AUDIO_FORMAT_INVALID, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
439 AUDIO_FORMAT_INVALID, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
440 AUDIO_FORMAT_INVALID, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
441 AUDIO_FORMAT_INVALID, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
442 AUDIO_FORMAT_INVALID, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
443 AUDIO_FORMAT_INVALID, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
444 AUDIO_FORMAT_INVALID, /* 23 - SNDRV_PCM_FORMAT_MPEG */
445 AUDIO_FORMAT_INVALID, /* 24 - SNDRV_PCM_FORMAT_GSM */
446 AUDIO_FORMAT_INVALID, /* 25 -> 30 (not assigned) */
447 AUDIO_FORMAT_INVALID,
448 AUDIO_FORMAT_INVALID,
449 AUDIO_FORMAT_INVALID,
450 AUDIO_FORMAT_INVALID,
451 AUDIO_FORMAT_INVALID,
452 AUDIO_FORMAT_INVALID, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700453 AUDIO_FORMAT_PCM_24_BIT_PACKED, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */
Paul McLeane32cbc12014-06-25 10:42:07 -0700454 AUDIO_FORMAT_INVALID, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
455 AUDIO_FORMAT_INVALID, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
456 AUDIO_FORMAT_INVALID, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
457 AUDIO_FORMAT_INVALID, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
458 AUDIO_FORMAT_INVALID, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
459 AUDIO_FORMAT_INVALID, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
460 AUDIO_FORMAT_INVALID, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
461 AUDIO_FORMAT_INVALID, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
462 AUDIO_FORMAT_INVALID, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
463 AUDIO_FORMAT_INVALID, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
464 AUDIO_FORMAT_INVALID, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
465 AUDIO_FORMAT_INVALID, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
466 AUDIO_FORMAT_INVALID, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
467 AUDIO_FORMAT_INVALID, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
468 AUDIO_FORMAT_INVALID, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
469 AUDIO_FORMAT_INVALID, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
470 AUDIO_FORMAT_INVALID /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
471};
472
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700473/*
474 * Returns true if mask indicates support for PCM_16.
475 */
476static bool mask_has_pcm_16(struct pcm_mask* mask) {
477 return (mask->bits[0] & 0x0004) != 0;
478}
479
Paul McLeane32cbc12014-06-25 10:42:07 -0700480static int get_format_for_mask(struct pcm_mask* mask)
481{
482 int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
483 int bits_per_slot = sizeof(mask->bits[0]) * 8;
484
485 int table_size = sizeof(format_value_map) / sizeof(format_value_map[0]);
486
487 int slot_index, bit_index, table_index;
488 table_index = 0;
489 int num_written = 0;
490 for (slot_index = 0; slot_index < num_slots; slot_index++) {
491 unsigned bit_mask = 1;
492 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
493 if ((mask->bits[slot_index] & bit_mask) != 0) {
494 /* just return the first one */
495 return table_index < table_size
496 ? format_value_map[table_index]
497 : AUDIO_FORMAT_INVALID;
498 }
499 bit_mask <<= 1;
500 table_index++;
501 }
502 }
503
504 return AUDIO_FORMAT_INVALID;
505}
506
507/*
508 * Maps from bit position in pcm_mask to AUDIO_ format constants.
509 */
510static int const pcm_format_value_map[] = {
511 PCM_FORMAT_S8, /* 00 - SNDRV_PCM_FORMAT_S8 */
512 0, /* 01 - SNDRV_PCM_FORMAT_U8 */
513 PCM_FORMAT_S16_LE, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
514 0, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
515 0, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
516 0, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
517 PCM_FORMAT_S24_3LE, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
518 0, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
519 0, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
520 0, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
521 PCM_FORMAT_S32_LE, /* 10 - SNDRV_PCM_FORMAT_S32_LE */
522 0, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
523 0, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
524 0, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
525 0, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
526 0, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
527 0, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
528 0, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
529 0, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
530 0, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
531 0, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
532 0, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
533 0, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
534 0, /* 23 - SNDRV_PCM_FORMAT_MPEG */
535 0, /* 24 - SNDRV_PCM_FORMAT_GSM */
536 0, /* 25 -> 30 (not assigned) */
537 0,
538 0,
539 0,
540 0,
541 0,
542 0, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
543 PCM_FORMAT_S24_3LE, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
544 0, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
545 0, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
546 0, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
547 0, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
548 0, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
549 0, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
550 0, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
551 0, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
552 0, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
553 0, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
554 0, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
555 0, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
556 0, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
557 0, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
558 0, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
559 0, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
560 0 /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
561};
562
563static int get_pcm_format_for_mask(struct pcm_mask* mask) {
564 int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
565 int bits_per_slot = sizeof(mask->bits[0]) * 8;
566
567 int table_size = sizeof(pcm_format_value_map) / sizeof(pcm_format_value_map[0]);
568
569 int slot_index, bit_index, table_index;
570 table_index = 0;
571 int num_written = 0;
572 for (slot_index = 0; slot_index < num_slots; slot_index++) {
573 unsigned bit_mask = 1;
574 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
575 if ((mask->bits[slot_index] & bit_mask) != 0) {
576 /* just return the first one */
577 return table_index < table_size
578 ? pcm_format_value_map[table_index]
Paul McLeanf62d75e2014-07-11 15:14:19 -0700579 : (int)AUDIO_FORMAT_INVALID;
Paul McLeane32cbc12014-06-25 10:42:07 -0700580 }
581 bit_mask <<= 1;
582 table_index++;
583 }
584 }
585
586 return 0; // is this right?
587}
588
Paul McLeanf62d75e2014-07-11 15:14:19 -0700589static bool test_out_sample_rate(struct audio_device_profile* dev_profile, unsigned rate) {
590 struct pcm_config local_config = cached_output_hardware_config;
591 local_config.rate = rate;
592
593 bool works = false; /* let's be pessimistic */
594 struct pcm * pcm =
595 pcm_open(dev_profile->card, dev_profile->device, dev_profile->direction, &local_config);
596
597 if (pcm != NULL) {
598 works = pcm_is_ready(pcm);
599 pcm_close(pcm);
600 }
601
602 return works;
603}
604
605/* sort these highest -> lowest */
606static const unsigned std_sample_rates[] =
607 {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
608
609static char* enum_std_sample_rates(struct audio_device_profile* dev_profile,
610 unsigned min, unsigned max)
611{
612 char buffer[128];
613 buffer[0] = '\0';
614 int buffSize = ARRAY_SIZE(buffer);
615
616 char numBuffer[32];
617
618 int numEntries = 0;
619 unsigned index;
620 for(index = 0; index < ARRAY_SIZE(std_sample_rates); index++) {
621 if (std_sample_rates[index] >= min && std_sample_rates[index] <= max &&
622 test_out_sample_rate(dev_profile, std_sample_rates[index])) {
623 if (numEntries++ != 0) {
624 strncat(buffer, "|", buffSize);
625 }
626 snprintf(numBuffer, sizeof(numBuffer), "%u", std_sample_rates[index]);
627 strncat(buffer, numBuffer, buffSize);
628 }
629 }
630
631 return strdup(buffer);
632}
633
634/*
635 * Logging
636 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700637static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
638 char buff[512];
639 char bit_buff[32];
640 int buffSize = sizeof(buff)/sizeof(buff[0]);
641
642 buff[0] = '\0';
643
644 int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
645 int bits_per_slot = sizeof(mask->bits[0]) * 8;
646
647 int slot_index, bit_index;
648 strcat(buff, "[");
649 for (slot_index = 0; slot_index < num_slots; slot_index++) {
650 unsigned bit_mask = 1;
651 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
652 strcat(buff, (mask->bits[slot_index] & bit_mask) != 0 ? "1" : "0");
653 bit_mask <<= 1;
654 }
655 if (slot_index < num_slots - 1) {
656 strcat(buff, ",");
657 }
658 }
659 strcat(buff, "]");
660
661 ALOGV("usb:audio_hw - %s mask:%s", mask_name, buff);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800662}
663
Paul McLeancf611912014-04-28 13:03:18 -0700664static void log_pcm_params(struct pcm_params * alsa_hw_params) {
665 ALOGV("usb:audio_hw - PCM_PARAM_SAMPLE_BITS min:%u, max:%u",
666 pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS),
667 pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS));
668 ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%u, max:%u",
669 pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS),
670 pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS));
Paul McLeane32cbc12014-06-25 10:42:07 -0700671 log_pcm_mask("PCM_PARAM_FORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
672 log_pcm_mask("PCM_PARAM_SUBFORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_SUBFORMAT));
Paul McLeancf611912014-04-28 13:03:18 -0700673 ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%u, max:%u",
674 pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
675 pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
676 ALOGV("usb:audio_hw - PCM_PARAM_RATE min:%u, max:%u",
677 pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
678 pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
679 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_TIME min:%u, max:%u",
680 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_TIME),
681 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_TIME));
682 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_SIZE min:%u, max:%u",
683 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE),
684 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE));
685 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_BYTES min:%u, max:%u",
686 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_BYTES),
687 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_BYTES));
688 ALOGV("usb:audio_hw - PCM_PARAM_PERIODS min:%u, max:%u",
689 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS),
690 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS));
691 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_TIME min:%u, max:%u",
692 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_TIME),
693 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_TIME));
694 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_SIZE min:%u, max:%u",
695 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE),
696 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_SIZE));
697 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_BYTES min:%u, max:%u",
698 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_BYTES),
699 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_BYTES));
700 ALOGV("usb:audio_hw - PCM_PARAM_TICK_TIME min:%u, max:%u",
701 pcm_params_get_min(alsa_hw_params, PCM_PARAM_TICK_TIME),
702 pcm_params_get_max(alsa_hw_params, PCM_PARAM_TICK_TIME));
703}
704
Paul McLeaneedc92e2013-12-19 15:46:15 -0800705/*
Paul McLean33a6b172014-06-19 12:35:28 -0700706 * Returns the supplied value rounded up to the next even multiple of 16
707 */
708static unsigned int round_to_16_mult(unsigned int size) {
709 return (size + 15) & 0xFFFFFFF0;
710}
711
Paul McLeane32cbc12014-06-25 10:42:07 -0700712/*TODO - Evaluate if this value should/can be retrieved from a device-specific property */
Paul McLean33a6b172014-06-19 12:35:28 -0700713#define MIN_BUFF_TIME 5 /* milliseconds */
714
715/*
716 * Returns the system defined minimum period size based on the supplied sample rate
717 */
718static unsigned int calc_min_period_size(unsigned int sample_rate) {
719 unsigned int period_size = (sample_rate * MIN_BUFF_TIME) / 1000;
720 return round_to_16_mult(period_size);
721}
722
723/*
Paul McLeaneedc92e2013-12-19 15:46:15 -0800724 * Reads and decodes configuration info from the specified ALSA card/device
725 */
Paul McLeanf62d75e2014-07-11 15:14:19 -0700726static int read_alsa_device_config(struct audio_device_profile * dev_profile,
727 struct pcm_config * config)
Paul McLeaneedc92e2013-12-19 15:46:15 -0800728{
Paul McLeanf62d75e2014-07-11 15:14:19 -0700729 ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
730 dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800731
Paul McLeanf62d75e2014-07-11 15:14:19 -0700732 if (dev_profile->card < 0 || dev_profile->device < 0) {
Paul McLeaneedc92e2013-12-19 15:46:15 -0800733 return -EINVAL;
734 }
735
Paul McLeanf62d75e2014-07-11 15:14:19 -0700736 struct pcm_params * alsa_hw_params =
737 pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800738 if (alsa_hw_params == NULL) {
739 return -EINVAL;
740 }
741
742 /*
743 * This Logging will be useful when testing new USB devices.
744 */
Paul McLeanf62d75e2014-07-11 15:14:19 -0700745#ifdef LOG_PCM_PARAMS
746 log_pcm_params(alsa_hw_params);
747#endif
Paul McLeaneedc92e2013-12-19 15:46:15 -0800748
749 config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
750 config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
Paul McLean33a6b172014-06-19 12:35:28 -0700751 config->period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE);
752 /* round this up to a multiple of 16 */
753 config->period_size = round_to_16_mult(config->period_size);
754 /* make sure it is above a minimum value to minimize jitter */
755 unsigned int min_period_size = calc_min_period_size(config->rate);
756 if (config->period_size < min_period_size) {
757 config->period_size = min_period_size;
758 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800759 config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
760
Paul McLeane32cbc12014-06-25 10:42:07 -0700761 config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
Paul McLeanf62d75e2014-07-11 15:14:19 -0700762
763 pcm_params_free(alsa_hw_params);
764
Paul McLeaneedc92e2013-12-19 15:46:15 -0800765 return 0;
766}
767
768/*
769 * HAl Functions
770 */
Simon Wilson19957a32012-04-06 16:17:12 -0700771/**
772 * NOTE: when multiple mutexes have to be acquired, always respect the
773 * following order: hw device > out stream
774 */
775
776/* Helper functions */
Simon Wilson19957a32012-04-06 16:17:12 -0700777static uint32_t out_get_sample_rate(const struct audio_stream *stream)
778{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800779 return cached_output_hardware_config.rate;
Simon Wilson19957a32012-04-06 16:17:12 -0700780}
781
782static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
783{
784 return 0;
785}
786
787static size_t out_get_buffer_size(const struct audio_stream *stream)
788{
Eric Laurentc5ae6a02014-07-02 13:45:32 -0700789 return cached_output_hardware_config.period_size *
790 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
Simon Wilson19957a32012-04-06 16:17:12 -0700791}
792
793static uint32_t out_get_channels(const struct audio_stream *stream)
794{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800795 // Always Stero for now. We will do *some* conversions in this HAL.
Paul McLeane32cbc12014-06-25 10:42:07 -0700796 /* TODO When AudioPolicyManager & AudioFlinger supports arbitrary channels
797 rewrite this to return the ACTUAL channel format */
Simon Wilson19957a32012-04-06 16:17:12 -0700798 return AUDIO_CHANNEL_OUT_STEREO;
799}
800
801static audio_format_t out_get_format(const struct audio_stream *stream)
802{
Paul McLeane32cbc12014-06-25 10:42:07 -0700803 return audio_format_from_pcm_format(cached_output_hardware_config.format);
Simon Wilson19957a32012-04-06 16:17:12 -0700804}
805
806static int out_set_format(struct audio_stream *stream, audio_format_t format)
807{
Paul McLeane32cbc12014-06-25 10:42:07 -0700808 cached_output_hardware_config.format = pcm_format_from_audio_format(format);
Simon Wilson19957a32012-04-06 16:17:12 -0700809 return 0;
810}
811
812static int out_standby(struct audio_stream *stream)
813{
814 struct stream_out *out = (struct stream_out *)stream;
815
816 pthread_mutex_lock(&out->dev->lock);
817 pthread_mutex_lock(&out->lock);
818
819 if (!out->standby) {
820 pcm_close(out->pcm);
821 out->pcm = NULL;
822 out->standby = true;
823 }
824
825 pthread_mutex_unlock(&out->lock);
826 pthread_mutex_unlock(&out->dev->lock);
827
828 return 0;
829}
830
831static int out_dump(const struct audio_stream *stream, int fd)
832{
833 return 0;
834}
835
836static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
837{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800838 ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
839
Simon Wilson19957a32012-04-06 16:17:12 -0700840 struct stream_out *out = (struct stream_out *)stream;
Simon Wilson19957a32012-04-06 16:17:12 -0700841 struct str_parms *parms;
842 char value[32];
Paul McLeaneedc92e2013-12-19 15:46:15 -0800843 int param_val;
Simon Wilson19957a32012-04-06 16:17:12 -0700844 int routing = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800845 int ret_value = 0;
Simon Wilson19957a32012-04-06 16:17:12 -0700846
847 parms = str_parms_create_str(kvpairs);
Paul McLeanf62d75e2014-07-11 15:14:19 -0700848 pthread_mutex_lock(&out->dev->lock);
849 pthread_mutex_lock(&out->lock);
Simon Wilson19957a32012-04-06 16:17:12 -0700850
Paul McLeaneedc92e2013-12-19 15:46:15 -0800851 bool recache_device_params = false;
852 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
853 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -0700854 out->profile->card = atoi(value);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800855 recache_device_params = true;
856 }
Simon Wilson19957a32012-04-06 16:17:12 -0700857
Paul McLeaneedc92e2013-12-19 15:46:15 -0800858 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
859 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -0700860 out->profile->device = atoi(value);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800861 recache_device_params = true;
862 }
863
Paul McLeanf62d75e2014-07-11 15:14:19 -0700864 if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
865 ret_value = read_alsa_device_config(out->profile, &cached_output_hardware_config);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800866 output_hardware_config_is_cached = (ret_value == 0);
867 }
Simon Wilson19957a32012-04-06 16:17:12 -0700868
Paul McLeanf62d75e2014-07-11 15:14:19 -0700869 pthread_mutex_unlock(&out->lock);
870 pthread_mutex_unlock(&out->dev->lock);
Simon Wilson19957a32012-04-06 16:17:12 -0700871 str_parms_destroy(parms);
872
Paul McLeaneedc92e2013-12-19 15:46:15 -0800873 return ret_value;
Simon Wilson19957a32012-04-06 16:17:12 -0700874}
875
Paul McLeanf62d75e2014-07-11 15:14:19 -0700876static char * device_get_parameters(struct audio_device_profile * dev_profile, const char *keys)
Paul McLean30f41852014-04-16 15:44:20 -0700877{
Paul McLeanf62d75e2014-07-11 15:14:19 -0700878 ALOGV("usb:audio_hw::device_get_parameters() keys:%s", keys);
Paul McLean30f41852014-04-16 15:44:20 -0700879
Paul McLeanf62d75e2014-07-11 15:14:19 -0700880 if (dev_profile->card < 0 || dev_profile->device < 0) {
Paul McLean30f41852014-04-16 15:44:20 -0700881 return strdup("");
Paul McLeanf62d75e2014-07-11 15:14:19 -0700882 }
Paul McLean30f41852014-04-16 15:44:20 -0700883
Paul McLeaneedc92e2013-12-19 15:46:15 -0800884 unsigned min, max;
885
886 struct str_parms *query = str_parms_create_str(keys);
887 struct str_parms *result = str_parms_create();
888
889 int num_written = 0;
890 char buffer[256];
891 int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
892 char* result_str = NULL;
893
Paul McLeanf62d75e2014-07-11 15:14:19 -0700894 struct pcm_params * alsa_hw_params =
895 pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800896
897 // These keys are from hardware/libhardware/include/audio.h
898 // supported sample rates
899 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
Paul McLeaneedc92e2013-12-19 15:46:15 -0800900 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
901 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
Paul McLeanf62d75e2014-07-11 15:14:19 -0700902
903 char* rates_list = enum_std_sample_rates(dev_profile, min, max);
904 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, rates_list);
905 free(rates_list);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800906 } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
907
908 // supported channel counts
909 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
Paul McLeanf62d75e2014-07-11 15:14:19 -0700910 // TODO remove this hack when it is superceeded by proper multi-channel support
911 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
912 dev_profile->direction == PCM_OUT
913 ? "AUDIO_CHANNEL_OUT_STEREO"
914 : "AUDIO_CHANNEL_IN_STEREO");
Paul McLeaneedc92e2013-12-19 15:46:15 -0800915 } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
916
917 // supported sample formats
918 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
Paul McLeanf62d75e2014-07-11 15:14:19 -0700919 // TODO remove this hack when we have support for input in non PCM16 formats
920 if (dev_profile->direction == PCM_IN) {
921 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, "AUDIO_FORMAT_PCM_16_BIT");
922 } else {
923 struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
924 char * format_params = get_format_str_for_mask(format_mask);
925 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
926 free(format_params);
927 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800928 } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
929
Paul McLeanf62d75e2014-07-11 15:14:19 -0700930 pcm_params_free(alsa_hw_params);
931
Paul McLeaneedc92e2013-12-19 15:46:15 -0800932 result_str = str_parms_to_str(result);
933
934 // done with these...
935 str_parms_destroy(query);
936 str_parms_destroy(result);
937
Paul McLeanf62d75e2014-07-11 15:14:19 -0700938 ALOGV("usb:audio_hw::device_get_parameters = %s", result_str);
Paul McLeane32cbc12014-06-25 10:42:07 -0700939
Paul McLeaneedc92e2013-12-19 15:46:15 -0800940 return result_str;
Simon Wilson19957a32012-04-06 16:17:12 -0700941}
942
Paul McLeanf62d75e2014-07-11 15:14:19 -0700943static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
944{
945 ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
946
947 struct stream_out *out = (struct stream_out *) stream;
948 pthread_mutex_lock(&out->dev->lock);
949 pthread_mutex_lock(&out->lock);
950
951 char * params_str = device_get_parameters(out->profile, keys);
952
953 pthread_mutex_unlock(&out->lock);
954 pthread_mutex_unlock(&out->dev->lock);
955
956 return params_str;
957}
958
Simon Wilson19957a32012-04-06 16:17:12 -0700959static uint32_t out_get_latency(const struct audio_stream_out *stream)
960{
Paul McLeanf62d75e2014-07-11 15:14:19 -0700961 // struct stream_out *out = (struct stream_out *) stream;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800962
Paul McLeane32cbc12014-06-25 10:42:07 -0700963 /*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
Paul McLean30f41852014-04-16 15:44:20 -0700964 uint32_t latency = (cached_output_hardware_config.period_size
Paul McLeane32cbc12014-06-25 10:42:07 -0700965 * cached_output_hardware_config.period_count * 1000)
966 / out_get_sample_rate(&stream->common);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800967 return latency;
Simon Wilson19957a32012-04-06 16:17:12 -0700968}
969
Paul McLean30f41852014-04-16 15:44:20 -0700970static int out_set_volume(struct audio_stream_out *stream, float left, float right)
Simon Wilson19957a32012-04-06 16:17:12 -0700971{
972 return -ENOSYS;
973}
974
Paul McLeaneedc92e2013-12-19 15:46:15 -0800975/* must be called with hw device and output stream mutexes locked */
976static int start_output_stream(struct stream_out *out)
977{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800978 int return_val = 0;
979
Paul McLean30f41852014-04-16 15:44:20 -0700980 ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
Paul McLeanf62d75e2014-07-11 15:14:19 -0700981 out->profile->card, out->profile->device);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800982
Paul McLeanf62d75e2014-07-11 15:14:19 -0700983 out->pcm = pcm_open(out->profile->card, out->profile->device, PCM_OUT,
984 &cached_output_hardware_config);
Paul McLeane32cbc12014-06-25 10:42:07 -0700985
Paul McLeaneedc92e2013-12-19 15:46:15 -0800986 if (out->pcm == NULL) {
987 return -ENOMEM;
988 }
989
990 if (out->pcm && !pcm_is_ready(out->pcm)) {
991 ALOGE("audio_hw audio_hw pcm_open() failed: %s", pcm_get_error(out->pcm));
992 pcm_close(out->pcm);
993 return -ENOMEM;
994 }
995
Paul McLeaneedc92e2013-12-19 15:46:15 -0800996 return 0;
997}
998
999static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes)
Simon Wilson19957a32012-04-06 16:17:12 -07001000{
1001 int ret;
1002 struct stream_out *out = (struct stream_out *)stream;
1003
1004 pthread_mutex_lock(&out->dev->lock);
1005 pthread_mutex_lock(&out->lock);
1006 if (out->standby) {
1007 ret = start_output_stream(out);
1008 if (ret != 0) {
1009 goto err;
1010 }
1011 out->standby = false;
1012 }
1013
Paul McLean30f41852014-04-16 15:44:20 -07001014 // Setup conversion buffer
1015 // compute maximum potential buffer size.
1016 // * 2 for stereo -> quad conversion
1017 // * 3/2 for 16bit -> 24 bit conversion
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001018 size_t required_conversion_buffer_size = (bytes * 3 * 2) / 2;
Paul McLean30f41852014-04-16 15:44:20 -07001019 if (required_conversion_buffer_size > out->conversion_buffer_size) {
Paul McLeane32cbc12014-06-25 10:42:07 -07001020 /* TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
1021 (and do these conversions themselves) */
Paul McLean30f41852014-04-16 15:44:20 -07001022 out->conversion_buffer_size = required_conversion_buffer_size;
1023 out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size);
1024 }
1025
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001026 const void * write_buff = buffer;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001027 int num_write_buff_bytes = bytes;
1028
1029 /*
1030 * Num Channels conversion
1031 */
1032 int num_device_channels = cached_output_hardware_config.channels;
1033 int num_req_channels = 2; /* always, for now */
Paul McLean30f41852014-04-16 15:44:20 -07001034 if (num_device_channels != num_req_channels) {
Paul McLeaneedc92e2013-12-19 15:46:15 -08001035 num_write_buff_bytes =
Paul McLean30f41852014-04-16 15:44:20 -07001036 expand_channels_16(write_buff, num_req_channels,
1037 out->conversion_buffer, num_device_channels,
1038 num_write_buff_bytes / sizeof(short));
Paul McLeaneedc92e2013-12-19 15:46:15 -08001039 write_buff = out->conversion_buffer;
1040 }
1041
Paul McLeaneedc92e2013-12-19 15:46:15 -08001042 if (write_buff != NULL && num_write_buff_bytes != 0) {
1043 pcm_write(out->pcm, write_buff, num_write_buff_bytes);
1044 }
Simon Wilson19957a32012-04-06 16:17:12 -07001045
1046 pthread_mutex_unlock(&out->lock);
1047 pthread_mutex_unlock(&out->dev->lock);
1048
1049 return bytes;
1050
1051err:
1052 pthread_mutex_unlock(&out->lock);
Amit Shekharf9953b72014-01-30 12:47:34 -08001053 pthread_mutex_unlock(&out->dev->lock);
Simon Wilson19957a32012-04-06 16:17:12 -07001054 if (ret != 0) {
Eric Laurentc5ae6a02014-07-02 13:45:32 -07001055 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
Simon Wilson19957a32012-04-06 16:17:12 -07001056 out_get_sample_rate(&stream->common));
1057 }
1058
1059 return bytes;
1060}
1061
Paul McLean30f41852014-04-16 15:44:20 -07001062static int out_get_render_position(const struct audio_stream_out *stream, uint32_t *dsp_frames)
Simon Wilson19957a32012-04-06 16:17:12 -07001063{
1064 return -EINVAL;
1065}
1066
1067static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1068{
1069 return 0;
1070}
1071
1072static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1073{
1074 return 0;
1075}
1076
Paul McLean30f41852014-04-16 15:44:20 -07001077static int out_get_next_write_timestamp(const struct audio_stream_out *stream, int64_t *timestamp)
Simon Wilson19957a32012-04-06 16:17:12 -07001078{
1079 return -EINVAL;
1080}
1081
1082static int adev_open_output_stream(struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -07001083 audio_io_handle_t handle,
1084 audio_devices_t devices,
1085 audio_output_flags_t flags,
1086 struct audio_config *config,
Simon Wilson19957a32012-04-06 16:17:12 -07001087 struct audio_stream_out **stream_out)
1088{
Paul McLean30f41852014-04-16 15:44:20 -07001089 ALOGV("usb:audio_hw::out adev_open_output_stream() handle:0x%X, device:0x%X, flags:0x%X",
Paul McLeaneedc92e2013-12-19 15:46:15 -08001090 handle, devices, flags);
1091
Simon Wilson19957a32012-04-06 16:17:12 -07001092 struct audio_device *adev = (struct audio_device *)dev;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001093
Simon Wilson19957a32012-04-06 16:17:12 -07001094 struct stream_out *out;
Simon Wilson19957a32012-04-06 16:17:12 -07001095
1096 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
1097 if (!out)
1098 return -ENOMEM;
1099
Paul McLeaneedc92e2013-12-19 15:46:15 -08001100 // setup function pointers
Simon Wilson19957a32012-04-06 16:17:12 -07001101 out->stream.common.get_sample_rate = out_get_sample_rate;
1102 out->stream.common.set_sample_rate = out_set_sample_rate;
1103 out->stream.common.get_buffer_size = out_get_buffer_size;
1104 out->stream.common.get_channels = out_get_channels;
1105 out->stream.common.get_format = out_get_format;
1106 out->stream.common.set_format = out_set_format;
1107 out->stream.common.standby = out_standby;
1108 out->stream.common.dump = out_dump;
1109 out->stream.common.set_parameters = out_set_parameters;
1110 out->stream.common.get_parameters = out_get_parameters;
1111 out->stream.common.add_audio_effect = out_add_audio_effect;
1112 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1113 out->stream.get_latency = out_get_latency;
1114 out->stream.set_volume = out_set_volume;
1115 out->stream.write = out_write;
1116 out->stream.get_render_position = out_get_render_position;
1117 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1118
1119 out->dev = adev;
1120
Paul McLeanf62d75e2014-07-11 15:14:19 -07001121 out->profile = &(adev->out_profile);
1122 out->profile->direction = PCM_OUT;
1123
Paul McLeaneedc92e2013-12-19 15:46:15 -08001124 if (output_hardware_config_is_cached) {
1125 config->sample_rate = cached_output_hardware_config.rate;
1126
Paul McLeane32cbc12014-06-25 10:42:07 -07001127 config->format = audio_format_from_pcm_format(cached_output_hardware_config.format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001128
1129 config->channel_mask =
1130 audio_channel_out_mask_from_count(cached_output_hardware_config.channels);
1131 if (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) {
1132 // Always report STEREO for now. AudioPolicyManagerBase/AudioFlinger dont' understand
1133 // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
Paul McLeane32cbc12014-06-25 10:42:07 -07001134 /*TODO remove this when the above restriction is removed. */
Paul McLeaneedc92e2013-12-19 15:46:15 -08001135 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1136 }
1137 } else {
1138 cached_output_hardware_config = default_alsa_out_config;
1139
1140 config->format = out_get_format(&out->stream.common);
1141 config->channel_mask = out_get_channels(&out->stream.common);
1142 config->sample_rate = out_get_sample_rate(&out->stream.common);
1143 }
Paul McLeaneedc92e2013-12-19 15:46:15 -08001144
1145 out->conversion_buffer = NULL;
1146 out->conversion_buffer_size = 0;
Simon Wilson19957a32012-04-06 16:17:12 -07001147
1148 out->standby = true;
1149
1150 *stream_out = &out->stream;
1151 return 0;
1152
1153err_open:
1154 free(out);
1155 *stream_out = NULL;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001156 return -ENOSYS;
Simon Wilson19957a32012-04-06 16:17:12 -07001157}
1158
1159static void adev_close_output_stream(struct audio_hw_device *dev,
1160 struct audio_stream_out *stream)
1161{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001162 ALOGV("usb:audio_hw::out adev_close_output_stream()");
Simon Wilson19957a32012-04-06 16:17:12 -07001163 struct stream_out *out = (struct stream_out *)stream;
1164
Paul McLeane32cbc12014-06-25 10:42:07 -07001165 // Close the pcm device
Simon Wilson19957a32012-04-06 16:17:12 -07001166 out_standby(&stream->common);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001167
1168 free(out->conversion_buffer);
1169 out->conversion_buffer = NULL;
1170 out->conversion_buffer_size = 0;
1171
Simon Wilson19957a32012-04-06 16:17:12 -07001172 free(stream);
1173}
1174
1175static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1176{
1177 return 0;
1178}
1179
Paul McLean30f41852014-04-16 15:44:20 -07001180static char * adev_get_parameters(const struct audio_hw_device *dev, const char *keys)
Simon Wilson19957a32012-04-06 16:17:12 -07001181{
1182 return strdup("");
1183}
1184
1185static int adev_init_check(const struct audio_hw_device *dev)
1186{
1187 return 0;
1188}
1189
1190static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1191{
1192 return -ENOSYS;
1193}
1194
1195static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1196{
1197 return -ENOSYS;
1198}
1199
1200static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1201{
1202 return 0;
1203}
1204
1205static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1206{
1207 return -ENOSYS;
1208}
1209
1210static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1211{
1212 return -ENOSYS;
1213}
1214
1215static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -07001216 const struct audio_config *config)
Simon Wilson19957a32012-04-06 16:17:12 -07001217{
1218 return 0;
1219}
1220
Paul McLeaneedc92e2013-12-19 15:46:15 -08001221/* Helper functions */
1222static uint32_t in_get_sample_rate(const struct audio_stream *stream)
1223{
Paul McLean30f41852014-04-16 15:44:20 -07001224 return cached_input_hardware_config.rate;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001225}
1226
1227static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1228{
1229 return -ENOSYS;
1230}
1231
1232static size_t in_get_buffer_size(const struct audio_stream *stream)
1233{
Eric Laurentc5ae6a02014-07-02 13:45:32 -07001234 size_t buffer_size = cached_input_hardware_config.period_size *
1235 audio_stream_in_frame_size((const struct audio_stream_in *)stream);
1236 ALOGV("usb: in_get_buffer_size() = %zu", buffer_size);
1237 return buffer_size;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001238}
1239
1240static uint32_t in_get_channels(const struct audio_stream *stream)
1241{
Paul McLean30f41852014-04-16 15:44:20 -07001242 // just report stereo for now
1243 return AUDIO_CHANNEL_IN_STEREO;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001244}
1245
1246static audio_format_t in_get_format(const struct audio_stream *stream)
1247{
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001248 const struct stream_in * in_stream = (const struct stream_in *)stream;
1249
1250 ALOGV("in_get_format() = %d -> %d", in_stream->input_framework_format,
1251 audio_format_from_pcm_format(in_stream->input_framework_format));
1252 /* return audio_format_from_pcm_format(cached_input_hardware_config.format); */
1253 return audio_format_from_pcm_format(in_stream->input_framework_format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001254}
1255
1256static int in_set_format(struct audio_stream *stream, audio_format_t format)
1257{
1258 return -ENOSYS;
1259}
1260
1261static int in_standby(struct audio_stream *stream)
1262{
Paul McLean30f41852014-04-16 15:44:20 -07001263 struct stream_in *in = (struct stream_in *) stream;
1264
1265 pthread_mutex_lock(&in->dev->lock);
1266 pthread_mutex_lock(&in->lock);
1267
1268 if (!in->standby) {
1269 pcm_close(in->pcm);
1270 in->pcm = NULL;
1271 in->standby = true;
1272 }
1273
1274 pthread_mutex_unlock(&in->lock);
1275 pthread_mutex_unlock(&in->dev->lock);
1276
Paul McLeaneedc92e2013-12-19 15:46:15 -08001277 return 0;
1278}
1279
1280static int in_dump(const struct audio_stream *stream, int fd)
1281{
1282 return 0;
1283}
1284
1285static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1286{
Paul McLean30f41852014-04-16 15:44:20 -07001287 ALOGV("usb: audio_hw::in in_set_parameters() keys:%s", kvpairs);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001288
1289 struct stream_in *in = (struct stream_in *)stream;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001290 struct str_parms *parms;
1291 char value[32];
1292 int param_val;
1293 int routing = 0;
1294 int ret_value = 0;
1295
1296 parms = str_parms_create_str(kvpairs);
Paul McLeanf62d75e2014-07-11 15:14:19 -07001297 pthread_mutex_lock(&in->dev->lock);
1298 pthread_mutex_lock(&in->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001299
Paul McLean30f41852014-04-16 15:44:20 -07001300 bool recache_device_params = false;
1301
Paul McLeaneedc92e2013-12-19 15:46:15 -08001302 // Card/Device
1303 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
1304 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001305 in->profile->card = atoi(value);
Paul McLean30f41852014-04-16 15:44:20 -07001306 recache_device_params = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001307 }
1308
1309 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
1310 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001311 in->profile->device = atoi(value);
Paul McLean30f41852014-04-16 15:44:20 -07001312 recache_device_params = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001313 }
1314
Paul McLeanf62d75e2014-07-11 15:14:19 -07001315 if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
1316 ret_value = read_alsa_device_config(in->profile, &cached_input_hardware_config);
Paul McLean30f41852014-04-16 15:44:20 -07001317 input_hardware_config_is_cached = (ret_value == 0);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001318 }
1319
Paul McLeanf62d75e2014-07-11 15:14:19 -07001320 pthread_mutex_unlock(&in->lock);
1321 pthread_mutex_unlock(&in->dev->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001322 str_parms_destroy(parms);
1323
1324 return ret_value;
1325}
1326
Paul McLean30f41852014-04-16 15:44:20 -07001327static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
1328 ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001329
Paul McLean30f41852014-04-16 15:44:20 -07001330 struct stream_in *in = (struct stream_in *)stream;
Paul McLeanf62d75e2014-07-11 15:14:19 -07001331 pthread_mutex_lock(&in->dev->lock);
1332 pthread_mutex_lock(&in->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001333
Paul McLeanf62d75e2014-07-11 15:14:19 -07001334 char * params_str = device_get_parameters(in->profile, keys);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001335
Paul McLeanf62d75e2014-07-11 15:14:19 -07001336 pthread_mutex_unlock(&in->lock);
1337 pthread_mutex_unlock(&in->dev->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001338
Paul McLeanf62d75e2014-07-11 15:14:19 -07001339 return params_str;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001340}
1341
1342static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1343{
1344 return 0;
1345}
1346
1347static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1348{
1349 return 0;
1350}
1351
Paul McLean30f41852014-04-16 15:44:20 -07001352static int in_set_gain(struct audio_stream_in *stream, float gain)
1353{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001354 return 0;
1355}
1356
Paul McLean30f41852014-04-16 15:44:20 -07001357/* must be called with hw device and output stream mutexes locked */
1358static int start_input_stream(struct stream_in *in) {
Paul McLean30f41852014-04-16 15:44:20 -07001359 int return_val = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001360
Paul McLean30f41852014-04-16 15:44:20 -07001361 ALOGV("usb:audio_hw::start_input_stream(card:%d device:%d)",
Paul McLeanf62d75e2014-07-11 15:14:19 -07001362 in->profile->card, in->profile->device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001363
Paul McLeanf62d75e2014-07-11 15:14:19 -07001364 in->pcm = pcm_open(in->profile->card, in->profile->device, PCM_IN,
1365 &cached_input_hardware_config);
Paul McLean30f41852014-04-16 15:44:20 -07001366 if (in->pcm == NULL) {
1367 ALOGE("usb:audio_hw pcm_open() in->pcm == NULL");
1368 return -ENOMEM;
1369 }
1370
1371 if (in->pcm && !pcm_is_ready(in->pcm)) {
1372 ALOGE("usb:audio_hw audio_hw pcm_open() failed: %s", pcm_get_error(in->pcm));
1373 pcm_close(in->pcm);
1374 return -ENOMEM;
1375 }
1376
1377 return 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001378}
1379
Paul McLeane32cbc12014-06-25 10:42:07 -07001380/* TODO mutex stuff here (see out_write) */
Paul McLean30f41852014-04-16 15:44:20 -07001381static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes)
1382{
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001383 size_t num_read_buff_bytes = 0;
Paul McLean30f41852014-04-16 15:44:20 -07001384 void * read_buff = buffer;
1385 void * out_buff = buffer;
1386
1387 struct stream_in * in = (struct stream_in *) stream;
1388
1389 pthread_mutex_lock(&in->dev->lock);
1390 pthread_mutex_lock(&in->lock);
1391
1392 if (in->standby) {
1393 if (start_input_stream(in) != 0) {
1394 goto err;
1395 }
1396 in->standby = false;
1397 }
1398
1399 // OK, we need to figure out how much data to read to be able to output the requested
1400 // number of bytes in the HAL format (16-bit, stereo).
1401 num_read_buff_bytes = bytes;
1402 int num_device_channels = cached_input_hardware_config.channels;
1403 int num_req_channels = 2; /* always, for now */
1404
1405 if (num_device_channels != num_req_channels) {
Paul McLeancf611912014-04-28 13:03:18 -07001406 num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
Paul McLean30f41852014-04-16 15:44:20 -07001407 }
1408
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001409 /* Assume (for now) that in->input_framework_format == PCM_FORMAT_S16_LE */
Eric Laurent7661a482014-06-11 12:00:16 -07001410 if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001411 /* 24-bit USB device */
Paul McLean30f41852014-04-16 15:44:20 -07001412 num_read_buff_bytes = (3 * num_read_buff_bytes) / 2;
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001413 } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
1414 /* 32-bit USB device */
1415 num_read_buff_bytes = num_read_buff_bytes * 2;
Paul McLean30f41852014-04-16 15:44:20 -07001416 }
1417
1418 // Setup/Realloc the conversion buffer (if necessary).
1419 if (num_read_buff_bytes != bytes) {
1420 if (num_read_buff_bytes > in->conversion_buffer_size) {
Paul McLeane32cbc12014-06-25 10:42:07 -07001421 /*TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
1422 (and do these conversions themselves) */
Paul McLean30f41852014-04-16 15:44:20 -07001423 in->conversion_buffer_size = num_read_buff_bytes;
1424 in->conversion_buffer = realloc(in->conversion_buffer, in->conversion_buffer_size);
1425 }
1426 read_buff = in->conversion_buffer;
1427 }
1428
1429 if (pcm_read(in->pcm, read_buff, num_read_buff_bytes) == 0) {
1430 /*
1431 * Do any conversions necessary to send the data in the format specified to/by the HAL
1432 * (but different from the ALSA format), such as 24bit ->16bit, or 4chan -> 2chan.
1433 */
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001434 if (cached_input_hardware_config.format != PCM_FORMAT_S16_LE) {
1435 // we need to convert
Paul McLean30f41852014-04-16 15:44:20 -07001436 if (num_device_channels != num_req_channels) {
1437 out_buff = read_buff;
1438 }
1439
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001440 if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
1441 num_read_buff_bytes =
1442 convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
1443 } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
1444 num_read_buff_bytes =
1445 convert_32_to_16(read_buff, num_read_buff_bytes / 4, out_buff);
1446 }
1447 else {
1448 goto err;
1449 }
Paul McLean30f41852014-04-16 15:44:20 -07001450 }
1451
1452 if (num_device_channels != num_req_channels) {
1453 out_buff = buffer;
1454 /* Num Channels conversion */
Paul McLeancf611912014-04-28 13:03:18 -07001455 if (num_device_channels < num_req_channels) {
1456 num_read_buff_bytes =
Paul McLeancf611912014-04-28 13:03:18 -07001457 expand_channels_16(read_buff, num_device_channels,
1458 out_buff, num_req_channels,
1459 num_read_buff_bytes / sizeof(short));
Eric Laurentfbc02dc2014-06-27 18:39:21 -07001460 } else {
1461 num_read_buff_bytes =
1462 contract_channels_16(read_buff, num_device_channels,
1463 out_buff, num_req_channels,
1464 num_read_buff_bytes / sizeof(short));
Paul McLeancf611912014-04-28 13:03:18 -07001465 }
Paul McLean30f41852014-04-16 15:44:20 -07001466 }
1467 }
1468
1469err:
1470 pthread_mutex_unlock(&in->lock);
1471 pthread_mutex_unlock(&in->dev->lock);
1472
1473 return num_read_buff_bytes;
1474}
1475
1476static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1477{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001478 return 0;
1479}
1480
Mike Lockwood46a98092012-04-24 16:41:18 -07001481static int adev_open_input_stream(struct audio_hw_device *dev,
1482 audio_io_handle_t handle,
1483 audio_devices_t devices,
Paul McLean30f41852014-04-16 15:44:20 -07001484 struct audio_config *config,
Simon Wilson19957a32012-04-06 16:17:12 -07001485 struct audio_stream_in **stream_in)
1486{
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001487 ALOGV("usb: in adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
Paul McLean30f41852014-04-16 15:44:20 -07001488 config->sample_rate, config->channel_mask, config->format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001489
1490 struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Eric Laurent7661a482014-06-11 12:00:16 -07001491 int ret = 0;
1492
Paul McLeaneedc92e2013-12-19 15:46:15 -08001493 if (in == NULL)
1494 return -ENOMEM;
1495
1496 // setup function pointers
1497 in->stream.common.get_sample_rate = in_get_sample_rate;
1498 in->stream.common.set_sample_rate = in_set_sample_rate;
1499 in->stream.common.get_buffer_size = in_get_buffer_size;
1500 in->stream.common.get_channels = in_get_channels;
1501 in->stream.common.get_format = in_get_format;
1502 in->stream.common.set_format = in_set_format;
1503 in->stream.common.standby = in_standby;
1504 in->stream.common.dump = in_dump;
1505 in->stream.common.set_parameters = in_set_parameters;
1506 in->stream.common.get_parameters = in_get_parameters;
1507 in->stream.common.add_audio_effect = in_add_audio_effect;
1508 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1509
1510 in->stream.set_gain = in_set_gain;
1511 in->stream.read = in_read;
1512 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1513
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001514 in->input_framework_format = PCM_FORMAT_S16_LE;
1515
Paul McLean30f41852014-04-16 15:44:20 -07001516 in->dev = (struct audio_device *)dev;
1517
Paul McLeanf62d75e2014-07-11 15:14:19 -07001518 in->profile = &(in->dev->in_profile);
1519 in->profile->direction = PCM_IN;
1520
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001521 if (!input_hardware_config_is_cached) {
1522 // just return defaults until we can actually query the device.
Paul McLean30f41852014-04-16 15:44:20 -07001523 cached_input_hardware_config = default_alsa_in_config;
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001524 }
Paul McLean30f41852014-04-16 15:44:20 -07001525
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001526 /* Rate */
1527 /* TODO Check that the requested rate is valid for the connected device */
1528 if (config->sample_rate == 0) {
1529 config->sample_rate = cached_input_hardware_config.rate;
1530 } else {
1531 cached_input_hardware_config.rate = config->sample_rate;
1532 }
1533
1534 /* Format */
1535 /* until the framework supports format conversion, just take what it asks for
1536 * i.e. AUDIO_FORMAT_PCM_16_BIT */
1537 /* config->format = audio_format_from_pcm_format(cached_input_hardware_config.format); */
1538 if (config->format == AUDIO_FORMAT_DEFAULT) {
1539 /* just return AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
1540 * formats */
1541 config->format = AUDIO_FORMAT_PCM_16_BIT;
1542 } else if (config->format == AUDIO_FORMAT_PCM_16_BIT) {
1543 /* Always accept AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
1544 * formats */
1545 } else {
1546 /* When the framework support other formats, validate here */
1547 config->format = AUDIO_FORMAT_PCM_16_BIT;
1548 ret = -EINVAL;
1549 }
1550
1551 /* don't change the cached_input_hardware_config, we will open it as what it is and
1552 * convert as necessary */
1553 if (config->channel_mask == AUDIO_CHANNEL_NONE) {
1554 /* just return AUDIO_CHANNEL_IN_STEREO until the framework supports other input
1555 * formats */
1556 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
1557 } else if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
1558 /* allow only stereo capture for now */
1559 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
1560 ret = -EINVAL;
Paul McLean30f41852014-04-16 15:44:20 -07001561 }
Paul McLeaneedc92e2013-12-19 15:46:15 -08001562
1563 in->standby = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001564
Paul McLean30f41852014-04-16 15:44:20 -07001565 in->conversion_buffer = NULL;
1566 in->conversion_buffer_size = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001567
1568 *stream_in = &in->stream;
1569
Eric Laurent7661a482014-06-11 12:00:16 -07001570 return ret;
Simon Wilson19957a32012-04-06 16:17:12 -07001571}
1572
Paul McLean30f41852014-04-16 15:44:20 -07001573static void adev_close_input_stream(struct audio_hw_device *dev, struct audio_stream_in *stream)
Simon Wilson19957a32012-04-06 16:17:12 -07001574{
Paul McLean30f41852014-04-16 15:44:20 -07001575 struct stream_in *in = (struct stream_in *)stream;
1576
Paul McLeane32cbc12014-06-25 10:42:07 -07001577 // Close the pcm device
Paul McLean30f41852014-04-16 15:44:20 -07001578 in_standby(&stream->common);
1579
1580 free(in->conversion_buffer);
1581
1582 free(stream);
Simon Wilson19957a32012-04-06 16:17:12 -07001583}
1584
1585static int adev_dump(const audio_hw_device_t *device, int fd)
1586{
1587 return 0;
1588}
1589
1590static int adev_close(hw_device_t *device)
1591{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001592 struct audio_device *adev = (struct audio_device *)device;
Simon Wilson19957a32012-04-06 16:17:12 -07001593 free(device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001594
1595 output_hardware_config_is_cached = false;
Paul McLean30f41852014-04-16 15:44:20 -07001596 input_hardware_config_is_cached = false;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001597
Simon Wilson19957a32012-04-06 16:17:12 -07001598 return 0;
1599}
1600
Paul McLean30f41852014-04-16 15:44:20 -07001601static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
Simon Wilson19957a32012-04-06 16:17:12 -07001602{
Simon Wilson19957a32012-04-06 16:17:12 -07001603 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1604 return -EINVAL;
1605
Paul McLeaneedc92e2013-12-19 15:46:15 -08001606 struct audio_device *adev = calloc(1, sizeof(struct audio_device));
Simon Wilson19957a32012-04-06 16:17:12 -07001607 if (!adev)
1608 return -ENOMEM;
1609
1610 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
Eric Laurent85e08e22012-08-28 14:30:35 -07001611 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
Simon Wilson19957a32012-04-06 16:17:12 -07001612 adev->hw_device.common.module = (struct hw_module_t *) module;
1613 adev->hw_device.common.close = adev_close;
1614
Simon Wilson19957a32012-04-06 16:17:12 -07001615 adev->hw_device.init_check = adev_init_check;
1616 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1617 adev->hw_device.set_master_volume = adev_set_master_volume;
1618 adev->hw_device.set_mode = adev_set_mode;
1619 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1620 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1621 adev->hw_device.set_parameters = adev_set_parameters;
1622 adev->hw_device.get_parameters = adev_get_parameters;
1623 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1624 adev->hw_device.open_output_stream = adev_open_output_stream;
1625 adev->hw_device.close_output_stream = adev_close_output_stream;
1626 adev->hw_device.open_input_stream = adev_open_input_stream;
1627 adev->hw_device.close_input_stream = adev_close_input_stream;
1628 adev->hw_device.dump = adev_dump;
1629
1630 *device = &adev->hw_device.common;
1631
1632 return 0;
1633}
1634
1635static struct hw_module_methods_t hal_module_methods = {
1636 .open = adev_open,
1637};
1638
1639struct audio_module HAL_MODULE_INFO_SYM = {
1640 .common = {
1641 .tag = HARDWARE_MODULE_TAG,
Mike Lockwood46a98092012-04-24 16:41:18 -07001642 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1643 .hal_api_version = HARDWARE_HAL_API_VERSION,
Simon Wilson19957a32012-04-06 16:17:12 -07001644 .id = AUDIO_HARDWARE_MODULE_ID,
1645 .name = "USB audio HW HAL",
1646 .author = "The Android Open Source Project",
1647 .methods = &hal_module_methods,
1648 },
1649};