32 #include "../include/tscope5/audio.h"
33 #include "../include/tscope5/audio_internal.h"
34 #include "../include/tscope5/system_internal.h"
65 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_frequency(%u)\n", frequency);
67 unsigned int retval = _ts5_status.audio.frequency;
69 if (frequency!=TS5_11025 && frequency!=TS5_22050 && frequency!=TS5_44100) {
70 ts5_fatal(
"ts5_set_audio_frequency: unknown frequency requested\n");
73 _ts5_status.audio.frequency = frequency;
76 "ts5_set_audio_frequency: set sample rate to %u (was %u)\n",
77 _ts5_status.audio.frequency, retval);
91 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_frequency()\n");
93 return al_get_voice_frequency(_ts5_data.audio.voice);
125 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_channels(%d)\n", channels);
127 unsigned int retval = _ts5_status.audio.channels;
129 if (channels!=TS5_MONO && channels!=TS5_STEREO) {
130 ts5_fatal(
"%s: %s\n",
"ts5_set_audio_channels",
131 "unknown number of channels requested");
134 _ts5_status.audio.channels = channels;
136 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %u (was %u)\n",
137 "ts5_set_audio_channels",
138 "set number of channels to",
139 _ts5_status.audio.channels, retval);
153 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_channels()\n");
155 ALLEGRO_CHANNEL_CONF channels =
156 al_get_voice_channels(_ts5_data.audio.voice);
160 if (channels == ALLEGRO_CHANNEL_CONF_1) {
163 else if (channels == ALLEGRO_CHANNEL_CONF_2) {
167 ts5_fatal(
"%s: %s\n",
"ts5_get_audio_channels",
168 "got an unknown number of channels");
207 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_depth(%d)\n", depth);
209 int retval = _ts5_status.audio.depth;
211 if (depth!=TS5_INTEGER && depth!=TS5_FLOAT) {
212 ts5_fatal(
"ts5_set_audio_depth: unknown sample depth requested\n");
215 _ts5_status.audio.depth = depth;
217 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
218 "ts5_set_audio_depth",
"set sample depth to",
219 _ts5_status.audio.depth, retval);
233 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_depth()\n");
235 ALLEGRO_AUDIO_DEPTH depth =
236 al_get_voice_depth(_ts5_data.audio.voice);
238 if (depth != TS5_INTEGER && depth !=TS5_FLOAT) {
239 ts5_fatal(
"ts5_get_audio_depth: got an unknown sample depth\n");
262 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_gain(%f)\n", gain);
264 double retval = _ts5_status.audio.gain;
267 ts5_fatal(
"ts5_set_audio_gain: gain should be >= 0.0\n");
270 _ts5_status.audio.gain = gain;
272 if (!al_set_mixer_gain(_ts5_data.audio.mixer, gain)) {
273 ts5_fatal(
"ts5_set_audio_gain: could not change audio gain\n");
276 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_gain: set gain to %f (was %f)\n",
277 _ts5_status.audio.gain, retval);
291 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_gain()\n");
293 return _ts5_status.audio.gain;
330 ts5_log(TS5_LOGLEVEL_2,
"ts5_alloc_sample(%f)\n", length);
332 unsigned int samples = length * _ts5_status.audio.frequency;
334 ALLEGRO_CHANNEL_CONF channels;
336 if (_ts5_status.audio.channels==TS5_MONO) {
337 channels=ALLEGRO_CHANNEL_CONF_1;
339 else if (_ts5_status.audio.channels==TS5_STEREO) {
340 channels=ALLEGRO_CHANNEL_CONF_2;
343 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
344 "unknown channel configuration requested");
347 unsigned int sample_size =
348 al_get_channel_count(channels) *
349 al_get_audio_depth_size(_ts5_status.audio.depth);
351 unsigned int bytes = samples * sample_size;
354 buff = al_malloc(bytes);
357 ts5_fatal(
"ts5_alloc_sample: could not allocate sample buffer\n");
360 TS5_SAMPLE *sample = NULL;
361 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
364 ts5_fatal(
"ts5_alloc_sample: could not allocate sample\n");
367 sample->sample = al_create_sample(buff, samples,
368 _ts5_status.audio.frequency,
369 _ts5_status.audio.depth, channels,
true);
371 if (!sample->sample) {
372 ts5_fatal(
"ts5_alloc_sample: could not create sample\n");
375 sample->instance = al_create_sample_instance(NULL);
377 if (!sample->instance) {
378 ts5_fatal(
"ts5_alloc_sample: could not create sample instance\n");
381 if (!al_set_sample(sample->instance, sample->sample)) {
382 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
383 "could not attach sample to sample instance");
386 if (!al_attach_sample_instance_to_mixer
387 (sample->instance, _ts5_data.audio.mixer)) {
388 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
389 "could not attach sample instance to mixer");
392 al_set_sample_instance_playing(sample->instance,
false);
394 sample->issample =
true;
395 sample->isfilestream =
false;
396 sample->ismemorystream =
false;
397 sample->stream = NULL;
417 ts5_log(TS5_LOGLEVEL_2,
"ts5_read_sample(%s)\n", file);
419 TS5_SAMPLE *sample = NULL;
420 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
423 ts5_fatal(
"ts5_read_sample: could not allocate sample\n");
426 sample->issample =
true;
427 sample->isfilestream =
false;
428 sample->ismemorystream =
false;
430 sample->sample = NULL;
431 sample->sample = al_load_sample(file);
433 if (!sample->sample) {
434 ts5_fatal(
"ts5_read_sample: could not read sample\n");
437 sample->instance = NULL;
438 sample->instance = al_create_sample_instance(NULL);
440 if (!sample->instance) {
441 ts5_fatal(
"ts5_read_sample: could not create sample instance\n");
444 if (!al_set_sample(sample->instance, sample->sample)) {
446 "could not attach sample to sample instance");
449 if (!al_attach_sample_instance_to_mixer
450 (sample->instance, _ts5_data.audio.mixer)) {
452 "could not attach sample instance to mixer");
455 al_set_sample_instance_playing(sample->instance,
false);
457 sample->stream = NULL;
477 ts5_log(TS5_LOGLEVEL_2,
"ts5_read_long_sample(%s)\n", file);
479 TS5_SAMPLE *sample = NULL;
480 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
483 ts5_fatal(
"ts5_read_long_sample: could not allocate sample\n");
486 sample->issample =
false;
487 sample->isfilestream =
true;
488 sample->ismemorystream =
false;
490 sample->sample = NULL;
491 sample->instance = NULL;
493 sample->stream = NULL;
494 sample->stream = al_load_audio_stream(file, 4, 2048);
496 if (!sample->stream) {
497 ts5_fatal(
"ts5_read_long_sample: could not read sample\n");
500 if (!al_attach_audio_stream_to_mixer
501 (sample->stream, _ts5_data.audio.mixer)) {
502 ts5_fatal(
"%s: %s\n",
"ts5_read_long_sample",
503 "could not attach sample stream to mixer");
506 al_set_audio_stream_playing(sample->stream,
false);
507 al_set_audio_stream_playmode(sample->stream, ALLEGRO_PLAYMODE_ONCE);
524 ts5_log(TS5_LOGLEVEL_2,
"ts5_write_sample(%s,%p)\n", file, sample);
526 if (!sample->issample) {
527 ts5_fatal(
"%s: %s\n",
"ts5_write_sample",
528 "writing of streams is not implemented yet\n");
531 if (!al_save_sample(file, sample->sample)) {
532 ts5_fatal(
"ts5_write_sample: could not write sample\n");
548 ts5_log(TS5_LOGLEVEL_2,
"ts5_free_sample(%p)\n", sample);
550 if (sample->issample) {
551 al_set_sample(sample->instance, NULL);
552 al_destroy_sample(sample->sample);
554 al_detach_sample_instance(sample->instance);
555 al_destroy_sample_instance(sample->instance);
557 else if (sample->isfilestream) {
558 al_detach_audio_stream(sample->stream);
559 al_destroy_audio_stream(sample->stream);
561 else if (sample->ismemorystream) {
562 ts5_fatal(
"ts5_free_sample: memory streams not implemented yet\n");
593 ts5_log(TS5_LOGLEVEL_5,
"ts5_play_sample(%p)\n", sample);
596 ts5_fatal(
"ts5_play_sample: sample pointer is null\n");
599 if (sample->issample) {
601 if (!al_set_sample_instance_playing(sample->instance, 1)) {
602 ts5_fatal(
"ts5_play_sample: could not play sample\n");
605 else if (sample->isfilestream) {
607 if (!al_set_audio_stream_playing(sample->stream, 1)) {
608 ts5_fatal(
"ts5_play_sample: could not play sample\n");
611 else if (sample->ismemorystream) {
612 ts5_fatal(
"ts5_play_sample: memory streams not implemented yet\n");
625 ts5_log(TS5_LOGLEVEL_5,
"ts5_pause_sample(%p)\n", sample);
628 ts5_fatal(
"ts5_pause_sample: sample pointer is null\n");
631 if (sample->issample) {
633 unsigned int position =
634 al_get_sample_instance_position(sample->instance);
636 if (!al_set_sample_instance_playing(sample->instance, 0)) {
637 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
640 if (!al_set_sample_instance_position(sample->instance, position)) {
641 ts5_fatal(
"ts5_pause_sample: could not change sample position\n");
644 else if (sample->isfilestream) {
646 if (!al_set_audio_stream_playing(sample->stream, 0)) {
647 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
650 else if (sample->ismemorystream) {
651 ts5_fatal(
"memory streams not implemented yet\n");
664 ts5_log(TS5_LOGLEVEL_5,
"ts5_stop_sample(%p)\n", sample);
667 ts5_fatal(
"ts5_stop_sample: sample pointer is null\n");
670 if (sample->issample) {
672 if (!al_set_sample_instance_playing(sample->instance, 0)) {
673 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
676 if (!al_set_sample_instance_position(sample->instance, 0)) {
677 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
680 else if (sample->isfilestream) {
682 al_drain_audio_stream(sample->stream);
684 if (!al_rewind_audio_stream(sample->stream)) {
685 ts5_fatal(
"ts5_stop_sample: could not rewind sample\n");
688 else if (sample->ismemorystream) {
689 ts5_fatal(
"ts5_stop_sample: memory streams not implemented yet\n");
722 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_sample_status(%p)\n", sample);
725 ts5_fatal(
"ts5_get_sample_status: sample pointer is null\n");
730 if (sample->issample) {
731 retval = al_get_sample_instance_playing(sample->instance);
733 else if (sample->isfilestream) {
734 retval = al_get_audio_stream_playing(sample->stream);
736 else if (sample->ismemorystream) {
737 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_status",
738 "memory streams not implemented yet");
741 ts5_fatal(
"ts5_get_sample_status: sample type unknown\n");
758 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_frequency(%p)\n", sample);
761 ts5_fatal(
"ts5_get_sample_frequency: sample pointer is null\n");
764 unsigned int retval = 0;
766 if (sample->issample) {
767 retval = al_get_sample_frequency(sample->sample);
769 else if (sample->isfilestream) {
770 retval = al_get_audio_stream_frequency(sample->stream);
772 else if (sample->ismemorystream) {
773 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_frequency",
774 "memory streams not implemented yet");
791 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_channels(%p)\n", sample);
794 ts5_fatal(
"ts5_get_sample_channels: sample pointer is null\n");
797 ALLEGRO_CHANNEL_CONF channels;
799 if (sample->issample) {
800 channels = al_get_sample_channels(sample->sample);
802 else if (sample->isfilestream) {
803 channels = al_get_audio_stream_channels(sample->stream);
805 else if (sample->ismemorystream) {
806 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
807 "memory streams not implemented yet");
810 unsigned int retval = 0;
812 if (channels == ALLEGRO_CHANNEL_CONF_1) {
815 else if (channels == ALLEGRO_CHANNEL_CONF_2) {
819 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
820 "got an unknown number of channels");
837 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_depth(%p)\n", sample);
840 ts5_fatal(
"ts5_get_sample_depth: sample pointer is null\n");
843 ALLEGRO_AUDIO_DEPTH depth;
845 if (sample->issample) {
846 depth = al_get_sample_depth(sample->sample);
848 else if (sample->isfilestream) {
849 depth = al_get_audio_stream_depth(sample->stream);
851 else if (sample->ismemorystream) {
852 ts5_fatal(
"ts5_get_sample_depth: memory streams not implemented yet\n");
857 if (depth == ALLEGRO_AUDIO_DEPTH_INT16) {
858 retval = TS5_INTEGER;
860 else if (depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) {
864 ts5_fatal(
"ts5_get_audio_depth: got an unknown sample depth\n");
881 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_length(%p)\n", sample);
884 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
887 unsigned int retval = 0;
889 if (sample->issample) {
890 retval = al_get_sample_length(sample->sample);
892 else if (sample->isfilestream) {
893 retval = al_get_audio_stream_length(sample->stream);
895 else if (sample->ismemorystream) {
896 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_length",
897 "memory streams not implemented yet");
917 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_position(%p,%u)\n",
921 ts5_fatal(
"ts5_set_sample_position: sample pointer is null\n");
924 unsigned int retval= 0;
926 if (sample->issample) {
928 unsigned int max = al_get_sample_length(sample->sample);
930 if (position > max) {
931 ts5_fatal(
"ts5_set_sample_position: position should be",
932 " <= the length of the sample (%d)\n", max);
935 retval = al_get_sample_instance_position(sample->instance);
937 if (!(al_set_sample_instance_position(sample->instance, position))) {
938 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
939 "could not change sample position");
942 else if (sample->isfilestream) {
944 unsigned int freq = al_get_audio_stream_frequency(sample->stream);
947 al_get_audio_stream_length_secs(sample->stream) * freq;
949 if (position > max) {
950 ts5_fatal(
"ts5_set_sample_position: position should be",
951 " <= the length of the sample (%d)\n", max);
954 retval = al_get_audio_stream_position_secs(sample->stream) * freq;
956 if (!(al_seek_audio_stream_secs(sample->stream, position / freq))) {
957 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
958 "could not change sample position");
961 else if (sample->ismemorystream) {
962 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
963 "memory streams not implemented yet");
980 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_position(%p)\n", sample);
983 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
986 unsigned int retval = 0;
988 if (sample->issample) {
989 retval = al_get_sample_instance_position(sample->instance);
991 else if (sample->isfilestream) {
992 unsigned int freq = al_get_audio_stream_frequency(sample->stream);
993 retval = al_get_audio_stream_position_secs(sample->stream) * freq;
995 else if (sample->ismemorystream) {
996 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_position",
997 "memory streams not implemented yet");
1015 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_speed(%p,%f)\n", sample, speed);
1018 ts5_fatal(
"ts5_set_sample_speed: sample pointer is null\n");
1022 ts5_fatal(
"ts5_set_sample_speed: speed should be >0 (is %f)\n", speed);
1025 double retval = 0.0;
1027 if (sample->issample) {
1029 retval = al_get_sample_instance_speed(sample->instance);
1031 if (!(al_set_sample_instance_speed(sample->instance, speed))) {
1032 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1033 "could not change sample speed", speed);
1036 else if (sample->isfilestream) {
1038 retval = al_get_audio_stream_speed(sample->stream);
1040 if (!(al_set_audio_stream_speed(sample->stream, speed))) {
1041 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1042 "could not change sample speed", speed);
1045 else if (sample->ismemorystream) {
1046 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_speed",
1047 "memory streams not implemented yet");
1064 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_speed(%p)\n", sample);
1067 ts5_fatal(
"ts5_get_sample_speed: sample pointer is null\n");
1070 double retval = 0.0;
1072 if (sample->issample) {
1073 retval = al_get_sample_instance_speed(sample->instance);
1075 else if (sample->isfilestream) {
1076 retval = al_get_audio_stream_speed(sample->stream);
1078 else if (sample->ismemorystream) {
1079 ts5_fatal(
"ts5_get_sample_speed: memory streams not implemented yet\n");
1097 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_gain(%p,%f)\n", sample, gain);
1100 ts5_fatal(
"ts5_set_sample_gain: sample pointer is null\n");
1104 ts5_fatal(
"ts5_set_sample_gain: gain should be >0 (is %f)\n", gain);
1107 double retval = 0.0;
1109 if (sample->issample) {
1111 retval = al_get_sample_instance_gain(sample->instance);
1113 if (!(al_set_sample_instance_gain(sample->instance, gain))) {
1114 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1115 "could not change sample gain", gain);
1118 else if (sample->isfilestream) {
1120 retval = al_get_audio_stream_gain(sample->stream);
1122 if (!(al_set_audio_stream_gain(sample->stream, gain))) {
1123 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1124 "could not change sample gain", gain);
1127 else if (sample->ismemorystream) {
1128 ts5_fatal(
"ts5_set_sample_gain: memory streams not implemented yet\n");
1145 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_gain(%p)\n", sample);
1148 ts5_fatal(
"ts5_get_sample_gain: sample pointer is null\n");
1151 double retval = 0.0;
1153 if (sample->issample) {
1154 retval = al_get_sample_instance_gain(sample->instance);
1156 else if (sample->isfilestream) {
1157 retval = al_get_audio_stream_gain(sample->stream);
1159 else if (sample->ismemorystream) {
1160 ts5_fatal(
"ts5_get_sample_gain: memory streams not implemented yet\n");
1179 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_pan(%p,%f)\n", sample, pan);
1182 ts5_fatal(
"ts5_set_sample_pan: sample pointer is null\n");
1185 if (pan < -1.0 || pan > 1) {
1186 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_sample_pan",
1187 "pan should be between -1.0 and 1.0", pan);
1190 double retval = 0.0;
1192 if (sample->issample) {
1194 retval = al_get_sample_instance_pan(sample->instance);
1196 if (!(al_set_sample_instance_pan(sample->instance, pan))) {
1197 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1198 "could not change sample pan", pan);
1201 else if (sample->isfilestream) {
1203 retval = al_get_audio_stream_pan(sample->stream);
1205 if (!(al_set_audio_stream_pan(sample->stream, pan))) {
1206 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1207 "could not change sample pan", pan);
1210 else if (sample->ismemorystream) {
1211 ts5_fatal(
"ts5_set_sample_pan: memory streams not implemented yet\n");
1228 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_pan(%p)\n", sample);
1231 ts5_fatal(
"ts5_get_sample_pan: sample pointer is null\n");
1234 double retval = 0.0;
1236 if (sample->issample) {
1237 retval = al_get_sample_instance_pan(sample->instance);
1239 else if (sample->isfilestream) {
1240 retval = al_get_audio_stream_pan(sample->stream);
1242 else if (sample->ismemorystream) {
1243 ts5_fatal(
"memory streams not implemented yet\n");
1261 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_playmode(%p,%d)\n",
1265 ts5_fatal(
"ts5_set_sample_playmode: sample pointer is null\n");
1268 if (playmode != TS5_PLAY_ONCE && playmode != TS5_PLAY_LOOP) {
1269 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1270 "playmode should be TS5_PLAY_ONCE or TS5_PLAY_LOOP");
1275 if (sample->issample) {
1277 retval = al_get_sample_instance_playmode(sample->instance);
1279 if (!(al_set_sample_instance_playmode(sample->instance, playmode))) {
1280 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1281 "could not change sample playmode");
1284 else if (sample->isfilestream) {
1286 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1288 if (!(al_set_audio_stream_playmode(sample->stream, playmode))) {
1289 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1290 "could not change sample playmode");
1293 else if (sample->ismemorystream) {
1294 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1295 "memory streams not implemented yet");
1312 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_playmode(%p)\n", sample);
1315 ts5_fatal(
"ts5_get_sample_playmode: sample pointer is null\n");
1320 if (sample->issample) {
1321 retval = al_get_sample_instance_playmode(sample->instance);
1323 else if (sample->isfilestream) {
1324 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1326 else if (sample->ismemorystream) {
1327 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_playmode",
1328 "memory streams not implemented yet");