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