1 /*
2 * Copyright 2023, 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 "AudioSPDIF"
18
19 #include <log/log.h>
20 #include <audio_utils/spdif/FrameScanner.h>
21
22 #include <map>
23 #include <string>
24
25 #include "SPDIFFrameScanner.h"
26
27 namespace android {
28
29 // Burst Preamble defined in IEC61937-1
30 const uint8_t SPDIFFrameScanner::kSyncBytes[] = {
31 (kSpdifSync1 & 0x00ff), (kSpdifSync1 & 0xff00) >> 8,
32 (kSpdifSync2 & 0x00ff), (kSpdifSync2 & 0xff00) >> 8,
33 };
34
getDataTypeForAudioFormat(audio_format_t format)35 static int getDataTypeForAudioFormat(audio_format_t format) {
36 static const std::map<audio_format_t, int> sMapAudioFormatToDataType = {
37 { AUDIO_FORMAT_AC3, kSpdifDataTypeAc3 },
38 { AUDIO_FORMAT_E_AC3, kSpdifDataTypeEac3 },
39 { AUDIO_FORMAT_E_AC3_JOC, kSpdifDataTypeEac3 }
40 };
41 if (sMapAudioFormatToDataType.find(format) != sMapAudioFormatToDataType.end()) {
42 return sMapAudioFormatToDataType.at(format);
43 }
44 return 0;
45 }
46
SPDIFFrameScanner(audio_format_t format)47 SPDIFFrameScanner::SPDIFFrameScanner(audio_format_t format)
48 : FrameScanner(getDataTypeForAudioFormat(format), SPDIFFrameScanner::kSyncBytes,
49 sizeof(SPDIFFrameScanner::kSyncBytes), 8) {
50 mRateMultiplier = spdif_rate_multiplier(format);
51 }
52
53 // Parse IEC61937 header.
54 //
55 // @return true if valid
parseHeader()56 bool SPDIFFrameScanner::parseHeader() {
57 // Parse Pc and Pd of IEC61937 preamble.
58 const uint16_t pc = mHeaderBuffer[4] | (mHeaderBuffer[5] << 8);
59 const uint16_t pd = mHeaderBuffer[6] | (mHeaderBuffer[7] << 8);
60 const uint8_t dataType = 0x007f & pc;
61 if (dataType != getDataType()) {
62 return false;
63 }
64 mDataType = dataType;
65 mErrorFlag = (pc >> 7) & 1;
66 if (mErrorFlag) {
67 return false;
68 }
69 mDataTypeInfo = (pc >> 8) & 0x1f;
70 mFrameSizeBytes = pd / ((mDataType == kSpdifDataTypeAc3) ? 8 : 1);
71 return true;
72 }
73
74 } // namespace android
75