blob: afe56b25a14583d9f72d9d71167e7553791a99a3 [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"
18/*#define LOG_NDEBUG 0*/
19
20#include <errno.h>
21#include <pthread.h>
22#include <stdint.h>
23#include <sys/time.h>
24#include <stdlib.h>
25
26#include <cutils/log.h>
27#include <cutils/str_parms.h>
28#include <cutils/properties.h>
29
30#include <hardware/hardware.h>
31#include <system/audio.h>
32#include <hardware/audio.h>
33
34#include <tinyalsa/asoundlib.h>
35
Paul McLeaneedc92e2013-12-19 15:46:15 -080036/* This is the default configuration to hand to The Framework on the initial
37 * adev_open_output_stream(). Actual device attributes will be used on the subsequent
38 * adev_open_output_stream() after the card and device number have been set in out_set_parameters()
39 */
40#define OUT_PERIOD_SIZE 1024
41#define OUT_PERIOD_COUNT 4
42#define OUT_SAMPLING_RATE 44100
43
44struct pcm_config default_alsa_out_config = {
Simon Wilson19957a32012-04-06 16:17:12 -070045 .channels = 2,
Paul McLeaneedc92e2013-12-19 15:46:15 -080046 .rate = OUT_SAMPLING_RATE,
47 .period_size = OUT_PERIOD_SIZE,
48 .period_count = OUT_PERIOD_COUNT,
Simon Wilson19957a32012-04-06 16:17:12 -070049 .format = PCM_FORMAT_S16_LE,
50};
51
Paul McLeaneedc92e2013-12-19 15:46:15 -080052/*
53 * Input defaults. See comment above.
54 */
55#define IN_PERIOD_SIZE 1024
56#define IN_PERIOD_COUNT 4
57#define IN_SAMPLING_RATE 44100
58
59struct pcm_config default_alsa_in_config = {
60 .channels = 2,
61 .rate = IN_SAMPLING_RATE,
62 .period_size = IN_PERIOD_SIZE,
63 .period_count = IN_PERIOD_COUNT,
64 .format = PCM_FORMAT_S16_LE,
65 .start_threshold = 1,
66 .stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
67};
68
Simon Wilson19957a32012-04-06 16:17:12 -070069struct audio_device {
70 struct audio_hw_device hw_device;
71
72 pthread_mutex_t lock; /* see note below on mutex acquisition order */
Paul McLeaneedc92e2013-12-19 15:46:15 -080073
74 /* output */
75 int out_card;
76 int out_device;
77
78 /* input */
79 int in_card;
80 int in_device;
81
Simon Wilson19957a32012-04-06 16:17:12 -070082 bool standby;
83};
84
85struct stream_out {
86 struct audio_stream_out stream;
87
Paul McLeaneedc92e2013-12-19 15:46:15 -080088 pthread_mutex_t lock; /* see note below on mutex acquisition order */
89 struct pcm *pcm; /* state of the stream */
90 bool standby;
91
92 struct audio_device *dev; /* hardware information */
93
94 void * conversion_buffer; /* any conversions are put into here
95 * they could come from here too if
96 * there was a previous conversion */
97 size_t conversion_buffer_size; /* in bytes */
98};
99
100/*
101 * Output Configuration Cache
102 * FIXME(pmclean) This is not rentrant. Should probably be moved into the stream structure
103 * but that will involve changes in The Framework.
104 */
105static struct pcm_config cached_output_hardware_config;
106static bool output_hardware_config_is_cached = false;
107
108struct stream_in {
109 struct audio_stream_in stream;
110
Simon Wilson19957a32012-04-06 16:17:12 -0700111 pthread_mutex_t lock; /* see note below on mutex acquisition order */
112 struct pcm *pcm;
113 bool standby;
114
Paul McLeaneedc92e2013-12-19 15:46:15 -0800115 struct pcm_config alsa_pcm_config;
116
Simon Wilson19957a32012-04-06 16:17:12 -0700117 struct audio_device *dev;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800118
119 struct audio_config hal_pcm_config;
120
121 unsigned int requested_rate;
122// struct resampler_itfe *resampler;
123// struct resampler_buffer_provider buf_provider;
124 int16_t *buffer;
125 size_t buffer_size;
126 size_t frames_in;
127 int read_status;
Simon Wilson19957a32012-04-06 16:17:12 -0700128};
129
Paul McLeaneedc92e2013-12-19 15:46:15 -0800130/*
131 * Utility
132 */
133/*
134 * Translates from ALSA format ID to ANDROID_AUDIO_CORE format ID
135 * (see master/system/core/include/core/audio.h)
136 * TODO(pmclean) Replace with audio_format_from_pcm_format() (in hardware/audio_alsaops.h).
137 * post-integration.
138 */
139static audio_format_t alsa_to_fw_format_id(int alsa_fmt_id)
140{
141 switch (alsa_fmt_id) {
142 case PCM_FORMAT_S8:
143 return AUDIO_FORMAT_PCM_8_BIT;
144
145 case PCM_FORMAT_S24_3LE:
146 //TODO(pmclean) make sure this is the 'right' sort of 24-bit
147 return AUDIO_FORMAT_PCM_8_24_BIT;
148
149 case PCM_FORMAT_S32_LE:
150 case PCM_FORMAT_S24_LE:
151 return AUDIO_FORMAT_PCM_32_BIT;
152 }
153
154 return AUDIO_FORMAT_PCM_16_BIT;
155}
156
157/*
158 * Data Conversions
159 */
160/*
161 * Convert a buffer of PCM16LE samples to packed (3-byte) PCM24LE samples.
162 * in_buff points to the buffer of PCM16 samples
163 * num_in_samples size of input buffer in SAMPLES
164 * out_buff points to the buffer to receive converted PCM24 LE samples.
165 * returns the number of BYTES of output data.
166 * We are doing this since we *always* present to The Framework as A PCM16LE device, but need to
167 * support PCM24_3LE (24-bit, packed).
168 * NOTE: we're just filling the low-order byte of the PCM24LE samples with 0.
169 * TODO(pmclean, hung) Move this to a utilities module.
170 */
171static size_t convert_16_to_24_3(unsigned short * in_buff,
172 size_t num_in_samples,
173 unsigned char * out_buff) {
174 /*
175 * Move from back to front so that the conversion can be done in-place
176 * i.e. in_buff == out_buff
177 */
178 int in_buff_size_in_bytes = num_in_samples * 2;
179 /* we need 3 bytes in the output for every 2 bytes in the input */
180 int out_buff_size_in_bytes = ((3 * in_buff_size_in_bytes) / 2);
181 unsigned char* dst_ptr = out_buff + out_buff_size_in_bytes - 1;
182 int src_smpl_index;
183 unsigned char* src_ptr = ((unsigned char *)in_buff) + in_buff_size_in_bytes - 1;
184 for (src_smpl_index = 0; src_smpl_index < num_in_samples; src_smpl_index++) {
185 *dst_ptr-- = *src_ptr--; /* hi-byte */
186 *dst_ptr-- = *src_ptr--; /* low-byte */
187 *dst_ptr-- = 0; /* zero-byte */
188 }
189
190 /* return number of *bytes* generated */
191 return out_buff_size_in_bytes;
192}
193
194/*
195 * Convert a buffer of 2-channel PCM16 samples to 4-channel PCM16 channels
196 * in_buff points to the buffer of PCM16 samples
197 * num_in_samples size of input buffer in SAMPLES
198 * out_buff points to the buffer to receive converted PCM16 samples.
199 * returns the number of BYTES of output data.
200 * NOTE channels 3 & 4 are filled with silence.
201 * We are doing this since we *always* present to The Framework as STEREO device, but need to
202 * support 4-channel devices.
203 * TODO(pmclean, hung) Move this to a utilities module.
204 */
205static size_t convert_2chan16_to_4chan16(unsigned short* in_buff,
206 size_t num_in_samples,
207 unsigned short* out_buff) {
208 /*
209 * Move from back to front so that the conversion can be done in-place
210 * i.e. in_buff == out_buff
211 */
212 int out_buff_size = num_in_samples * 2;
213 unsigned short* dst_ptr = out_buff + out_buff_size - 1;
214 int src_index;
215 unsigned short* src_ptr = in_buff + num_in_samples - 1;
216 for (src_index = 0; src_index < num_in_samples; src_index += 2) {
217 *dst_ptr-- = 0; /* chan 4 */
218 *dst_ptr-- = 0; /* chan 3 */
219 *dst_ptr-- = *src_ptr--; /* chan 2 */
220 *dst_ptr-- = *src_ptr--; /* chan 1 */
221 }
222
223 /* return number of *bytes* generated */
224 return out_buff_size * 2;
225}
226
227/*
228 * ALSA Utilities
229 */
230/*
231 * gets the ALSA bit-format flag from a bits-per-sample value.
232 * TODO(pmclean, hung) Move this to a utilities module.
233 */
234static int bits_to_alsa_format(int bits_per_sample, int default_format)
235{
236 enum pcm_format format;
237 for (format = PCM_FORMAT_S16_LE; format < PCM_FORMAT_MAX; format++) {
238 if (pcm_format_to_bits(format) == bits_per_sample) {
239 return format;
240 }
241 }
242 return default_format;
243}
244
245/*
246 * Reads and decodes configuration info from the specified ALSA card/device
247 */
248static int read_alsa_device_config(int card, int device, int io_type, struct pcm_config * config)
249{
250 ALOGV("usb:audio_hw - read_alsa_device_config(card:%d device:%d)", card, device);
251
252 if (card < 0 || device < 0) {
253 return -EINVAL;
254 }
255
256 struct pcm_params * alsa_hw_params = pcm_params_get(card, device, io_type);
257 if (alsa_hw_params == NULL) {
258 return -EINVAL;
259 }
260
261 /*
262 * This Logging will be useful when testing new USB devices.
263 */
264 /* ALOGV("usb:audio_hw - PCM_PARAM_SAMPLE_BITS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS)); */
265 /* ALOGV("usb:audio_hw - PCM_PARAM_FRAME_BITS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_FRAME_BITS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_FRAME_BITS)); */
266 /* ALOGV("usb:audio_hw - PCM_PARAM_CHANNELS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS)); */
267 /* ALOGV("usb:audio_hw - PCM_PARAM_RATE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE)); */
268 /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_TIME)); */
269 /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_SIZE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE)); */
270 /* ALOGV("usb:audio_hw - PCM_PARAM_PERIOD_BYTES min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_BYTES), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_BYTES)); */
271 /* ALOGV("usb:audio_hw - PCM_PARAM_PERIODS min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS), pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS)); */
272 /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_TIME)); */
273 /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_SIZE min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_SIZE), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_SIZE)); */
274 /* ALOGV("usb:audio_hw - PCM_PARAM_BUFFER_BYTES min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_BUFFER_BYTES), pcm_params_get_max(alsa_hw_params, PCM_PARAM_BUFFER_BYTES)); */
275 /* ALOGV("usb:audio_hw - PCM_PARAM_TICK_TIME min:%d, max:%d", pcm_params_get_min(alsa_hw_params, PCM_PARAM_TICK_TIME), pcm_params_get_max(alsa_hw_params, PCM_PARAM_TICK_TIME)); */
276
277 config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
278 config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
279 config->period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIODS);
280 config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
281
282 int bits_per_sample = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
283 config->format = bits_to_alsa_format(bits_per_sample, PCM_FORMAT_S16_LE);
284
285 return 0;
286}
287
288/*
289 * HAl Functions
290 */
Simon Wilson19957a32012-04-06 16:17:12 -0700291/**
292 * NOTE: when multiple mutexes have to be acquired, always respect the
293 * following order: hw device > out stream
294 */
295
296/* Helper functions */
Simon Wilson19957a32012-04-06 16:17:12 -0700297static uint32_t out_get_sample_rate(const struct audio_stream *stream)
298{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800299 return cached_output_hardware_config.rate;
Simon Wilson19957a32012-04-06 16:17:12 -0700300}
301
302static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
303{
304 return 0;
305}
306
307static size_t out_get_buffer_size(const struct audio_stream *stream)
308{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800309 return cached_output_hardware_config.period_size * audio_stream_frame_size(stream);
Simon Wilson19957a32012-04-06 16:17:12 -0700310}
311
312static uint32_t out_get_channels(const struct audio_stream *stream)
313{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800314 // Always Stero for now. We will do *some* conversions in this HAL.
315 // TODO(pmclean) When AudioPolicyManager & AudioFlinger supports arbitrary channels
316 // rewrite this to return the ACTUAL channel format
Simon Wilson19957a32012-04-06 16:17:12 -0700317 return AUDIO_CHANNEL_OUT_STEREO;
318}
319
320static audio_format_t out_get_format(const struct audio_stream *stream)
321{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800322 // Always return 16-bit PCM. We will do *some* conversions in this HAL.
323 // TODO(pmclean) When AudioPolicyManager & AudioFlinger supports arbitrary PCM formats
324 // rewrite this to return the ACTUAL data format
Simon Wilson19957a32012-04-06 16:17:12 -0700325 return AUDIO_FORMAT_PCM_16_BIT;
326}
327
328static int out_set_format(struct audio_stream *stream, audio_format_t format)
329{
330 return 0;
331}
332
333static int out_standby(struct audio_stream *stream)
334{
335 struct stream_out *out = (struct stream_out *)stream;
336
337 pthread_mutex_lock(&out->dev->lock);
338 pthread_mutex_lock(&out->lock);
339
340 if (!out->standby) {
341 pcm_close(out->pcm);
342 out->pcm = NULL;
343 out->standby = true;
344 }
345
346 pthread_mutex_unlock(&out->lock);
347 pthread_mutex_unlock(&out->dev->lock);
348
349 return 0;
350}
351
352static int out_dump(const struct audio_stream *stream, int fd)
353{
354 return 0;
355}
356
357static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
358{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800359 ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
360
Simon Wilson19957a32012-04-06 16:17:12 -0700361 struct stream_out *out = (struct stream_out *)stream;
362 struct audio_device *adev = out->dev;
363 struct str_parms *parms;
364 char value[32];
Paul McLeaneedc92e2013-12-19 15:46:15 -0800365 int param_val;
Simon Wilson19957a32012-04-06 16:17:12 -0700366 int routing = 0;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800367 int ret_value = 0;
Simon Wilson19957a32012-04-06 16:17:12 -0700368
369 parms = str_parms_create_str(kvpairs);
370 pthread_mutex_lock(&adev->lock);
371
Paul McLeaneedc92e2013-12-19 15:46:15 -0800372 bool recache_device_params = false;
373 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
374 if (param_val >= 0) {
375 adev->out_card = atoi(value);
376 recache_device_params = true;
377 }
Simon Wilson19957a32012-04-06 16:17:12 -0700378
Paul McLeaneedc92e2013-12-19 15:46:15 -0800379 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
380 if (param_val >= 0) {
381 adev->out_device = atoi(value);
382 recache_device_params = true;
383 }
384
385 if (recache_device_params && adev->out_card >= 0 && adev->out_device >= 0) {
386 ret_value = read_alsa_device_config(adev->out_card, adev->out_device, PCM_OUT,
387 &(cached_output_hardware_config));
388 output_hardware_config_is_cached = (ret_value == 0);
389 }
Simon Wilson19957a32012-04-06 16:17:12 -0700390
391 pthread_mutex_unlock(&adev->lock);
392 str_parms_destroy(parms);
393
Paul McLeaneedc92e2013-12-19 15:46:15 -0800394 return ret_value;
Simon Wilson19957a32012-04-06 16:17:12 -0700395}
396
Paul McLeaneedc92e2013-12-19 15:46:15 -0800397//TODO(pmclean) it seems like both out_get_parameters() and in_get_parameters()
398// could be written in terms of a get_device_parameters(io_type)
399
400static char * out_get_parameters(const struct audio_stream *stream, const char *keys) {
401 struct stream_out *out = (struct stream_out *) stream;
402 struct audio_device *adev = out->dev;
403
404 unsigned min, max;
405
406 struct str_parms *query = str_parms_create_str(keys);
407 struct str_parms *result = str_parms_create();
408
409 int num_written = 0;
410 char buffer[256];
411 int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
412 char* result_str = NULL;
413
414 struct pcm_params * alsa_hw_params = pcm_params_get(adev->out_card, adev->out_device, PCM_OUT);
415
416 // These keys are from hardware/libhardware/include/audio.h
417 // supported sample rates
418 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
419 // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
420 // if they are different, return a list containing those two values, otherwise just the one.
421 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
422 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
423 num_written = snprintf(buffer, buffer_size, "%d", min);
424 if (min != max) {
425 snprintf(buffer + num_written, buffer_size - num_written, "|%d",
426 max);
427 }
428 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
429 buffer);
430 } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
431
432 // supported channel counts
433 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
434 // Similarly for output channels count
435 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
436 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
437 num_written = snprintf(buffer, buffer_size, "%d", min);
438 if (min != max) {
439 snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
440 }
441 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, buffer);
442 } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
443
444 // supported sample formats
445 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
446 // Similarly for output channels count
447 //TODO(pmclean): this is wrong.
448 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
449 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
450 num_written = snprintf(buffer, buffer_size, "%d", min);
451 if (min != max) {
452 snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
453 }
454 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
455 } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
456
457 result_str = str_parms_to_str(result);
458
459 // done with these...
460 str_parms_destroy(query);
461 str_parms_destroy(result);
462
463 return result_str;
Simon Wilson19957a32012-04-06 16:17:12 -0700464}
465
466static uint32_t out_get_latency(const struct audio_stream_out *stream)
467{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800468 struct stream_out *out = (struct stream_out *)stream;
469
470 //TODO(pmclean): Do we need a term here for the USB latency
471 // (as reported in the USB descriptors)?
472 uint32_t latency = (cached_output_hardware_config.period_size *
473 cached_output_hardware_config.period_count * 1000) / out_get_sample_rate(&stream->common);
474 return latency;
Simon Wilson19957a32012-04-06 16:17:12 -0700475}
476
477static int out_set_volume(struct audio_stream_out *stream, float left,
478 float right)
479{
480 return -ENOSYS;
481}
482
Paul McLeaneedc92e2013-12-19 15:46:15 -0800483/* must be called with hw device and output stream mutexes locked */
484static int start_output_stream(struct stream_out *out)
485{
486 struct audio_device *adev = out->dev;
487 int return_val = 0;
488
489 ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
490 adev->out_card, adev->out_device);
491
492 out->pcm = pcm_open(adev->out_card, adev->out_device, PCM_OUT, &cached_output_hardware_config);
493 if (out->pcm == NULL) {
494 return -ENOMEM;
495 }
496
497 if (out->pcm && !pcm_is_ready(out->pcm)) {
498 ALOGE("audio_hw audio_hw pcm_open() failed: %s", pcm_get_error(out->pcm));
499 pcm_close(out->pcm);
500 return -ENOMEM;
501 }
502
503 // Setup conversion buffer
504 size_t buffer_size = out_get_buffer_size(&(out->stream.common));
505
506 // computer maximum potential buffer size.
507 // * 2 for stereo -> quad conversion
508 // * 3/2 for 16bit -> 24 bit conversion
509 //TODO(pmclean) - remove this when AudioPolicyManger/AudioFlinger support arbitrary formats
510 // (and do these conversions themselves)
511 out->conversion_buffer_size = (buffer_size * 3 * 2) / 2;
512 out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size);
513
514 return 0;
515}
516
517static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes)
Simon Wilson19957a32012-04-06 16:17:12 -0700518{
519 int ret;
520 struct stream_out *out = (struct stream_out *)stream;
521
522 pthread_mutex_lock(&out->dev->lock);
523 pthread_mutex_lock(&out->lock);
524 if (out->standby) {
525 ret = start_output_stream(out);
526 if (ret != 0) {
527 goto err;
528 }
529 out->standby = false;
530 }
531
Paul McLeaneedc92e2013-12-19 15:46:15 -0800532 void * write_buff = buffer;
533 int num_write_buff_bytes = bytes;
534
535 /*
536 * Num Channels conversion
537 */
538 int num_device_channels = cached_output_hardware_config.channels;
539 int num_req_channels = 2; /* always, for now */
540 if (num_device_channels != num_req_channels && num_device_channels == 4) {
541 num_write_buff_bytes =
542 convert_2chan16_to_4chan16(write_buff, num_write_buff_bytes / 2,
543 out->conversion_buffer);
544 write_buff = out->conversion_buffer;
545 }
546
547 /*
548 * 16 vs 24-bit logic here
549 */
550 switch (cached_output_hardware_config.format) {
551 case PCM_FORMAT_S16_LE:
552 // the output format is the same as the input format, so just write it out
553 break;
554
555 case PCM_FORMAT_S24_3LE:
556 // 16-bit LE2 - 24-bit LE3
557 num_write_buff_bytes =
558 convert_16_to_24_3(write_buff, num_write_buff_bytes / 2, out->conversion_buffer);
559 write_buff = out->conversion_buffer;
560 break;
561
562 default:
563 // hmmmmm.....
564 ALOGV("usb:Unknown Format!!!");
565 break;
566 }
567
568 if (write_buff != NULL && num_write_buff_bytes != 0) {
569 pcm_write(out->pcm, write_buff, num_write_buff_bytes);
570 }
Simon Wilson19957a32012-04-06 16:17:12 -0700571
572 pthread_mutex_unlock(&out->lock);
573 pthread_mutex_unlock(&out->dev->lock);
574
575 return bytes;
576
577err:
578 pthread_mutex_unlock(&out->lock);
Amit Shekharf9953b72014-01-30 12:47:34 -0800579 pthread_mutex_unlock(&out->dev->lock);
Simon Wilson19957a32012-04-06 16:17:12 -0700580 if (ret != 0) {
581 usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
582 out_get_sample_rate(&stream->common));
583 }
584
585 return bytes;
586}
587
588static int out_get_render_position(const struct audio_stream_out *stream,
589 uint32_t *dsp_frames)
590{
591 return -EINVAL;
592}
593
594static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
595{
596 return 0;
597}
598
599static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
600{
601 return 0;
602}
603
604static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
605 int64_t *timestamp)
606{
607 return -EINVAL;
608}
609
610static int adev_open_output_stream(struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -0700611 audio_io_handle_t handle,
612 audio_devices_t devices,
613 audio_output_flags_t flags,
614 struct audio_config *config,
Simon Wilson19957a32012-04-06 16:17:12 -0700615 struct audio_stream_out **stream_out)
616{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800617 ALOGV("usb:audio_hw::out adev_open_output_stream() handle:0x%X, devices:0x%X, flags:0x%X",
618 handle, devices, flags);
619
Simon Wilson19957a32012-04-06 16:17:12 -0700620 struct audio_device *adev = (struct audio_device *)dev;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800621
Simon Wilson19957a32012-04-06 16:17:12 -0700622 struct stream_out *out;
Simon Wilson19957a32012-04-06 16:17:12 -0700623
624 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
625 if (!out)
626 return -ENOMEM;
627
Paul McLeaneedc92e2013-12-19 15:46:15 -0800628 // setup function pointers
Simon Wilson19957a32012-04-06 16:17:12 -0700629 out->stream.common.get_sample_rate = out_get_sample_rate;
630 out->stream.common.set_sample_rate = out_set_sample_rate;
631 out->stream.common.get_buffer_size = out_get_buffer_size;
632 out->stream.common.get_channels = out_get_channels;
633 out->stream.common.get_format = out_get_format;
634 out->stream.common.set_format = out_set_format;
635 out->stream.common.standby = out_standby;
636 out->stream.common.dump = out_dump;
637 out->stream.common.set_parameters = out_set_parameters;
638 out->stream.common.get_parameters = out_get_parameters;
639 out->stream.common.add_audio_effect = out_add_audio_effect;
640 out->stream.common.remove_audio_effect = out_remove_audio_effect;
641 out->stream.get_latency = out_get_latency;
642 out->stream.set_volume = out_set_volume;
643 out->stream.write = out_write;
644 out->stream.get_render_position = out_get_render_position;
645 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
646
647 out->dev = adev;
648
Paul McLeaneedc92e2013-12-19 15:46:15 -0800649 if (output_hardware_config_is_cached) {
650 config->sample_rate = cached_output_hardware_config.rate;
651
652 config->format = alsa_to_fw_format_id(cached_output_hardware_config.format);
653 if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
654 // Always report PCM16 for now. AudioPolicyManagerBase/AudioFlinger dont' understand
655 // formats with more other format, so we won't get chosen (say with a 24bit DAC).
656 //TODO(pmclean) remove this when the above restriction is removed.
657 config->format = AUDIO_FORMAT_PCM_16_BIT;
658 }
659
660 config->channel_mask =
661 audio_channel_out_mask_from_count(cached_output_hardware_config.channels);
662 if (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) {
663 // Always report STEREO for now. AudioPolicyManagerBase/AudioFlinger dont' understand
664 // formats with more channels, so we won't get chosen (say with a 4-channel DAC).
665 //TODO(pmclean) remove this when the above restriction is removed.
666 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
667 }
668 } else {
669 cached_output_hardware_config = default_alsa_out_config;
670
671 config->format = out_get_format(&out->stream.common);
672 config->channel_mask = out_get_channels(&out->stream.common);
673 config->sample_rate = out_get_sample_rate(&out->stream.common);
674 }
675 ALOGV("usb:audio_hw config->sample_rate:%d", config->sample_rate);
676 ALOGV("usb:audio_hw config->format:0x%X", config->format);
677 ALOGV("usb:audio_hw config->channel_mask:0x%X", config->channel_mask);
678
679 out->conversion_buffer = NULL;
680 out->conversion_buffer_size = 0;
Simon Wilson19957a32012-04-06 16:17:12 -0700681
682 out->standby = true;
683
684 *stream_out = &out->stream;
685 return 0;
686
687err_open:
688 free(out);
689 *stream_out = NULL;
Paul McLeaneedc92e2013-12-19 15:46:15 -0800690 return -ENOSYS;
Simon Wilson19957a32012-04-06 16:17:12 -0700691}
692
693static void adev_close_output_stream(struct audio_hw_device *dev,
694 struct audio_stream_out *stream)
695{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800696 ALOGV("usb:audio_hw::out adev_close_output_stream()");
Simon Wilson19957a32012-04-06 16:17:12 -0700697 struct stream_out *out = (struct stream_out *)stream;
698
Paul McLeaneedc92e2013-12-19 15:46:15 -0800699 //TODO(pmclean) why are we doing this when stream get's freed at the end
700 // because it closes the pcm device
Simon Wilson19957a32012-04-06 16:17:12 -0700701 out_standby(&stream->common);
Paul McLeaneedc92e2013-12-19 15:46:15 -0800702
703 free(out->conversion_buffer);
704 out->conversion_buffer = NULL;
705 out->conversion_buffer_size = 0;
706
Simon Wilson19957a32012-04-06 16:17:12 -0700707 free(stream);
708}
709
710static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
711{
712 return 0;
713}
714
715static char * adev_get_parameters(const struct audio_hw_device *dev,
716 const char *keys)
717{
718 return strdup("");
719}
720
721static int adev_init_check(const struct audio_hw_device *dev)
722{
723 return 0;
724}
725
726static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
727{
728 return -ENOSYS;
729}
730
731static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
732{
733 return -ENOSYS;
734}
735
736static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
737{
738 return 0;
739}
740
741static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
742{
743 return -ENOSYS;
744}
745
746static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
747{
748 return -ENOSYS;
749}
750
751static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
Mike Lockwood46a98092012-04-24 16:41:18 -0700752 const struct audio_config *config)
Simon Wilson19957a32012-04-06 16:17:12 -0700753{
754 return 0;
755}
756
Paul McLeaneedc92e2013-12-19 15:46:15 -0800757/* Helper functions */
758static uint32_t in_get_sample_rate(const struct audio_stream *stream)
759{
760 struct stream_in *in = (struct stream_in *)stream;
761 return in->alsa_pcm_config.rate;
762}
763
764static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
765{
766 return -ENOSYS;
767}
768
769static size_t in_get_buffer_size(const struct audio_stream *stream)
770{
771 struct stream_in *in = (struct stream_in *)stream;
772 size_t buff_size =
773 in->alsa_pcm_config.period_size
774 * audio_stream_frame_size((struct audio_stream *)stream);
775 return buff_size;
776}
777
778static uint32_t in_get_channels(const struct audio_stream *stream)
779{
780 struct stream_in *in = (struct stream_in *)stream;
781 //TODO(pmclean) this should be done with a num_channels_to_alsa_channels()
782 return in->alsa_pcm_config.channels == 2
783 ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_IN_MONO;
784}
785
786static audio_format_t in_get_format(const struct audio_stream *stream)
787{
788 // just report 16-bit, pcm for now.
789 return AUDIO_FORMAT_PCM_16_BIT;
790}
791
792static int in_set_format(struct audio_stream *stream, audio_format_t format)
793{
794 return -ENOSYS;
795}
796
797static int in_standby(struct audio_stream *stream)
798{
799 ALOGV("-pcm-audio_hw::in in_standby() [Not Implemented]");
800 return 0;
801}
802
803static int in_dump(const struct audio_stream *stream, int fd)
804{
805 return 0;
806}
807
808static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
809{
810 ALOGV("Vaudio_hw::in in_set_parameters() keys:%s", kvpairs);
811
812 struct stream_in *in = (struct stream_in *)stream;
813 struct audio_device *adev = in->dev;
814 struct str_parms *parms;
815 char value[32];
816 int param_val;
817 int routing = 0;
818 int ret_value = 0;
819
820 parms = str_parms_create_str(kvpairs);
821 pthread_mutex_lock(&adev->lock);
822
823 // Card/Device
824 param_val = str_parms_get_str(parms, "card", value, sizeof(value));
825 if (param_val >= 0) {
826 adev->in_card = atoi(value);
827 }
828
829 param_val = str_parms_get_str(parms, "device", value, sizeof(value));
830 if (param_val >= 0) {
831 adev->in_device = atoi(value);
832 }
833
834 if (adev->in_card >= 0 && adev->in_device >= 0) {
835 ret_value = read_alsa_device_config(adev->in_card, adev->in_device, PCM_IN, &(in->alsa_pcm_config));
836 }
837
838 pthread_mutex_unlock(&adev->lock);
839 str_parms_destroy(parms);
840
841 return ret_value;
842}
843
844//TODO(pmclean) it seems like both out_get_parameters() and in_get_parameters()
845// could be written in terms of a get_device_parameters(io_type)
846
847static char * in_get_parameters(const struct audio_stream *stream, const char *keys)
848{
849 ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
850
851 struct stream_in *in = (struct stream_in *)stream;
852 struct audio_device *adev = in->dev;
853
854 struct pcm_params * alsa_hw_params = pcm_params_get(adev->in_card, adev->in_device, PCM_IN);
855 if (alsa_hw_params == NULL)
856 return strdup("");
857
858 struct str_parms *query = str_parms_create_str(keys);
859 struct str_parms *result = str_parms_create();
860
861 int num_written = 0;
862 char buffer[256];
863 int buffer_size = sizeof(buffer)/sizeof(buffer[0]);
864 char* result_str = NULL;
865
866 unsigned min, max;
867
868 // These keys are from hardware/libhardware/include/audio.h
869 // supported sample rates
870 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
871 // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
872 // if they are different, return a list containing those two values, otherwise just the one.
873 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
874 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
875 num_written = snprintf(buffer, buffer_size, "%d", min);
876 if (min != max) {
877 snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
878 }
879 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, buffer);
880 } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
881
882 // supported channel counts
883 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
884 // Similarly for output channels count
885 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
886 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
887 num_written = snprintf(buffer, buffer_size, "%d", min);
888 if (min != max) {
889 snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
890 }
891 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_CHANNELS, buffer);
892 } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
893
894 // supported sample formats
895 if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
896 //TODO(pmclean): this is wrong.
897 min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
898 max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_SAMPLE_BITS);
899 num_written = snprintf(buffer, buffer_size, "%d", min);
900 if (min != max) {
901 snprintf(buffer + num_written, buffer_size - num_written, "|%d", max);
902 }
903 str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buffer);
904 } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
905
906 result_str = str_parms_to_str(result);
907
908 // done with these...
909 str_parms_destroy(query);
910 str_parms_destroy(result);
911
912 return result_str;
913}
914
915static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
916{
917 return 0;
918}
919
920static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
921{
922 return 0;
923}
924
925static int in_set_gain(struct audio_stream_in *stream, float gain) {
926 return 0;
927}
928
929static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes) {
930 struct stream_in * in = (struct stream_in *)stream;
931
932 int err = pcm_read(in->pcm, buffer, bytes);
933
934 return err == 0 ? bytes : 0;
935}
936
937static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) {
938 return 0;
939}
940
Mike Lockwood46a98092012-04-24 16:41:18 -0700941static int adev_open_input_stream(struct audio_hw_device *dev,
942 audio_io_handle_t handle,
943 audio_devices_t devices,
Paul McLeaneedc92e2013-12-19 15:46:15 -0800944 struct audio_config *hal_config,
Simon Wilson19957a32012-04-06 16:17:12 -0700945 struct audio_stream_in **stream_in)
946{
Paul McLeaneedc92e2013-12-19 15:46:15 -0800947 ALOGV("usb:audio_hw::in adev_open_input_stream() rate:%d, chanMask:0x%X, fmt:%d",
948 hal_config->sample_rate,
949 hal_config->channel_mask,
950 hal_config->format);
951
952 struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
953 if (in == NULL)
954 return -ENOMEM;
955
956 // setup function pointers
957 in->stream.common.get_sample_rate = in_get_sample_rate;
958 in->stream.common.set_sample_rate = in_set_sample_rate;
959 in->stream.common.get_buffer_size = in_get_buffer_size;
960 in->stream.common.get_channels = in_get_channels;
961 in->stream.common.get_format = in_get_format;
962 in->stream.common.set_format = in_set_format;
963 in->stream.common.standby = in_standby;
964 in->stream.common.dump = in_dump;
965 in->stream.common.set_parameters = in_set_parameters;
966 in->stream.common.get_parameters = in_get_parameters;
967 in->stream.common.add_audio_effect = in_add_audio_effect;
968 in->stream.common.remove_audio_effect = in_remove_audio_effect;
969
970 in->stream.set_gain = in_set_gain;
971 in->stream.read = in_read;
972 in->stream.get_input_frames_lost = in_get_input_frames_lost;
973
974 struct audio_device *adev = (struct audio_device *)dev;
975 in->dev = adev;
976
977 in->standby = true;
978 in->requested_rate = hal_config->sample_rate;
979 in->alsa_pcm_config = default_alsa_in_config;
980
981 if (hal_config->sample_rate != 0)
982 in->alsa_pcm_config.rate = hal_config->sample_rate;
983
984 //TODO(pmclean) is this correct, or do we need to map from ALSA format?
985 // hal_config->format is an audio_format_t
986 // logical
987 // hal_config->format = default_alsa_in_config.format;
988 //TODO(pmclean) use audio_format_from_pcm_format() (in hardware/audio_alsaops.h)
989 switch (default_alsa_in_config.format) {
990 case PCM_FORMAT_S32_LE:
991 hal_config->format = AUDIO_FORMAT_PCM_32_BIT;
992 break;
993
994 case PCM_FORMAT_S8:
995 hal_config->format = AUDIO_FORMAT_PCM_8_BIT;
996 break;
997
998 case PCM_FORMAT_S24_LE:
999 hal_config->format = AUDIO_FORMAT_PCM_8_24_BIT;
1000 break;
1001
1002 case PCM_FORMAT_S24_3LE:
1003 hal_config->format = AUDIO_FORMAT_PCM_8_24_BIT;
1004 break;
1005
1006 default:
1007 case PCM_FORMAT_S16_LE:
1008 hal_config->format = AUDIO_FORMAT_PCM_16_BIT;
1009 break;
1010 }
1011
1012 *stream_in = &in->stream;
1013
1014 return 0;
Simon Wilson19957a32012-04-06 16:17:12 -07001015}
1016
1017static void adev_close_input_stream(struct audio_hw_device *dev,
1018 struct audio_stream_in *stream)
1019{
1020}
1021
1022static int adev_dump(const audio_hw_device_t *device, int fd)
1023{
1024 return 0;
1025}
1026
1027static int adev_close(hw_device_t *device)
1028{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001029 ALOGV("usb:audio_hw::adev_close()");
Simon Wilson19957a32012-04-06 16:17:12 -07001030
Paul McLeaneedc92e2013-12-19 15:46:15 -08001031 struct audio_device *adev = (struct audio_device *)device;
Simon Wilson19957a32012-04-06 16:17:12 -07001032 free(device);
Paul McLeaneedc92e2013-12-19 15:46:15 -08001033
1034 output_hardware_config_is_cached = false;
1035
Simon Wilson19957a32012-04-06 16:17:12 -07001036 return 0;
1037}
1038
Simon Wilson19957a32012-04-06 16:17:12 -07001039static int adev_open(const hw_module_t* module, const char* name,
1040 hw_device_t** device)
1041{
Paul McLeaneedc92e2013-12-19 15:46:15 -08001042 // ALOGV("usb:audio_hw::adev_open(%s)", name);
Simon Wilson19957a32012-04-06 16:17:12 -07001043
1044 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1045 return -EINVAL;
1046
Paul McLeaneedc92e2013-12-19 15:46:15 -08001047 struct audio_device *adev = calloc(1, sizeof(struct audio_device));
Simon Wilson19957a32012-04-06 16:17:12 -07001048 if (!adev)
1049 return -ENOMEM;
1050
1051 adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
Eric Laurent85e08e22012-08-28 14:30:35 -07001052 adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
Simon Wilson19957a32012-04-06 16:17:12 -07001053 adev->hw_device.common.module = (struct hw_module_t *) module;
1054 adev->hw_device.common.close = adev_close;
1055
Simon Wilson19957a32012-04-06 16:17:12 -07001056 adev->hw_device.init_check = adev_init_check;
1057 adev->hw_device.set_voice_volume = adev_set_voice_volume;
1058 adev->hw_device.set_master_volume = adev_set_master_volume;
1059 adev->hw_device.set_mode = adev_set_mode;
1060 adev->hw_device.set_mic_mute = adev_set_mic_mute;
1061 adev->hw_device.get_mic_mute = adev_get_mic_mute;
1062 adev->hw_device.set_parameters = adev_set_parameters;
1063 adev->hw_device.get_parameters = adev_get_parameters;
1064 adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
1065 adev->hw_device.open_output_stream = adev_open_output_stream;
1066 adev->hw_device.close_output_stream = adev_close_output_stream;
1067 adev->hw_device.open_input_stream = adev_open_input_stream;
1068 adev->hw_device.close_input_stream = adev_close_input_stream;
1069 adev->hw_device.dump = adev_dump;
1070
1071 *device = &adev->hw_device.common;
1072
1073 return 0;
1074}
1075
1076static struct hw_module_methods_t hal_module_methods = {
1077 .open = adev_open,
1078};
1079
1080struct audio_module HAL_MODULE_INFO_SYM = {
1081 .common = {
1082 .tag = HARDWARE_MODULE_TAG,
Mike Lockwood46a98092012-04-24 16:41:18 -07001083 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
1084 .hal_api_version = HARDWARE_HAL_API_VERSION,
Simon Wilson19957a32012-04-06 16:17:12 -07001085 .id = AUDIO_HARDWARE_MODULE_ID,
1086 .name = "USB audio HW HAL",
1087 .author = "The Android Open Source Project",
1088 .methods = &hal_module_methods,
1089 },
1090};