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 */ 52 void setSampleRate(int sampleRate); 53 54 /** 55 * Set the frequency of the output signal. 56 * @param freq Signal frequency in Hz. 57 */ setFreq(float freq)58 void setFreq(float freq) { 59 mFreq = freq; 60 } 61 62 /** 63 * Resets the playback position to the 1st sample. 64 */ reset()65 void reset() override { 66 mSrcPhase = 0.0f; 67 } 68 69 virtual int getNumChannels() override; 70 71 virtual int getEncoding() override; 72 73 /** 74 * Fills the specified buffer with values generated from the wave table which will playback 75 * at the specified frequency. 76 * 77 * @param buffer The buffer to be filled. 78 * @param numFrames The number of frames of audio to provide. 79 * @param numChans The number of channels (in the buffer) required by the player. 80 * @return The number of samples generated. Since we are generating a continuous periodic 81 * signal, this will always be <code>numFrames</code>. 82 */ 83 virtual int pull(float* buffer, int numFrames, int numChans) override; 84 85 /* 86 * Standard wavetable generators 87 */ 88 static void genSinWave(float* buffer, int length); 89 static void genTriangleWave(float* buffer, int size, float maxValue, float minValue, 90 float dutyCycle); 91 static void genPulseWave(float* buffer, int size,float maxValue, float minValue, 92 float dutyCycle); 93 94 protected: 95 static const int DEFAULT_WAVETABLE_LENGTH = 2049; 96 97 /** 98 * Calculates the "Nominal" frequency of the wave table. 99 */ 100 void calcFN(); 101 102 /** The samples defining one cycle of the waveform to play */ 103 //TODO - make this a shared_ptr 104 float* mWaveTable; 105 106 /** The number of samples in the wave table. Note that the wave table is presumed to contain 107 * an "extra" sample (a copy of the 1st sample) in order to simplify the interpolation 108 * calculation. Thus, this value will be 1 less than the length of mWaveTable. 109 */ 110 int mNumWaveTableSamples; 111 112 /** The phase (offset within the wave table) of the next output sample. 113 * Note that this may (will) be a fractional value. Range 0.0 -> mNumWaveTableSamples. 114 */ 115 float mSrcPhase; 116 117 /** The sample rate at which playback occurs */ 118 float mSampleRate = 48000; // This seems likely, but can be changed 119 120 /** The frequency of the generated audio signal */ 121 float mFreq = 1000; // Some reasonable default frequency 122 123 /** The "Nominal" frequency of the wavetable. i.e., the frequency that would be generated if 124 * each sample in the wave table was sent in turn to the output at the specified sample rate. 125 */ 126 float mFN; 127 128 /** 1 / mFN. Calculated when mFN is set to avoid a division on each call to fill() */ 129 float mFNInverse; 130 }; 131 132 #endif // MEGA_PLAYER_WAVETABLESOURCE_H 133