1 /*
2  * Copyright (C) 2018 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_AAUDIO_FLOW_GRAPH_H
18 #define ANDROID_AAUDIO_FLOW_GRAPH_H
19 
20 #include <memory>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <system/audio.h>
24 
25 #include <aaudio/AAudio.h>
26 #include <audio_utils/Balance.h>
27 #include <flowgraph/Limiter.h>
28 #include <flowgraph/ManyToMultiConverter.h>
29 #include <flowgraph/MonoBlend.h>
30 #include <flowgraph/MonoToMultiConverter.h>
31 #include <flowgraph/MultiToManyConverter.h>
32 #include <flowgraph/RampLinear.h>
33 #include <flowgraph/SampleRateConverter.h>
34 
35 class AAudioFlowGraph {
36 public:
37     /** Connect several modules together to convert from source to sink.
38      * This should only be called once for each instance.
39      *
40      * @param sourceFormat
41      * @param sourceChannelCount
42      * @param sourceSampleRate
43      * @param sinkFormat
44      * @param sinkChannelCount
45      * @param sinkSampleRate
46      * @param useMonoBlend
47      * @param useVolumeRamps
48      * @param audioBalance
49      * @param resamplerQuality
50      * @return
51      */
52     aaudio_result_t configure(audio_format_t sourceFormat,
53                               int32_t sourceChannelCount,
54                               int32_t sourceSampleRate,
55                               audio_format_t sinkFormat,
56                               int32_t sinkChannelCount,
57                               int32_t sinkSampleRate,
58                               bool useMonoBlend,
59                               bool useVolumeRamps,
60                               float audioBalance,
61                               aaudio::resampler::MultiChannelResampler::Quality resamplerQuality);
62 
63     /**
64      * Attempt to read targetFramesToRead from the flowgraph.
65      * This function returns the number of frames actually read.
66      *
67      * This function does nothing if process() was not called before.
68      *
69      * @param destination
70      * @param targetFramesToRead
71      * @return numFramesRead
72      */
73     int32_t pull(void *destination, int32_t targetFramesToRead);
74 
75     // Reset the entire graph so that volume ramps start at their
76     // target value and sample rate converters start with no phase offset.
reset()77     void reset() {
78         mSink->pullReset();
79     }
80 
81     /**
82      * Set numFramesToWrite frames from the source into the flowgraph.
83      * Then, attempt to read targetFramesToRead from the flowgraph.
84      * This function returns the number of frames actually read.
85      *
86      * There may be data still in the flowgraph if targetFramesToRead is not large enough.
87      * Before calling process() again, pull() must be called until until all the data is consumed.
88      *
89      * TODO: b/289510598 - Calculate the exact number of input frames needed for Y output frames.
90      *
91      * @param source
92      * @param numFramesToWrite
93      * @param destination
94      * @param targetFramesToRead
95      * @return numFramesRead
96      */
97     int32_t process(const void *source, int32_t numFramesToWrite, void *destination,
98                     int32_t targetFramesToRead);
99 
100     /**
101      * @param volume between 0.0 and 1.0
102      */
103     void setTargetVolume(float volume);
104 
105     /**
106      * @param audioBalance between -1.0 and 1.0
107      */
108     void setAudioBalance(float audioBalance);
109 
110     /**
111      * @param numFrames to slowly adjust for volume changes
112      */
113     void setRampLengthInFrames(int32_t numFrames);
114 
115 private:
116     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSourceBuffered> mSource;
117     std::unique_ptr<RESAMPLER_OUTER_NAMESPACE::resampler::MultiChannelResampler> mResampler;
118     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::SampleRateConverter> mRateConverter;
119     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoBlend> mMonoBlend;
120     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::Limiter> mLimiter;
121     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoToMultiConverter> mChannelConverter;
122     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::ManyToMultiConverter>
123             mManyToMultiConverter;
124     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MultiToManyConverter>
125             mMultiToManyConverter;
126     std::vector<std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::RampLinear>> mVolumeRamps;
127     std::vector<float> mPanningVolumes;
128     float mTargetVolume = 1.0f;
129     android::audio_utils::Balance mBalance;
130     std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSink> mSink;
131 };
132 
133 
134 #endif //ANDROID_AAUDIO_FLOW_GRAPH_H
135