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 
26 class AudioResampler;
27 class PassthruBufferProvider;
28 
29 namespace 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  */
42 class RecordBufferConverter
43 {
44 public:
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
initCheck()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 
81 private:
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