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