• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
145 protected:
146     audio_utils::channels::ChannelMix mChannelMix;
147     bool mIsValid = false;
148 };
149 
150 // RemixBufferProvider derives from CopyBufferProvider to perform an
151 // upmix or downmix to the proper channel count and mask.
152 class RemixBufferProvider : public CopyBufferProvider {
153 public:
154     RemixBufferProvider(audio_channel_mask_t inputChannelMask,
155             audio_channel_mask_t outputChannelMask, audio_format_t format,
156             size_t bufferFrameCount);
157     //Overrides
158     virtual void copyFrames(void *dst, const void *src, size_t frames);
159 
160 protected:
161     const audio_format_t mFormat;
162     const size_t         mSampleSize;
163     const size_t         mInputChannels;
164     const size_t         mOutputChannels;
165     int8_t               mIdxAry[sizeof(uint32_t) * 8]; // 32 bits => channel indices
166 };
167 
168 // ReformatBufferProvider derives from CopyBufferProvider to convert the input data
169 // to an acceptable mixer input format type.
170 class ReformatBufferProvider : public CopyBufferProvider {
171 public:
172     ReformatBufferProvider(int32_t channelCount,
173             audio_format_t inputFormat, audio_format_t outputFormat,
174             size_t bufferFrameCount);
175     virtual void copyFrames(void *dst, const void *src, size_t frames);
176 
177 protected:
178     const uint32_t       mChannelCount;
179     const audio_format_t mInputFormat;
180     const audio_format_t mOutputFormat;
181 };
182 
183 // ClampFloatBufferProvider derives from CopyBufferProvider to clamp floats inside -3db
184 class ClampFloatBufferProvider : public CopyBufferProvider {
185 public:
186     ClampFloatBufferProvider(int32_t channelCount,
187             size_t bufferFrameCount);
188     virtual void copyFrames(void *dst, const void *src, size_t frames);
189 
190 protected:
191     const uint32_t       mChannelCount;
192 };
193 
194 // TimestretchBufferProvider derives from PassthruBufferProvider for time stretching
195 class TimestretchBufferProvider : public PassthruBufferProvider {
196 public:
197     TimestretchBufferProvider(int32_t channelCount,
198             audio_format_t format, uint32_t sampleRate,
199             const AudioPlaybackRate &playbackRate);
200     virtual ~TimestretchBufferProvider();
201 
202     // Overrides AudioBufferProvider methods
203     virtual status_t getNextBuffer(Buffer* buffer);
204     virtual void releaseBuffer(Buffer* buffer);
205 
206     // Overrides PassthruBufferProvider
207     virtual void reset();
208     void setBufferProvider(AudioBufferProvider *p) override;
209 
210     virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
211 
212     // processes frames
213     // dstBuffer is where to place the data
214     // dstFrames [in/out] is the desired frames (return with actual placed in buffer)
215     // srcBuffer is the source data
216     // srcFrames [in/out] is the available source frames (return with consumed)
217     virtual void processFrames(void *dstBuffer, size_t *dstFrames,
218             const void *srcBuffer, size_t *srcFrames);
219 
220 protected:
221     const uint32_t       mChannelCount;
222     const audio_format_t mFormat;
223     const uint32_t       mSampleRate; // const for now (TODO change this)
224     const size_t         mFrameSize;
225     AudioPlaybackRate    mPlaybackRate;
226 
227 private:
228     AudioBufferProvider::Buffer mBuffer;          // for upstream request
229     size_t               mLocalBufferFrameCount;  // size of local buffer
230     void                *mLocalBufferData;        // internally allocated buffer for data returned
231                                                   // to caller
232     size_t               mRemaining;              // remaining data in local buffer
233     sonicStream          mSonicStream;            // handle to sonic timestretch object
234     //FIXME: this dependency should be abstracted out
235     bool                 mFallbackFailErrorShown; // log fallback error only once
236     bool                 mAudioPlaybackRateValid; // flag for current parameters validity
237 };
238 
239 // AdjustChannelsBufferProvider derives from CopyBufferProvider to adjust sample data.
240 // Expands or contracts sample data from one interleaved channel format to another.
241 // Extra expanded channels are filled with zeros and put at the end of each audio frame.
242 // Contracted channels are copied to the end of the output buffer(storage should be
243 // allocated appropriately).
244 // Contracted channels could be written to output buffer and got adjusted. When the contracted
245 // channels are adjusted in the contracted buffer, the input channel count will be calculated
246 // as `inChannelCount - outChannelCount`. The output channel count is provided by caller, which
247 // is `contractedOutChannelCount`. Currently, adjusting contracted channels is used for audio
248 // coupled haptic playback. If the device supports two haptic channels while apps only provide
249 // single haptic channel, the second haptic channel will be duplicated with the first haptic
250 // channel's data. If the device supports single haptic channels while apps provide two haptic
251 // channels, the second channel will be contracted.
252 class AdjustChannelsBufferProvider : public CopyBufferProvider {
253 public:
254     // Contracted data is converted to contractedFormat and put into contractedBuffer.
255     AdjustChannelsBufferProvider(audio_format_t format, size_t inChannelCount,
256             size_t outChannelCount, size_t frameCount,
257             audio_format_t contractedFormat = AUDIO_FORMAT_INVALID,
258             void* contractedBuffer = nullptr,
259             size_t contractedOutChannelCount = 0);
260     //Overrides
261     status_t getNextBuffer(Buffer* pBuffer) override;
262     void copyFrames(void *dst, const void *src, size_t frames) override;
263     void reset() override;
264 
clearContractedFrames()265     void clearContractedFrames() { mContractedWrittenFrames = 0; }
266 
267 protected:
268     const audio_format_t mFormat;
269     const size_t         mInChannelCount;
270     const size_t         mOutChannelCount;
271     const size_t         mSampleSizeInBytes;
272     const size_t         mFrameCount;
273     const audio_format_t mContractedFormat;
274     const size_t         mContractedInChannelCount;
275     const size_t         mContractedOutChannelCount;
276     const size_t         mContractedSampleSizeInBytes;
277     const size_t         mContractedInputFrameSize; // contracted input frame size
278     void                *mContractedBuffer;
279     size_t               mContractedWrittenFrames;
280     size_t               mContractedOutputFrameSize; // contracted output frame size
281 };
282 // ----------------------------------------------------------------------------
283 } // namespace android
284 
285 #endif // ANDROID_BUFFER_PROVIDERS_H
286