1 /*
2  *    Example program for the Allegro library.
3  */
4 
5 #include <math.h>
6 
7 #include "allegro5/allegro.h"
8 #include "allegro5/allegro_audio.h"
9 #include "allegro5/allegro_font.h"
10 
11 #include "common.c"
12 
13 
14 #define RESERVED_SAMPLES   16
15 #define PERIOD             5
16 
17 
18 static ALLEGRO_DISPLAY *display;
19 static ALLEGRO_FONT *font;
20 static ALLEGRO_SAMPLE *ping;
21 static ALLEGRO_TIMER *timer;
22 static ALLEGRO_EVENT_QUEUE *event_queue;
23 
24 
create_sample_s16(int freq,int len)25 static ALLEGRO_SAMPLE *create_sample_s16(int freq, int len)
26 {
27    char *buf = al_malloc(freq * len * sizeof(int16_t));
28 
29    return al_create_sample(buf, len, freq, ALLEGRO_AUDIO_DEPTH_INT16,
30 			   ALLEGRO_CHANNEL_CONF_1, true);
31 }
32 
33 
34 /* Adapted from SPEED. */
generate_ping(void)35 static ALLEGRO_SAMPLE *generate_ping(void)
36 {
37    float osc1, osc2, vol, ramp;
38    int16_t *p;
39    int len;
40    int i;
41 
42    /* ping consists of two sine waves */
43    len = 8192;
44    ping = create_sample_s16(22050, len);
45    if (!ping)
46       return NULL;
47 
48    p = (int16_t *)al_get_sample_data(ping);
49 
50    osc1 = 0;
51    osc2 = 0;
52 
53    for (i=0; i<len; i++) {
54       vol = (float)(len - i) / (float)len * 4000;
55 
56       ramp = (float)i / (float)len * 8;
57       if (ramp < 1.0f)
58          vol *= ramp;
59 
60       *p = (sin(osc1) + sin(osc2) - 1) * vol;
61 
62       osc1 += 0.1;
63       osc2 += 0.15;
64 
65       p++;
66    }
67 
68    return ping;
69 }
70 
71 
main(int argc,char ** argv)72 int main(int argc, char **argv)
73 {
74    ALLEGRO_TRANSFORM trans;
75    ALLEGRO_EVENT event;
76    int bps = 4;
77    bool redraw = false;
78    unsigned int last_timer = 0;
79 
80    (void)argc;
81    (void)argv;
82 
83    if (!al_init()) {
84       abort_example("Could not init Allegro.\n");
85    }
86 
87    open_log();
88 
89    al_install_keyboard();
90 
91    display = al_create_display(640, 480);
92    if (!display) {
93       abort_example("Could not create display\n");
94    }
95 
96    font = al_create_builtin_font();
97    if (!font) {
98       abort_example("Could not create font\n");
99    }
100 
101    if (!al_install_audio()) {
102       abort_example("Could not init sound\n");
103    }
104 
105    if (!al_reserve_samples(RESERVED_SAMPLES)) {
106       abort_example("Could not set up voice and mixer\n");
107    }
108 
109    ping = generate_ping();
110    if (!ping) {
111       abort_example("Could not generate sample\n");
112    }
113 
114    timer = al_create_timer(1.0 / bps);
115    al_set_timer_count(timer, -1);
116 
117    event_queue = al_create_event_queue();
118    al_register_event_source(event_queue, al_get_keyboard_event_source());
119    al_register_event_source(event_queue, al_get_timer_event_source(timer));
120 
121    al_identity_transform(&trans);
122    al_scale_transform(&trans, 16.0, 16.0);
123    al_use_transform(&trans);
124 
125    al_start_timer(timer);
126 
127    while (true) {
128       al_wait_for_event(event_queue, &event);
129       if (event.type == ALLEGRO_EVENT_TIMER) {
130          const float speed = pow(21.0/20.0, (event.timer.count % PERIOD));
131          if (!al_play_sample(ping, 1.0, 0.0, speed, ALLEGRO_PLAYMODE_ONCE, NULL)) {
132             log_printf("Not enough reserved samples.\n");
133          }
134          redraw = true;
135          last_timer = event.timer.count;
136       }
137       else if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
138          if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
139             break;
140          }
141          if (event.keyboard.unichar == '+' || event.keyboard.unichar == '=') {
142             if (bps < 32) {
143                bps++;
144                al_set_timer_speed(timer, 1.0 / bps);
145             }
146          }
147          else if (event.keyboard.unichar == '-') {
148             if (bps > 1) {
149                bps--;
150                al_set_timer_speed(timer, 1.0 / bps);
151             }
152          }
153       }
154 
155       if (redraw && al_is_event_queue_empty(event_queue)) {
156          ALLEGRO_COLOR c;
157          if (last_timer % PERIOD == 0)
158             c = al_map_rgb_f(1, 1, 1);
159          else
160             c = al_map_rgb_f(0.5, 0.5, 1.0);
161 
162          al_clear_to_color(al_map_rgb(0, 0, 0));
163          al_draw_textf(font, c, 640/32, 480/32 - 4, ALLEGRO_ALIGN_CENTRE,
164             "%u", last_timer);
165          al_flip_display();
166       }
167    }
168 
169    close_log(false);
170 
171    return 0;
172 }
173 
174 /* vim: set sts=3 sw=3 et: */
175