1 //------------------------------------------------------------------------------
2 //  saudio.d
3 //  Test sokol-audio D bindings
4 //------------------------------------------------------------------------------
5 module examples.saudio;
6 
7 import sg = sokol.gfx;
8 import app = sokol.app;
9 import log = sokol.log;
10 import sglue = sokol.glue;
11 import saudio = sokol.audio;
12 
13 extern (C):
14 @safe:
15 
16 enum NUM_SAMPLES = 32;
17 
18 struct State {
19     sg.PassAction pass_action = {
20         colors: [
21             { load_action: sg.LoadAction.Clear, clear_value: {r: 1.0, g: 0.5, b: 0.0, a: 1.0} },
22         ]
23     };
24     int even_odd;
25     size_t sample_pos;
26     float[NUM_SAMPLES] samples;
27 }
28 static State state;
29 
30 void init() {
31     sg.Desc gfx = {
32         environment: sglue.environment,
33         logger: { func: &log.slog_func }
34     };
35     sg.setup(gfx);
36     saudio.Desc audio = {
37         logger: { func: &log.slog_func }
38     };
39     saudio.setup(audio);
40 }
41 
42 void frame() {
43     immutable num_frames = saudio.expect();
44     foreach (_; 0 .. num_frames) {
45         state.even_odd += 1;
46         state.sample_pos += 1;
47         if (state.sample_pos == NUM_SAMPLES) {
48             state.sample_pos = 0;
49             saudio.push(&state.samples[0], NUM_SAMPLES);
50         }
51         state.samples[state.sample_pos] = (0 != (state.even_odd & 0x20)) ? 0.1 : -0.1;
52     }
53     sg.Pass pass = { action: state.pass_action, swapchain: sglue.swapchain() };
54     sg.beginPass(pass);
55     sg.endPass();
56     sg.commit();
57 }
58 
59 void cleanup() {
60     saudio.shutdown();
61     sg.shutdown();
62 }
63 
64 void main() {
65     app.Desc runner = {
66         window_title: "saudio.d",
67         init_cb: &init,
68         frame_cb: &frame,
69         cleanup_cb: &cleanup,
70         width: 640,
71         height: 480,
72         icon: {sokol_default: true},
73         logger: {func: &log.func}
74     };
75     app.run(runner);
76 }