1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef SINEWAVEGENERATOR_H_ 6 #define SINEWAVEGENERATOR_H_ 7 8 #include "MediaSegment.h" 9 10 namespace mozilla { 11 12 // generate 1k sine wave per second 13 class SineWaveGenerator { 14 public: 15 static const int bytesPerSample = 2; 16 static const int millisecondsPerSecond = PR_MSEC_PER_SEC; 17 SineWaveGenerator(uint32_t aSampleRate,uint32_t aFrequency)18 explicit SineWaveGenerator(uint32_t aSampleRate, uint32_t aFrequency) 19 : mTotalLength(aSampleRate / aFrequency), mReadLength(0) { 20 // If we allow arbitrary frequencies, there's no guarantee we won't get 21 // rounded here We could include an error term and adjust for it in 22 // generation; not worth the trouble 23 // MOZ_ASSERT(mTotalLength * aFrequency == aSampleRate); 24 mAudioBuffer = MakeUnique<int16_t[]>(mTotalLength); 25 for (int i = 0; i < mTotalLength; i++) { 26 // Set volume to -20db. It's from 32768.0 * 10^(-20/20) = 3276.8 27 mAudioBuffer[i] = (3276.8f * sin(2 * M_PI * i / mTotalLength)); 28 } 29 } 30 31 // NOTE: only safely called from a single thread (MSG callback) generate(int16_t * aBuffer,TrackTicks aLengthInSamples)32 void generate(int16_t* aBuffer, TrackTicks aLengthInSamples) { 33 TrackTicks remaining = aLengthInSamples; 34 35 while (remaining) { 36 TrackTicks processSamples = 0; 37 38 if (mTotalLength - mReadLength >= remaining) { 39 processSamples = remaining; 40 } else { 41 processSamples = mTotalLength - mReadLength; 42 } 43 memcpy(aBuffer, &mAudioBuffer[mReadLength], 44 processSamples * bytesPerSample); 45 aBuffer += processSamples; 46 mReadLength += processSamples; 47 remaining -= processSamples; 48 if (mReadLength == mTotalLength) { 49 mReadLength = 0; 50 } 51 } 52 } 53 54 private: 55 UniquePtr<int16_t[]> mAudioBuffer; 56 TrackTicks mTotalLength; 57 TrackTicks mReadLength; 58 }; 59 60 } // namespace mozilla 61 62 #endif /* SINEWAVEGENERATOR_H_ */ 63