1 /*
2 * Copyright 2015, 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 //#define LOG_NDEBUG 0
19
20 #include <assert.h>
21 #include <string.h>
22
23 #include <utils/Log.h>
24 #include <audio_utils/spdif/FrameScanner.h>
25
26 #include "BitFieldParser.h"
27 #include "DTSFrameScanner.h"
28
29 namespace android {
30
31 // TODO Handle termination frames.
32 // TODO assert if parse past end of header buffer
33 // TODO Handle DTS_HD
34
35 const uint8_t DTSFrameScanner::kSyncBytes[] =
36 { 0x7F, 0xFE, 0x80, 0x01 };
37
38 const int32_t DTSFrameScanner::kDTSSampleRateTable[DTS_NUM_SAMPLE_RATE_TABLE_ENTRIES]
39 = { -1, 8000, 16000, 32000, -1, -1,
40 11025, 22050, 44100, -1, -1, 12000, 24000, 48000, -1, -1 };
41
42 // Defined in IEC61937-2
43 #define IEC61937_DATA_TYPE_DTS_I 11
44 #define IEC61937_DATA_TYPE_DTS_II 12
45 #define IEC61937_DATA_TYPE_DTS_III 13
46 #define IEC61937_DATA_TYPE_DTS_IV 17
47
48 #define IEC61937_MAX_SAMPLES_TYPE_I 512
49 #define IEC61937_MAX_SAMPLES_TYPE_II 1024
50 #define IEC61937_MAX_SAMPLES_TYPE_III 2048
51
52 // Limits defined in DTS spec paragraph 5.3.1
53 #define DTS_MINIMUM_NBLKS 5
54 #define DTS_MINIMUM_FSIZE 95
55
56 #define DTS_HEADER_BYTES_NEEDED 12
57
58 // Scanner for DTS byte streams.
DTSFrameScanner()59 DTSFrameScanner::DTSFrameScanner()
60 : FrameScanner(IEC61937_DATA_TYPE_DTS_I,
61 DTSFrameScanner::kSyncBytes,
62 sizeof(DTSFrameScanner::kSyncBytes),
63 DTS_HEADER_BYTES_NEEDED)
64 , mSampleFramesPerSyncFrame(0)
65 {
66 }
67
~DTSFrameScanner()68 DTSFrameScanner::~DTSFrameScanner()
69 {
70 }
71
72 // Parse DTS header.
73 // Detect whether the stream is DTS or DTS_HD. Extract data depending on type.
74 // Sets mDataType, mFrameSizeBytes,
75 // mSampleRate, mRateMultiplier, mLengthCode.
76 //
77 // @return true if valid
parseHeader()78 bool DTSFrameScanner::parseHeader()
79 {
80 BitFieldParser parser(&mHeaderBuffer[mSyncLength]);
81
82 // These variables are named after the fields in the DTS spec 5.3.1
83 // Extract field in order.
84 uint32_t ftype = parser.readBits(1);
85 uint32_t deficit = parser.readBits(5); // "short"
86 uint32_t cpf = parser.readBits(1);
87 uint32_t nblks = parser.readBits(7);
88 uint32_t fsize = parser.readBits(14);
89 uint32_t amode = parser.readBits(6);
90 uint32_t sfreq = parser.readBits(4);
91 // make sure we did not read past collected data
92 ALOG_ASSERT((mSyncLength + ((parser.getBitCursor() + 7) >> 3))
93 <= mHeaderLength);
94
95 // Validate fields.
96 if (cpf != 0) {
97 ALOGE("DTSFrameScanner: ERROR - CPF not zero!");
98 return false;
99 }
100 if (nblks < DTS_MINIMUM_NBLKS) {
101 ALOGE("DTSFrameScanner: ERROR - nblks = %u", nblks);
102 return false;
103 }
104 if (fsize < DTS_MINIMUM_FSIZE) {
105 ALOGE("DTSFrameScanner: ERROR - fsize = %u", fsize);
106 return false;
107 }
108
109 int32_t sampleRate = kDTSSampleRateTable[sfreq];
110 if (sampleRate < 0) {
111 ALOGE("DTSFrameScanner: ERROR - invalid sampleRate[%u] = %d", sfreq, sampleRate);
112 return false;
113 }
114 mSampleRate = (uint32_t) sampleRate;
115
116 mSampleFramesPerSyncFrame = (nblks + 1) * DTS_PCM_FRAMES_PER_BLOCK;
117 if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_I) {
118 mDataType = IEC61937_DATA_TYPE_DTS_I;
119 } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_II) {
120 mDataType = IEC61937_DATA_TYPE_DTS_II;
121 } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_III) {
122 mDataType = IEC61937_DATA_TYPE_DTS_III;
123 } else {
124 mDataType = IEC61937_DATA_TYPE_DTS_IV;
125 // TODO set bits 8,10
126 }
127
128 mFrameSizeBytes = fsize + 1;
129
130 mRateMultiplier = 1; // TODO what about "frequency extension"?
131 ALOGI_IF((mFormatDumpCount == 0),
132 "DTS frame rate = %d * %d, size = %d\n",
133 mSampleRate, mRateMultiplier, mFrameSizeBytes);
134 mFormatDumpCount++;
135 return true;
136 }
137
138
139 } // namespace android
140