2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "alsa_device_profile"
18 /*#define LOG_NDEBUG 0*/
19 /*#define LOG_PCM_PARAMS 0*/
28 #include "include/alsa_device_profile.h"
29 #include "include/alsa_format.h"
30 #include "include/alsa_logging.h"
32 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
34 /*TODO - Evaluate if this value should/can be retrieved from a device-specific property */
35 #define BUFF_DURATION_MS 5
37 #define DEFAULT_PERIOD_SIZE 1024
39 static const char * const format_string_map[] = {
40 "AUDIO_FORMAT_PCM_16_BIT", /* "PCM_FORMAT_S16_LE", */
41 "AUDIO_FORMAT_PCM_32_BIT", /* "PCM_FORMAT_S32_LE", */
42 "AUDIO_FORMAT_PCM_8_BIT", /* "PCM_FORMAT_S8", */
43 "AUDIO_FORMAT_PCM_8_24_BIT", /* "PCM_FORMAT_S24_LE", */
44 "AUDIO_FORMAT_PCM_24_BIT_PACKED"/* "PCM_FORMAT_S24_3LE" */
47 extern int8_t const pcm_format_value_map[50];
49 /* Sort these in terms of preference (best first).
50 192 kHz is not first because it requires significant resources for possibly worse
51 quality and driver instability (depends on device).
52 The order here determines the default sample rate for the device.
53 AudioPolicyManager may not respect this ordering when picking sample rates.
54 Update MAX_PROFILE_SAMPLE_RATES after changing the array size.
56 TODO: remove 32000, 22050, 12000, 11025? Each sample rate check
57 requires opening the device which may cause pops. */
58 static const unsigned std_sample_rates[] =
59 {96000, 88200, 192000, 176400, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
61 static void profile_reset(alsa_device_profile* profile)
63 profile->card = profile->device = -1;
65 /* terminate the attribute arrays with invalid values */
66 profile->formats[0] = PCM_FORMAT_INVALID;
67 profile->sample_rates[0] = 0;
68 profile->channel_counts[0] = 0;
70 profile->min_period_size = profile->max_period_size = 0;
71 profile->min_channel_count = profile->max_channel_count = DEFAULT_CHANNEL_COUNT;
73 profile->is_valid = false;
76 void profile_init(alsa_device_profile* profile, int direction)
78 profile->direction = direction;
79 profile_reset(profile);
82 bool profile_is_initialized(alsa_device_profile* profile)
84 return profile->card >= 0 && profile->device >= 0;
87 bool profile_is_valid(alsa_device_profile* profile) {
88 return profile->is_valid;
91 bool profile_is_cached_for(alsa_device_profile* profile, int card, int device) {
92 return card == profile->card && device == profile->device;
95 void profile_decache(alsa_device_profile* profile) {
96 profile_reset(profile);
100 * Returns the supplied value rounded up to the next even multiple of 16
102 static unsigned int round_to_16_mult(unsigned int size)
104 return (size + 15) & ~15; /* 0xFFFFFFF0; */
108 * Returns the system defined minimum period size based on the supplied sample rate.
110 unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate)
112 ALOGV("profile_calc_min_period_size(%p, rate:%d)", profile, sample_rate);
113 if (profile == NULL) {
114 return DEFAULT_PERIOD_SIZE;
116 unsigned num_sample_frames = (sample_rate * BUFF_DURATION_MS) / 1000;
117 if (num_sample_frames < profile->min_period_size) {
118 num_sample_frames = profile->min_period_size;
120 return round_to_16_mult(num_sample_frames) * 2;
124 unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate)
126 unsigned int period_size = profile_calc_min_period_size(profile, sample_rate);
127 ALOGV("profile_get_period_size(rate:%d) = %d", sample_rate, period_size);
134 unsigned profile_get_default_sample_rate(alsa_device_profile* profile)
137 * TODO this won't be right in general. we should store a preferred rate as we are scanning.
138 * But right now it will return the highest rate, which may be correct.
140 return profile_is_valid(profile) ? profile->sample_rates[0] : DEFAULT_SAMPLE_RATE;
143 bool profile_is_sample_rate_valid(alsa_device_profile* profile, unsigned rate)
145 if (profile_is_valid(profile)) {
147 for (index = 0; profile->sample_rates[index] != 0; index++) {
148 if (profile->sample_rates[index] == rate) {
155 return rate == DEFAULT_SAMPLE_RATE;
162 enum pcm_format profile_get_default_format(alsa_device_profile* profile)
165 * TODO this won't be right in general. we should store a preferred format as we are scanning.
167 return profile_is_valid(profile) ? profile->formats[0] : DEFAULT_SAMPLE_FORMAT;
170 bool profile_is_format_valid(alsa_device_profile* profile, enum pcm_format fmt) {
171 if (profile_is_valid(profile)) {
173 for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
174 if (profile->formats[index] == fmt) {
181 return fmt == DEFAULT_SAMPLE_FORMAT;
188 unsigned profile_get_default_channel_count(alsa_device_profile* profile)
190 return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
193 bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
195 if (profile_is_initialized(profile)) {
196 return count >= profile->min_channel_count && count <= profile->max_channel_count;
198 return count == DEFAULT_CHANNEL_COUNT;
202 static bool profile_test_sample_rate(alsa_device_profile* profile, unsigned rate)
204 struct pcm_config config = profile->default_config;
207 bool works = false; /* let's be pessimistic */
208 struct pcm * pcm = pcm_open(profile->card, profile->device,
209 profile->direction, &config);
212 works = pcm_is_ready(pcm);
219 static unsigned profile_enum_sample_rates(alsa_device_profile* profile, unsigned min, unsigned max)
221 unsigned num_entries = 0;
224 for (index = 0; index < ARRAY_SIZE(std_sample_rates) &&
225 num_entries < ARRAY_SIZE(profile->sample_rates) - 1;
227 if (std_sample_rates[index] >= min && std_sample_rates[index] <= max
228 && profile_test_sample_rate(profile, std_sample_rates[index])) {
229 profile->sample_rates[num_entries++] = std_sample_rates[index];
232 profile->sample_rates[num_entries] = 0; /* terminate */
233 return num_entries; /* return # of supported rates */
236 static unsigned profile_enum_sample_formats(alsa_device_profile* profile, struct pcm_mask * mask)
238 const int num_slots = ARRAY_SIZE(mask->bits);
239 const int bits_per_slot = sizeof(mask->bits[0]) * 8;
241 const int table_size = ARRAY_SIZE(pcm_format_value_map);
243 int slot_index, bit_index, table_index;
246 for (slot_index = 0; slot_index < num_slots && table_index < table_size;
248 unsigned bit_mask = 1;
250 bit_index < bits_per_slot && table_index < table_size;
252 if ((mask->bits[slot_index] & bit_mask) != 0) {
253 enum pcm_format format = pcm_format_value_map[table_index];
254 /* Never return invalid (unrecognized) or 8-bit */
255 if (format != PCM_FORMAT_INVALID && format != PCM_FORMAT_S8) {
256 profile->formats[num_written++] = format;
257 if (num_written == ARRAY_SIZE(profile->formats) - 1) {
258 /* leave at least one PCM_FORMAT_INVALID at the end */
268 profile->formats[num_written] = PCM_FORMAT_INVALID;
272 static unsigned profile_enum_channel_counts(alsa_device_profile* profile, unsigned min,
275 /* modify alsa_device_profile.h if you change the std_channel_counts[] array. */
276 static const unsigned std_channel_counts[] = {8, 7, 6, 5, 4, 3, 2, 1};
278 unsigned num_counts = 0;
280 /* TODO write a profile_test_channel_count() */
281 /* Ensure there is at least one invalid channel count to terminate the channel counts array */
282 for (index = 0; index < ARRAY_SIZE(std_channel_counts) &&
283 num_counts < ARRAY_SIZE(profile->channel_counts) - 1;
285 /* TODO Do we want a channel counts test? */
286 if (std_channel_counts[index] >= min && std_channel_counts[index] <= max /* &&
287 profile_test_channel_count(profile, channel_counts[index])*/) {
288 profile->channel_counts[num_counts++] = std_channel_counts[index];
291 // if we have no match with the standard counts, we use the largest (preferred) std count.
292 if (num_counts == 0) {
293 ALOGW("usb device does not match std channel counts, setting to %d",
294 std_channel_counts[0]);
295 profile->channel_counts[num_counts++] = std_channel_counts[0];
297 profile->channel_counts[num_counts] = 0;
298 return num_counts; /* return # of supported counts */
302 * Reads and decodes configuration info from the specified ALSA card/device.
304 static int read_alsa_device_config(alsa_device_profile * profile, struct pcm_config * config)
306 ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
307 profile->card, profile->device, profile->direction);
309 if (profile->card < 0 || profile->device < 0) {
313 struct pcm_params * alsa_hw_params =
314 pcm_params_get(profile->card, profile->device, profile->direction);
315 if (alsa_hw_params == NULL) {
319 profile->min_period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
320 profile->max_period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
322 profile->min_channel_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
323 profile->max_channel_count = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
328 * This Logging will be useful when testing new USB devices.
330 #ifdef LOG_PCM_PARAMS
331 log_pcm_params(alsa_hw_params);
334 config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
335 // For output devices, let's make sure we choose at least stereo
336 // (assuming the device supports it).
337 if (profile->direction == PCM_OUT &&
338 config->channels < 2 && pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS) >= 2) {
339 config->channels = 2;
341 config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
342 // Prefer 48K or 44.1K
343 if (config->rate < 48000 &&
344 pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE) >= 48000) {
345 config->rate = 48000;
346 } else if (config->rate < 441000 &&
347 pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE) >= 44100) {
348 config->rate = 44100;
350 config->period_size = profile_calc_min_period_size(profile, config->rate);
351 config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
352 config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
353 #ifdef LOG_PCM_PARAMS
354 log_pcm_config(config, "read_alsa_device_config");
356 if (config->format == PCM_FORMAT_INVALID) {
360 pcm_params_free(alsa_hw_params);
365 bool profile_read_device_info(alsa_device_profile* profile)
367 if (!profile_is_initialized(profile)) {
371 /* let's get some defaults */
372 read_alsa_device_config(profile, &profile->default_config);
373 ALOGV("default_config chans:%d rate:%d format:%d count:%d size:%d",
374 profile->default_config.channels, profile->default_config.rate,
375 profile->default_config.format, profile->default_config.period_count,
376 profile->default_config.period_size);
378 struct pcm_params * alsa_hw_params = pcm_params_get(profile->card,
381 if (alsa_hw_params == NULL) {
386 struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
387 profile_enum_sample_formats(profile, format_mask);
390 profile_enum_channel_counts(
391 profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
392 pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
395 profile_enum_sample_rates(
396 profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
397 pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
399 profile->is_valid = true;
404 char * profile_get_sample_rate_strs(alsa_device_profile* profile)
406 /* if we assume that rate strings are about 5 characters (48000 is 5), plus ~1 for a
407 * delimiter "|" this buffer has room for about 22 rate strings which seems like
408 * way too much, but it's a stack variable so only temporary.
412 size_t buffSize = ARRAY_SIZE(buffer);
413 size_t curStrLen = 0;
417 size_t numEntries = 0;
419 for (index = 0; profile->sample_rates[index] != 0; index++) {
420 snprintf(numBuffer, sizeof(numBuffer), "%u", profile->sample_rates[index]);
421 // account for both the null, and potentially the bar.
422 if (buffSize - curStrLen < strlen(numBuffer) + (numEntries != 0 ? 2 : 1)) {
423 /* we don't have room for another, so bail at this point rather than
424 * return a malformed rate string
428 if (numEntries++ != 0) {
429 strlcat(buffer, "|", buffSize);
431 curStrLen = strlcat(buffer, numBuffer, buffSize);
434 return strdup(buffer);
437 char * profile_get_format_strs(alsa_device_profile* profile)
439 /* if we assume that format strings are about 24 characters (AUDIO_FORMAT_PCM_16_BIT is 23),
440 * plus ~1 for a delimiter "|" this buffer has room for about 10 format strings which seems
441 * like way too much, but it's a stack variable so only temporary.
445 size_t buffSize = ARRAY_SIZE(buffer);
446 size_t curStrLen = 0;
448 size_t numEntries = 0;
450 for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
451 // account for both the null, and potentially the bar.
452 if (buffSize - curStrLen < strlen(format_string_map[profile->formats[index]])
453 + (numEntries != 0 ? 2 : 1)) {
454 /* we don't have room for another, so bail at this point rather than
455 * return a malformed rate string
459 if (numEntries++ != 0) {
460 strlcat(buffer, "|", buffSize);
462 curStrLen = strlcat(buffer, format_string_map[profile->formats[index]], buffSize);
465 return strdup(buffer);
468 char * profile_get_channel_count_strs(alsa_device_profile* profile)
470 // FIXME implicit fixed channel count assumption here (FCC_8).
471 // we use only the canonical even number channel position masks.
472 static const char * const out_chans_strs[] = {
473 /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
474 /* 1 */"AUDIO_CHANNEL_OUT_MONO",
475 /* 2 */"AUDIO_CHANNEL_OUT_STEREO",
476 /* 3 */ /* "AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
477 /* 4 */"AUDIO_CHANNEL_OUT_QUAD",
478 /* 5 */ /* "AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
479 /* 6 */"AUDIO_CHANNEL_OUT_5POINT1",
480 /* 7 */ /* "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_BACK_CENTER" */ NULL,
481 /* 8 */"AUDIO_CHANNEL_OUT_7POINT1",
482 /* channel counts greater than this not considered */
485 static const char * const in_chans_strs[] = {
486 /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
487 /* 1 */"AUDIO_CHANNEL_IN_MONO",
488 /* 2 */"AUDIO_CHANNEL_IN_STEREO",
489 /* channel counts greater than this not considered */
492 static const char * const index_chans_strs[] = {
493 /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
494 /* 1 */"AUDIO_CHANNEL_INDEX_MASK_1",
495 /* 2 */"AUDIO_CHANNEL_INDEX_MASK_2",
496 /* 3 */"AUDIO_CHANNEL_INDEX_MASK_3",
497 /* 4 */"AUDIO_CHANNEL_INDEX_MASK_4",
498 /* 5 */"AUDIO_CHANNEL_INDEX_MASK_5",
499 /* 6 */"AUDIO_CHANNEL_INDEX_MASK_6",
500 /* 7 */"AUDIO_CHANNEL_INDEX_MASK_7",
501 /* 8 */"AUDIO_CHANNEL_INDEX_MASK_8",
504 const bool isOutProfile = profile->direction == PCM_OUT;
506 const char * const * const chans_strs = isOutProfile ? out_chans_strs : in_chans_strs;
507 const size_t chans_strs_size =
508 isOutProfile ? ARRAY_SIZE(out_chans_strs) : ARRAY_SIZE(in_chans_strs);
511 * If we assume each channel string is 26 chars ("AUDIO_CHANNEL_INDEX_MASK_8" is 26) + 1 for,
512 * the "|" delimiter, then we allocate room for 16 strings.
514 char buffer[27 * 16 + 1]; /* caution, may need to be expanded */
516 size_t buffSize = ARRAY_SIZE(buffer);
517 size_t curStrLen = 0;
519 /* We currently support MONO and STEREO, and always report STEREO but some (many)
520 * USB Audio Devices may only announce support for MONO (a headset mic for example), or
521 * The total number of output channels. SO, if the device itself doesn't explicitly
522 * support STEREO, append to the channel config strings we are generating.
524 * The MONO and STEREO positional channel masks are provided for legacy compatibility.
525 * For multichannel (n > 2) we only expose channel index masks.
527 // Always support stereo
528 curStrLen = strlcat(buffer, chans_strs[2], buffSize);
531 unsigned channel_count;
533 (channel_count = profile->channel_counts[index]) != 0;
536 /* we only show positional information for mono (stereo handled already) */
537 if (channel_count < chans_strs_size
538 && chans_strs[channel_count] != NULL
539 && channel_count < 2 /* positional only for fewer than 2 channels */) {
540 // account for the '|' and the '\0'
541 if (buffSize - curStrLen < strlen(chans_strs[channel_count]) + 2) {
542 /* we don't have room for another, so bail at this point rather than
543 * return a malformed rate string
548 strlcat(buffer, "|", buffSize);
549 curStrLen = strlcat(buffer, chans_strs[channel_count], buffSize);
552 // handle channel index masks for both input and output
553 // +2 to account for the '|' and the '\0'
554 if (buffSize - curStrLen < strlen(index_chans_strs[channel_count]) + 2) {
555 /* we don't have room for another, so bail at this point rather than
556 * return a malformed rate string
561 strlcat(buffer, "|", buffSize);
562 curStrLen = strlcat(buffer, index_chans_strs[channel_count], buffSize);
565 return strdup(buffer);