1 /*
2  * Copyright (C) 2016 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 SINE_GENERATOR_H
18 #define SINE_GENERATOR_H
19 
20 #include <math.h>
21 
22 class SineGenerator
23 {
24 public:
SineGenerator()25     SineGenerator() {}
26     virtual ~SineGenerator() = default;
27 
setup(double frequency,double frameRate)28     void setup(double frequency, double frameRate) {
29         mFrameRate = frameRate;
30         mPhaseIncrement = frequency * M_PI * 2 / frameRate;
31     }
32 
setSweep(double frequencyLow,double frequencyHigh,double seconds)33     void setSweep(double frequencyLow, double frequencyHigh, double seconds) {
34         mSweeping = seconds > 0.0;
35         if (mSweeping) {
36             mPhaseIncrementLow = frequencyLow * M_PI * 2 / mFrameRate;
37             mPhaseIncrementHigh = frequencyHigh * M_PI * 2 / mFrameRate;
38             double numFrames = seconds * mFrameRate;
39             mUpScaler = pow((frequencyHigh / frequencyLow), (1.0 / numFrames));
40             mDownScaler = 1.0 / mUpScaler;
41         }
42     }
43 
render(int16_t * buffer,int32_t channelStride,int32_t numFrames)44     void render(int16_t *buffer, int32_t channelStride, int32_t numFrames) {
45         int sampleIndex = 0;
46         for (int i = 0; i < numFrames; i++) {
47             buffer[sampleIndex] = (int16_t) (INT16_MAX * sin(mPhase) * mAmplitude);
48             sampleIndex += channelStride;
49             advancePhase();
50         }
51     }
render(float * buffer,int32_t channelStride,int32_t numFrames)52     void render(float *buffer, int32_t channelStride, int32_t numFrames) {
53         int sampleIndex = 0;
54         for (int i = 0; i < numFrames; i++) {
55             buffer[sampleIndex] = sin(mPhase) * mAmplitude;
56             sampleIndex += channelStride;
57             advancePhase();
58         }
59     }
60 
setAmplitude(double amplitude)61     void setAmplitude(double amplitude) {
62         mAmplitude = amplitude;
63     }
64 
getAmplitude()65     double getAmplitude() const {
66         return mAmplitude;
67     }
68 
69 private:
advancePhase()70     void advancePhase() {
71         mPhase += mPhaseIncrement;
72         if (mPhase > M_PI * 2) {
73             mPhase -= M_PI * 2;
74         }
75         if (mSweeping) {
76             if (mGoingUp) {
77                 mPhaseIncrement *= mUpScaler;
78                 if (mPhaseIncrement > mPhaseIncrementHigh) {
79                     mGoingUp = false;
80                 }
81             } else {
82                 mPhaseIncrement *= mDownScaler;
83                 if (mPhaseIncrement < mPhaseIncrementLow) {
84                     mGoingUp = true;
85                 }
86             }
87         }
88     }
89 
90     double mAmplitude = 0.05;  // unitless scaler
91     double mPhase = 0.0;
92     double mPhaseIncrement = 440 * M_PI * 2 / 48000;
93     double mFrameRate = 48000;
94     double mPhaseIncrementLow;
95     double mPhaseIncrementHigh;
96     double mUpScaler = 1.0;
97     double mDownScaler = 1.0;
98     bool   mGoingUp = false;
99     bool   mSweeping = false;
100 };
101 
102 #endif /* SINE_GENERATOR_H */
103 
104