/* * Copyright 2015, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "AudioSPDIF" //#define LOG_NDEBUG 0 #include <assert.h> #include <string.h> #include <utils/Log.h> #include <audio_utils/spdif/FrameScanner.h> #include "BitFieldParser.h" #include "DTSFrameScanner.h" namespace android { // TODO Handle termination frames. // TODO assert if parse past end of header buffer // TODO Handle DTS_HD const uint8_t DTSFrameScanner::kSyncBytes[] = { 0x7F, 0xFE, 0x80, 0x01 }; const int32_t DTSFrameScanner::kDTSSampleRateTable[DTS_NUM_SAMPLE_RATE_TABLE_ENTRIES] = { -1, 8000, 16000, 32000, -1, -1, 11025, 22050, 44100, -1, -1, 12000, 24000, 48000, -1, -1 }; // Defined in IEC61937-2 #define IEC61937_DATA_TYPE_DTS_I 11 #define IEC61937_DATA_TYPE_DTS_II 12 #define IEC61937_DATA_TYPE_DTS_III 13 #define IEC61937_DATA_TYPE_DTS_IV 17 #define IEC61937_MAX_SAMPLES_TYPE_I 512 #define IEC61937_MAX_SAMPLES_TYPE_II 1024 #define IEC61937_MAX_SAMPLES_TYPE_III 2048 // Limits defined in DTS spec paragraph 5.3.1 #define DTS_MINIMUM_NBLKS 5 #define DTS_MINIMUM_FSIZE 95 #define DTS_HEADER_BYTES_NEEDED 12 // Scanner for DTS byte streams. DTSFrameScanner::DTSFrameScanner() : FrameScanner(IEC61937_DATA_TYPE_DTS_I, DTSFrameScanner::kSyncBytes, sizeof(DTSFrameScanner::kSyncBytes), DTS_HEADER_BYTES_NEEDED) , mSampleFramesPerSyncFrame(0) { } DTSFrameScanner::~DTSFrameScanner() { } // Parse DTS header. // Detect whether the stream is DTS or DTS_HD. Extract data depending on type. // Sets mDataType, mFrameSizeBytes, // mSampleRate, mRateMultiplier, mLengthCode. // // @return true if valid bool DTSFrameScanner::parseHeader() { BitFieldParser parser(&mHeaderBuffer[mSyncLength]); // These variables are named after the fields in the DTS spec 5.3.1 // Extract field in order. (void) /* uint32_t ftype = */ parser.readBits(1); (void) /* uint32_t deficit = */ parser.readBits(5); // "short" uint32_t cpf = parser.readBits(1); uint32_t nblks = parser.readBits(7); uint32_t fsize = parser.readBits(14); (void) /* uint32_t amode = */ parser.readBits(6); uint32_t sfreq = parser.readBits(4); // make sure we did not read past collected data ALOG_ASSERT((mSyncLength + ((parser.getBitCursor() + 7) >> 3)) <= mHeaderLength); // Validate fields. if (cpf != 0) { ALOGE("DTSFrameScanner: ERROR - CPF not zero!"); return false; } if (nblks < DTS_MINIMUM_NBLKS) { ALOGE("DTSFrameScanner: ERROR - nblks = %u", nblks); return false; } if (fsize < DTS_MINIMUM_FSIZE) { ALOGE("DTSFrameScanner: ERROR - fsize = %u", fsize); return false; } int32_t sampleRate = kDTSSampleRateTable[sfreq]; if (sampleRate < 0) { ALOGE("DTSFrameScanner: ERROR - invalid sampleRate[%u] = %d", sfreq, sampleRate); return false; } mSampleRate = (uint32_t) sampleRate; mSampleFramesPerSyncFrame = (nblks + 1) * DTS_PCM_FRAMES_PER_BLOCK; if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_I) { mDataType = IEC61937_DATA_TYPE_DTS_I; } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_II) { mDataType = IEC61937_DATA_TYPE_DTS_II; } else if (mSampleFramesPerSyncFrame <= IEC61937_MAX_SAMPLES_TYPE_III) { mDataType = IEC61937_DATA_TYPE_DTS_III; } else { mDataType = IEC61937_DATA_TYPE_DTS_IV; // TODO set bits 8,10 } mFrameSizeBytes = fsize + 1; mRateMultiplier = 1; // TODO what about "frequency extension"? ALOGI_IF((mFormatDumpCount == 0), "DTS frame rate = %d * %d, size = %zu", mSampleRate, mRateMultiplier, mFrameSizeBytes); mFormatDumpCount++; return true; } } // namespace android