samples/audio; Installer: Added SineTone sample
[sdk] / samples / audio / SineTone / sineTone.ec
1 import "EcereAudio"
2
3 class ToneSound : private Sound
4 {
5    bits = 16;
6    channels = 1;
7    frequency = 44100;
8
9    void GenerateTone(float freq, int duration, double volume)
10    {
11       uint length = this.length = frequency * duration;
12       short * data = (short *)(this.data = (byte *)new short[length]);
13       int i;
14
15       for(i = 0; i < length; i++)
16       {
17          Angle x = 2 * Pi * i * freq / frequency;
18          ((short *)data)[i] = (short)(sin(x) * volume * 32767);
19       }
20    }
21 }
22
23 class BeepForm : Window
24 {
25    caption = "Beep";
26    background = activeBorder;
27    borderStyle = sizable;
28    hasMaximize = true;
29    hasMinimize = true;
30    hasClose = true;
31    size = { 640, 480 };
32
33    ToneSound sound { };
34    int pos;
35
36    Button button1
37    {
38       this, caption = "Play", position = { 200, 168 };
39
40       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
41       {
42          pos = 0;
43          PauseAudio(0);
44          return true;
45       }
46    };
47
48    bool OnPostCreate()
49    {
50       AudioSpec wantedSpec
51       {
52          freq = 44100;
53          bits = 16;
54          channels = 1;
55          samples = AUDIO_BUFFER_SIZE;
56          callback = AudioCallback;
57          userdata = this;
58          windowHandle = systemHandle;
59          volume = 100;
60       };
61       AudioSpec spec { };
62
63       sound.GenerateTone(440, 1, 0.25);   // 1 second of 440Hz A at quarter volume
64
65       if(OpenAudio(wantedSpec, spec) < 0)
66       {
67          MessageBox { contents = "OpenAudio epic fail" }.Modal();
68          return false;
69       }
70       return true;
71    }
72
73    void OnDestroy()
74    {
75       CloseAudio();
76    }
77
78    void AudioCallback(byte *stream, int len)
79    {
80       static byte buffer[AUDIO_BUFFER_SIZE];
81       int s = Min(sound.length * (sound.bits == 16 ? 2 : 1) - pos, len);
82       memcpy(buffer, sound.data + pos, s);
83       pos += s;
84       if(s < len)
85       {
86          if(sound.bits == 8)
87             memset(buffer + s, 128, len - s);
88          else
89             memset(buffer + s, 0, len - s);
90       }
91       memcpy(stream, buffer, len);
92    }
93 }
94
95 BeepForm beep { };