OSDN Git Service

Update USB alsa to only use channel index masks for multichannel
[android-x86/system-media.git] / alsa_utils / alsa_device_profile.c
1 /*
2  * Copyright (C) 2014 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 "alsa_device_profile"
18 /*#define LOG_NDEBUG 0*/
19 /*#define LOG_PCM_PARAMS 0*/
20
21 #include <errno.h>
22 #include <inttypes.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25
26 #include <log/log.h>
27
28 #include "include/alsa_device_profile.h"
29 #include "include/alsa_format.h"
30 #include "include/alsa_logging.h"
31
32 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
33
34 /*TODO - Evaluate if this value should/can be retrieved from a device-specific property */
35 #define BUFF_DURATION_MS   5
36
37 #define DEFAULT_PERIOD_SIZE 1024
38
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" */
45 };
46
47 static const unsigned const format_byte_size_map[] = {
48     2, /* PCM_FORMAT_S16_LE */
49     4, /* PCM_FORMAT_S32_LE */
50     1, /* PCM_FORMAT_S8 */
51     4, /* PCM_FORMAT_S24_LE */
52     3, /* PCM_FORMAT_S24_3LE */
53 };
54
55 extern int8_t const pcm_format_value_map[50];
56
57 /* Sort these in terms of preference (best first).
58    192 kHz is not first because it requires significant resources for possibly worse
59    quality and driver instability (depends on device).
60    The order here determines the default sample rate for the device.
61    AudioPolicyManager may not respect this ordering when picking sample rates.
62    Update MAX_PROFILE_SAMPLE_RATES after changing the array size.
63
64    TODO: remove 32000, 22050, 12000, 11025?  Each sample rate check
65    requires opening the device which may cause pops. */
66 static const unsigned std_sample_rates[] =
67     {96000, 88200, 192000, 176400, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
68
69 static void profile_reset(alsa_device_profile* profile)
70 {
71     profile->card = profile->device = -1;
72
73     /* terminate the attribute arrays with invalid values */
74     profile->formats[0] = PCM_FORMAT_INVALID;
75     profile->sample_rates[0] = 0;
76     profile->channel_counts[0] = 0;
77
78     profile->min_period_size = profile->max_period_size = 0;
79     profile->min_channel_count = profile->max_channel_count = DEFAULT_CHANNEL_COUNT;
80
81     profile->is_valid = false;
82 }
83
84 void profile_init(alsa_device_profile* profile, int direction)
85 {
86     profile->direction = direction;
87     profile_reset(profile);
88 }
89
90 bool profile_is_initialized(alsa_device_profile* profile)
91 {
92     return profile->card >= 0 && profile->device >= 0;
93 }
94
95 bool profile_is_valid(alsa_device_profile* profile) {
96     return profile->is_valid;
97 }
98
99 bool profile_is_cached_for(alsa_device_profile* profile, int card, int device) {
100     return card == profile->card && device == profile->device;
101 }
102
103 void profile_decache(alsa_device_profile* profile) {
104     profile_reset(profile);
105 }
106
107 /*
108  * Returns the supplied value rounded up to the next even multiple of 16
109  */
110 static unsigned int round_to_16_mult(unsigned int size)
111 {
112     return (size + 15) & ~15;   /* 0xFFFFFFF0; */
113 }
114
115 /*
116  * Returns the system defined minimum period size based on the supplied sample rate.
117  */
118 unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate)
119 {
120     ALOGV("profile_calc_min_period_size(%p, rate:%d)", profile, sample_rate);
121     if (profile == NULL) {
122         return DEFAULT_PERIOD_SIZE;
123     } else {
124         unsigned num_sample_frames = (sample_rate * BUFF_DURATION_MS) / 1000;
125         if (num_sample_frames < profile->min_period_size) {
126             num_sample_frames = profile->min_period_size;
127         }
128         return round_to_16_mult(num_sample_frames) * 2;
129     }
130 }
131
132 unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate)
133 {
134     unsigned int period_size = profile_calc_min_period_size(profile, sample_rate);
135     ALOGV("profile_get_period_size(rate:%d) = %d", sample_rate, period_size);
136     return period_size;
137 }
138
139 /*
140  * Sample Rate
141  */
142 unsigned profile_get_default_sample_rate(alsa_device_profile* profile)
143 {
144     /*
145      * TODO this won't be right in general. we should store a preferred rate as we are scanning.
146      * But right now it will return the highest rate, which may be correct.
147      */
148     return profile_is_valid(profile) ? profile->sample_rates[0] : DEFAULT_SAMPLE_RATE;
149 }
150
151 bool profile_is_sample_rate_valid(alsa_device_profile* profile, unsigned rate)
152 {
153     if (profile_is_valid(profile)) {
154         size_t index;
155         for (index = 0; profile->sample_rates[index] != 0; index++) {
156             if (profile->sample_rates[index] == rate) {
157                 return true;
158             }
159         }
160
161         return false;
162     } else {
163         return rate == DEFAULT_SAMPLE_RATE;
164     }
165 }
166
167 /*
168  * Format
169  */
170 enum pcm_format profile_get_default_format(alsa_device_profile* profile)
171 {
172     /*
173      * TODO this won't be right in general. we should store a preferred format as we are scanning.
174      */
175     return profile_is_valid(profile) ? profile->formats[0] : DEFAULT_SAMPLE_FORMAT;
176 }
177
178 bool profile_is_format_valid(alsa_device_profile* profile, enum pcm_format fmt) {
179     if (profile_is_valid(profile)) {
180         size_t index;
181         for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
182             if (profile->formats[index] == fmt) {
183                 return true;
184             }
185         }
186
187         return false;
188     } else {
189         return fmt == DEFAULT_SAMPLE_FORMAT;
190     }
191 }
192
193 /*
194  * Channels
195  */
196 unsigned profile_get_default_channel_count(alsa_device_profile* profile)
197 {
198     return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
199 }
200
201 bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
202 {
203     if (profile_is_initialized(profile)) {
204         return count >= profile->min_channel_count && count <= profile->max_channel_count;
205     } else {
206         return count == DEFAULT_CHANNEL_COUNT;
207     }
208 }
209
210 static bool profile_test_sample_rate(alsa_device_profile* profile, unsigned rate)
211 {
212     struct pcm_config config = profile->default_config;
213     config.rate = rate;
214
215     bool works = false; /* let's be pessimistic */
216     struct pcm * pcm = pcm_open(profile->card, profile->device,
217                                 profile->direction, &config);
218
219     if (pcm != NULL) {
220         works = pcm_is_ready(pcm);
221         pcm_close(pcm);
222     }
223
224     return works;
225 }
226
227 static unsigned profile_enum_sample_rates(alsa_device_profile* profile, unsigned min, unsigned max)
228 {
229     unsigned num_entries = 0;
230     unsigned index;
231
232     for (index = 0; index < ARRAY_SIZE(std_sample_rates) &&
233                     num_entries < ARRAY_SIZE(profile->sample_rates) - 1;
234          index++) {
235         if (std_sample_rates[index] >= min && std_sample_rates[index] <= max
236                 && profile_test_sample_rate(profile, std_sample_rates[index])) {
237             profile->sample_rates[num_entries++] = std_sample_rates[index];
238         }
239     }
240     profile->sample_rates[num_entries] = 0; /* terminate */
241     return num_entries; /* return # of supported rates */
242 }
243
244 static unsigned profile_enum_sample_formats(alsa_device_profile* profile, struct pcm_mask * mask)
245 {
246     const int num_slots = ARRAY_SIZE(mask->bits);
247     const int bits_per_slot = sizeof(mask->bits[0]) * 8;
248
249     const int table_size = ARRAY_SIZE(pcm_format_value_map);
250
251     int slot_index, bit_index, table_index;
252     table_index = 0;
253     int num_written = 0;
254     for (slot_index = 0; slot_index < num_slots && table_index < table_size;
255             slot_index++) {
256         unsigned bit_mask = 1;
257         for (bit_index = 0;
258                 bit_index < bits_per_slot && table_index < table_size;
259                 bit_index++) {
260             if ((mask->bits[slot_index] & bit_mask) != 0) {
261                 enum pcm_format format = pcm_format_value_map[table_index];
262                 /* Never return invalid (unrecognized) or 8-bit */
263                 if (format != PCM_FORMAT_INVALID && format != PCM_FORMAT_S8) {
264                     profile->formats[num_written++] = format;
265                     if (num_written == ARRAY_SIZE(profile->formats) - 1) {
266                         /* leave at least one PCM_FORMAT_INVALID at the end */
267                         goto end;
268                     }
269                 }
270             }
271             bit_mask <<= 1;
272             table_index++;
273         }
274     }
275 end:
276     profile->formats[num_written] = PCM_FORMAT_INVALID;
277     return num_written;
278 }
279
280 static unsigned profile_enum_channel_counts(alsa_device_profile* profile, unsigned min,
281         unsigned max)
282 {
283     /* modify alsa_device_profile.h if you change the std_channel_counts[] array. */
284     static const unsigned std_channel_counts[] = {8, 7, 6, 5, 4, 3, 2, 1};
285
286     unsigned num_counts = 0;
287     unsigned index;
288     /* TODO write a profile_test_channel_count() */
289     /* Ensure there is at least one invalid channel count to terminate the channel counts array */
290     for (index = 0; index < ARRAY_SIZE(std_channel_counts) &&
291                     num_counts < ARRAY_SIZE(profile->channel_counts) - 1;
292          index++) {
293         /* TODO Do we want a channel counts test? */
294         if (std_channel_counts[index] >= min && std_channel_counts[index] <= max /* &&
295             profile_test_channel_count(profile, channel_counts[index])*/) {
296             profile->channel_counts[num_counts++] = std_channel_counts[index];
297         }
298     }
299     profile->channel_counts[num_counts] = 0;
300     return num_counts; /* return # of supported counts */
301 }
302
303 /*
304  * Reads and decodes configuration info from the specified ALSA card/device.
305  */
306 static int read_alsa_device_config(alsa_device_profile * profile, struct pcm_config * config)
307 {
308     ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
309           profile->card, profile->device, profile->direction);
310
311     if (profile->card < 0 || profile->device < 0) {
312         return -EINVAL;
313     }
314
315     struct pcm_params * alsa_hw_params =
316         pcm_params_get(profile->card, profile->device, profile->direction);
317     if (alsa_hw_params == NULL) {
318         return -EINVAL;
319     }
320
321     profile->min_period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
322     profile->max_period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
323
324     profile->min_channel_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
325     profile->max_channel_count = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
326
327     int ret = 0;
328
329     /*
330      * This Logging will be useful when testing new USB devices.
331      */
332 #ifdef LOG_PCM_PARAMS
333     log_pcm_params(alsa_hw_params);
334 #endif
335
336     config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
337     config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
338     config->period_size = profile_calc_min_period_size(profile, config->rate);
339     config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
340     config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
341 #ifdef LOG_PCM_PARAMS
342     log_pcm_config(config, "read_alsa_device_config");
343 #endif
344     if (config->format == PCM_FORMAT_INVALID) {
345         ret = -EINVAL;
346     }
347
348     pcm_params_free(alsa_hw_params);
349
350     return ret;
351 }
352
353 bool profile_read_device_info(alsa_device_profile* profile)
354 {
355     if (!profile_is_initialized(profile)) {
356         return false;
357     }
358
359     /* let's get some defaults */
360     read_alsa_device_config(profile, &profile->default_config);
361     ALOGV("default_config chans:%d rate:%d format:%d count:%d size:%d",
362           profile->default_config.channels, profile->default_config.rate,
363           profile->default_config.format, profile->default_config.period_count,
364           profile->default_config.period_size);
365
366     struct pcm_params * alsa_hw_params = pcm_params_get(profile->card,
367                                                         profile->device,
368                                                         profile->direction);
369     if (alsa_hw_params == NULL) {
370         return false;
371     }
372
373     /* Formats */
374     struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
375     profile_enum_sample_formats(profile, format_mask);
376
377     /* Channels */
378     profile_enum_channel_counts(
379             profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
380             pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
381
382     /* Sample Rates */
383     profile_enum_sample_rates(
384             profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
385             pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
386
387     profile->is_valid = true;
388
389     return true;
390 }
391
392 char * profile_get_sample_rate_strs(alsa_device_profile* profile)
393 {
394     /* if we assume that rate strings are about 5 characters (48000 is 5), plus ~1 for a
395      * delimiter "|" this buffer has room for about 22 rate strings which seems like
396      * way too much, but it's a stack variable so only temporary.
397      */
398     char buffer[128];
399     buffer[0] = '\0';
400     size_t buffSize = ARRAY_SIZE(buffer);
401     size_t curStrLen = 0;
402
403     char numBuffer[32];
404
405     size_t numEntries = 0;
406     size_t index;
407     for (index = 0; profile->sample_rates[index] != 0; index++) {
408         snprintf(numBuffer, sizeof(numBuffer), "%u", profile->sample_rates[index]);
409         // account for both the null, and potentially the bar.
410         if (buffSize - curStrLen < strlen(numBuffer) + (numEntries != 0 ? 2 : 1)) {
411             /* we don't have room for another, so bail at this point rather than
412              * return a malformed rate string
413              */
414             break;
415         }
416         if (numEntries++ != 0) {
417             strlcat(buffer, "|", buffSize);
418         }
419         curStrLen = strlcat(buffer, numBuffer, buffSize);
420     }
421
422     return strdup(buffer);
423 }
424
425 char * profile_get_format_strs(alsa_device_profile* profile)
426 {
427     /* if we assume that format strings are about 24 characters (AUDIO_FORMAT_PCM_16_BIT is 23),
428      * plus ~1 for a delimiter "|" this buffer has room for about 10 format strings which seems
429      *  like way too much, but it's a stack variable so only temporary.
430      */
431     char buffer[256];
432     buffer[0] = '\0';
433     size_t buffSize = ARRAY_SIZE(buffer);
434     size_t curStrLen = 0;
435
436     size_t numEntries = 0;
437     size_t index = 0;
438     for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
439         // account for both the null, and potentially the bar.
440         if (buffSize - curStrLen < strlen(format_string_map[profile->formats[index]])
441                                    + (numEntries != 0 ? 2 : 1)) {
442             /* we don't have room for another, so bail at this point rather than
443              * return a malformed rate string
444              */
445             break;
446         }
447         if (numEntries++ != 0) {
448             strlcat(buffer, "|", buffSize);
449         }
450         curStrLen = strlcat(buffer, format_string_map[profile->formats[index]], buffSize);
451     }
452
453     return strdup(buffer);
454 }
455
456 char * profile_get_channel_count_strs(alsa_device_profile* profile)
457 {
458     // FIXME implicit fixed channel count assumption here (FCC_8).
459     // we use only the canonical even number channel position masks.
460     static const char * const out_chans_strs[] = {
461         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
462         /* 1 */"AUDIO_CHANNEL_OUT_MONO",
463         /* 2 */"AUDIO_CHANNEL_OUT_STEREO",
464         /* 3 */ /* "AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
465         /* 4 */"AUDIO_CHANNEL_OUT_QUAD",
466         /* 5 */ /* "AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
467         /* 6 */"AUDIO_CHANNEL_OUT_5POINT1",
468         /* 7 */ /* "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_BACK_CENTER" */ NULL,
469         /* 8 */"AUDIO_CHANNEL_OUT_7POINT1",
470         /* channel counts greater than this not considered */
471     };
472
473     static const char * const in_chans_strs[] = {
474         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
475         /* 1 */"AUDIO_CHANNEL_IN_MONO",
476         /* 2 */"AUDIO_CHANNEL_IN_STEREO",
477         /* channel counts greater than this not considered */
478     };
479
480     static const char * const index_chans_strs[] = {
481         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
482         /* 1 */"AUDIO_CHANNEL_INDEX_MASK_1",
483         /* 2 */"AUDIO_CHANNEL_INDEX_MASK_2",
484         /* 3 */"AUDIO_CHANNEL_INDEX_MASK_3",
485         /* 4 */"AUDIO_CHANNEL_INDEX_MASK_4",
486         /* 5 */"AUDIO_CHANNEL_INDEX_MASK_5",
487         /* 6 */"AUDIO_CHANNEL_INDEX_MASK_6",
488         /* 7 */"AUDIO_CHANNEL_INDEX_MASK_7",
489         /* 8 */"AUDIO_CHANNEL_INDEX_MASK_8",
490     };
491
492     const bool isOutProfile = profile->direction == PCM_OUT;
493
494     const char * const * const chans_strs = isOutProfile ? out_chans_strs : in_chans_strs;
495     const size_t chans_strs_size =
496             isOutProfile ? ARRAY_SIZE(out_chans_strs) : ARRAY_SIZE(in_chans_strs);
497
498     /*
499      * If we assume each channel string is 26 chars ("AUDIO_CHANNEL_INDEX_MASK_8" is 26) + 1 for,
500      * the "|" delimiter, then we allocate room for 16 strings.
501      */
502     char buffer[27 * 16 + 1]; /* caution, may need to be expanded */
503     buffer[0] = '\0';
504     size_t buffSize = ARRAY_SIZE(buffer);
505     size_t curStrLen = 0;
506
507     /* We currently support MONO and STEREO, and always report STEREO but some (many)
508      * USB Audio Devices may only announce support for MONO (a headset mic for example), or
509      * The total number of output channels. SO, if the device itself doesn't explicitly
510      * support STEREO, append to the channel config strings we are generating.
511      *
512      * The MONO and STEREO positional channel masks are provided for legacy compatibility.
513      * For multichannel (n > 2) we only expose channel index masks.
514      */
515     // Always support stereo
516     curStrLen = strlcat(buffer, chans_strs[2], buffSize);
517
518     size_t index;
519     unsigned channel_count;
520     for (index = 0;
521          (channel_count = profile->channel_counts[index]) != 0;
522          index++) {
523
524         /* we only show positional information for mono (stereo handled already) */
525         if (channel_count < chans_strs_size
526                 && chans_strs[channel_count] != NULL
527                 && channel_count < 2 /* positional only for fewer than 2 channels */) {
528             // account for the '|' and the '\0'
529             if (buffSize - curStrLen < strlen(chans_strs[channel_count]) + 2) {
530                 /* we don't have room for another, so bail at this point rather than
531                  * return a malformed rate string
532                  */
533                 break;
534             }
535
536             strlcat(buffer, "|", buffSize);
537             curStrLen = strlcat(buffer, chans_strs[channel_count], buffSize);
538         }
539
540         // handle channel index masks for both input and output
541         // +2 to account for the '|' and the '\0'
542          if (buffSize - curStrLen < strlen(index_chans_strs[channel_count]) + 2) {
543              /* we don't have room for another, so bail at this point rather than
544               * return a malformed rate string
545               */
546              break;
547          }
548
549          strlcat(buffer, "|", buffSize);
550          curStrLen = strlcat(buffer, index_chans_strs[channel_count], buffSize);
551     }
552
553     return strdup(buffer);
554 }