aml_amaudioutils: audio hal utilities library [1/1]
PD#SWPL-17555
Problem:
This is the initial import of the utility library
to support audio hal implementation on Linux.
Solution:
This library is added on Linux for:
1. The resampler routines from speex
2. The Android SPDIF encoder
3. Partial Android libcutils support needed
as dependencies for audio hal.
Verify:
Local
Change-Id: I28cbc154c82bf6c395aba2f066a2fe0e6f6349db
Signed-off-by: Tim Yao <tim.yao@amlogic.com>
diff --git a/src/spdif/DTSFrameScanner.cpp b/src/spdif/DTSFrameScanner.cpp
new file mode 100644
index 0000000..941e8b9
--- /dev/null
+++ b/src/spdif/DTSFrameScanner.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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 <cutils/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