1/*
2 * Copyright (C) 2017 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_RECORD_BUFFER_CONVERTER_H
18#define ANDROID_RECORD_BUFFER_CONVERTER_H
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <media/AudioBufferProvider.h>
24#include <system/audio.h>
25
26class AudioResampler;
27class PassthruBufferProvider;
28
29namespace android {
30
31/* The RecordBufferConverter is used for format, channel, and sample rate
32 * conversion for a RecordTrack.
33 *
34 * RecordBufferConverter uses the convert() method rather than exposing a
35 * buffer provider interface; this is to save a memory copy.
36 *
37 * There are legacy conversion requirements for this converter, specifically
38 * due to mono handling, so be careful about modifying.
39 *
40 * Original source audioflinger/Threads.{h,cpp}
41 */
42class RecordBufferConverter
43{
44public:
45    RecordBufferConverter(
46            audio_channel_mask_t srcChannelMask, audio_format_t srcFormat,
47            uint32_t srcSampleRate,
48            audio_channel_mask_t dstChannelMask, audio_format_t dstFormat,
49            uint32_t dstSampleRate);
50
51    ~RecordBufferConverter();
52
53    /* Converts input data from an AudioBufferProvider by format, channelMask,
54     * and sampleRate to a destination buffer.
55     *
56     * Parameters
57     *      dst:  buffer to place the converted data.
58     * provider:  buffer provider to obtain source data.
59     *   frames:  number of frames to convert
60     *
61     * Returns the number of frames converted.
62     */
63    size_t convert(void *dst, AudioBufferProvider *provider, size_t frames);
64
65    // returns NO_ERROR if constructor was successful
66    status_t initCheck() const {
67        // mSrcChannelMask set on successful updateParameters
68        return mSrcChannelMask != AUDIO_CHANNEL_INVALID ? NO_ERROR : NO_INIT;
69    }
70
71    // allows dynamic reconfigure of all parameters
72    status_t updateParameters(
73            audio_channel_mask_t srcChannelMask, audio_format_t srcFormat,
74            uint32_t srcSampleRate,
75            audio_channel_mask_t dstChannelMask, audio_format_t dstFormat,
76            uint32_t dstSampleRate);
77
78    // called to reset resampler buffers on record track discontinuity
79    void reset();
80
81private:
82    // format conversion when not using resampler
83    void convertNoResampler(void *dst, const void *src, size_t frames);
84
85    // format conversion when using resampler; modifies src in-place
86    void convertResampler(void *dst, /*not-a-const*/ void *src, size_t frames);
87
88    // user provided information
89    audio_channel_mask_t mSrcChannelMask;
90    audio_format_t       mSrcFormat;
91    uint32_t             mSrcSampleRate;
92    audio_channel_mask_t mDstChannelMask;
93    audio_format_t       mDstFormat;
94    uint32_t             mDstSampleRate;
95
96    // derived information
97    uint32_t             mSrcChannelCount;
98    uint32_t             mDstChannelCount;
99    size_t               mDstFrameSize;
100
101    // format conversion buffer
102    void                *mBuf;
103    size_t               mBufFrames;
104    size_t               mBufFrameSize;
105
106    // resampler info
107    AudioResampler      *mResampler;
108
109    bool                 mIsLegacyDownmix;  // legacy stereo to mono conversion needed
110    bool                 mIsLegacyUpmix;    // legacy mono to stereo conversion needed
111    bool                 mRequiresFloat;    // data processing requires float (e.g. resampler)
112    PassthruBufferProvider *mInputConverterProvider;    // converts input to float
113    int8_t               mIdxAry[sizeof(uint32_t) * 8]; // used for channel mask conversion
114};
115
116// ----------------------------------------------------------------------------
117} // namespace android
118
119#endif // ANDROID_RECORD_BUFFER_CONVERTER_H
120