• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2014, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #define LOG_TAG "AudioHAL:alsa_utils"
19 
20 #include "alsa_utils.h"
21 
22 #ifndef ALSA_UTILS_PRINT_FORMATS
23 #define ALSA_UTILS_PRINT_FORMATS  1
24 #endif
25 
find_alsa_card_by_name(const char * name)26 int find_alsa_card_by_name(const char* name) {
27     int card_id = 0;
28     int ret = -1;
29     int fd;
30 
31     do {
32         int fd;
33         int amt;
34         char tmp[256];
35 
36         snprintf(tmp, sizeof(tmp), "/proc/asound/card%d/id", card_id);
37         tmp[sizeof(tmp) - 1] = 0;
38         fd = open(tmp, O_RDONLY);
39         if (fd < 0)
40             break;
41 
42         amt = read(fd, tmp, sizeof(tmp) - 1);
43         if (amt > 0) {
44             // replace the '\n' at the end of the proc file with '\0'
45             tmp[amt - 1] = 0;
46             if (!strcmp(name, tmp))
47                 ret = card_id;
48         }
49 
50         close(fd);
51 
52         card_id++;
53     } while (ret < 0);
54 
55     ALOGI("%s: returning card %d for name %s", __func__, ret, name);
56     return ret;
57 }
58 
59 #ifdef __cplusplus
60 #include <tinyalsa/asoundlib.h>
61 #include <utils/misc.h>
62 
63 namespace android {
64 
65 static const char *kCtrlNames[] = {
66     "Basic Audio Supported",
67     "Speaker Allocation",
68     "Audio Mode Count",
69     "Audio Mode To Query",
70     "Query Mode : Format",
71     "Query Mode : Max Ch Count",
72     "Query Mode : Sample Rate Mask",
73     "Query Mode : PCM Bits/Sample Mask",
74     "Query Mode : Max Compressed Bitrate"
75 };
76 static const size_t kCtrlCount    = sizeof(kCtrlNames)/sizeof(*kCtrlNames);
77 static const size_t kBasicAudNdx  = 0;
78 static const size_t kSpeakerAlloc = 1;
79 static const size_t kModeCntNdx   = 2;
80 static const size_t kModeSelNdx   = 3;
81 static const size_t kFmtNdx       = 4;
82 static const size_t kMaxChCntNdx  = 5;
83 static const size_t kSampRateNdx  = 6;
84 static const size_t kBPSNdx       = 7;
85 static const size_t kMaxCompBRNdx = 8;
86 
HDMIAudioCaps()87 HDMIAudioCaps::HDMIAudioCaps()
88 {
89     // Its unlikely we will need storage for more than 16 modes, but if we do,
90     // the vector will resize for us.
91     mModes.setCapacity(16);
92     reset();
93 }
94 
loadCaps(int ALSADeviceID)95 bool HDMIAudioCaps::loadCaps(int ALSADeviceID) {
96     bool ret = false;
97     struct mixer* mixer = NULL;
98     struct mixer_ctl* ctrls[kCtrlCount] = {NULL};
99     int tmp, mode_cnt;
100     Mutex::Autolock _l(mLock);
101 
102     ALOGE("%s: start", __func__);
103 
104     reset_l();
105 
106     // Open the mixer for the chosen ALSA device
107     if (NULL == (mixer = mixer_open(ALSADeviceID))) {
108         ALOGE("%s: mixer_open(%d) failed", __func__, ALSADeviceID);
109         goto bailout;
110     }
111 
112     // Gather handles to all of the controls we will need in order to enumerate
113     // the audio capabilities of this HDMI link.  No need to free/release these
114     // later, they are just pointers into the tinyalsa mixer structure itself.
115     for (size_t i = 0; i < kCtrlCount; ++i) {
116         ctrls[i] = mixer_get_ctl_by_name(mixer, kCtrlNames[i]);
117         if (NULL == ctrls[i]) {
118             ALOGE("%s: mixer_get_ctrl_by_name(%s) failed", __func__, kCtrlNames[i]);
119             goto bailout;
120 	}
121     }
122 
123     // Start by checking to see if this HDMI connection supports even basic
124     // audio.  If it does not, there is no point in proceeding.
125     if ((tmp = mixer_ctl_get_value(ctrls[kBasicAudNdx], 0)) <= 0) {
126         ALOGI("%s: Basic audio not supported by attached device", __func__);
127         goto bailout;
128     }
129 
130     // Looks like we support basic audio.  Get a count of the available
131     // non-basic modes.
132     mBasicAudioSupported = true;
133     if ((mode_cnt = mixer_ctl_get_value(ctrls[kModeCntNdx], 0)) < 0)
134         goto bailout;
135 
136     // Fetch the speaker allocation data block, if available.
137     if ((tmp = mixer_ctl_get_value(ctrls[kSpeakerAlloc], 0)) < 0)
138         goto bailout;
139     mSpeakerAlloc = static_cast<uint16_t>(tmp);
140     ALOGI("%s: Speaker Allocation Map for attached device is: 0x%hx", __func__, mSpeakerAlloc);
141 
142     // If there are no non-basic modes available, then we are done.  Be sure to
143     // flag this as a successful operation.
144     if (!mode_cnt) {
145         ret = true;
146         goto bailout;
147     }
148 
149     // Now enumerate the non-basic modes.  Any errors at this point in time
150     // should indicate that the HDMI cable was unplugged and we should just
151     // abort with an empty set of audio capabilities.
152     for (int i = 0; i < mode_cnt; ++i) {
153         Mode m;
154 
155         // Pick the mode we want to fetch info for.
156         if (mixer_ctl_set_value(ctrls[kModeSelNdx], 0, i) < 0)
157             goto bailout;
158 
159         // Now fetch the common fields.
160         if ((tmp = mixer_ctl_get_value(ctrls[kFmtNdx], 0)) < 0)
161             goto bailout;
162         m.fmt = static_cast<AudFormat>(tmp);
163         ALOGI("Got mode %d from ALSA driver.", m.fmt);
164 
165         if ((tmp = mixer_ctl_get_value(ctrls[kMaxChCntNdx], 0)) < 0)
166             goto bailout;
167         m.max_ch = static_cast<uint32_t>(tmp);
168 
169         if ((tmp = mixer_ctl_get_value(ctrls[kSampRateNdx], 0)) < 0)
170             goto bailout;
171         m.sr_bitmask = static_cast<uint32_t>(tmp);
172 
173         // Now for the mode dependent fields.  Only LPCM has the bits-per-sample
174         // mask.  Only AC3 through ATRAC have the compressed bitrate field.
175         m.bps_bitmask = 0;
176         m.comp_bitrate = 0;
177 
178         if (m.fmt == kFmtLPCM) {
179             if ((tmp = mixer_ctl_get_value(ctrls[kBPSNdx], 0)) < 0)
180                 goto bailout;
181             m.bps_bitmask = static_cast<uint32_t>(tmp);
182         } else if ((m.fmt >= kFmtAC3) && (m.fmt <= kFmtATRAC)) { // FIXME ATRAC is not last format!?
183             // FIXME SHould we extend the range up to kFmtDTSHD or kFmtMPGSUR?
184             if ((tmp = mixer_ctl_get_value(ctrls[kMaxCompBRNdx], 0)) < 0)
185                 goto bailout;
186             m.comp_bitrate = static_cast<uint32_t>(tmp);
187         }
188 
189         // Finally, sanity check the info.  If it passes, add it to the vector
190         // of available modes.
191         if (sanityCheckMode(m))  {
192             ALOGI("Passed sanity check for mode %d from ALSA driver.", m.fmt);
193             mModes.add(m);
194         }
195     }
196 
197     // Looks like we managed to enumerate all of the modes before someone
198     // unplugged the HDMI cable.  Signal success and get out.
199     ret = true;
200 
201 bailout:
202     if (NULL != mixer)
203         mixer_close(mixer);
204 
205     if (!ret)
206         reset_l();
207 
208     return ret;
209 }
210 
reset()211 void HDMIAudioCaps::reset() {
212     Mutex::Autolock _l(mLock);
213     reset_l();
214 }
215 
reset_l()216 void HDMIAudioCaps::reset_l() {
217     mBasicAudioSupported = false;
218     mSpeakerAlloc = 0;
219     mModes.clear();
220 }
221 
getFmtsForAF(String8 & fmts)222 void HDMIAudioCaps::getFmtsForAF(String8& fmts) {
223     Mutex::Autolock _l(mLock);
224     fmts.clear();
225 
226     // If the sink does not support basic audio, then it supports no audio.
227     if (!mBasicAudioSupported) {
228         ALOGI("ALSAFORMATS: basic audio not supported");
229         return;
230     }
231 
232     // These names must match formats in android.media.AudioFormat
233     fmts.append("AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_PCM_8_24_BIT");
234     // TODO: when we can start to expect 20 and 24 bit audio modes coming from
235     // AF, we need to implement support to enumerate those modes.
236 
237     for (size_t i = 0; i < mModes.size(); ++i) {
238         switch (mModes[i].fmt) {
239             case kFmtAC3:
240                 fmts.append("|AUDIO_FORMAT_AC3");
241                 break;
242             case kFmtEAC3:
243                 fmts.append("|AUDIO_FORMAT_E_AC3");
244                 break;
245             case kFmtDTS:
246                 fmts.append("|AUDIO_FORMAT_DTS");
247                 break;
248             case kFmtDTSHD:
249                 fmts.append("|AUDIO_FORMAT_DTS_HD");
250                 break;
251             default:
252                 break;
253         }
254     }
255     // HDMI supports IEC61937 S/PDIF audio wrapper.
256     fmts.append("|AUDIO_FORMAT_IEC61937");
257 
258 #if ALSA_UTILS_PRINT_FORMATS
259     ALOGI("ALSAFORMATS: formats = %s", fmts.string());
260 
261     for (size_t i = 0; i < mModes.size(); ++i) {
262         ALOGI("ALSAFORMATS: ------- fmt[%d] = 0x%08X = %s",
263             i, mModes[i].fmt, fmtToString(mModes[i].fmt));
264         ALOGI("ALSAFORMATS:   comp_bitrate[%d] = 0x%08X = %d",
265             i, mModes[i].comp_bitrate, mModes[i].comp_bitrate);
266         ALOGI("ALSAFORMATS:   max_ch[%d] = 0x%08X = %d",
267             i, mModes[i].max_ch, mModes[i].max_ch);
268         ALOGI("ALSAFORMATS:   bps_bitmask[%d] = 0x%08X", i, mModes[i].bps_bitmask);
269         uint32_t bpsm = mModes[i].bps_bitmask;
270         while(bpsm) {
271             uint32_t bpsm_next = bpsm & (bpsm - 1);
272             uint32_t bpsm_single = bpsm ^ bpsm_next;
273             if (bpsm_single) {
274                 ALOGI("ALSAFORMATS:      bits  = %d", bpsMaskToBPS(bpsm_single));
275             }
276             bpsm = bpsm_next;
277         }
278         ALOGI("ALSAFORMATS:   sr_bitmask[%d] = 0x%08X", i, mModes[i].sr_bitmask);
279         uint32_t srs = mModes[i].sr_bitmask;
280         while(srs) {
281             uint32_t srs_next = srs & (srs - 1);
282             uint32_t srs_single = srs ^ srs_next;
283             if (srs_single) {
284                 ALOGI("ALSAFORMATS:      srate = %d", srMaskToSR(srs_single));
285             }
286             srs = srs_next;
287         }
288     }
289 #endif /* ALSA_UTILS_PRINT_FORMATS */
290 }
291 
292 /* static */
alsaFormatFromAndroidFormat(audio_format_t format)293 HDMIAudioCaps::AudFormat HDMIAudioCaps::alsaFormatFromAndroidFormat(audio_format_t format)
294 {
295     AudFormat alsaFormat = kFmtInvalid;
296     switch (audio_get_main_format(format)) {
297         case AUDIO_FORMAT_PCM: alsaFormat = kFmtLPCM; break;
298         case AUDIO_FORMAT_AC3: alsaFormat = kFmtAC3; break;
299         case AUDIO_FORMAT_E_AC3: alsaFormat = kFmtAC3; break; // FIXME should this be kFmtEAC3?
300         case AUDIO_FORMAT_DTS: alsaFormat = kFmtDTS; break;
301         case AUDIO_FORMAT_DTS_HD: alsaFormat = kFmtDTSHD; break;
302         case AUDIO_FORMAT_IEC61937: alsaFormat = kFmtLPCM; break;
303         default:
304             ALOGE("supportsFormat() says format %#x not supported", format);
305             break;
306     }
307     return alsaFormat;
308 }
309 
getModeForFormat(HDMIAudioCaps::AudFormat format)310 const HDMIAudioCaps::Mode *HDMIAudioCaps::getModeForFormat(HDMIAudioCaps::AudFormat format)
311 {
312     for (size_t i = 0; i < mModes.size(); ++i) {
313         if (mModes[i].fmt == format) {
314             return &mModes[i];
315         }
316     }
317     return nullptr;
318 }
319 
getRatesForAF(String8 & rates,audio_format_t format)320 void HDMIAudioCaps::getRatesForAF(String8& rates, audio_format_t format) {
321     Mutex::Autolock _l(mLock);
322     rates.clear();
323 
324     // If the sink does not support basic audio, then it supports no audio.
325     if (!mBasicAudioSupported)
326         return;
327 
328     uint32_t tmp = 0;
329     // No format provided: returns rates for format with max channels
330     if (format == AUDIO_FORMAT_INVALID) {
331         ssize_t ndx = getMaxChModeNdx_l();
332         if (ndx >= 0)
333             tmp = mModes[ndx].sr_bitmask;
334     } else {
335         AudFormat alsaFormat = alsaFormatFromAndroidFormat(format);
336         if (alsaFormat == kFmtInvalid) {
337             return;
338         }
339         const Mode *mode =  getModeForFormat(alsaFormat);
340         if (mode == nullptr) {
341             return;
342         }
343         tmp = mode->sr_bitmask;
344     }
345     bool first = true;
346     for (uint32_t i = 1; tmp; i <<= 1) {
347         if (i & tmp) {
348             rates.appendFormat(first ? "%d" : "|%d", srMaskToSR(i));
349             first = false;
350             tmp &= ~i;
351         }
352     }
353 }
354 
getChannelMasksForAF(String8 & masks,audio_format_t format)355 void HDMIAudioCaps::getChannelMasksForAF(String8& masks, audio_format_t format) {
356     Mutex::Autolock _l(mLock);
357     masks.clear();
358     const Mode *mode = nullptr;
359 
360     // If the sink does not support basic audio, then it supports no audio.
361     if (!mBasicAudioSupported)
362         return;
363 
364     if (format == AUDIO_FORMAT_INVALID) {
365         // To keep things simple, only report mode information for the mode
366         // which supports the maximum number of channels.
367         ssize_t ndx = getMaxChModeNdx_l();
368         if (ndx < 0)
369             return;
370         mode = &mModes[ndx];
371     } else {
372         AudFormat alsaFormat = alsaFormatFromAndroidFormat(format);
373         if (alsaFormat == kFmtInvalid) {
374             return;
375         }
376         mode = getModeForFormat(alsaFormat);
377         if (mode == nullptr) {
378             return;
379         }
380     }
381 
382     if (mode != nullptr) {
383         // allow mono for non-pcm formats, e.g. AC3
384         if (mode->max_ch >= 1 && mode->fmt != kFmtLPCM) {
385             masks.append("AUDIO_CHANNEL_OUT_MONO");
386         }
387         if (mode->max_ch >= 2) {
388             if (masks.length()) masks.append("|");
389             masks.append("AUDIO_CHANNEL_OUT_STEREO");
390         }
391         if (mode->max_ch >= 4) {
392             if (masks.length()) masks.append("|");
393             masks.append("AUDIO_CHANNEL_OUT_QUAD");
394         }
395         if (mode->max_ch >= 6) {
396             if (masks.length()) masks.append("|");
397             masks.append("AUDIO_CHANNEL_OUT_5POINT1");
398         }
399         if (mode->max_ch >= 8) {
400             if (masks.length()) masks.append("|");
401             masks.append("AUDIO_CHANNEL_OUT_7POINT1");
402         }
403     }
404 }
405 
getMaxChModeNdx_l()406 ssize_t HDMIAudioCaps::getMaxChModeNdx_l() {
407     ssize_t max_ch_ndx = -1;
408     uint32_t max_ch = 0;
409 
410     for (size_t i = 0; i < mModes.size(); ++i) {
411         if (max_ch < mModes[i].max_ch) {
412             max_ch = mModes[i].max_ch;
413             max_ch_ndx = i;
414         }
415     }
416 
417     return max_ch_ndx;
418 }
419 
supportsFormat(audio_format_t format,uint32_t sampleRate,uint32_t channelCount,bool isIec958NonAudio)420 bool HDMIAudioCaps::supportsFormat(audio_format_t format,
421                                       uint32_t sampleRate,
422                                       uint32_t channelCount,
423                                       bool isIec958NonAudio) {
424     Mutex::Autolock _l(mLock);
425 
426     ALOGV("supportsFormat() format = 0x%08X, sampleRate = %u, channels = 0x%08X, iec958 = %d",
427                 format, sampleRate, channelCount, isIec958NonAudio ? 1 : 0);
428     // If the sink does not support basic audio, then it supports no audio.
429     if (!mBasicAudioSupported)
430         return false;
431 
432     AudFormat alsaFormat = alsaFormatFromAndroidFormat(format);
433     if (alsaFormat == kFmtInvalid)
434         return false;
435 
436     isIec958NonAudio |= (format == AUDIO_FORMAT_IEC61937);
437 
438     // EAC3 uses a PCM sample rate of 4X the base rate.
439     // We try to detect that situation and allow 4X rate even if the
440     // EDID does not report that it is supported.
441     // This rate was chosen because it is between the region of typical PCM rates
442     // and the extreme rates used for IEC61973.
443     // It is > 96000 and < 4*32000.
444     const uint32_t maxReasonableRate = 100000; // FIXME review for N
445     if (isIec958NonAudio && (alsaFormat == kFmtLPCM) && (sampleRate > maxReasonableRate)) {
446         ALOGI("supportsFormat() dividing sample %u by 4 to test support for EAC3 over HDMI",
447                 sampleRate);
448         sampleRate = sampleRate / 4;
449     }
450 
451     SRMask srMask;
452     switch (sampleRate) {
453         case 32000:  srMask = kSR_32000;  break;
454         case 44100:  srMask = kSR_44100;  break;
455         case 48000:  srMask = kSR_48000;  break;
456         case 88200:  srMask = kSR_88200;  break;
457         case 96000:  srMask = kSR_96000;  break;
458         case 176400: srMask = kSR_176400; break;
459         case 192000: srMask = kSR_192000; break;
460         default: return false;
461     }
462 
463     // if PCM then determine actual bits per sample.
464     if (alsaFormat == kFmtLPCM) {
465         BPSMask bpsMask;
466         switch (format) {
467         // FIXME: (legacy code). We match on 16 bits, but on Fugu we hard code to use
468         // PCM_FORMAT_S24_LE.
469             case AUDIO_FORMAT_PCM_16_BIT: // fall through
470             case AUDIO_FORMAT_PCM_8_24_BIT:
471             case AUDIO_FORMAT_IEC61937:
472                 bpsMask = kBPS_16bit;
473                 break;
474             default:
475                 return false;
476         }
477 
478         // Is the caller requesting basic audio?  If so, we should be good to go.
479         // Otherwise, we need to check the mode table.
480         if ((2 == channelCount) && (sampleRate <= 48000))
481             return true;
482 
483         // Check the modes in the table to see if there is one which
484         // supports the caller's format.
485         for (size_t i = 0; i < mModes.size(); ++i) {
486             const Mode& m = mModes[i];
487             if ((m.fmt == kFmtLPCM) &&
488                 (m.max_ch >= channelCount) &&
489                 (m.sr_bitmask & srMask) &&
490                 (m.bps_bitmask & bpsMask))
491                 return true;
492         }
493     } else {
494         // Check the modes in the table to see if there is one which
495         // supports the caller's format.
496         for (size_t i = 0; i < mModes.size(); ++i) {
497             const Mode& m = mModes[i];
498             // ignore bps_bitmask
499             if ((m.fmt == alsaFormat) &&
500                 (m.max_ch >= channelCount) &&
501                 (m.sr_bitmask & srMask))
502                 return true;
503         }
504     }
505 
506     // Looks like no compatible modes were found.
507     return false;
508 }
509 
sanityCheckMode(const Mode & m)510 bool HDMIAudioCaps::sanityCheckMode(const Mode& m) {
511     if ((m.fmt < kFmtLPCM) || (m.fmt > kFmtMPGSUR))
512         return false;
513 
514     if (m.max_ch > 8)
515         return false;
516 
517     if (m.sr_bitmask & ~(kSR_32000 | kSR_44100 | kSR_48000 | kSR_88200 |
518                          kSR_96000 | kSR_176400 | kSR_192000))
519         return false;
520 
521     if (m.bps_bitmask & ~(kBPS_16bit | kBPS_20bit | kBPS_24bit))
522         return false;
523 
524     return true;
525 }
526 
fmtToString(AudFormat fmt)527 const char* HDMIAudioCaps::fmtToString(AudFormat fmt) {
528     static const char* fmts[] = {
529         "invalid", "LPCM", "AC-3", "MPEG-1", "MPEG-1 Layer 3",
530         "MPEG-2", "AAC-LC", "DTS", "ATRAC", "DSD", "E-AC3",
531         "DTS-HD", "MLP", "DST", "WMA Pro", "Extended" };
532 
533     if (fmt >= NELEM(fmts))
534         return "invalid";
535 
536     return fmts[fmt];
537 }
538 
srMaskToSR(uint32_t mask)539 uint32_t HDMIAudioCaps::srMaskToSR(uint32_t mask) {
540     switch (mask) {
541         case kSR_32000: return 32000;
542         case kSR_44100: return 44100;
543         case kSR_48000: return 48000;
544         case kSR_88200: return 88200;
545         case kSR_96000: return 96000;
546         case kSR_176400: return 176400;
547         case kSR_192000: return 192000;
548         default: return 0;
549     }
550 }
551 
bpsMaskToBPS(uint32_t mask)552 uint32_t HDMIAudioCaps::bpsMaskToBPS(uint32_t mask) {
553     switch (mask) {
554         case kBPS_16bit: return 16;
555         case kBPS_20bit: return 20;
556         case kBPS_24bit: return 24;
557         default: return 0;
558     }
559 }
560 
saMaskToString(uint32_t mask)561 const char* HDMIAudioCaps::saMaskToString(uint32_t mask) {
562     switch (mask) {
563         case kSA_FLFR:   return "Front Left/Right";
564         case kSA_LFE:    return "LFE";
565         case kSA_FC:     return "Front Center";
566         case kSA_RLRR:   return "Rear Left/Right";
567         case kSA_RC:     return "Rear Center";
568         case kSA_FLCFRC: return "Front Left/Right Center";
569         case kSA_RLCRRC: return "Rear Left/Right Center";
570         case kSA_FLWFRW: return "Front Left/Right Wide";
571         case kSA_FLHFRH: return "Front Left/Right High";
572         case kSA_TC:     return "Top Center (overhead)";
573         case kSA_FCH:    return "Front Center High";
574         default: return "unknown";
575     }
576 }
577 
578 }  // namespace android
579 #endif  // __cplusplus
580