xref: /aosp_15_r20/cts/apps/CtsVerifier/jni/megaaudio/player/WaveTableSource.h (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker  * Copyright 2020 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker  *
4*b7c941bbSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker  *
8*b7c941bbSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker  *
10*b7c941bbSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker  * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker  */
16*b7c941bbSAndroid Build Coastguard Worker 
17*b7c941bbSAndroid Build Coastguard Worker #ifndef MEGA_PLAYER_WAVETABLESOURCE_H
18*b7c941bbSAndroid Build Coastguard Worker #define MEGA_PLAYER_WAVETABLESOURCE_H
19*b7c941bbSAndroid Build Coastguard Worker 
20*b7c941bbSAndroid Build Coastguard Worker #include <memory>
21*b7c941bbSAndroid Build Coastguard Worker 
22*b7c941bbSAndroid Build Coastguard Worker #include "AudioSource.h"
23*b7c941bbSAndroid Build Coastguard Worker 
24*b7c941bbSAndroid Build Coastguard Worker class WaveTableSource: public AudioSource {
25*b7c941bbSAndroid Build Coastguard Worker public:
26*b7c941bbSAndroid Build Coastguard Worker     /**
27*b7c941bbSAndroid Build Coastguard Worker      * Constructor. Sets up to play samples from the provided wave table.
28*b7c941bbSAndroid Build Coastguard Worker      * @param waveTbl Contains the samples defining a single cycle of the desired waveform.
29*b7c941bbSAndroid Build Coastguard Worker      */
30*b7c941bbSAndroid Build Coastguard Worker     WaveTableSource();
31*b7c941bbSAndroid Build Coastguard Worker 
32*b7c941bbSAndroid Build Coastguard Worker     /**
33*b7c941bbSAndroid Build Coastguard Worker      * Sets up to play samples from the provided wave table.
34*b7c941bbSAndroid Build Coastguard Worker      * @param waveTbl Contains the samples defining a single cycle of the desired waveform.
35*b7c941bbSAndroid Build Coastguard Worker      *                This wave table contains a redundant sample in the last slot (== first slot)
36*b7c941bbSAndroid Build Coastguard Worker      *                to make the interpolation calculation simpler, so the logical length of
37*b7c941bbSAndroid Build Coastguard Worker      *                the wave table is one less than the length of the array.
38*b7c941bbSAndroid Build Coastguard Worker      * NOTE: WaveTableSource DOES NOT take ownership of the wave table. The user of WaveTableSource
39*b7c941bbSAndroid Build Coastguard Worker      * is responsible for managing the lifetime of othe wave table.
40*b7c941bbSAndroid Build Coastguard Worker      */
setWaveTable(float * waveTable,int length)41*b7c941bbSAndroid Build Coastguard Worker     void setWaveTable(float* waveTable, int length) {
42*b7c941bbSAndroid Build Coastguard Worker         mWaveTable = waveTable;
43*b7c941bbSAndroid Build Coastguard Worker         mNumWaveTableSamples = length - 1;
44*b7c941bbSAndroid Build Coastguard Worker 
45*b7c941bbSAndroid Build Coastguard Worker         calcFN();
46*b7c941bbSAndroid Build Coastguard Worker     }
47*b7c941bbSAndroid Build Coastguard Worker 
48*b7c941bbSAndroid Build Coastguard Worker     /**
49*b7c941bbSAndroid Build Coastguard Worker      * Sets the playback sample rate for which samples will be generated.
50*b7c941bbSAndroid Build Coastguard Worker      * @param sampleRate
51*b7c941bbSAndroid Build Coastguard Worker      */
52*b7c941bbSAndroid Build Coastguard Worker     void setSampleRate(int sampleRate);
53*b7c941bbSAndroid Build Coastguard Worker 
54*b7c941bbSAndroid Build Coastguard Worker     /**
55*b7c941bbSAndroid Build Coastguard Worker      * Set the frequency of the output signal.
56*b7c941bbSAndroid Build Coastguard Worker      * @param freq  Signal frequency in Hz.
57*b7c941bbSAndroid Build Coastguard Worker      */
setFreq(float freq)58*b7c941bbSAndroid Build Coastguard Worker     void setFreq(float freq) {
59*b7c941bbSAndroid Build Coastguard Worker         mFreq = freq;
60*b7c941bbSAndroid Build Coastguard Worker     }
61*b7c941bbSAndroid Build Coastguard Worker 
62*b7c941bbSAndroid Build Coastguard Worker     /**
63*b7c941bbSAndroid Build Coastguard Worker      * Resets the playback position to the 1st sample.
64*b7c941bbSAndroid Build Coastguard Worker      */
reset()65*b7c941bbSAndroid Build Coastguard Worker     void reset()  override {
66*b7c941bbSAndroid Build Coastguard Worker         mSrcPhase = 0.0f;
67*b7c941bbSAndroid Build Coastguard Worker     }
68*b7c941bbSAndroid Build Coastguard Worker 
69*b7c941bbSAndroid Build Coastguard Worker     virtual int getNumChannels() override;
70*b7c941bbSAndroid Build Coastguard Worker 
71*b7c941bbSAndroid Build Coastguard Worker     virtual int getEncoding() override;
72*b7c941bbSAndroid Build Coastguard Worker 
73*b7c941bbSAndroid Build Coastguard Worker     /**
74*b7c941bbSAndroid Build Coastguard Worker      * Fills the specified buffer with values generated from the wave table which will playback
75*b7c941bbSAndroid Build Coastguard Worker      * at the specified frequency.
76*b7c941bbSAndroid Build Coastguard Worker      *
77*b7c941bbSAndroid Build Coastguard Worker      * @param buffer The buffer to be filled.
78*b7c941bbSAndroid Build Coastguard Worker      * @param numFrames The number of frames of audio to provide.
79*b7c941bbSAndroid Build Coastguard Worker      * @param numChans The number of channels (in the buffer) required by the player.
80*b7c941bbSAndroid Build Coastguard Worker      * @return  The number of samples generated. Since we are generating a continuous periodic
81*b7c941bbSAndroid Build Coastguard Worker      * signal, this will always be <code>numFrames</code>.
82*b7c941bbSAndroid Build Coastguard Worker      */
83*b7c941bbSAndroid Build Coastguard Worker     virtual int pull(float* buffer, int numFrames, int numChans) override;
84*b7c941bbSAndroid Build Coastguard Worker 
85*b7c941bbSAndroid Build Coastguard Worker     /*
86*b7c941bbSAndroid Build Coastguard Worker      * Standard wavetable generators
87*b7c941bbSAndroid Build Coastguard Worker      */
88*b7c941bbSAndroid Build Coastguard Worker     static void genSinWave(float* buffer, int length);
89*b7c941bbSAndroid Build Coastguard Worker     static void genTriangleWave(float* buffer, int size, float maxValue, float minValue,
90*b7c941bbSAndroid Build Coastguard Worker                                            float dutyCycle);
91*b7c941bbSAndroid Build Coastguard Worker     static void genPulseWave(float* buffer, int size,float maxValue, float minValue,
92*b7c941bbSAndroid Build Coastguard Worker                                             float dutyCycle);
93*b7c941bbSAndroid Build Coastguard Worker 
94*b7c941bbSAndroid Build Coastguard Worker protected:
95*b7c941bbSAndroid Build Coastguard Worker     static const int DEFAULT_WAVETABLE_LENGTH = 2049;
96*b7c941bbSAndroid Build Coastguard Worker 
97*b7c941bbSAndroid Build Coastguard Worker     /**
98*b7c941bbSAndroid Build Coastguard Worker      * Calculates the "Nominal" frequency of the wave table.
99*b7c941bbSAndroid Build Coastguard Worker      */
100*b7c941bbSAndroid Build Coastguard Worker     void calcFN();
101*b7c941bbSAndroid Build Coastguard Worker 
102*b7c941bbSAndroid Build Coastguard Worker     /** The samples defining one cycle of the waveform to play */
103*b7c941bbSAndroid Build Coastguard Worker     //TODO - make this a shared_ptr
104*b7c941bbSAndroid Build Coastguard Worker     float*  mWaveTable;
105*b7c941bbSAndroid Build Coastguard Worker 
106*b7c941bbSAndroid Build Coastguard Worker     /** The number of samples in the wave table. Note that the wave table is presumed to contain
107*b7c941bbSAndroid Build Coastguard Worker      * an "extra" sample (a copy of the 1st sample) in order to simplify the interpolation
108*b7c941bbSAndroid Build Coastguard Worker      * calculation. Thus, this value will be 1 less than the length of mWaveTable.
109*b7c941bbSAndroid Build Coastguard Worker      */
110*b7c941bbSAndroid Build Coastguard Worker     int mNumWaveTableSamples;
111*b7c941bbSAndroid Build Coastguard Worker 
112*b7c941bbSAndroid Build Coastguard Worker     /** The phase (offset within the wave table) of the next output sample.
113*b7c941bbSAndroid Build Coastguard Worker      *  Note that this may (will) be a fractional value. Range 0.0 -> mNumWaveTableSamples.
114*b7c941bbSAndroid Build Coastguard Worker      */
115*b7c941bbSAndroid Build Coastguard Worker     float mSrcPhase;
116*b7c941bbSAndroid Build Coastguard Worker 
117*b7c941bbSAndroid Build Coastguard Worker     /** The sample rate at which playback occurs */
118*b7c941bbSAndroid Build Coastguard Worker     float mSampleRate = 48000;  // This seems likely, but can be changed
119*b7c941bbSAndroid Build Coastguard Worker 
120*b7c941bbSAndroid Build Coastguard Worker     /** The frequency of the generated audio signal */
121*b7c941bbSAndroid Build Coastguard Worker     float mFreq = 1000;         // Some reasonable default frequency
122*b7c941bbSAndroid Build Coastguard Worker 
123*b7c941bbSAndroid Build Coastguard Worker     /** The "Nominal" frequency of the wavetable. i.e., the frequency that would be generated if
124*b7c941bbSAndroid Build Coastguard Worker      * each sample in the wave table was sent in turn to the output at the specified sample rate.
125*b7c941bbSAndroid Build Coastguard Worker      */
126*b7c941bbSAndroid Build Coastguard Worker     float mFN;
127*b7c941bbSAndroid Build Coastguard Worker 
128*b7c941bbSAndroid Build Coastguard Worker     /** 1 / mFN. Calculated when mFN is set to avoid a division on each call to fill() */
129*b7c941bbSAndroid Build Coastguard Worker     float mFNInverse;
130*b7c941bbSAndroid Build Coastguard Worker };
131*b7c941bbSAndroid Build Coastguard Worker 
132*b7c941bbSAndroid Build Coastguard Worker #endif // MEGA_PLAYER_WAVETABLESOURCE_H
133