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 #include <android/log.h> 18 19 //static const char * const TAG = "WaveTableOscillator"; 20 21 #include "WaveTableOscillator.h" 22 #include "SystemParams.h" 23 24 namespace ndkaudio { 25 26 WaveTableOscillator::WaveTableOscillator(int numChannels, float* waveTable, 27 int waveTableSize) 28 : PeriodicAudioSource(numChannels), 29 waveTable_(waveTable), 30 waveTableSize_(waveTableSize), 31 fN_(0.0f), 32 srcPhase_(0.0f), 33 prevFillTime_(0) 34 { 35 setWaveTable(waveTable, waveTableSize); 36 } 37 38 void WaveTableOscillator::setWaveTable(float* waveTable, int waveTableSize) { 39 waveTable_ = waveTable; 40 waveTableSize_ = waveTableSize - 1; 41 42 // The frequency that would be played if we took every sample from the table and 43 // played it at the system sample-rate. The "Nominal" frequency 44 fN_ = SystemParams::getSampleRate() / (float) waveTableSize_; 45 } 46 47 int WaveTableOscillator::getData(long time, float* outBuff, int numFrames, 48 int /*outChans*/) { 49 prevFillTime_ = time; 50 51 // Frequency - main 52 float currentFreq = targetFreq_; 53 54 float phaseIncr = currentFreq / fN_; 55 56 // __android_log_print(ANDROID_LOG_INFO, TAG, "getData() freq:%f, fN_:%f, phs:%f incr:%f", currentFreq, fN_, srcPhase_, phaseIncr); 57 58 if (numChannels_ == 1) { 59 // calculate wave values 60 for (int dstIndex = 0; dstIndex < numFrames; ++dstIndex) { 61 // 'mod' back into the waveTable 62 if (srcPhase_ >= (float) waveTableSize_) { 63 srcPhase_ -= (float) waveTableSize_; 64 } 65 66 // linear-interpolate 67 int srcIndex = (int) srcPhase_; 68 float delta0 = srcPhase_ - srcIndex; 69 float delta1 = 1.0f - delta0; 70 outBuff[dstIndex] = ((waveTable_[srcIndex] * delta1) 71 + (waveTable_[srcIndex + 1] * delta0)) / 2.0f; 72 73 srcPhase_ += phaseIncr; 74 } 75 } else if (numChannels_ == 2) { 76 // calculate wave values 77 int dstIndex = 0; 78 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 79 // 'mod' back into the waveTable 80 if (srcPhase_ >= (float) waveTableSize_) { 81 srcPhase_ -= (float) waveTableSize_; 82 } 83 84 // linear-interpolate 85 int srcIndex = (int) srcPhase_; 86 float delta0 = srcPhase_ - srcIndex; 87 float delta1 = 1.0f - delta0; 88 float out = ((waveTable_[srcIndex] * delta1) 89 + (waveTable_[srcIndex + 1] * delta0)) / 2.0f; 90 91 outBuff[dstIndex++] = out; 92 outBuff[dstIndex++] = out; 93 94 srcPhase_ += phaseIncr; 95 } 96 } 97 98 // __android_log_print(ANDROID_LOG_INFO, TAG, " %d samples", numSamples); 99 return numFrames; 100 } 101 102 } // namespace ndkaudio 103