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