1 /*
2  * Copyright (C) 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 #ifndef ANDROID_BUFFER_PROVIDERS_H
18 #define ANDROID_BUFFER_PROVIDERS_H
19 
20 #include <stdint.h>
21 #include <sys/types.h>
22 
23 #include <audio_utils/ChannelMix.h>
24 #include <media/AudioBufferProvider.h>
25 #include <media/AudioResamplerPublic.h>
26 #include <system/audio.h>
27 #include <system/audio_effect.h>
28 #include <utils/StrongPointer.h>
29 
30 // external forward declaration from external/sonic/sonic.h
31 struct sonicStreamStruct;
32 typedef struct sonicStreamStruct *sonicStream;
33 
34 namespace android {
35 
36 class EffectBufferHalInterface;
37 class EffectHalInterface;
38 class EffectsFactoryHalInterface;
39 
40 // ----------------------------------------------------------------------------
41 
42 class PassthruBufferProvider : public AudioBufferProvider {
43 public:
PassthruBufferProvider()44     PassthruBufferProvider() : mTrackBufferProvider(NULL) { }
45 
~PassthruBufferProvider()46     virtual ~PassthruBufferProvider() { }
47 
48     // call this to release the buffer to the upstream provider.
49     // treat it as an audio discontinuity for future samples.
reset()50     virtual void reset() { }
51 
52     // set the upstream buffer provider. Consider calling "reset" before this function.
setBufferProvider(AudioBufferProvider * p)53     virtual void setBufferProvider(AudioBufferProvider *p) {
54         mTrackBufferProvider = p;
55     }
56 
57 protected:
58     AudioBufferProvider *mTrackBufferProvider;
59 };
60 
61 // Base AudioBufferProvider class used for DownMixerBufferProvider, RemixBufferProvider,
62 // and ReformatBufferProvider.
63 // It handles a private buffer for use in converting format or channel masks from the
64 // input data to a form acceptable by the mixer.
65 // TODO: Make a ResamplerBufferProvider when integers are entirely removed from the
66 // processing pipeline.
67 class CopyBufferProvider : public PassthruBufferProvider {
68 public:
69     // Use a private buffer of bufferFrameCount frames (each frame is outputFrameSize bytes).
70     // If bufferFrameCount is 0, no private buffer is created and in-place modification of
71     // the upstream buffer provider's buffers is performed by copyFrames().
72     CopyBufferProvider(size_t inputFrameSize, size_t outputFrameSize,
73             size_t bufferFrameCount);
74     virtual ~CopyBufferProvider();
75 
76     // Overrides AudioBufferProvider methods
77     virtual status_t getNextBuffer(Buffer *buffer);
78     virtual void releaseBuffer(Buffer *buffer);
79 
80     // Overrides PassthruBufferProvider
81     virtual void reset();
82     void setBufferProvider(AudioBufferProvider *p) override;
83 
84     // this function should be supplied by the derived class.  It converts
85     // #frames in the *src pointer to the *dst pointer.  It is public because
86     // some providers will allow this to work on arbitrary buffers outside
87     // of the internal buffers.
88     virtual void copyFrames(void *dst, const void *src, size_t frames) = 0;
89 
90 protected:
91     const size_t         mInputFrameSize;
92     const size_t         mOutputFrameSize;
93 private:
94     AudioBufferProvider::Buffer mBuffer;
95     const size_t         mLocalBufferFrameCount;
96     void                *mLocalBufferData;
97     size_t               mConsumed;
98 };
99 
100 // DownmixerBufferProvider derives from CopyBufferProvider to provide
101 // position dependent downmixing by an Audio Effect.
102 class DownmixerBufferProvider : public CopyBufferProvider {
103 public:
104     DownmixerBufferProvider(audio_channel_mask_t inputChannelMask,
105             audio_channel_mask_t outputChannelMask, audio_format_t format,
106             uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount);
107     virtual ~DownmixerBufferProvider();
108     //Overrides
109     virtual void copyFrames(void *dst, const void *src, size_t frames);
110 
isValid()111     bool isValid() const { return mDownmixInterface.get() != NULL; }
112     static status_t init();
isMultichannelCapable()113     static bool isMultichannelCapable() { return sIsMultichannelCapable; }
114 
115 protected:
116     sp<EffectsFactoryHalInterface> mEffectsFactory;
117     sp<EffectHalInterface> mDownmixInterface;
118     size_t mInFrameSize;
119     size_t mOutFrameSize;
120     sp<EffectBufferHalInterface> mInBuffer;
121     sp<EffectBufferHalInterface> mOutBuffer;
122     effect_config_t    mDownmixConfig;
123 
124     // effect descriptor for the downmixer used by the mixer
125     static effect_descriptor_t sDwnmFxDesc;
126     // indicates whether a downmix effect has been found and is usable by this mixer
127     static bool                sIsMultichannelCapable;
128     // FIXME: should we allow effects outside of the framework?
129     // We need to here. A special ioId that must be <= -2 so it does not map to a session.
130     static const int32_t SESSION_ID_INVALID_AND_IGNORED = -2;
131 };
132 
133 // ChannelMixBufferProvider derives from CopyBufferProvider to perform an
134 // downmix to the proper channel count and mask.
135 class ChannelMixBufferProvider : public CopyBufferProvider {
136 public:
137     ChannelMixBufferProvider(audio_channel_mask_t inputChannelMask,
138             audio_channel_mask_t outputChannelMask, audio_format_t format,
139             size_t bufferFrameCount);
140 
141     void copyFrames(void *dst, const void *src, size_t frames) override;
142 
isValid()143     bool isValid() const { return mIsValid; }
144 
isOutputChannelMaskSupported(audio_channel_mask_t outputChannelMask)145     static bool isOutputChannelMaskSupported(audio_channel_mask_t outputChannelMask) {
146         return audio_utils::channels::IChannelMix::isOutputChannelMaskSupported(
147                 outputChannelMask);
148     }
149 
150 protected:
151     const std::shared_ptr<audio_utils::channels::IChannelMix> mChannelMix;
152     const bool mIsValid;
153 };
154 
155 // RemixBufferProvider derives from CopyBufferProvider to perform an
156 // upmix or downmix to the proper channel count and mask.
157 class RemixBufferProvider : public CopyBufferProvider {
158 public:
159     RemixBufferProvider(audio_channel_mask_t inputChannelMask,
160             audio_channel_mask_t outputChannelMask, audio_format_t format,
161             size_t bufferFrameCount);
162     //Overrides
163     virtual void copyFrames(void *dst, const void *src, size_t frames);
164 
165 protected:
166     const audio_format_t mFormat;
167     const size_t         mSampleSize;
168     const size_t         mInputChannels;
169     const size_t         mOutputChannels;
170     int8_t               mIdxAry[sizeof(uint32_t) * 8]; // 32 bits => channel indices
171 };
172 
173 // ReformatBufferProvider derives from CopyBufferProvider to convert the input data
174 // to an acceptable mixer input format type.
175 class ReformatBufferProvider : public CopyBufferProvider {
176 public:
177     ReformatBufferProvider(int32_t channelCount,
178             audio_format_t inputFormat, audio_format_t outputFormat,
179             size_t bufferFrameCount);
180     virtual void copyFrames(void *dst, const void *src, size_t frames);
181 
182 protected:
183     const uint32_t       mChannelCount;
184     const audio_format_t mInputFormat;
185     const audio_format_t mOutputFormat;
186 };
187 
188 // ClampFloatBufferProvider derives from CopyBufferProvider to clamp floats inside -3db
189 class ClampFloatBufferProvider : public CopyBufferProvider {
190 public:
191     ClampFloatBufferProvider(int32_t channelCount,
192             size_t bufferFrameCount);
193     virtual void copyFrames(void *dst, const void *src, size_t frames);
194 
195 protected:
196     const uint32_t       mChannelCount;
197 };
198 
199 // TimestretchBufferProvider derives from PassthruBufferProvider for time stretching
200 class TimestretchBufferProvider : public PassthruBufferProvider {
201 public:
202     TimestretchBufferProvider(int32_t channelCount,
203             audio_format_t format, uint32_t sampleRate,
204             const AudioPlaybackRate &playbackRate);
205     virtual ~TimestretchBufferProvider();
206 
207     // Overrides AudioBufferProvider methods
208     virtual status_t getNextBuffer(Buffer* buffer);
209     virtual void releaseBuffer(Buffer* buffer);
210 
211     // Overrides PassthruBufferProvider
212     virtual void reset();
213     void setBufferProvider(AudioBufferProvider *p) override;
214 
215     virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
216 
217     // processes frames
218     // dstBuffer is where to place the data
219     // dstFrames [in/out] is the desired frames (return with actual placed in buffer)
220     // srcBuffer is the source data
221     // srcFrames [in/out] is the available source frames (return with consumed)
222     virtual void processFrames(void *dstBuffer, size_t *dstFrames,
223             const void *srcBuffer, size_t *srcFrames);
224 
225 protected:
226     const uint32_t       mChannelCount;
227     const audio_format_t mFormat;
228     const uint32_t       mSampleRate; // const for now (TODO change this)
229     const size_t         mFrameSize;
230     AudioPlaybackRate    mPlaybackRate;
231 
232 private:
233     AudioBufferProvider::Buffer mBuffer;          // for upstream request
234     size_t               mLocalBufferFrameCount;  // size of local buffer
235     void                *mLocalBufferData;        // internally allocated buffer for data returned
236                                                   // to caller
237     size_t               mRemaining;              // remaining data in local buffer
238     sonicStream          mSonicStream;            // handle to sonic timestretch object
239     //FIXME: this dependency should be abstracted out
240     bool                 mFallbackFailErrorShown; // log fallback error only once
241     bool                 mAudioPlaybackRateValid; // flag for current parameters validity
242 };
243 
244 // AdjustChannelsBufferProvider derives from CopyBufferProvider to adjust sample data.
245 // Expands or contracts sample data from one interleaved channel format to another.
246 // Extra expanded channels are filled with zeros and put at the end of each audio frame.
247 // Contracted channels are copied to the end of the output buffer(storage should be
248 // allocated appropriately).
249 // Contracted channels could be written to output buffer and got adjusted. When the contracted
250 // channels are adjusted in the contracted buffer, the input channel count will be calculated
251 // as `inChannelCount - outChannelCount`. The output channel count is provided by caller, which
252 // is `contractedOutChannelCount`. Currently, adjusting contracted channels is used for audio
253 // coupled haptic playback. If the device supports two haptic channels while apps only provide
254 // single haptic channel, the second haptic channel will be duplicated with the first haptic
255 // channel's data. If the device supports single haptic channels while apps provide two haptic
256 // channels, the second channel will be contracted.
257 class AdjustChannelsBufferProvider : public CopyBufferProvider {
258 public:
259     // Contracted data is converted to contractedFormat and put into contractedBuffer.
260     AdjustChannelsBufferProvider(audio_format_t format, size_t inChannelCount,
261             size_t outChannelCount, size_t frameCount,
262             audio_format_t contractedFormat = AUDIO_FORMAT_INVALID,
263             void* contractedBuffer = nullptr,
264             size_t contractedOutChannelCount = 0);
265     //Overrides
266     status_t getNextBuffer(Buffer* pBuffer) override;
267     void copyFrames(void *dst, const void *src, size_t frames) override;
268     void reset() override;
269 
clearContractedFrames()270     void clearContractedFrames() { mContractedWrittenFrames = 0; }
271 
272 protected:
273     const audio_format_t mFormat;
274     const size_t         mInChannelCount;
275     const size_t         mOutChannelCount;
276     const size_t         mSampleSizeInBytes;
277     const size_t         mFrameCount;
278     const audio_format_t mContractedFormat;
279     const size_t         mContractedInChannelCount;
280     const size_t         mContractedOutChannelCount;
281     const size_t         mContractedSampleSizeInBytes;
282     const size_t         mContractedInputFrameSize; // contracted input frame size
283     void                *mContractedBuffer;
284     size_t               mContractedWrittenFrames;
285     size_t               mContractedOutputFrameSize; // contracted output frame size
286 };
287 
288 class TeeBufferProvider : public CopyBufferProvider {
289 public:
TeeBufferProvider(size_t inputFrameSize,size_t outputFrameSize,size_t bufferFrameCount,uint8_t * teeBuffer,int teeBufferFrameCount)290     TeeBufferProvider(
291             size_t inputFrameSize, size_t outputFrameSize,
292             size_t bufferFrameCount, uint8_t* teeBuffer, int teeBufferFrameCount)
293             : CopyBufferProvider(inputFrameSize, outputFrameSize, bufferFrameCount),
294               mTeeBuffer(teeBuffer), mTeeBufferFrameCount(teeBufferFrameCount),
295               mFrameCopied(0) {};
296 
297     void copyFrames(void *dst, const void *src, size_t frames) override;
298 
299     void clearFramesCopied();
300 
301 protected:
302     AudioBufferProvider *mTrackBufferProvider;
303     uint8_t* mTeeBuffer;
304     const int mTeeBufferFrameCount;
305     int mFrameCopied;
306 };
307 
308 // ----------------------------------------------------------------------------
309 } // namespace android
310 
311 #endif // ANDROID_BUFFER_PROVIDERS_H
312