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