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
29namespace android {
30
31// TODO Handle termination frames.
32// TODO assert if parse past end of header buffer
33// TODO Handle DTS_HD
34
35const uint8_t DTSFrameScanner::kSyncBytes[] =
36        { 0x7F, 0xFE, 0x80, 0x01 };
37
38const 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.
59DTSFrameScanner::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
68DTSFrameScanner::~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
78bool 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    (void) /* uint32_t ftype = */ parser.readBits(1);
85    (void) /* 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    (void) /* 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 = %zu",
133            mSampleRate, mRateMultiplier, mFrameSizeBytes);
134    mFormatDumpCount++;
135    return true;
136}
137
138
139}  // namespace android
140