OSDN Git Service

Allow up to 192kHz sampling rate for usb
[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     static const unsigned std_channel_counts[] = {8, 4, 2, 1};
284
285     unsigned num_counts = 0;
286     unsigned index;
287     /* TODO write a profile_test_channel_count() */
288     /* Ensure there is at least one invalid channel count to terminate the channel counts array */
289     for (index = 0; index < ARRAY_SIZE(std_channel_counts) &&
290                     num_counts < ARRAY_SIZE(profile->channel_counts) - 1;
291          index++) {
292         /* TODO Do we want a channel counts test? */
293         if (std_channel_counts[index] >= min && std_channel_counts[index] <= max /* &&
294             profile_test_channel_count(profile, channel_counts[index])*/) {
295             profile->channel_counts[num_counts++] = std_channel_counts[index];
296         }
297     }
298     profile->channel_counts[num_counts] = 0;
299     return num_counts; /* return # of supported counts */
300 }
301
302 /*
303  * Reads and decodes configuration info from the specified ALSA card/device.
304  */
305 static int read_alsa_device_config(alsa_device_profile * profile, struct pcm_config * config)
306 {
307     ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
308           profile->card, profile->device, profile->direction);
309
310     if (profile->card < 0 || profile->device < 0) {
311         return -EINVAL;
312     }
313
314     struct pcm_params * alsa_hw_params =
315         pcm_params_get(profile->card, profile->device, profile->direction);
316     if (alsa_hw_params == NULL) {
317         return -EINVAL;
318     }
319
320     profile->min_period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
321     profile->max_period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
322
323     profile->min_channel_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
324     profile->max_channel_count = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
325
326     int ret = 0;
327
328     /*
329      * This Logging will be useful when testing new USB devices.
330      */
331 #ifdef LOG_PCM_PARAMS
332     log_pcm_params(alsa_hw_params);
333 #endif
334
335     config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
336     config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
337     config->period_size = profile_calc_min_period_size(profile, config->rate);
338     config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
339     config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
340 #ifdef LOG_PCM_PARAMS
341     log_pcm_config(config, "read_alsa_device_config");
342 #endif
343     if (config->format == PCM_FORMAT_INVALID) {
344         ret = -EINVAL;
345     }
346
347     pcm_params_free(alsa_hw_params);
348
349     return ret;
350 }
351
352 bool profile_read_device_info(alsa_device_profile* profile)
353 {
354     if (!profile_is_initialized(profile)) {
355         return false;
356     }
357
358     /* let's get some defaults */
359     read_alsa_device_config(profile, &profile->default_config);
360     ALOGV("default_config chans:%d rate:%d format:%d count:%d size:%d",
361           profile->default_config.channels, profile->default_config.rate,
362           profile->default_config.format, profile->default_config.period_count,
363           profile->default_config.period_size);
364
365     struct pcm_params * alsa_hw_params = pcm_params_get(profile->card,
366                                                         profile->device,
367                                                         profile->direction);
368     if (alsa_hw_params == NULL) {
369         return false;
370     }
371
372     /* Formats */
373     struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
374     profile_enum_sample_formats(profile, format_mask);
375
376     /* Channels */
377     profile_enum_channel_counts(
378             profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
379             pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));
380
381     /* Sample Rates */
382     profile_enum_sample_rates(
383             profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
384             pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));
385
386     profile->is_valid = true;
387
388     return true;
389 }
390
391 char * profile_get_sample_rate_strs(alsa_device_profile* profile)
392 {
393     /* if we assume that rate strings are about 5 characters (48000 is 5), plus ~1 for a
394      * delimiter "|" this buffer has room for about 22 rate strings which seems like
395      * way too much, but it's a stack variable so only temporary.
396      */
397     char buffer[128];
398     buffer[0] = '\0';
399     size_t buffSize = ARRAY_SIZE(buffer);
400     size_t curStrLen = 0;
401
402     char numBuffer[32];
403
404     size_t numEntries = 0;
405     size_t index;
406     for (index = 0; profile->sample_rates[index] != 0; index++) {
407         snprintf(numBuffer, sizeof(numBuffer), "%u", profile->sample_rates[index]);
408         // account for both the null, and potentially the bar.
409         if (buffSize - curStrLen < strlen(numBuffer) + (numEntries != 0 ? 2 : 1)) {
410             /* we don't have room for another, so bail at this point rather than
411              * return a malformed rate string
412              */
413             break;
414         }
415         if (numEntries++ != 0) {
416             strlcat(buffer, "|", buffSize);
417         }
418         curStrLen = strlcat(buffer, numBuffer, buffSize);
419     }
420
421     return strdup(buffer);
422 }
423
424 char * profile_get_format_strs(alsa_device_profile* profile)
425 {
426     /* if we assume that format strings are about 24 characters (AUDIO_FORMAT_PCM_16_BIT is 23),
427      * plus ~1 for a delimiter "|" this buffer has room for about 10 format strings which seems
428      *  like way too much, but it's a stack variable so only temporary.
429      */
430     char buffer[256];
431     buffer[0] = '\0';
432     size_t buffSize = ARRAY_SIZE(buffer);
433     size_t curStrLen = 0;
434
435     size_t numEntries = 0;
436     size_t index = 0;
437     for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
438         // account for both the null, and potentially the bar.
439         if (buffSize - curStrLen < strlen(format_string_map[profile->formats[index]])
440                                    + (numEntries != 0 ? 2 : 1)) {
441             /* we don't have room for another, so bail at this point rather than
442              * return a malformed rate string
443              */
444             break;
445         }
446         if (numEntries++ != 0) {
447             strlcat(buffer, "|", buffSize);
448         }
449         curStrLen = strlcat(buffer, format_string_map[profile->formats[index]], buffSize);
450     }
451
452     return strdup(buffer);
453 }
454
455 char * profile_get_channel_count_strs(alsa_device_profile* profile)
456 {
457     static const char * const out_chans_strs[] = {
458         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
459         /* 1 */"AUDIO_CHANNEL_OUT_MONO",
460         /* 2 */"AUDIO_CHANNEL_OUT_STEREO",
461         /* 3 */ /* "AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
462         /* 4 */"AUDIO_CHANNEL_OUT_QUAD",
463         /* 5 */ /* "AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_FRONT_CENTER" */ NULL,
464         /* 6 */"AUDIO_CHANNEL_OUT_5POINT1",
465         /* 7 */ /* "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_BACK_CENTER" */ NULL,
466         /* 8 */ "AUDIO_CHANNEL_OUT_7POINT1",
467         /* channel counts greater than this not considered */
468     };
469
470     static const char * const in_chans_strs[] = {
471         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
472         /* 1 */"AUDIO_CHANNEL_IN_MONO",
473         /* 2 */"AUDIO_CHANNEL_IN_STEREO",
474         /* channel counts greater than this not considered */
475     };
476
477     static const char * const index_chans_strs[] = {
478         /* 0 */"AUDIO_CHANNEL_NONE", /* will never be taken as this is a terminator */
479         /* 1 */"AUDIO_CHANNEL_INDEX_MASK_1",
480         /* 2 */"AUDIO_CHANNEL_INDEX_MASK_2",
481         /* 3 */"AUDIO_CHANNEL_INDEX_MASK_3",
482         /* 4 */"AUDIO_CHANNEL_INDEX_MASK_4",
483         /* 5 */"AUDIO_CHANNEL_INDEX_MASK_5",
484         /* 6 */"AUDIO_CHANNEL_INDEX_MASK_6",
485         /* 7 */"AUDIO_CHANNEL_INDEX_MASK_7",
486         /* 8 */"AUDIO_CHANNEL_INDEX_MASK_8",
487     };
488
489     const bool isOutProfile = profile->direction == PCM_OUT;
490
491     const char * const * const chans_strs = isOutProfile ? out_chans_strs : in_chans_strs;
492     const size_t chans_strs_size =
493             isOutProfile ? ARRAY_SIZE(out_chans_strs) : ARRAY_SIZE(in_chans_strs);
494
495     /*
496      * If we assume each channel string is 26 chars ("AUDIO_CHANNEL_INDEX_MASK_8" is 26) + 1 for,
497      * the "|" delimiter, then we allocate room for 16 strings.
498      */
499     char buffer[27 * 16 + 1]; /* caution, may need to be expanded */
500     buffer[0] = '\0';
501     size_t buffSize = ARRAY_SIZE(buffer);
502     size_t curStrLen = 0;
503
504     /* We currently support MONO and STEREO, and always report STEREO but some (many)
505      * USB Audio Devices may only announce support for MONO (a headset mic for example), or
506      * The total number of output channels. SO, if the device itself doesn't explicitly
507      * support STEREO, append to the channel config strings we are generating.
508      */
509     // Always support stereo
510     curStrLen = strlcat(buffer, chans_strs[2], buffSize);
511
512     size_t index;
513     unsigned channel_count;
514     for (index = 0;
515          (channel_count = profile->channel_counts[index]) != 0;
516          index++) {
517         if (channel_count < chans_strs_size
518                 && chans_strs[channel_count] != NULL
519                 && channel_count != 2 /* stereo already supported */) {
520             // account for the '|' and the '\0'
521             if (buffSize - curStrLen < strlen(chans_strs[channel_count]) + 2) {
522                 /* we don't have room for another, so bail at this point rather than
523                  * return a malformed rate string
524                  */
525                 break;
526             }
527
528             strlcat(buffer, "|", buffSize);
529             curStrLen = strlcat(buffer, chans_strs[channel_count], buffSize);
530         }
531
532         // handle channel index masks for both input and output
533         // +2 to account for the '|' and the '\0'
534          if (buffSize - curStrLen < strlen(index_chans_strs[channel_count]) + 2) {
535              /* we don't have room for another, so bail at this point rather than
536               * return a malformed rate string
537               */
538              break;
539          }
540
541          strlcat(buffer, "|", buffSize);
542          curStrLen = strlcat(buffer, index_chans_strs[channel_count], buffSize);
543     }
544
545     return strdup(buffer);
546 }