1 /* 2 * Copyright 2020 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 MEGA_PLAYER_WAVETABLESOURCE_H 18 #define MEGA_PLAYER_WAVETABLESOURCE_H 19 20 #include <memory> 21 22 #include "AudioSource.h" 23 24 class WaveTableSource: public AudioSource { 25 public: 26 /** 27 * Constructor. Sets up to play samples from the provided wave table. 28 * @param waveTbl Contains the samples defining a single cycle of the desired waveform. 29 */ 30 WaveTableSource(); 31 32 /** 33 * Sets up to play samples from the provided wave table. 34 * @param waveTbl Contains the samples defining a single cycle of the desired waveform. 35 * This wave table contains a redundant sample in the last slot (== first slot) 36 * to make the interpolation calculation simpler, so the logical length of 37 * the wave table is one less than the length of the array. 38 * NOTE: WaveTableSource DOES NOT take ownership of the wave table. The user of WaveTableSource 39 * is responsible for managing the lifetime of othe wave table. 40 */ setWaveTable(float * waveTable,int length)41 void setWaveTable(float* waveTable, int length) { 42 mWaveTable = waveTable; 43 mNumWaveTableSamples = length - 1; 44 45 calcFN(); 46 } 47 48 /** 49 * Sets the playback sample rate for which samples will be generated. 50 * @param sampleRate 51 */ setSampleRate(float sampleRate)52 void setSampleRate(float sampleRate) { 53 mSampleRate = sampleRate; 54 calcFN(); 55 } 56 57 /** 58 * Set the frequency of the output signal. 59 * @param freq Signal frequency in Hz. 60 */ setFreq(float freq)61 void setFreq(float freq) { 62 mFreq = freq; 63 } 64 65 /** 66 * Resets the playback position to the 1st sample. 67 */ reset()68 void reset() override { 69 mSrcPhase = 0.0f; 70 } 71 72 virtual int getNumChannels() override; 73 74 virtual int getEncoding() override; 75 76 /** 77 * Fills the specified buffer with values generated from the wave table which will playback 78 * at the specified frequency. 79 * 80 * @param buffer The buffer to be filled. 81 * @param numFrames The number of frames of audio to provide. 82 * @param numChans The number of channels (in the buffer) required by the player. 83 * @return The number of samples generated. Since we are generating a continuous periodic 84 * signal, this will always be <code>numFrames</code>. 85 */ 86 virtual int pull(float* buffer, int numFrames, int numChans) override; 87 88 /* 89 * Standard wavetable generators 90 */ 91 static void genSinWave(float* buffer, int length); 92 static void genTriangleWave(float* buffer, int size, float maxValue, float minValue, 93 float dutyCycle); 94 static void genPulseWave(float* buffer, int size,float maxValue, float minValue, 95 float dutyCycle); 96 97 protected: 98 static const int DEFAULT_WAVETABLE_LENGTH = 2049; 99 100 /** 101 * Calculates the "Nominal" frequency of the wave table. 102 */ 103 void calcFN(); 104 105 /** The samples defining one cycle of the waveform to play */ 106 //TODO - make this a shared_ptr 107 float* mWaveTable; 108 109 /** The number of samples in the wave table. Note that the wave table is presumed to contain 110 * an "extra" sample (a copy of the 1st sample) in order to simplify the interpolation 111 * calculation. Thus, this value will be 1 less than the length of mWaveTable. 112 */ 113 int mNumWaveTableSamples; 114 115 /** The phase (offset within the wave table) of the next output sample. 116 * Note that this may (will) be a fractional value. Range 0.0 -> mNumWaveTableSamples. 117 */ 118 float mSrcPhase; 119 120 /** The sample rate at which playback occurs */ 121 float mSampleRate = 48000; // This seems likely, but can be changed 122 123 /** The frequency of the generated audio signal */ 124 float mFreq = 1000; // Some reasonable default frequency 125 126 /** The "Nominal" frequency of the wavetable. i.e., the frequency that would be generated if 127 * each sample in the wave table was sent in turn to the output at the specified sample rate. 128 */ 129 float mFN; 130 131 /** 1 / mFN. Calculated when mFN is set to avoid a division on each call to fill() */ 132 float mFNInverse; 133 }; 134 135 #endif // MEGA_PLAYER_WAVETABLESOURCE_H 136