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