1 /* 2 * Copyright 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 NATIVEOBOE_OSCILLATORBASE_H 18 #define NATIVEOBOE_OSCILLATORBASE_H 19 20 #include "flowgraph/FlowGraphNode.h" 21 22 /** 23 * Base class for various oscillators. 24 * The oscillator has a phase that ranges from -1.0 to +1.0. 25 * That makes it easier to implement simple algebraic waveforms. 26 * 27 * Subclasses must implement onProcess(). 28 * 29 * This module has "frequency" and "amplitude" ports for control. 30 */ 31 32 class OscillatorBase : public oboe::flowgraph::FlowGraphNode { 33 public: 34 OscillatorBase(); 35 36 virtual ~OscillatorBase() = default; 37 setSampleRate(float sampleRate)38 void setSampleRate(float sampleRate) { 39 mSampleRate = sampleRate; 40 mFrequencyToPhaseIncrement = 2.0f / sampleRate; // -1 to +1 is a range of 2 41 } 42 getSampleRate()43 float getSampleRate() { 44 return mSampleRate; 45 } 46 47 /** 48 * This can be used to set the initial phase of an oscillator before starting. 49 * This is mostly used with an LFO. 50 * Calling this while the oscillator is running will cause sharp pops. 51 * @param phase between -1.0 and +1.0 52 */ setPhase(float phase)53 void setPhase(float phase) { 54 mPhase = phase; 55 } 56 getPhase()57 float getPhase() { 58 return mPhase; 59 } 60 61 /** 62 * Control the frequency of the oscillator in Hz. 63 */ 64 oboe::flowgraph::FlowGraphPortFloatInput frequency; 65 66 /** 67 * Control the linear amplitude of the oscillator. 68 * Silence is 0.0. 69 * A typical full amplitude would be 1.0. 70 */ 71 oboe::flowgraph::FlowGraphPortFloatInput amplitude; 72 73 oboe::flowgraph::FlowGraphPortFloatOutput output; 74 75 protected: 76 /** 77 * Increment phase based on frequency in Hz. 78 * Frequency may be positive or negative. 79 * 80 * Frequency should not exceed +/- Nyquist Rate. 81 * Nyquist Rate is sampleRate/2. 82 */ incrementPhase(float frequency)83 float incrementPhase(float frequency) { 84 mPhase += frequency * mFrequencyToPhaseIncrement; 85 // Wrap phase in the range of -1 to +1 86 if (mPhase >= 1.0f) { 87 mPhase -= 2.0f; 88 } else if (mPhase < -1.0f) { 89 mPhase += 2.0f; 90 } 91 return mPhase; 92 } 93 94 float mPhase = 0.0f; // phase that ranges from -1.0 to +1.0 95 float mSampleRate = 0.0f; 96 float mFrequencyToPhaseIncrement = 0.0f; // scaler for converting frequency to phase increment 97 }; 98 99 100 #endif //NATIVEOBOE_OSCILLATORBASE_H 101