1 #include <math.h>
2 #include "basic_source.h"
3 #include "internal.h"
4 #include "types.h"
5 
6 namespace audiere {
7 
8   static const double PI = 3.14159265358979323846;
9 
10   class SineWave : public BasicSource {
11   public:
SineWave(double frequency)12     SineWave(double frequency) {
13       m_frequency = frequency;
14       doReset(); // not supposed to call virtual functions in constructors
15     }
16 
getFormat(int & channel_count,int & sample_rate,SampleFormat & sample_format)17     void ADR_CALL getFormat(
18       int& channel_count,
19       int& sample_rate,
20       SampleFormat& sample_format)
21     {
22       channel_count = 1;
23       sample_rate   = 44100;
24       sample_format = SF_S16;
25     }
26 
doRead(int frame_count,void * buffer)27     int doRead(int frame_count, void* buffer) {
28       // if frequency is 0 Hz, use silence
29       if (m_frequency == 0) {
30         memset(buffer, 0, frame_count * 2);
31         return frame_count;
32       }
33 
34       s16* out = (s16*)buffer;
35       for (int i = 0; i < frame_count; ++i) {
36         double h = sin(2 * PI * m_frequency / 44100 * elapsed++);
37         out[i] = normal_to_s16(h);
38       }
39       return frame_count;
40     }
41 
reset()42     void ADR_CALL reset() {
43       doReset();
44     }
45 
46   private:
doReset()47     void doReset() {
48       elapsed = 0;
49     }
50 
normal_to_s16(double d)51     s16 normal_to_s16(double d) {
52       d = (d + 1) / 2; // convert from [-1, 1] to [0, 1]
53       return s16(d * 32767 - 16384);
54     }
55 
56     double m_frequency;
57     long elapsed;
58   };
59 
60 
AdrCreateTone(double frequency)61   ADR_EXPORT(SampleSource*) AdrCreateTone(double frequency) {
62     return new SineWave(frequency);
63   }
64 
65 }
66