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. 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 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 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 (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