Home | History | Annotate | Download | only in utils
      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:
     25     SineGenerator() {}
     26     virtual ~SineGenerator() = default;
     27 
     28     void setup(double frequency, double frameRate) {
     29         mFrameRate = frameRate;
     30         mPhaseIncrement = frequency * M_PI * 2 / frameRate;
     31     }
     32 
     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 
     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     }
     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     void setAmplitude(double amplitude) {
     62         mAmplitude = amplitude;
     63     }
     64     double getAmplitude() const {
     65         return mAmplitude;
     66     }
     67 
     68 private:
     69     void advancePhase() {
     70         mPhase += mPhaseIncrement;
     71         if (mPhase > M_PI * 2) {
     72             mPhase -= M_PI * 2;
     73         }
     74         if (mSweeping) {
     75             if (mGoingUp) {
     76                 mPhaseIncrement *= mUpScaler;
     77                 if (mPhaseIncrement > mPhaseIncrementHigh) {
     78                     mGoingUp = false;
     79                 }
     80             } else {
     81                 mPhaseIncrement *= mDownScaler;
     82                 if (mPhaseIncrement < mPhaseIncrementLow) {
     83                     mGoingUp = true;
     84                 }
     85             }
     86         }
     87     }
     88 
     89     double mAmplitude = 0.05;  // unitless scaler
     90     double mPhase = 0.0;
     91     double mPhaseIncrement = 440 * M_PI * 2 / 48000;
     92     double mFrameRate = 48000;
     93     double mPhaseIncrementLow;
     94     double mPhaseIncrementHigh;
     95     double mUpScaler = 1.0;
     96     double mDownScaler = 1.0;
     97     bool   mGoingUp = false;
     98     bool   mSweeping = false;
     99 };
    100 
    101 #endif /* SINE_GENERATOR_H */
    102 
    103