summaryrefslogtreecommitdiffstats
path: root/audio_utils/include/audio_utils/spdif/FrameScanner.h
diff options
context:
space:
mode:
Diffstat (limited to 'audio_utils/include/audio_utils/spdif/FrameScanner.h')
-rw-r--r--audio_utils/include/audio_utils/spdif/FrameScanner.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/audio_utils/include/audio_utils/spdif/FrameScanner.h b/audio_utils/include/audio_utils/spdif/FrameScanner.h
new file mode 100644
index 00000000..f1f2cd1e
--- /dev/null
+++ b/audio_utils/include/audio_utils/spdif/FrameScanner.h
@@ -0,0 +1,174 @@
+/*
+**
+** Copyright 2014, 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.
+*/
+
+#ifndef ANDROID_AUDIO_FRAME_SCANNER_H
+#define ANDROID_AUDIO_FRAME_SCANNER_H
+
+#include <stdint.h>
+
+namespace android {
+
+
+/**
+ * Scan a byte stream looking for the start of an encoded frame.
+ * Parse the sample rate and the size of the encoded frame.
+ * Buffer the sync header so it can be prepended to the remaining data.
+ *
+ * This is used directly by the SPDIFEncoder. External clients will
+ * generally not call this class.
+ */
+class FrameScanner {
+public:
+
+ FrameScanner(int dataType);
+ virtual ~FrameScanner();
+
+ /**
+ * Pass each byte of the encoded stream to this scanner.
+ * @return true if a complete and valid header was detected
+ */
+ virtual bool scan(uint8_t) = 0;
+
+ /**
+ * @return address of where the sync header was stored by scan()
+ */
+ virtual const uint8_t *getHeaderAddress() const = 0;
+
+ /**
+ * @return number of bytes in sync header stored by scan()
+ */
+ virtual size_t getHeaderSizeBytes() const = 0;
+
+ /**
+ * @return sample rate of the encoded audio
+ */
+ uint32_t getSampleRate() const { return mSampleRate; }
+
+ /**
+ * Some formats, for example EAC3, are wrapped in data bursts that have
+ * a sample rate that is a multiple of the encoded sample rate.
+ * The default multiplier is 1.
+ * @return sample rate multiplier for the SP/DIF PCM data bursts
+ */
+ uint32_t getRateMultiplier() const { return mRateMultiplier; }
+
+ size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
+
+ /**
+ * dataType is defined by the SPDIF standard for each format
+ */
+ virtual int getDataType() const { return mDataType; }
+ virtual int getDataTypeInfo() const { return mDataTypeInfo; }
+
+ /**
+ * lengthCode is defined by the SPDIF standard
+ * @return length of the frame in bits or bytes, depending on the format.
+ */
+ virtual int getLengthCode() const = 0;
+ virtual int getMaxChannels() const = 0;
+
+ /**
+ * @return the number of pcm frames that correspond to one encoded frame
+ */
+ virtual int getMaxSampleFramesPerSyncFrame() const = 0;
+ virtual int getSampleFramesPerSyncFrame() const = 0;
+
+ /**
+ * @return true if this parsed frame must be the first frame in a data burst.
+ */
+ virtual bool isFirstInBurst() = 0;
+
+ /**
+ * If this returns false then the previous frame may or may not be the last frame.
+ * @return true if this parsed frame is definitely the last frame in a data burst.
+ */
+ virtual bool isLastInBurst() = 0;
+
+protected:
+ uint32_t mSampleRate;
+ uint32_t mRateMultiplier;
+ size_t mFrameSizeBytes;
+ int mDataType;
+ int mDataTypeInfo;
+};
+
+#define AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES 3
+#define AC3_NUM_FRAME_SIZE_TABLE_ENTRIES 38
+#define AC3_PCM_FRAMES_PER_BLOCK 256
+#define AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK 6
+#define EAC3_RATE_MULTIPLIER 4
+#define EAC3_NUM_SAMPLE_RATE_TABLE_ENTRIES 3
+#define EAC3_NUM_BLOCKS_PER_FRAME_TABLE_ENTRIES 38
+
+class AC3FrameScanner : public FrameScanner
+{
+public:
+ AC3FrameScanner();
+ virtual ~AC3FrameScanner();
+
+ virtual bool scan(uint8_t);
+
+ virtual const uint8_t *getHeaderAddress() const { return mHeaderBuffer; }
+ virtual size_t getHeaderSizeBytes() const { return sizeof(mHeaderBuffer); }
+
+ virtual int getDataType() const { return mDataType; }
+ virtual int getDataTypeInfo() const { return 0; }
+ virtual int getLengthCode() const { return mLengthCode; }
+ virtual int getMaxChannels() const { return 5 + 1; }
+
+ virtual int getMaxSampleFramesPerSyncFrame() const { return EAC3_RATE_MULTIPLIER
+ * AC3_MAX_BLOCKS_PER_SYNC_FRAME_BLOCK * AC3_PCM_FRAMES_PER_BLOCK; }
+ virtual int getSampleFramesPerSyncFrame() const;
+
+ virtual bool isFirstInBurst();
+ virtual bool isLastInBurst();
+
+protected:
+
+ // Preamble state machine states.
+ enum State {
+ STATE_EXPECTING_SYNC_1,
+ STATE_EXPECTING_SYNC_2,
+ STATE_GATHERING,
+ STATE_GOT_HEADER,
+ };
+
+ State parseHeader(void);
+
+ State mState;
+ uint32_t mBytesSkipped;
+ uint8_t mHeaderBuffer[6];
+ int mLengthCode;
+ int mAudioBlocksPerSyncFrame;
+ uint mCursor;
+ uint mStreamType;
+ uint mSubstreamID;
+ uint mFormatDumpCount;
+
+ static const uint8_t kAC3SyncByte1;
+ static const uint8_t kAC3SyncByte2;
+ static const uint16_t kAC3SampleRateTable[AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES];
+ static const uint16_t kAC3FrameSizeTable[AC3_NUM_FRAME_SIZE_TABLE_ENTRIES]
+ [AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES];
+
+ static const uint16_t kEAC3ReducedSampleRateTable[AC3_NUM_SAMPLE_RATE_TABLE_ENTRIES];
+ static const uint16_t kEAC3BlocksPerFrameTable[EAC3_NUM_BLOCKS_PER_FRAME_TABLE_ENTRIES];
+
+};
+
+} // namespace android
+#endif // ANDROID_AUDIO_FRAME_SCANNER_H