1 /*
2  * Copyright 2014, 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 #ifndef ANDROID_AUDIO_SPDIF_ENCODER_H
18 #define ANDROID_AUDIO_SPDIF_ENCODER_H
19 
20 #include <stdint.h>
21 #include <hardware/audio.h>
22 #include <audio_utils/spdif/FrameScanner.h>
23 
24 namespace android {
25 
26 /**
27  * Scan the incoming byte stream for a frame sync.
28  * Then wrap the encoded frame in a data burst and send it as if it were PCM.
29  * The receiver will see the data burst header and decode the wrapped frame.
30  */
31 #define SPDIF_MAX_CHANNELS          8
32 #define SPDIF_ENCODED_CHANNEL_COUNT 2
33 
34 class SPDIFEncoder {
35 public:
36 
37     SPDIFEncoder(audio_format_t format);
38     // Defaults to AC3 format. Was in original API.
39     SPDIFEncoder();
40 
41     virtual ~SPDIFEncoder();
42 
43     /**
44      * Write encoded data to be wrapped for SPDIF.
45      * The compressed frames do not have to be aligned.
46      * @return number of bytes written or negative error
47      */
48     ssize_t write( const void* buffer, size_t numBytes );
49 
50     /**
51      * Called by SPDIFEncoder when it is ready to output a data burst.
52      * Must be implemented in the subclass.
53      * @return number of bytes written or negative error
54      */
55     virtual ssize_t writeOutput( const void* buffer, size_t numBytes ) = 0;
56 
57     /**
58      * Get ratio of the encoded data burst sample rate to the encoded rate.
59      * For example, EAC3 data bursts are 4X the encoded rate.
60      */
getRateMultiplier()61     uint32_t getRateMultiplier() const { return mRateMultiplier; }
62 
63     /**
64      * @return number of PCM frames in a data burst
65      */
getBurstFrames()66     uint32_t getBurstFrames() const { return mBurstFrames; }
67 
68     /**
69      * @return number of bytes per PCM frame for the data burst
70      */
71     int      getBytesPerOutputFrame();
72 
73     /**
74      * @return  true if we can wrap this format in an SPDIF stream
75      */
76     static bool isFormatSupported(audio_format_t format);
77 
78     /**
79      * Discard any data in the buffer. Reset frame scanners.
80      * This should be called when seeking to a new position in the stream.
81      */
82     void reset();
83 
84 protected:
85     void   clearBurstBuffer();
86     void   writeBurstBufferShorts(const uint16_t* buffer, size_t numBytes);
87     void   writeBurstBufferBytes(const uint8_t* buffer, size_t numBytes);
88     void   sendZeroPad();
89     void   flushBurstBuffer();
90     void   startDataBurst();
91     size_t startSyncFrame();
92 
93     // Works with various formats including AC3.
94     FrameScanner *mFramer;
95 
96     uint32_t  mSampleRate;
97     size_t    mFrameSize;   // size of sync frame in bytes
98     uint16_t *mBurstBuffer; // ALSA wants to get SPDIF data as shorts.
99     size_t    mBurstBufferSizeBytes;
100     uint32_t  mRateMultiplier;
101     uint32_t  mBurstFrames;
102     size_t    mByteCursor;  // cursor into data burst
103     int       mBitstreamNumber;
104     size_t    mPayloadBytesPending; // number of bytes needed to finish burst
105     // state variable, true if scanning for start of frame
106     bool      mScanning;
107 
108     static const unsigned short kSPDIFSync1; // Pa
109     static const unsigned short kSPDIFSync2; // Pb
110 };
111 
112 }  // namespace android
113 
114 #endif  // ANDROID_AUDIO_SPDIF_ENCODER_H
115