blob: 8945791995ba5dd176212bb7653a48259d4e8a61 [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.
Paul McLeaneb192972014-07-11 16:29:41 -0700234 * num_in_bytes size of input buffer in BYTES
Paul McLean30f41852014-04-16 15:44:20 -0700235 * 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 */
Paul McLeaneb192972014-07-11 16:29:41 -0700244static size_t expand_channels_16(const int16_t* in_buff, int in_buff_chans,
245 int16_t* out_buff, int out_buff_chans,
246 size_t num_in_bytes)
Paul McLeane32cbc12014-06-25 10:42:07 -0700247{
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 McLeaneb192972014-07-11 16:29:41 -0700253 size_t num_in_samples = num_in_bytes / sizeof(int16_t);
254
255 size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
Paul McLean30f41852014-04-16 15:44:20 -0700256
257 short* dst_ptr = out_buff + num_out_samples - 1;
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700258 size_t src_index;
259 const short* src_ptr = in_buff + num_in_samples - 1;
Paul McLean30f41852014-04-16 15:44:20 -0700260 int num_zero_chans = out_buff_chans - in_buff_chans;
261 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
262 int dst_offset;
Paul McLeane32cbc12014-06-25 10:42:07 -0700263 for (dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700264 *dst_ptr-- = 0;
265 }
Paul McLeane32cbc12014-06-25 10:42:07 -0700266 for (; dst_offset < out_buff_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700267 *dst_ptr-- = *src_ptr--;
268 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800269 }
270
271 /* return number of *bytes* generated */
Paul McLeaneb192972014-07-11 16:29:41 -0700272 return num_out_samples * sizeof(int16_t);
Paul McLean30f41852014-04-16 15:44:20 -0700273}
274
275/*
276 * Convert a buffer of N-channel, interleaved PCM16 samples to M-channel PCM16 channels
277 * (where N > M).
278 * in_buff points to the buffer of PCM16 samples
279 * in_buff_channels Specifies the number of channels in the input buffer.
280 * out_buff points to the buffer to receive converted PCM16 samples.
281 * out_buff_channels Specifies the number of channels in the output buffer.
Paul McLeaneb192972014-07-11 16:29:41 -0700282 * num_in_bytes size of input buffer in BYTES
Paul McLean30f41852014-04-16 15:44:20 -0700283 * returns
284 * the number of BYTES of output data.
285 * NOTE
286 * channels > N are thrown away.
287 * This conversion is safe to do in-place (in_buff == out_buff)
288 * We are doing this since we *always* present to The Framework as STEREO device, but need to
289 * support 4-channel devices.
Paul McLeane32cbc12014-06-25 10:42:07 -0700290 * TODO Move this to a utilities module.
Paul McLean30f41852014-04-16 15:44:20 -0700291 */
Paul McLeaneb192972014-07-11 16:29:41 -0700292static size_t contract_channels_16(const int16_t* in_buff, size_t in_buff_chans,
293 int16_t* out_buff, size_t out_buff_chans,
294 size_t num_in_bytes)
Paul McLeane32cbc12014-06-25 10:42:07 -0700295{
Paul McLean30f41852014-04-16 15:44:20 -0700296 /*
297 * Move from front to back so that the conversion can be done in-place
298 * i.e. in_buff == out_buff
299 * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
300 */
Paul McLeaneb192972014-07-11 16:29:41 -0700301 size_t num_in_samples = num_in_bytes / sizeof(int16_t);
Paul McLean30f41852014-04-16 15:44:20 -0700302
Paul McLeaneb192972014-07-11 16:29:41 -0700303 size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
Paul McLean30f41852014-04-16 15:44:20 -0700304
Paul McLeaneb192972014-07-11 16:29:41 -0700305 size_t num_skip_samples = in_buff_chans - out_buff_chans;
306
307 int16_t* dst_ptr = out_buff;
308 const int16_t* src_ptr = in_buff;
Mark Salyzyn88e458a2014-04-28 12:30:44 -0700309 size_t src_index;
Paul McLean30f41852014-04-16 15:44:20 -0700310 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
Paul McLeaneb192972014-07-11 16:29:41 -0700311 size_t dst_offset;
Paul McLeane32cbc12014-06-25 10:42:07 -0700312 for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
Paul McLean30f41852014-04-16 15:44:20 -0700313 *dst_ptr++ = *src_ptr++;
314 }
315 src_ptr += num_skip_samples;
316 }
317
318 /* return number of *bytes* generated */
Paul McLeaneb192972014-07-11 16:29:41 -0700319 return num_out_samples * sizeof(int16_t);
320}
321
322/*
323 * Convert a buffer of N-channel, interleaved PCM32 samples to M-channel PCM32 channels
324 * (where N < M).
325 * in_buff points to the buffer of PCM32 samples
326 * in_buff_channels Specifies the number of channels in the input buffer.
327 * out_buff points to the buffer to receive converted PCM32 samples.
328 * out_buff_channels Specifies the number of channels in the output buffer.
329 * num_in_bytes size of input buffer in BYTES
330 * returns
331 * the number of BYTES of output data.
332 * NOTE
333 * channels > N are filled with silence.
334 * This conversion is safe to do in-place (in_buff == out_buff)
335 * We are doing this since we *always* present to The Framework as STEREO device, but need to
336 * support 4-channel devices.
337 * TODO Move this to a utilities module.
338 */
339static size_t expand_channels_32(const int32_t* in_buff, size_t in_buff_chans,
340 int32_t* out_buff, size_t out_buff_chans,
341 size_t num_in_bytes)
342{
343 /*
344 * Move from back to front so that the conversion can be done in-place
345 * i.e. in_buff == out_buff
346 * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
347 */
348 size_t num_in_samples = num_in_bytes / sizeof(int32_t);
349
350 size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
351
352 int32_t* dst_ptr = out_buff + num_out_samples - 1;
353 const int32_t* src_ptr = in_buff + num_in_samples - 1;
354 size_t num_zero_chans = out_buff_chans - in_buff_chans;
355 size_t src_index;
356 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
357 size_t dst_offset;
358 for (dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
359 *dst_ptr-- = 0;
360 }
361 for (; dst_offset < out_buff_chans; dst_offset++) {
362 *dst_ptr-- = *src_ptr--;
363 }
364 }
365
366 /* return number of *bytes* generated */
367 return num_out_samples * sizeof(int32_t);
368}
369
370/*
371 * Convert a buffer of N-channel, interleaved PCM32 samples to M-channel PCM16 channels
372 * (where N > M).
373 * in_buff points to the buffer of PCM32 samples
374 * in_buff_channels Specifies the number of channels in the input buffer.
375 * out_buff points to the buffer to receive converted PCM16 samples.
376 * out_buff_channels Specifies the number of channels in the output buffer.
377 * num_in_bytes size of input buffer in BYTES
378 * returns
379 * the number of BYTES of output data.
380 * NOTE
381 * channels > N are thrown away.
382 * This conversion is safe to do in-place (in_buff == out_buff)
383 * We are doing this since we *always* present to The Framework as STEREO device, but need to
384 * support 4-channel devices.
385 * TODO Move this to a utilities module.
386 */
387static size_t contract_channels_32(const int32_t* in_buff, size_t in_buff_chans,
388 int32_t* out_buff, size_t out_buff_chans,
389 size_t num_in_bytes)
390{
391 /*
392 * Move from front to back so that the conversion can be done in-place
393 * i.e. in_buff == out_buff
394 * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
395 */
396 size_t num_in_samples = num_in_bytes / sizeof(int32_t);
397
398 size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
399
400 size_t num_skip_samples = in_buff_chans - out_buff_chans;
401
402 int32_t* dst_ptr = out_buff;
403 const int32_t* src_ptr = in_buff;
404 size_t src_index;
405 for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
406 size_t dst_offset;
407 for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
408 *dst_ptr++ = *src_ptr++;
409 }
410 src_ptr += num_skip_samples;
411 }
412
413 /* return number of *bytes* generated */
414 return num_out_samples * sizeof(int32_t);
415}
416
417static size_t contract_channels(const void* in_buff, size_t in_buff_chans,
418 void* out_buff, size_t out_buff_chans,
419 unsigned sample_size_in_bytes, size_t num_in_bytes)
420{
421 switch (sample_size_in_bytes) {
422 case 2:
423 return contract_channels_16((const int16_t*)in_buff, in_buff_chans,
424 (int16_t*)out_buff, out_buff_chans,
425 num_in_bytes);
426
427 /* TODO - do this conversion when we have a device to test it with */
428 case 3:
429 ALOGE("24-bit channel contraction not supported.");
430 return 0;
431
432 case 4:
433 return contract_channels_32((const int32_t*)in_buff, in_buff_chans,
434 (int32_t*)out_buff, out_buff_chans,
435 num_in_bytes);
436
437 default:
438 return 0;
439 }
440}
441
442static size_t expand_channels(const void* in_buff, size_t in_buff_chans,
443 void* out_buff, size_t out_buff_chans,
444 unsigned sample_size_in_bytes, size_t num_in_bytes)
445{
446 switch (sample_size_in_bytes) {
447 case 2:
448 return expand_channels_16((const int16_t*)in_buff, in_buff_chans,
449 (int16_t*)out_buff, out_buff_chans,
450 num_in_bytes);
451
452 /* TODO - do this conversion when we have a device to test it with */
453 case 3:
454 ALOGE("24-bit channel expansion not supported.");
455 return 0;
456
457 case 4:
458 return expand_channels_32((const int32_t*)in_buff, in_buff_chans,
459 (int32_t*)out_buff, out_buff_chans,
460 num_in_bytes);
461
462 default:
463 return 0;
464 }
465}
466
467static size_t adjust_channels(const void* in_buff, size_t in_buff_chans,
468 void* out_buff, size_t out_buff_chans,
469 unsigned sample_size_in_bytes, size_t num_in_bytes)
470{
471 if (out_buff_chans > in_buff_chans) {
472 return expand_channels(in_buff, in_buff_chans, out_buff, out_buff_chans,
473 sample_size_in_bytes, num_in_bytes);
474 } else if (out_buff_chans < in_buff_chans) {
475 return contract_channels(in_buff, in_buff_chans, out_buff, out_buff_chans,
476 sample_size_in_bytes, num_in_bytes);
477 } else if (in_buff != out_buff) {
478 memcpy(out_buff, in_buff, num_in_bytes);
479 }
480
481 return num_in_bytes;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800482}
483
484/*
485 * ALSA Utilities
486 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700487/*TODO This table and the function that uses it should be moved to a utilities module (probably) */
Paul McLeaneedc92e2013-12-19 15:46:15 -0800488/*
Paul McLeane32cbc12014-06-25 10:42:07 -0700489 * Maps bit-positions in a pcm_mask to the corresponding AUDIO_ format string.
Paul McLeaneedc92e2013-12-19 15:46:15 -0800490 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700491static const char * const format_string_map[] = {
492 "AUDIO_FORMAT_PCM_8_BIT", /* 00 - SNDRV_PCM_FORMAT_S8 */
493 "AUDIO_FORMAT_PCM_8_BIT", /* 01 - SNDRV_PCM_FORMAT_U8 */
494 "AUDIO_FORMAT_PCM_16_BIT", /* 02 - SNDRV_PCM_FORMAT_S16_LE */
495 NULL, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
496 NULL, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
497 NULL, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
498 "AUDIO_FORMAT_PCM_24_BIT_PACKED", /* 06 - SNDRV_PCM_FORMAT_S24_LE */
499 NULL, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
500 NULL, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
501 NULL, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
502 "AUDIO_FORMAT_PCM_32_BIT", /* 10 - SNDRV_PCM_FORMAT_S32_LE */
503 NULL, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
504 NULL, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
505 NULL, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
506 "AUDIO_FORMAT_PCM_FLOAT", /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
507 NULL, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
508 NULL, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
509 NULL, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
510 NULL, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
511 NULL, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
512 NULL, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
513 NULL, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
514 NULL, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
515 NULL, /* 23 - SNDRV_PCM_FORMAT_MPEG */
516 NULL, /* 24 - SNDRV_PCM_FORMAT_GSM */
517 NULL, NULL, NULL, NULL, NULL, NULL, /* 25 -> 30 (not assigned) */
518 NULL, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
519 "AUDIO_FORMAT_PCM_24_BIT_PACKED", /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
520 NULL, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
521 NULL, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
522 NULL, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
523 NULL, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
524 NULL, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
525 NULL, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
526 NULL, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
527 NULL, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
528 NULL, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
529 NULL, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
530 NULL, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
531 NULL, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
532 NULL, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
533 NULL, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
534 NULL, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
535 NULL, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
536 NULL /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
537};
538
539/*
540 * Generate string containing a bar ("|") delimited list of AUDIO_ formats specified in
541 * the mask parameter.
542 *
543 */
544static char* get_format_str_for_mask(struct pcm_mask* mask)
Paul McLeaneedc92e2013-12-19 15:46:15 -0800545{
Paul McLeane32cbc12014-06-25 10:42:07 -0700546 char buffer[256];
547 int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
548 buffer[0] = '\0';
549
550 int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
551 int bits_per_slot = sizeof(mask->bits[0]) * 8;
552
553 const char* format_str = NULL;
554 int table_size = sizeof(format_string_map)/sizeof(format_string_map[0]);
555
556 int slot_index, bit_index, table_index;
557 table_index = 0;
558 int num_written = 0;
559 for (slot_index = 0; slot_index < num_slots; slot_index++) {
560 unsigned bit_mask = 1;
561 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
562 if ((mask->bits[slot_index] & bit_mask) != 0) {
563 format_str = table_index < table_size
564 ? format_string_map[table_index]
565 : NULL;
566 if (format_str != NULL) {
567 if (num_written != 0) {
568 num_written += snprintf(buffer + num_written,
569 buffer_size - num_written, "|");
570 }
571 num_written += snprintf(buffer + num_written, buffer_size - num_written,
572 "%s", format_str);
573 }
574 }
575 bit_mask <<= 1;
576 table_index++;
Paul McLean30f41852014-04-16 15:44:20 -0700577 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800578 }
Paul McLeane32cbc12014-06-25 10:42:07 -0700579
580 return strdup(buffer);
581}
582
583/*
584 * Maps from bit position in pcm_mask to AUDIO_ format constants.
585 */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700586static audio_format_t const format_value_map[] = {
Paul McLeane32cbc12014-06-25 10:42:07 -0700587 AUDIO_FORMAT_PCM_8_BIT, /* 00 - SNDRV_PCM_FORMAT_S8 */
588 AUDIO_FORMAT_PCM_8_BIT, /* 01 - SNDRV_PCM_FORMAT_U8 */
589 AUDIO_FORMAT_PCM_16_BIT, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
590 AUDIO_FORMAT_INVALID, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
591 AUDIO_FORMAT_INVALID, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
592 AUDIO_FORMAT_INVALID, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700593 AUDIO_FORMAT_INVALID, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
Paul McLeane32cbc12014-06-25 10:42:07 -0700594 AUDIO_FORMAT_INVALID, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
595 AUDIO_FORMAT_INVALID, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
596 AUDIO_FORMAT_INVALID, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
597 AUDIO_FORMAT_PCM_32_BIT, /* 10 - SNDRV_PCM_FORMAT_S32_LE */
598 AUDIO_FORMAT_INVALID, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
599 AUDIO_FORMAT_INVALID, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
600 AUDIO_FORMAT_INVALID, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
601 AUDIO_FORMAT_PCM_FLOAT, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
602 AUDIO_FORMAT_INVALID, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
603 AUDIO_FORMAT_INVALID, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
604 AUDIO_FORMAT_INVALID, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
605 AUDIO_FORMAT_INVALID, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
606 AUDIO_FORMAT_INVALID, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
607 AUDIO_FORMAT_INVALID, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
608 AUDIO_FORMAT_INVALID, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
609 AUDIO_FORMAT_INVALID, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
610 AUDIO_FORMAT_INVALID, /* 23 - SNDRV_PCM_FORMAT_MPEG */
611 AUDIO_FORMAT_INVALID, /* 24 - SNDRV_PCM_FORMAT_GSM */
612 AUDIO_FORMAT_INVALID, /* 25 -> 30 (not assigned) */
613 AUDIO_FORMAT_INVALID,
614 AUDIO_FORMAT_INVALID,
615 AUDIO_FORMAT_INVALID,
616 AUDIO_FORMAT_INVALID,
617 AUDIO_FORMAT_INVALID,
618 AUDIO_FORMAT_INVALID, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700619 AUDIO_FORMAT_PCM_24_BIT_PACKED, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */
Paul McLeane32cbc12014-06-25 10:42:07 -0700620 AUDIO_FORMAT_INVALID, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
621 AUDIO_FORMAT_INVALID, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
622 AUDIO_FORMAT_INVALID, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
623 AUDIO_FORMAT_INVALID, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
624 AUDIO_FORMAT_INVALID, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
625 AUDIO_FORMAT_INVALID, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
626 AUDIO_FORMAT_INVALID, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
627 AUDIO_FORMAT_INVALID, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
628 AUDIO_FORMAT_INVALID, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
629 AUDIO_FORMAT_INVALID, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
630 AUDIO_FORMAT_INVALID, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
631 AUDIO_FORMAT_INVALID, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
632 AUDIO_FORMAT_INVALID, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
633 AUDIO_FORMAT_INVALID, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
634 AUDIO_FORMAT_INVALID, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
635 AUDIO_FORMAT_INVALID, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
636 AUDIO_FORMAT_INVALID /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
637};
638
Paul McLean6b1c0fe2014-07-02 07:27:41 -0700639/*
640 * Returns true if mask indicates support for PCM_16.
641 */
642static bool mask_has_pcm_16(struct pcm_mask* mask) {
643 return (mask->bits[0] & 0x0004) != 0;
644}
645
Paul McLeaneb192972014-07-11 16:29:41 -0700646static audio_format_t get_format_for_mask(struct pcm_mask* mask)
Paul McLeane32cbc12014-06-25 10:42:07 -0700647{
648 int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
649 int bits_per_slot = sizeof(mask->bits[0]) * 8;
650
651 int table_size = sizeof(format_value_map) / sizeof(format_value_map[0]);
652
653 int slot_index, bit_index, table_index;
654 table_index = 0;
655 int num_written = 0;
656 for (slot_index = 0; slot_index < num_slots; slot_index++) {
657 unsigned bit_mask = 1;
658 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
659 if ((mask->bits[slot_index] & bit_mask) != 0) {
660 /* just return the first one */
661 return table_index < table_size
662 ? format_value_map[table_index]
663 : AUDIO_FORMAT_INVALID;
664 }
665 bit_mask <<= 1;
666 table_index++;
667 }
668 }
669
670 return AUDIO_FORMAT_INVALID;
671}
672
673/*
674 * Maps from bit position in pcm_mask to AUDIO_ format constants.
675 */
676static int const pcm_format_value_map[] = {
677 PCM_FORMAT_S8, /* 00 - SNDRV_PCM_FORMAT_S8 */
678 0, /* 01 - SNDRV_PCM_FORMAT_U8 */
679 PCM_FORMAT_S16_LE, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
680 0, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
681 0, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
682 0, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
683 PCM_FORMAT_S24_3LE, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
684 0, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
685 0, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
686 0, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
687 PCM_FORMAT_S32_LE, /* 10 - SNDRV_PCM_FORMAT_S32_LE */
688 0, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
689 0, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
690 0, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
691 0, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
692 0, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
693 0, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
694 0, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
695 0, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
696 0, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
697 0, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
698 0, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
699 0, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
700 0, /* 23 - SNDRV_PCM_FORMAT_MPEG */
701 0, /* 24 - SNDRV_PCM_FORMAT_GSM */
702 0, /* 25 -> 30 (not assigned) */
703 0,
704 0,
705 0,
706 0,
707 0,
708 0, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
709 PCM_FORMAT_S24_3LE, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
710 0, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
711 0, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
712 0, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
713 0, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
714 0, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
715 0, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
716 0, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
717 0, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
718 0, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
719 0, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
720 0, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
721 0, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
722 0, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
723 0, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
724 0, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
725 0, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
726 0 /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
727};
728
Paul McLeaneb192972014-07-11 16:29:41 -0700729/*
730 * Scans the provided format mask and returns the first non-8 bit sample
731 * format supported by the devices.
732 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700733static int get_pcm_format_for_mask(struct pcm_mask* mask) {
734 int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
735 int bits_per_slot = sizeof(mask->bits[0]) * 8;
736
737 int table_size = sizeof(pcm_format_value_map) / sizeof(pcm_format_value_map[0]);
738
739 int slot_index, bit_index, table_index;
740 table_index = 0;
741 int num_written = 0;
Paul McLeaneb192972014-07-11 16:29:41 -0700742 for (slot_index = 0; slot_index < num_slots && table_index < table_size; slot_index++) {
Paul McLeane32cbc12014-06-25 10:42:07 -0700743 unsigned bit_mask = 1;
Paul McLeaneb192972014-07-11 16:29:41 -0700744 for (bit_index = 0; bit_index < bits_per_slot && table_index < table_size; bit_index++) {
Paul McLeane32cbc12014-06-25 10:42:07 -0700745 if ((mask->bits[slot_index] & bit_mask) != 0) {
Paul McLeaneb192972014-07-11 16:29:41 -0700746 if (table_index != 0) { /* Don't pick 8-bit */
747 /* just return the first one */
748 return pcm_format_value_map[table_index];
749 }
Paul McLeane32cbc12014-06-25 10:42:07 -0700750 }
751 bit_mask <<= 1;
752 table_index++;
753 }
754 }
755
Paul McLeaneb192972014-07-11 16:29:41 -0700756 return -1; /* error */
Paul McLeane32cbc12014-06-25 10:42:07 -0700757}
758
Paul McLeanf62d75e2014-07-11 15:14:19 -0700759static bool test_out_sample_rate(struct audio_device_profile* dev_profile, unsigned rate) {
760 struct pcm_config local_config = cached_output_hardware_config;
761 local_config.rate = rate;
762
763 bool works = false; /* let's be pessimistic */
764 struct pcm * pcm =
765 pcm_open(dev_profile->card, dev_profile->device, dev_profile->direction, &local_config);
766
767 if (pcm != NULL) {
768 works = pcm_is_ready(pcm);
769 pcm_close(pcm);
770 }
771
772 return works;
773}
774
775/* sort these highest -> lowest */
776static const unsigned std_sample_rates[] =
777 {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
778
779static char* enum_std_sample_rates(struct audio_device_profile* dev_profile,
780 unsigned min, unsigned max)
781{
782 char buffer[128];
783 buffer[0] = '\0';
784 int buffSize = ARRAY_SIZE(buffer);
785
786 char numBuffer[32];
787
788 int numEntries = 0;
789 unsigned index;
790 for(index = 0; index < ARRAY_SIZE(std_sample_rates); index++) {
791 if (std_sample_rates[index] >= min && std_sample_rates[index] <= max &&
792 test_out_sample_rate(dev_profile, std_sample_rates[index])) {
793 if (numEntries++ != 0) {
794 strncat(buffer, "|", buffSize);
795 }
796 snprintf(numBuffer, sizeof(numBuffer), "%u", std_sample_rates[index]);
797 strncat(buffer, numBuffer, buffSize);
798 }
799 }
800
801 return strdup(buffer);
802}
803
804/*
805 * Logging
806 */
Paul McLeane32cbc12014-06-25 10:42:07 -0700807static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
808 char buff[512];
809 char bit_buff[32];
810 int buffSize = sizeof(buff)/sizeof(buff[0]);
811
812 buff[0] = '\0';
813
814 int num_slots = sizeof(mask->bits) / sizeof(mask->bits[0]);
815 int bits_per_slot = sizeof(mask->bits[0]) * 8;
816
817 int slot_index, bit_index;
818 strcat(buff, "[");
819 for (slot_index = 0; slot_index < num_slots; slot_index++) {
820 unsigned bit_mask = 1;
821 for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
822 strcat(buff, (mask->bits[slot_index] & bit_mask) != 0 ? "1" : "0");
823 bit_mask <<= 1;
824 }
825 if (slot_index < num_slots - 1) {
826 strcat(buff, ",");
827 }
828 }
829 strcat(buff, "]");
830
831 ALOGV("usb:audio_hw - %s mask:%s", mask_name, buff);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800832}
833
Paul McLeancf611912014-04-28 13:03:18 -0700834static void log_pcm_params(struct pcm_params * alsa_hw_params) {
835 ALOGV("usb:audio_hw - PCM_PARAM_SAMPLE_BITS min:%u, max:%u",
836 pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS),
837 pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS));
838 ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%u, max:%u",
839 pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS),
840 pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS));
Paul McLeane32cbc12014-06-25 10:42:07 -0700841 log_pcm_mask("PCM_PARAM_FORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
842 log_pcm_mask("PCM_PARAM_SUBFORMAT", pcm_params_get_mask(alsa_hw_params, PCM_PARAM_SUBFORMAT));
Paul McLeancf611912014-04-28 13:03:18 -0700843 ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%u, max:%u",
844 pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
845 pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
846 ALOGV("usb:audio_hw - PCM_PARAM_RATE min:%u, max:%u",
847 pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
848 pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
849 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_TIME min:%u, max:%u",
850 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_TIME),
851 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_TIME));
852 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_SIZE min:%u, max:%u",
853 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE),
854 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE));
855 ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_BYTES min:%u, max:%u",
856 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_BYTES),
857 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_BYTES));
858 ALOGV("usb:audio_hw - PCM_PARAM_PERIODS min:%u, max:%u",
859 pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS),
860 pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS));
861 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_TIME min:%u, max:%u",
862 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_TIME),
863 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_TIME));
864 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_SIZE min:%u, max:%u",
865 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE),
866 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_SIZE));
867 ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_BYTES min:%u, max:%u",
868 pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_BYTES),
869 pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_BYTES));
870 ALOGV("usb:audio_hw - PCM_PARAM_TICK_TIME min:%u, max:%u",
871 pcm_params_get_min(alsa_hw_params, PCM_PARAM_TICK_TIME),
872 pcm_params_get_max(alsa_hw_params, PCM_PARAM_TICK_TIME));
873}
874
Paul McLeaneedc92e2013-12-19 15:46:15 -0800875/*
Paul McLean33a6b172014-06-19 12:35:28 -0700876 * Returns the supplied value rounded up to the next even multiple of 16
877 */
878static unsigned int round_to_16_mult(unsigned int size) {
879 return (size + 15) & 0xFFFFFFF0;
880}
881
Paul McLeane32cbc12014-06-25 10:42:07 -0700882/*TODO - Evaluate if this value should/can be retrieved from a device-specific property */
Paul McLean33a6b172014-06-19 12:35:28 -0700883#define MIN_BUFF_TIME 5 /* milliseconds */
884
885/*
886 * Returns the system defined minimum period size based on the supplied sample rate
887 */
888static unsigned int calc_min_period_size(unsigned int sample_rate) {
889 unsigned int period_size = (sample_rate * MIN_BUFF_TIME) / 1000;
890 return round_to_16_mult(period_size);
891}
892
893/*
Paul McLeaneedc92e2013-12-19 15:46:15 -0800894 * Reads and decodes configuration info from the specified ALSA card/device
895 */
Paul McLeanf62d75e2014-07-11 15:14:19 -0700896static int read_alsa_device_config(struct audio_device_profile * dev_profile,
897 struct pcm_config * config)
Paul McLeaneedc92e2013-12-19 15:46:15 -0800898{
Paul McLeanf62d75e2014-07-11 15:14:19 -0700899 ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
900 dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800901
Paul McLeanf62d75e2014-07-11 15:14:19 -0700902 if (dev_profile->card < 0 || dev_profile->device < 0) {
Paul McLeaneedc92e2013-12-19 15:46:15 -0800903 return -EINVAL;
904 }
905
Paul McLeanf62d75e2014-07-11 15:14:19 -0700906 struct pcm_params * alsa_hw_params =
907 pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800908 if (alsa_hw_params == NULL) {
909 return -EINVAL;
910 }
911
Paul McLeaneb192972014-07-11 16:29:41 -0700912 int ret = 0;
913
Paul McLeaneedc92e2013-12-19 15:46:15 -0800914 /*
915 * This Logging will be useful when testing new USB devices.
916 */
Paul McLeanf62d75e2014-07-11 15:14:19 -0700917#ifdef LOG_PCM_PARAMS
918 log_pcm_params(alsa_hw_params);
919#endif
Paul McLeaneedc92e2013-12-19 15:46:15 -0800920
921 config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
922 config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
Paul McLean33a6b172014-06-19 12:35:28 -0700923 config->period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE);
924 /* round this up to a multiple of 16 */
925 config->period_size = round_to_16_mult(config->period_size);
926 /* make sure it is above a minimum value to minimize jitter */
927 unsigned int min_period_size = calc_min_period_size(config->rate);
928 if (config->period_size < min_period_size) {
929 config->period_size = min_period_size;
930 }
Paul McLeaneedc92e2013-12-19 15:46:15 -0800931 config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
932
Paul McLeaneb192972014-07-11 16:29:41 -0700933 int format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
934 if (format == -1) {
935 ret = -EINVAL;
936 } else {
937 config->format = format;
938 }
Paul McLeanf62d75e2014-07-11 15:14:19 -0700939
940 pcm_params_free(alsa_hw_params);
Paul McLeaneb192972014-07-11 16:29:41 -0700941 return ret;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800942}
943
944/*
945 * HAl Functions
946 */
Simon Wilson19957a32012-04-06 16:17:12 -0700947/**
948 * NOTE: when multiple mutexes have to be acquired, always respect the
949 * following order: hw device > out stream
950 */
951
952/* Helper functions */
Simon Wilson19957a32012-04-06 16:17:12 -0700953static uint32_t out_get_sample_rate(const struct audio_stream *stream)
954{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800955 return cached_output_hardware_config.rate;
Simon Wilson19957a32012-04-06 16:17:12 -0700956}
957
958static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
959{
960 return 0;
961}
962
963static size_t out_get_buffer_size(const struct audio_stream *stream)
964{
Eric Laurentc5ae6a02014-07-02 13:45:32 -0700965 return cached_output_hardware_config.period_size *
966 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
Simon Wilson19957a32012-04-06 16:17:12 -0700967}
968
969static uint32_t out_get_channels(const struct audio_stream *stream)
970{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800971 // Always Stero for now. We will do *some* conversions in this HAL.
Paul McLeane32cbc12014-06-25 10:42:07 -0700972 /* TODO When AudioPolicyManager & AudioFlinger supports arbitrary channels
973 rewrite this to return the ACTUAL channel format */
Simon Wilson19957a32012-04-06 16:17:12 -0700974 return AUDIO_CHANNEL_OUT_STEREO;
975}
976
977static audio_format_t out_get_format(const struct audio_stream *stream)
978{
Paul McLeane32cbc12014-06-25 10:42:07 -0700979 return audio_format_from_pcm_format(cached_output_hardware_config.format);
Simon Wilson19957a32012-04-06 16:17:12 -0700980}
981
982static int out_set_format(struct audio_stream *stream, audio_format_t format)
983{
Paul McLeane32cbc12014-06-25 10:42:07 -0700984 cached_output_hardware_config.format = pcm_format_from_audio_format(format);
Simon Wilson19957a32012-04-06 16:17:12 -0700985 return 0;
986}
987
988static int out_standby(struct audio_stream *stream)
989{
990 struct stream_out *out = (struct stream_out *)stream;
991
992 pthread_mutex_lock(&out->dev->lock);
993 pthread_mutex_lock(&out->lock);
994
995 if (!out->standby) {
996 pcm_close(out->pcm);
997 out->pcm = NULL;
998 out->standby = true;
999 }
1000
1001 pthread_mutex_unlock(&out->lock);
1002 pthread_mutex_unlock(&out->dev->lock);
1003
1004 return 0;
1005}
1006
1007static int out_dump(const struct audio_stream *stream, int fd)
1008{
1009 return 0;
1010}
1011
1012static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1013{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001014 ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
1015
Simon Wilson19957a32012-04-06 16:17:12 -07001016 struct stream_out *out = (struct stream_out *)stream;
Simon Wilson19957a32012-04-06 16:17:12 -07001017 struct str_parms *parms;
1018 char value[32];
Paul McLeaneedc92e2013-12-19 15:46:15 -08001019 int param_val;
Simon Wilson19957a32012-04-06 16:17:12 -07001020 int routing = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001021 int ret_value = 0;
Simon Wilson19957a32012-04-06 16:17:12 -07001022
1023 parms = str_parms_create_str(kvpairs);
Paul McLeanf62d75e2014-07-11 15:14:19 -07001024 pthread_mutex_lock(&out->dev->lock);
1025 pthread_mutex_lock(&out->lock);
Simon Wilson19957a32012-04-06 16:17:12 -07001026
Paul McLeaneedc92e2013-12-19 15:46:15 -08001027 bool recache_device_params = false;
1028 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
1029 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001030 out->profile->card = atoi(value);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001031 recache_device_params = true;
1032 }
Simon Wilson19957a32012-04-06 16:17:12 -07001033
Paul McLeaneedc92e2013-12-19 15:46:15 -08001034 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
1035 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001036 out->profile->device = atoi(value);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001037 recache_device_params = true;
1038 }
1039
Paul McLeanf62d75e2014-07-11 15:14:19 -07001040 if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
1041 ret_value = read_alsa_device_config(out->profile, &cached_output_hardware_config);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001042 output_hardware_config_is_cached = (ret_value == 0);
1043 }
Simon Wilson19957a32012-04-06 16:17:12 -07001044
Paul McLeanf62d75e2014-07-11 15:14:19 -07001045 pthread_mutex_unlock(&out->lock);
1046 pthread_mutex_unlock(&out->dev->lock);
Simon Wilson19957a32012-04-06 16:17:12 -07001047 str_parms_destroy(parms);
1048
Paul McLeaneedc92e2013-12-19 15:46:15 -08001049 return ret_value;
Simon Wilson19957a32012-04-06 16:17:12 -07001050}
1051
Paul McLeanf62d75e2014-07-11 15:14:19 -07001052static char * device_get_parameters(struct audio_device_profile * dev_profile, const char *keys)
Paul McLean30f41852014-04-16 15:44:20 -07001053{
Paul McLeanf62d75e2014-07-11 15:14:19 -07001054 ALOGV("usb:audio_hw::device_get_parameters() keys:%s", keys);
Paul McLean30f41852014-04-16 15:44:20 -07001055
Paul McLeanf62d75e2014-07-11 15:14:19 -07001056 if (dev_profile->card < 0 || dev_profile->device < 0) {
Paul McLean30f41852014-04-16 15:44:20 -07001057 return strdup("");
Paul McLeanf62d75e2014-07-11 15:14:19 -07001058 }
Paul McLean30f41852014-04-16 15:44:20 -07001059
Paul McLeaneedc92e2013-12-19 15:46:15 -08001060 unsigned min, max;
1061
1062 struct str_parms *query = str_parms_create_str(keys);
1063 struct str_parms *result = str_parms_create();
1064
1065 int num_written = 0;
1066 char buffer[256];
1067 int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
1068 char* result_str = NULL;
1069
Paul McLeanf62d75e2014-07-11 15:14:19 -07001070 struct pcm_params * alsa_hw_params =
1071 pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001072
1073 // These keys are from hardware/libhardware/include/audio.h
1074 // supported sample rates
1075 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
Paul McLeaneedc92e2013-12-19 15:46:15 -08001076 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
1077 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
Paul McLeanf62d75e2014-07-11 15:14:19 -07001078
1079 char* rates_list = enum_std_sample_rates(dev_profile, min, max);
1080 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, rates_list);
1081 free(rates_list);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001082 } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
1083
1084 // supported channel counts
1085 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001086 // TODO remove this hack when it is superceeded by proper multi-channel support
1087 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
1088 dev_profile->direction == PCM_OUT
1089 ? "AUDIO_CHANNEL_OUT_STEREO"
1090 : "AUDIO_CHANNEL_IN_STEREO");
Paul McLeaneedc92e2013-12-19 15:46:15 -08001091 } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
1092
1093 // supported sample formats
1094 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001095 // TODO remove this hack when we have support for input in non PCM16 formats
1096 if (dev_profile->direction == PCM_IN) {
1097 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, "AUDIO_FORMAT_PCM_16_BIT");
1098 } else {
1099 struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
1100 char * format_params = get_format_str_for_mask(format_mask);
1101 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
1102 free(format_params);
1103 }
Paul McLeaneedc92e2013-12-19 15:46:15 -08001104 } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
1105
Paul McLeanf62d75e2014-07-11 15:14:19 -07001106 pcm_params_free(alsa_hw_params);
1107
Paul McLeaneedc92e2013-12-19 15:46:15 -08001108 result_str = str_parms_to_str(result);
1109
1110 // done with these...
1111 str_parms_destroy(query);
1112 str_parms_destroy(result);
1113
Paul McLeanf62d75e2014-07-11 15:14:19 -07001114 ALOGV("usb:audio_hw::device_get_parameters = %s", result_str);
Paul McLeane32cbc12014-06-25 10:42:07 -07001115
Paul McLeaneedc92e2013-12-19 15:46:15 -08001116 return result_str;
Simon Wilson19957a32012-04-06 16:17:12 -07001117}
1118
Paul McLeanf62d75e2014-07-11 15:14:19 -07001119static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
1120{
1121 ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
1122
1123 struct stream_out *out = (struct stream_out *) stream;
1124 pthread_mutex_lock(&out->dev->lock);
1125 pthread_mutex_lock(&out->lock);
1126
1127 char * params_str = device_get_parameters(out->profile, keys);
1128
1129 pthread_mutex_unlock(&out->lock);
1130 pthread_mutex_unlock(&out->dev->lock);
1131
1132 return params_str;
1133}
1134
Simon Wilson19957a32012-04-06 16:17:12 -07001135static uint32_t out_get_latency(const struct audio_stream_out *stream)
1136{
Paul McLeanf62d75e2014-07-11 15:14:19 -07001137 // struct stream_out *out = (struct stream_out *) stream;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001138
Paul McLeane32cbc12014-06-25 10:42:07 -07001139 /*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
Paul McLean30f41852014-04-16 15:44:20 -07001140 uint32_t latency = (cached_output_hardware_config.period_size
Paul McLeane32cbc12014-06-25 10:42:07 -07001141 * cached_output_hardware_config.period_count * 1000)
1142 / out_get_sample_rate(&stream->common);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001143 return latency;
Simon Wilson19957a32012-04-06 16:17:12 -07001144}
1145
Paul McLean30f41852014-04-16 15:44:20 -07001146static int out_set_volume(struct audio_stream_out *stream, float left, float right)
Simon Wilson19957a32012-04-06 16:17:12 -07001147{
1148 return -ENOSYS;
1149}
1150
Paul McLeaneedc92e2013-12-19 15:46:15 -08001151/* must be called with hw device and output stream mutexes locked */
1152static int start_output_stream(struct stream_out *out)
1153{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001154 int return_val = 0;
1155
Paul McLean30f41852014-04-16 15:44:20 -07001156 ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
Paul McLeanf62d75e2014-07-11 15:14:19 -07001157 out->profile->card, out->profile->device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001158
Paul McLeanf62d75e2014-07-11 15:14:19 -07001159 out->pcm = pcm_open(out->profile->card, out->profile->device, PCM_OUT,
1160 &cached_output_hardware_config);
Paul McLeane32cbc12014-06-25 10:42:07 -07001161
Paul McLeaneedc92e2013-12-19 15:46:15 -08001162 if (out->pcm == NULL) {
1163 return -ENOMEM;
1164 }
1165
1166 if (out->pcm && !pcm_is_ready(out->pcm)) {
1167 ALOGE("audio_hw audio_hw pcm_open() failed: %s", pcm_get_error(out->pcm));
1168 pcm_close(out->pcm);
1169 return -ENOMEM;
1170 }
1171
Paul McLeaneedc92e2013-12-19 15:46:15 -08001172 return 0;
1173}
1174
1175static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes)
Simon Wilson19957a32012-04-06 16:17:12 -07001176{
1177 int ret;
1178 struct stream_out *out = (struct stream_out *)stream;
1179
1180 pthread_mutex_lock(&out->dev->lock);
1181 pthread_mutex_lock(&out->lock);
1182 if (out->standby) {
1183 ret = start_output_stream(out);
1184 if (ret != 0) {
1185 goto err;
1186 }
1187 out->standby = false;
1188 }
1189
Paul McLean30f41852014-04-16 15:44:20 -07001190 // Setup conversion buffer
1191 // compute maximum potential buffer size.
1192 // * 2 for stereo -> quad conversion
1193 // * 3/2 for 16bit -> 24 bit conversion
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001194 size_t required_conversion_buffer_size = (bytes * 3 * 2) / 2;
Paul McLean30f41852014-04-16 15:44:20 -07001195 if (required_conversion_buffer_size > out->conversion_buffer_size) {
Paul McLeane32cbc12014-06-25 10:42:07 -07001196 /* TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
1197 (and do these conversions themselves) */
Paul McLean30f41852014-04-16 15:44:20 -07001198 out->conversion_buffer_size = required_conversion_buffer_size;
1199 out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size);
1200 }
1201
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001202 const void * write_buff = buffer;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001203 int num_write_buff_bytes = bytes;
1204
1205 /*
1206 * Num Channels conversion
1207 */
1208 int num_device_channels = cached_output_hardware_config.channels;
1209 int num_req_channels = 2; /* always, for now */
Paul McLean30f41852014-04-16 15:44:20 -07001210 if (num_device_channels != num_req_channels) {
Paul McLeaneb192972014-07-11 16:29:41 -07001211 audio_format_t audio_format = out_get_format(&(out->stream.common));
1212 unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001213 num_write_buff_bytes =
Paul McLeaneb192972014-07-11 16:29:41 -07001214 adjust_channels(write_buff, num_req_channels,
1215 out->conversion_buffer, num_device_channels,
1216 sample_size_in_bytes, num_write_buff_bytes);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001217 write_buff = out->conversion_buffer;
1218 }
1219
Paul McLeaneedc92e2013-12-19 15:46:15 -08001220 if (write_buff != NULL && num_write_buff_bytes != 0) {
1221 pcm_write(out->pcm, write_buff, num_write_buff_bytes);
1222 }
Simon Wilson19957a32012-04-06 16:17:12 -07001223
1224 pthread_mutex_unlock(&out->lock);
1225 pthread_mutex_unlock(&out->dev->lock);
1226
1227 return bytes;
1228
1229err:
1230 pthread_mutex_unlock(&out->lock);
Amit Shekharf9953b72014-01-30 12:47:34 -08001231 pthread_mutex_unlock(&out->dev->lock);
Simon Wilson19957a32012-04-06 16:17:12 -07001232 if (ret != 0) {
Eric Laurentc5ae6a02014-07-02 13:45:32 -07001233 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
Simon Wilson19957a32012-04-06 16:17:12 -07001234 out_get_sample_rate(&stream->common));
1235 }
1236
1237 return bytes;
1238}
1239
Paul McLean30f41852014-04-16 15:44:20 -07001240static int out_get_render_position(const struct audio_stream_out *stream, uint32_t *dsp_frames)
Simon Wilson19957a32012-04-06 16:17:12 -07001241{
1242 return -EINVAL;
1243}
1244
1245static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1246{
1247 return 0;
1248}
1249
1250static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1251{
1252 return 0;
1253}
1254
Paul McLean30f41852014-04-16 15:44:20 -07001255static int out_get_next_write_timestamp(const struct audio_stream_out *stream, int64_t *timestamp)
Simon Wilson19957a32012-04-06 16:17:12 -07001256{
1257 return -EINVAL;
1258}
1259
1260static int adev_open_output_stream(struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -07001261 audio_io_handle_t handle,
1262 audio_devices_t devices,
1263 audio_output_flags_t flags,
1264 struct audio_config *config,
Simon Wilson19957a32012-04-06 16:17:12 -07001265 struct audio_stream_out **stream_out)
1266{
Paul McLean30f41852014-04-16 15:44:20 -07001267 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 -08001268 handle, devices, flags);
1269
Simon Wilson19957a32012-04-06 16:17:12 -07001270 struct audio_device *adev = (struct audio_device *)dev;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001271
Simon Wilson19957a32012-04-06 16:17:12 -07001272 struct stream_out *out;
Simon Wilson19957a32012-04-06 16:17:12 -07001273
1274 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
1275 if (!out)
1276 return -ENOMEM;
1277
Paul McLeaneedc92e2013-12-19 15:46:15 -08001278 // setup function pointers
Simon Wilson19957a32012-04-06 16:17:12 -07001279 out->stream.common.get_sample_rate = out_get_sample_rate;
1280 out->stream.common.set_sample_rate = out_set_sample_rate;
1281 out->stream.common.get_buffer_size = out_get_buffer_size;
1282 out->stream.common.get_channels = out_get_channels;
1283 out->stream.common.get_format = out_get_format;
1284 out->stream.common.set_format = out_set_format;
1285 out->stream.common.standby = out_standby;
1286 out->stream.common.dump = out_dump;
1287 out->stream.common.set_parameters = out_set_parameters;
1288 out->stream.common.get_parameters = out_get_parameters;
1289 out->stream.common.add_audio_effect = out_add_audio_effect;
1290 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1291 out->stream.get_latency = out_get_latency;
1292 out->stream.set_volume = out_set_volume;
1293 out->stream.write = out_write;
1294 out->stream.get_render_position = out_get_render_position;
1295 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1296
1297 out->dev = adev;
1298
Paul McLeanf62d75e2014-07-11 15:14:19 -07001299 out->profile = &(adev->out_profile);
1300 out->profile->direction = PCM_OUT;
1301
Paul McLeaneedc92e2013-12-19 15:46:15 -08001302 if (output_hardware_config_is_cached) {
1303 config->sample_rate = cached_output_hardware_config.rate;
1304
Paul McLeane32cbc12014-06-25 10:42:07 -07001305 config->format = audio_format_from_pcm_format(cached_output_hardware_config.format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001306
1307 config->channel_mask =
1308 audio_channel_out_mask_from_count(cached_output_hardware_config.channels);
1309 if (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) {
1310 // Always report STEREO for now. AudioPolicyManagerBase/AudioFlinger dont' understand
1311 // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
Paul McLeane32cbc12014-06-25 10:42:07 -07001312 /*TODO remove this when the above restriction is removed. */
Paul McLeaneedc92e2013-12-19 15:46:15 -08001313 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1314 }
1315 } else {
1316 cached_output_hardware_config = default_alsa_out_config;
1317
1318 config->format = out_get_format(&out->stream.common);
1319 config->channel_mask = out_get_channels(&out->stream.common);
1320 config->sample_rate = out_get_sample_rate(&out->stream.common);
1321 }
Paul McLeaneedc92e2013-12-19 15:46:15 -08001322
1323 out->conversion_buffer = NULL;
1324 out->conversion_buffer_size = 0;
Simon Wilson19957a32012-04-06 16:17:12 -07001325
1326 out->standby = true;
1327
1328 *stream_out = &out->stream;
1329 return 0;
1330
1331err_open:
1332 free(out);
1333 *stream_out = NULL;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001334 return -ENOSYS;
Simon Wilson19957a32012-04-06 16:17:12 -07001335}
1336
1337static void adev_close_output_stream(struct audio_hw_device *dev,
1338 struct audio_stream_out *stream)
1339{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001340 ALOGV("usb:audio_hw::out adev_close_output_stream()");
Simon Wilson19957a32012-04-06 16:17:12 -07001341 struct stream_out *out = (struct stream_out *)stream;
1342
Paul McLeane32cbc12014-06-25 10:42:07 -07001343 // Close the pcm device
Simon Wilson19957a32012-04-06 16:17:12 -07001344 out_standby(&stream->common);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001345
1346 free(out->conversion_buffer);
1347 out->conversion_buffer = NULL;
1348 out->conversion_buffer_size = 0;
1349
Simon Wilson19957a32012-04-06 16:17:12 -07001350 free(stream);
1351}
1352
1353static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1354{
1355 return 0;
1356}
1357
Paul McLean30f41852014-04-16 15:44:20 -07001358static char * adev_get_parameters(const struct audio_hw_device *dev, const char *keys)
Simon Wilson19957a32012-04-06 16:17:12 -07001359{
1360 return strdup("");
1361}
1362
1363static int adev_init_check(const struct audio_hw_device *dev)
1364{
1365 return 0;
1366}
1367
1368static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1369{
1370 return -ENOSYS;
1371}
1372
1373static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1374{
1375 return -ENOSYS;
1376}
1377
1378static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
1379{
1380 return 0;
1381}
1382
1383static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1384{
1385 return -ENOSYS;
1386}
1387
1388static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1389{
1390 return -ENOSYS;
1391}
1392
1393static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -07001394 const struct audio_config *config)
Simon Wilson19957a32012-04-06 16:17:12 -07001395{
1396 return 0;
1397}
1398
Paul McLeaneedc92e2013-12-19 15:46:15 -08001399/* Helper functions */
1400static uint32_t in_get_sample_rate(const struct audio_stream *stream)
1401{
Paul McLean30f41852014-04-16 15:44:20 -07001402 return cached_input_hardware_config.rate;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001403}
1404
1405static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1406{
1407 return -ENOSYS;
1408}
1409
1410static size_t in_get_buffer_size(const struct audio_stream *stream)
1411{
Eric Laurentc5ae6a02014-07-02 13:45:32 -07001412 size_t buffer_size = cached_input_hardware_config.period_size *
1413 audio_stream_in_frame_size((const struct audio_stream_in *)stream);
1414 ALOGV("usb: in_get_buffer_size() = %zu", buffer_size);
1415 return buffer_size;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001416}
1417
1418static uint32_t in_get_channels(const struct audio_stream *stream)
1419{
Paul McLean30f41852014-04-16 15:44:20 -07001420 // just report stereo for now
1421 return AUDIO_CHANNEL_IN_STEREO;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001422}
1423
1424static audio_format_t in_get_format(const struct audio_stream *stream)
1425{
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001426 const struct stream_in * in_stream = (const struct stream_in *)stream;
1427
1428 ALOGV("in_get_format() = %d -> %d", in_stream->input_framework_format,
1429 audio_format_from_pcm_format(in_stream->input_framework_format));
1430 /* return audio_format_from_pcm_format(cached_input_hardware_config.format); */
1431 return audio_format_from_pcm_format(in_stream->input_framework_format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001432}
1433
1434static int in_set_format(struct audio_stream *stream, audio_format_t format)
1435{
1436 return -ENOSYS;
1437}
1438
1439static int in_standby(struct audio_stream *stream)
1440{
Paul McLean30f41852014-04-16 15:44:20 -07001441 struct stream_in *in = (struct stream_in *) stream;
1442
1443 pthread_mutex_lock(&in->dev->lock);
1444 pthread_mutex_lock(&in->lock);
1445
1446 if (!in->standby) {
1447 pcm_close(in->pcm);
1448 in->pcm = NULL;
1449 in->standby = true;
1450 }
1451
1452 pthread_mutex_unlock(&in->lock);
1453 pthread_mutex_unlock(&in->dev->lock);
1454
Paul McLeaneedc92e2013-12-19 15:46:15 -08001455 return 0;
1456}
1457
1458static int in_dump(const struct audio_stream *stream, int fd)
1459{
1460 return 0;
1461}
1462
1463static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1464{
Paul McLean30f41852014-04-16 15:44:20 -07001465 ALOGV("usb: audio_hw::in in_set_parameters() keys:%s", kvpairs);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001466
1467 struct stream_in *in = (struct stream_in *)stream;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001468 struct str_parms *parms;
1469 char value[32];
1470 int param_val;
1471 int routing = 0;
1472 int ret_value = 0;
1473
1474 parms = str_parms_create_str(kvpairs);
Paul McLeanf62d75e2014-07-11 15:14:19 -07001475 pthread_mutex_lock(&in->dev->lock);
1476 pthread_mutex_lock(&in->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001477
Paul McLean30f41852014-04-16 15:44:20 -07001478 bool recache_device_params = false;
1479
Paul McLeaneedc92e2013-12-19 15:46:15 -08001480 // Card/Device
1481 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
1482 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001483 in->profile->card = atoi(value);
Paul McLean30f41852014-04-16 15:44:20 -07001484 recache_device_params = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001485 }
1486
1487 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
1488 if (param_val >= 0) {
Paul McLeanf62d75e2014-07-11 15:14:19 -07001489 in->profile->device = atoi(value);
Paul McLean30f41852014-04-16 15:44:20 -07001490 recache_device_params = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001491 }
1492
Paul McLeanf62d75e2014-07-11 15:14:19 -07001493 if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
1494 ret_value = read_alsa_device_config(in->profile, &cached_input_hardware_config);
Paul McLean30f41852014-04-16 15:44:20 -07001495 input_hardware_config_is_cached = (ret_value == 0);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001496 }
1497
Paul McLeanf62d75e2014-07-11 15:14:19 -07001498 pthread_mutex_unlock(&in->lock);
1499 pthread_mutex_unlock(&in->dev->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001500 str_parms_destroy(parms);
1501
1502 return ret_value;
1503}
1504
Paul McLean30f41852014-04-16 15:44:20 -07001505static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
1506 ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001507
Paul McLean30f41852014-04-16 15:44:20 -07001508 struct stream_in *in = (struct stream_in *)stream;
Paul McLeanf62d75e2014-07-11 15:14:19 -07001509 pthread_mutex_lock(&in->dev->lock);
1510 pthread_mutex_lock(&in->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001511
Paul McLeanf62d75e2014-07-11 15:14:19 -07001512 char * params_str = device_get_parameters(in->profile, keys);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001513
Paul McLeanf62d75e2014-07-11 15:14:19 -07001514 pthread_mutex_unlock(&in->lock);
1515 pthread_mutex_unlock(&in->dev->lock);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001516
Paul McLeanf62d75e2014-07-11 15:14:19 -07001517 return params_str;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001518}
1519
1520static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1521{
1522 return 0;
1523}
1524
1525static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1526{
1527 return 0;
1528}
1529
Paul McLean30f41852014-04-16 15:44:20 -07001530static int in_set_gain(struct audio_stream_in *stream, float gain)
1531{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001532 return 0;
1533}
1534
Paul McLean30f41852014-04-16 15:44:20 -07001535/* must be called with hw device and output stream mutexes locked */
1536static int start_input_stream(struct stream_in *in) {
Paul McLean30f41852014-04-16 15:44:20 -07001537 int return_val = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001538
Paul McLean30f41852014-04-16 15:44:20 -07001539 ALOGV("usb:audio_hw::start_input_stream(card:%d device:%d)",
Paul McLeanf62d75e2014-07-11 15:14:19 -07001540 in->profile->card, in->profile->device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001541
Paul McLeanf62d75e2014-07-11 15:14:19 -07001542 in->pcm = pcm_open(in->profile->card, in->profile->device, PCM_IN,
1543 &cached_input_hardware_config);
Paul McLean30f41852014-04-16 15:44:20 -07001544 if (in->pcm == NULL) {
1545 ALOGE("usb:audio_hw pcm_open() in->pcm == NULL");
1546 return -ENOMEM;
1547 }
1548
1549 if (in->pcm && !pcm_is_ready(in->pcm)) {
1550 ALOGE("usb:audio_hw audio_hw pcm_open() failed: %s", pcm_get_error(in->pcm));
1551 pcm_close(in->pcm);
1552 return -ENOMEM;
1553 }
1554
1555 return 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001556}
1557
Paul McLeane32cbc12014-06-25 10:42:07 -07001558/* TODO mutex stuff here (see out_write) */
Paul McLean30f41852014-04-16 15:44:20 -07001559static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes)
1560{
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001561 size_t num_read_buff_bytes = 0;
Paul McLean30f41852014-04-16 15:44:20 -07001562 void * read_buff = buffer;
1563 void * out_buff = buffer;
1564
1565 struct stream_in * in = (struct stream_in *) stream;
1566
1567 pthread_mutex_lock(&in->dev->lock);
1568 pthread_mutex_lock(&in->lock);
1569
1570 if (in->standby) {
1571 if (start_input_stream(in) != 0) {
1572 goto err;
1573 }
1574 in->standby = false;
1575 }
1576
1577 // OK, we need to figure out how much data to read to be able to output the requested
1578 // number of bytes in the HAL format (16-bit, stereo).
1579 num_read_buff_bytes = bytes;
1580 int num_device_channels = cached_input_hardware_config.channels;
1581 int num_req_channels = 2; /* always, for now */
1582
1583 if (num_device_channels != num_req_channels) {
Paul McLeancf611912014-04-28 13:03:18 -07001584 num_read_buff_bytes = (num_device_channels * num_read_buff_bytes) / num_req_channels;
Paul McLean30f41852014-04-16 15:44:20 -07001585 }
1586
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001587 /* Assume (for now) that in->input_framework_format == PCM_FORMAT_S16_LE */
Eric Laurent7661a482014-06-11 12:00:16 -07001588 if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001589 /* 24-bit USB device */
Paul McLean30f41852014-04-16 15:44:20 -07001590 num_read_buff_bytes = (3 * num_read_buff_bytes) / 2;
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001591 } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
1592 /* 32-bit USB device */
1593 num_read_buff_bytes = num_read_buff_bytes * 2;
Paul McLean30f41852014-04-16 15:44:20 -07001594 }
1595
1596 // Setup/Realloc the conversion buffer (if necessary).
1597 if (num_read_buff_bytes != bytes) {
1598 if (num_read_buff_bytes > in->conversion_buffer_size) {
Paul McLeane32cbc12014-06-25 10:42:07 -07001599 /*TODO Remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
1600 (and do these conversions themselves) */
Paul McLean30f41852014-04-16 15:44:20 -07001601 in->conversion_buffer_size = num_read_buff_bytes;
1602 in->conversion_buffer = realloc(in->conversion_buffer, in->conversion_buffer_size);
1603 }
1604 read_buff = in->conversion_buffer;
1605 }
1606
1607 if (pcm_read(in->pcm, read_buff, num_read_buff_bytes) == 0) {
1608 /*
1609 * Do any conversions necessary to send the data in the format specified to/by the HAL
1610 * (but different from the ALSA format), such as 24bit ->16bit, or 4chan -> 2chan.
1611 */
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001612 if (cached_input_hardware_config.format != PCM_FORMAT_S16_LE) {
1613 // we need to convert
Paul McLean30f41852014-04-16 15:44:20 -07001614 if (num_device_channels != num_req_channels) {
1615 out_buff = read_buff;
1616 }
1617
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001618 if (cached_input_hardware_config.format == PCM_FORMAT_S24_3LE) {
1619 num_read_buff_bytes =
1620 convert_24_3_to_16(read_buff, num_read_buff_bytes / 3, out_buff);
1621 } else if (cached_input_hardware_config.format == PCM_FORMAT_S32_LE) {
1622 num_read_buff_bytes =
1623 convert_32_to_16(read_buff, num_read_buff_bytes / 4, out_buff);
1624 }
1625 else {
1626 goto err;
1627 }
Paul McLean30f41852014-04-16 15:44:20 -07001628 }
1629
1630 if (num_device_channels != num_req_channels) {
1631 out_buff = buffer;
1632 /* Num Channels conversion */
Paul McLeaneb192972014-07-11 16:29:41 -07001633 if (num_device_channels != num_req_channels) {
1634 audio_format_t audio_format = in_get_format(&(in->stream.common));
1635 unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
1636
Paul McLeancf611912014-04-28 13:03:18 -07001637 num_read_buff_bytes =
Paul McLeaneb192972014-07-11 16:29:41 -07001638 adjust_channels(read_buff, num_device_channels,
1639 out_buff, num_req_channels,
1640 sample_size_in_bytes, num_read_buff_bytes);
Paul McLeancf611912014-04-28 13:03:18 -07001641 }
Paul McLean30f41852014-04-16 15:44:20 -07001642 }
1643 }
1644
1645err:
1646 pthread_mutex_unlock(&in->lock);
1647 pthread_mutex_unlock(&in->dev->lock);
1648
1649 return num_read_buff_bytes;
1650}
1651
1652static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1653{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001654 return 0;
1655}
1656
Mike Lockwood46a98092012-04-24 16:41:18 -07001657static int adev_open_input_stream(struct audio_hw_device *dev,
1658 audio_io_handle_t handle,
1659 audio_devices_t devices,
Paul McLean30f41852014-04-16 15:44:20 -07001660 struct audio_config *config,
Simon Wilson19957a32012-04-06 16:17:12 -07001661 struct audio_stream_in **stream_in)
1662{
Mark Salyzyn88e458a2014-04-28 12:30:44 -07001663 ALOGV("usb: in adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
Paul McLean30f41852014-04-16 15:44:20 -07001664 config->sample_rate, config->channel_mask, config->format);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001665
1666 struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Eric Laurent7661a482014-06-11 12:00:16 -07001667 int ret = 0;
1668
Paul McLeaneedc92e2013-12-19 15:46:15 -08001669 if (in == NULL)
1670 return -ENOMEM;
1671
1672 // setup function pointers
1673 in->stream.common.get_sample_rate = in_get_sample_rate;
1674 in->stream.common.set_sample_rate = in_set_sample_rate;
1675 in->stream.common.get_buffer_size = in_get_buffer_size;
1676 in->stream.common.get_channels = in_get_channels;
1677 in->stream.common.get_format = in_get_format;
1678 in->stream.common.set_format = in_set_format;
1679 in->stream.common.standby = in_standby;
1680 in->stream.common.dump = in_dump;
1681 in->stream.common.set_parameters = in_set_parameters;
1682 in->stream.common.get_parameters = in_get_parameters;
1683 in->stream.common.add_audio_effect = in_add_audio_effect;
1684 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1685
1686 in->stream.set_gain = in_set_gain;
1687 in->stream.read = in_read;
1688 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1689
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001690 in->input_framework_format = PCM_FORMAT_S16_LE;
1691
Paul McLean30f41852014-04-16 15:44:20 -07001692 in->dev = (struct audio_device *)dev;
1693
Paul McLeanf62d75e2014-07-11 15:14:19 -07001694 in->profile = &(in->dev->in_profile);
1695 in->profile->direction = PCM_IN;
1696
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001697 if (!input_hardware_config_is_cached) {
1698 // just return defaults until we can actually query the device.
Paul McLean30f41852014-04-16 15:44:20 -07001699 cached_input_hardware_config = default_alsa_in_config;
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001700 }
Paul McLean30f41852014-04-16 15:44:20 -07001701
Paul McLean6b1c0fe2014-07-02 07:27:41 -07001702 /* Rate */
1703 /* TODO Check that the requested rate is valid for the connected device */
1704 if (config->sample_rate == 0) {
1705 config->sample_rate = cached_input_hardware_config.rate;
1706 } else {
1707 cached_input_hardware_config.rate = config->sample_rate;
1708 }
1709
1710 /* Format */
1711 /* until the framework supports format conversion, just take what it asks for
1712 * i.e. AUDIO_FORMAT_PCM_16_BIT */
1713 /* config->format = audio_format_from_pcm_format(cached_input_hardware_config.format); */
1714 if (config->format == AUDIO_FORMAT_DEFAULT) {
1715 /* just return AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
1716 * formats */
1717 config->format = AUDIO_FORMAT_PCM_16_BIT;
1718 } else if (config->format == AUDIO_FORMAT_PCM_16_BIT) {
1719 /* Always accept AUDIO_FORMAT_PCM_16_BIT until the framework supports other input
1720 * formats */
1721 } else {
1722 /* When the framework support other formats, validate here */
1723 config->format = AUDIO_FORMAT_PCM_16_BIT;
1724 ret = -EINVAL;
1725 }
1726
1727 /* don't change the cached_input_hardware_config, we will open it as what it is and
1728 * convert as necessary */
1729 if (config->channel_mask == AUDIO_CHANNEL_NONE) {
1730 /* just return AUDIO_CHANNEL_IN_STEREO until the framework supports other input
1731 * formats */
1732 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
1733 } else if (config->channel_mask != AUDIO_CHANNEL_IN_STEREO) {
1734 /* allow only stereo capture for now */
1735 config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
1736 ret = -EINVAL;
Paul McLean30f41852014-04-16 15:44:20 -07001737 }
Paul McLeaneedc92e2013-12-19 15:46:15 -08001738
1739 in->standby = true;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001740
Paul McLean30f41852014-04-16 15:44:20 -07001741 in->conversion_buffer = NULL;
1742 in->conversion_buffer_size = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001743
1744 *stream_in = &in->stream;
1745
Eric Laurent7661a482014-06-11 12:00:16 -07001746 return ret;
Simon Wilson19957a32012-04-06 16:17:12 -07001747}
1748
Paul McLean30f41852014-04-16 15:44:20 -07001749static void adev_close_input_stream(struct audio_hw_device *dev, struct audio_stream_in *stream)
Simon Wilson19957a32012-04-06 16:17:12 -07001750{
Paul McLean30f41852014-04-16 15:44:20 -07001751 struct stream_in *in = (struct stream_in *)stream;
1752
Paul McLeane32cbc12014-06-25 10:42:07 -07001753 // Close the pcm device
Paul McLean30f41852014-04-16 15:44:20 -07001754 in_standby(&stream->common);
1755
1756 free(in->conversion_buffer);
1757
1758 free(stream);
Simon Wilson19957a32012-04-06 16:17:12 -07001759}
1760
1761static int adev_dump(const audio_hw_device_t *device, int fd)
1762{
1763 return 0;
1764}
1765
1766static int adev_close(hw_device_t *device)
1767{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001768 struct audio_device *adev = (struct audio_device *)device;
Simon Wilson19957a32012-04-06 16:17:12 -07001769 free(device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001770
1771 output_hardware_config_is_cached = false;
Paul McLean30f41852014-04-16 15:44:20 -07001772 input_hardware_config_is_cached = false;
Paul McLeaneedc92e2013-12-19 15:46:15 -08001773
Simon Wilson19957a32012-04-06 16:17:12 -07001774 return 0;
1775}
1776
Paul McLean30f41852014-04-16 15:44:20 -07001777static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
Simon Wilson19957a32012-04-06 16:17:12 -07001778{
Simon Wilson19957a32012-04-06 16:17:12 -07001779 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1780 return -EINVAL;
1781
Paul McLeaneedc92e2013-12-19 15:46:15 -08001782 struct audio_device *adev = calloc(1, sizeof(struct audio_device));
Simon Wilson19957a32012-04-06 16:17:12 -07001783 if (!adev)
1784 return -ENOMEM;
1785
1786 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
Eric Laurent85e08e22012-08-28 14:30:35 -07001787 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
Simon Wilson19957a32012-04-06 16:17:12 -07001788 adev->hw_device.common.module = (struct hw_module_t *) module;
1789 adev->hw_device.common.close = adev_close;
1790
Simon Wilson19957a32012-04-06 16:17:12 -07001791 adev->hw_device.init_check = adev_init_check;
1792 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1793 adev->hw_device.set_master_volume = adev_set_master_volume;
1794 adev->hw_device.set_mode = adev_set_mode;
1795 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1796 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1797 adev->hw_device.set_parameters = adev_set_parameters;
1798 adev->hw_device.get_parameters = adev_get_parameters;
1799 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1800 adev->hw_device.open_output_stream = adev_open_output_stream;
1801 adev->hw_device.close_output_stream = adev_close_output_stream;
1802 adev->hw_device.open_input_stream = adev_open_input_stream;
1803 adev->hw_device.close_input_stream = adev_close_input_stream;
1804 adev->hw_device.dump = adev_dump;
1805
1806 *device = &adev->hw_device.common;
1807
1808 return 0;
1809}
1810
1811static struct hw_module_methods_t hal_module_methods = {
1812 .open = adev_open,
1813};
1814
1815struct audio_module HAL_MODULE_INFO_SYM = {
1816 .common = {
1817 .tag = HARDWARE_MODULE_TAG,
Mike Lockwood46a98092012-04-24 16:41:18 -07001818 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1819 .hal_api_version = HARDWARE_HAL_API_VERSION,
Simon Wilson19957a32012-04-06 16:17:12 -07001820 .id = AUDIO_HARDWARE_MODULE_ID,
1821 .name = "USB audio HW HAL",
1822 .author = "The Android Open Source Project",
1823 .methods = &hal_module_methods,
1824 },
1825};