Andy Hung | 857d5a2 | 2015-03-26 18:46:00 -0700 | [diff] [blame] | 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 <hardware/audio_effect.h> |
| 24 | #include <media/AudioBufferProvider.h> |
| 25 | #include <system/audio.h> |
Ricardo Garcia | f097cae | 2015-04-13 12:17:21 -0700 | [diff] [blame] | 26 | #include <sonic.h> |
Andy Hung | 857d5a2 | 2015-03-26 18:46:00 -0700 | [diff] [blame] | 27 | |
| 28 | namespace android { |
| 29 | |
| 30 | // ---------------------------------------------------------------------------- |
| 31 | |
| 32 | class PassthruBufferProvider : public AudioBufferProvider { |
| 33 | public: |
| 34 | PassthruBufferProvider() : mTrackBufferProvider(NULL) { } |
| 35 | |
| 36 | virtual ~PassthruBufferProvider() { } |
| 37 | |
| 38 | // call this to release the buffer to the upstream provider. |
| 39 | // treat it as an audio discontinuity for future samples. |
| 40 | virtual void reset() { } |
| 41 | |
| 42 | // set the upstream buffer provider. Consider calling "reset" before this function. |
| 43 | virtual void setBufferProvider(AudioBufferProvider *p) { |
| 44 | mTrackBufferProvider = p; |
| 45 | } |
| 46 | |
| 47 | protected: |
| 48 | AudioBufferProvider *mTrackBufferProvider; |
| 49 | }; |
| 50 | |
| 51 | // Base AudioBufferProvider class used for DownMixerBufferProvider, RemixBufferProvider, |
| 52 | // and ReformatBufferProvider. |
| 53 | // It handles a private buffer for use in converting format or channel masks from the |
| 54 | // input data to a form acceptable by the mixer. |
| 55 | // TODO: Make a ResamplerBufferProvider when integers are entirely removed from the |
| 56 | // processing pipeline. |
| 57 | class CopyBufferProvider : public PassthruBufferProvider { |
| 58 | public: |
| 59 | // Use a private buffer of bufferFrameCount frames (each frame is outputFrameSize bytes). |
| 60 | // If bufferFrameCount is 0, no private buffer is created and in-place modification of |
| 61 | // the upstream buffer provider's buffers is performed by copyFrames(). |
| 62 | CopyBufferProvider(size_t inputFrameSize, size_t outputFrameSize, |
| 63 | size_t bufferFrameCount); |
| 64 | virtual ~CopyBufferProvider(); |
| 65 | |
| 66 | // Overrides AudioBufferProvider methods |
Glenn Kasten | d79072e | 2016-01-06 08:41:20 -0800 | [diff] [blame] | 67 | virtual status_t getNextBuffer(Buffer *buffer); |
Andy Hung | 857d5a2 | 2015-03-26 18:46:00 -0700 | [diff] [blame] | 68 | virtual void releaseBuffer(Buffer *buffer); |
| 69 | |
| 70 | // Overrides PassthruBufferProvider |
| 71 | virtual void reset(); |
| 72 | |
| 73 | // this function should be supplied by the derived class. It converts |
| 74 | // #frames in the *src pointer to the *dst pointer. It is public because |
| 75 | // some providers will allow this to work on arbitrary buffers outside |
| 76 | // of the internal buffers. |
| 77 | virtual void copyFrames(void *dst, const void *src, size_t frames) = 0; |
| 78 | |
| 79 | protected: |
| 80 | const size_t mInputFrameSize; |
| 81 | const size_t mOutputFrameSize; |
| 82 | private: |
| 83 | AudioBufferProvider::Buffer mBuffer; |
| 84 | const size_t mLocalBufferFrameCount; |
| 85 | void *mLocalBufferData; |
| 86 | size_t mConsumed; |
| 87 | }; |
| 88 | |
| 89 | // DownmixerBufferProvider derives from CopyBufferProvider to provide |
| 90 | // position dependent downmixing by an Audio Effect. |
| 91 | class DownmixerBufferProvider : public CopyBufferProvider { |
| 92 | public: |
| 93 | DownmixerBufferProvider(audio_channel_mask_t inputChannelMask, |
| 94 | audio_channel_mask_t outputChannelMask, audio_format_t format, |
| 95 | uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount); |
| 96 | virtual ~DownmixerBufferProvider(); |
| 97 | //Overrides |
| 98 | virtual void copyFrames(void *dst, const void *src, size_t frames); |
| 99 | |
| 100 | bool isValid() const { return mDownmixHandle != NULL; } |
| 101 | static status_t init(); |
| 102 | static bool isMultichannelCapable() { return sIsMultichannelCapable; } |
| 103 | |
| 104 | protected: |
| 105 | effect_handle_t mDownmixHandle; |
| 106 | effect_config_t mDownmixConfig; |
| 107 | |
| 108 | // effect descriptor for the downmixer used by the mixer |
| 109 | static effect_descriptor_t sDwnmFxDesc; |
| 110 | // indicates whether a downmix effect has been found and is usable by this mixer |
| 111 | static bool sIsMultichannelCapable; |
| 112 | // FIXME: should we allow effects outside of the framework? |
| 113 | // We need to here. A special ioId that must be <= -2 so it does not map to a session. |
| 114 | static const int32_t SESSION_ID_INVALID_AND_IGNORED = -2; |
| 115 | }; |
| 116 | |
| 117 | // RemixBufferProvider derives from CopyBufferProvider to perform an |
| 118 | // upmix or downmix to the proper channel count and mask. |
| 119 | class RemixBufferProvider : public CopyBufferProvider { |
| 120 | public: |
| 121 | RemixBufferProvider(audio_channel_mask_t inputChannelMask, |
| 122 | audio_channel_mask_t outputChannelMask, audio_format_t format, |
| 123 | size_t bufferFrameCount); |
| 124 | //Overrides |
| 125 | virtual void copyFrames(void *dst, const void *src, size_t frames); |
| 126 | |
| 127 | protected: |
| 128 | const audio_format_t mFormat; |
| 129 | const size_t mSampleSize; |
| 130 | const size_t mInputChannels; |
| 131 | const size_t mOutputChannels; |
| 132 | int8_t mIdxAry[sizeof(uint32_t) * 8]; // 32 bits => channel indices |
| 133 | }; |
| 134 | |
| 135 | // ReformatBufferProvider derives from CopyBufferProvider to convert the input data |
| 136 | // to an acceptable mixer input format type. |
| 137 | class ReformatBufferProvider : public CopyBufferProvider { |
| 138 | public: |
| 139 | ReformatBufferProvider(int32_t channelCount, |
| 140 | audio_format_t inputFormat, audio_format_t outputFormat, |
| 141 | size_t bufferFrameCount); |
| 142 | virtual void copyFrames(void *dst, const void *src, size_t frames); |
| 143 | |
| 144 | protected: |
| 145 | const uint32_t mChannelCount; |
| 146 | const audio_format_t mInputFormat; |
| 147 | const audio_format_t mOutputFormat; |
| 148 | }; |
| 149 | |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 150 | // TimestretchBufferProvider derives from PassthruBufferProvider for time stretching |
| 151 | class TimestretchBufferProvider : public PassthruBufferProvider { |
| 152 | public: |
| 153 | TimestretchBufferProvider(int32_t channelCount, |
Ricardo Garcia | 5a8a95d | 2015-04-18 14:47:04 -0700 | [diff] [blame] | 154 | audio_format_t format, uint32_t sampleRate, |
| 155 | const AudioPlaybackRate &playbackRate); |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 156 | virtual ~TimestretchBufferProvider(); |
| 157 | |
| 158 | // Overrides AudioBufferProvider methods |
Glenn Kasten | d79072e | 2016-01-06 08:41:20 -0800 | [diff] [blame] | 159 | virtual status_t getNextBuffer(Buffer* buffer); |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 160 | virtual void releaseBuffer(Buffer* buffer); |
| 161 | |
| 162 | // Overrides PassthruBufferProvider |
| 163 | virtual void reset(); |
| 164 | |
Ricardo Garcia | 5a8a95d | 2015-04-18 14:47:04 -0700 | [diff] [blame] | 165 | virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate); |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 166 | |
| 167 | // processes frames |
| 168 | // dstBuffer is where to place the data |
| 169 | // dstFrames [in/out] is the desired frames (return with actual placed in buffer) |
| 170 | // srcBuffer is the source data |
| 171 | // srcFrames [in/out] is the available source frames (return with consumed) |
| 172 | virtual void processFrames(void *dstBuffer, size_t *dstFrames, |
| 173 | const void *srcBuffer, size_t *srcFrames); |
| 174 | |
| 175 | protected: |
| 176 | const uint32_t mChannelCount; |
| 177 | const audio_format_t mFormat; |
| 178 | const uint32_t mSampleRate; // const for now (TODO change this) |
| 179 | const size_t mFrameSize; |
Ricardo Garcia | 5a8a95d | 2015-04-18 14:47:04 -0700 | [diff] [blame] | 180 | AudioPlaybackRate mPlaybackRate; |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 181 | |
| 182 | private: |
Ricardo Garcia | 5a8a95d | 2015-04-18 14:47:04 -0700 | [diff] [blame] | 183 | AudioBufferProvider::Buffer mBuffer; // for upstream request |
| 184 | size_t mLocalBufferFrameCount; // size of local buffer |
| 185 | void *mLocalBufferData; // internally allocated buffer for data returned |
| 186 | // to caller |
| 187 | size_t mRemaining; // remaining data in local buffer |
| 188 | sonicStream mSonicStream; // handle to sonic timestretch object |
| 189 | //FIXME: this dependency should be abstracted out |
| 190 | bool mFallbackFailErrorShown; // log fallback error only once |
Ricardo Garcia | 6c7f062 | 2015-04-30 18:39:16 -0700 | [diff] [blame] | 191 | bool mAudioPlaybackRateValid; // flag for current parameters validity |
Andy Hung | c5656cc | 2015-03-26 19:04:33 -0700 | [diff] [blame] | 192 | }; |
| 193 | |
Andy Hung | 857d5a2 | 2015-03-26 18:46:00 -0700 | [diff] [blame] | 194 | // ---------------------------------------------------------------------------- |
| 195 | } // namespace android |
| 196 | |
| 197 | #endif // ANDROID_BUFFER_PROVIDERS_H |