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