summaryrefslogtreecommitdiff
path: root/src/tone.cpp
blob: 1d7b033c2374712c501d868f41a1cf7636d3a52e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <math.h>
#include "basic_source.h"
#include "internal.h"
#include "types.h"

namespace audiere {

  static const double PI = 3.14159265358979323846;

  class SineWave : public BasicSource {
  public:
    SineWave(double frequency) {
      m_frequency = frequency;
      doReset(); // not supposed to call virtual functions in constructors
    }

    void ADR_CALL getFormat(
      int& channel_count,
      int& sample_rate,
      SampleFormat& sample_format)
    {
      channel_count = 1;
      sample_rate   = 44100;
      sample_format = SF_S16;
    }

    int doRead(int frame_count, void* buffer) {
      // if frequency is 0 Hz, use silence
      if (m_frequency == 0) {
        memset(buffer, 0, frame_count * 2);
        return frame_count;
      }

      s16* out = (s16*)buffer;
      for (int i = 0; i < frame_count; ++i) {
        double h = sin(2 * PI * m_frequency / 44100 * elapsed++);
        out[i] = normal_to_s16(h);
      }
      return frame_count;
    }

    void ADR_CALL reset() {
      doReset();
    }

  private:
    void doReset() {
      elapsed = 0;
    }

    s16 normal_to_s16(double d) {
      d = (d + 1) / 2; // convert from [-1, 1] to [0, 1]
      return s16(d * 32767 - 16384);
    }

    double m_frequency;
    long elapsed;
  };


  ADR_EXPORT(SampleSource*) AdrCreateTone(double frequency) {
    return new SineWave(frequency);
  }

}