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         mPhaseIncrementLow = frequencyLow * M_PI * 2 / mFrameRate;
35         mPhaseIncrementHigh = frequencyHigh * M_PI * 2 / mFrameRate;
36 
37         double numFrames = seconds * mFrameRate;
38         mUpScaler = pow((frequencyHigh / frequencyLow), (1.0 / numFrames));
39         mDownScaler = 1.0 / mUpScaler;
40         mGoingUp = true;
41         mSweeping = true;
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) (32767 * 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 
61 private:
advancePhase()62     void advancePhase() {
63         mPhase += mPhaseIncrement;
64         if (mPhase > M_PI * 2) {
65             mPhase -= M_PI * 2;
66         }
67         if (mSweeping) {
68             if (mGoingUp) {
69                 mPhaseIncrement *= mUpScaler;
70                 if (mPhaseIncrement > mPhaseIncrementHigh) {
71                     mGoingUp = false;
72                 }
73             } else {
74                 mPhaseIncrement *= mDownScaler;
75                 if (mPhaseIncrement < mPhaseIncrementLow) {
76                     mGoingUp = true;
77                 }
78             }
79         }
80     }
81 
82     double mAmplitude = 0.05;  // unitless scaler
83     double mPhase = 0.0;
84     double mPhaseIncrement = 440 * M_PI * 2 / 48000;
85     double mFrameRate = 48000;
86     double mPhaseIncrementLow;
87     double mPhaseIncrementHigh;
88     double mUpScaler = 1.0;
89     double mDownScaler = 1.0;
90     bool   mGoingUp = false;
91     bool   mSweeping = false;
92 };
93 
94 #endif /* SINE_GENERATOR_H */
95 
96