SineWaveGenerator.h (1697B)
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 #include "prtime.h" 10 11 namespace mozilla { 12 13 // generate 1k sine wave per second 14 template <typename Sample> 15 class SineWaveGenerator { 16 static_assert(std::is_same<Sample, int16_t>::value || 17 std::is_same<Sample, float>::value); 18 19 public: 20 static const int bytesPerSample = sizeof(Sample); 21 static const int millisecondsPerSecond = PR_MSEC_PER_SEC; 22 static constexpr float twopi = 2 * M_PI; 23 24 /* If more than 1 channel, generated samples are interleaved. */ 25 SineWaveGenerator(uint32_t aSampleRate, uint32_t aFrequency) 26 : mPhase(0.), mPhaseIncrement(twopi * aFrequency / aSampleRate) {} 27 28 // NOTE: only safely called from a single thread (MTG callback) 29 void generate(Sample* aBuffer, TrackTicks aFrameCount, 30 uint32_t aChannelCount = 1) { 31 while (aFrameCount--) { 32 Sample value = sin(mPhase) * Amplitude(); 33 for (uint32_t channel = 0; channel < aChannelCount; channel++) { 34 *aBuffer++ = value; 35 } 36 mPhase += mPhaseIncrement; 37 if (mPhase > twopi) { 38 mPhase -= twopi; 39 } 40 } 41 } 42 43 static float Amplitude() { 44 // Set volume to -20db. 45 if (std::is_same<Sample, int16_t>::value) { 46 return 3276.8; // 32768.0 * 10^(-20/20) = 3276.8 47 } 48 return 0.1f; // 1.0 * 10^(-20/20) = 0.1 49 } 50 51 private: 52 double mPhase; 53 const double mPhaseIncrement; 54 }; 55 56 } // namespace mozilla 57 58 #endif /* SINEWAVEGENERATOR_H_ */