35 #include "../include/tscope5/audio.h"
36 #include "../include/tscope5/audio_internal.h"
37 #include "../include/tscope5/system_internal.h"
70 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_samplerate(%u)\n", samplerate);
72 unsigned int retval = _ts5_status.audio.samplerate;
74 if (samplerate!=TS5_11025 && samplerate!=TS5_22050 && samplerate!=TS5_44100) {
75 ts5_fatal(
"ts5_set_audio_samplerate: unknown samplerate requested\n");
78 _ts5_status.audio.samplerate = samplerate;
81 "ts5_set_audio_samplerate: set sample rate to %u (was %u)\n",
82 _ts5_status.audio.samplerate, retval);
96 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_samplerate()\n");
98 return _ts5_status.audio.samplerate;
130 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_channels(%d)\n", channels);
132 unsigned int retval = _ts5_status.audio.channels;
134 if (channels!=TS5_MONO && channels!=TS5_STEREO) {
135 ts5_fatal(
"%s: %s\n",
"ts5_set_audio_channels",
136 "unknown number of channels requested");
139 _ts5_status.audio.channels = channels;
141 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %u (was %u)\n",
142 "ts5_set_audio_channels",
143 "set number of channels to",
144 _ts5_status.audio.channels, retval);
158 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_channels()\n");
160 ALLEGRO_CHANNEL_CONF channels =
161 al_get_voice_channels(_ts5_data.audio.voice);
165 if (channels == ALLEGRO_CHANNEL_CONF_1) {
168 else if (channels == ALLEGRO_CHANNEL_CONF_2) {
172 ts5_fatal(
"%s: %s\n",
"ts5_get_audio_channels",
173 "got an unknown number of channels");
212 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_depth(%d)\n", depth);
214 int retval = _ts5_status.audio.depth;
216 if (depth!=TS5_INTEGER && depth!=TS5_FLOAT) {
217 ts5_fatal(
"ts5_set_audio_depth: unknown sample depth requested\n");
220 _ts5_status.audio.depth = depth;
222 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
223 "ts5_set_audio_depth",
"set sample depth to",
224 _ts5_status.audio.depth, retval);
238 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_depth()\n");
240 ALLEGRO_AUDIO_DEPTH depth =
241 al_get_voice_depth(_ts5_data.audio.voice);
243 if (depth != TS5_INTEGER && depth !=TS5_FLOAT) {
244 ts5_fatal(
"ts5_get_audio_depth: got an unknown sample depth\n");
267 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_gain(%f)\n", gain);
269 double retval = _ts5_status.audio.gain;
272 ts5_fatal(
"ts5_set_audio_gain: gain should be >= 0.0\n");
275 _ts5_status.audio.gain = gain;
277 if (!al_set_mixer_gain(_ts5_data.audio.mixer, gain)) {
278 ts5_fatal(
"ts5_set_audio_gain: could not change audio gain\n");
281 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_audio_gain: set gain to %f (was %f)\n",
282 _ts5_status.audio.gain, retval);
296 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_audio_gain()\n");
298 return _ts5_status.audio.gain;
337 ts5_log(TS5_LOGLEVEL_2,
"ts5_alloc_sample(%f)\n", length);
340 TS5_SAMPLE *sample = NULL;
341 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
344 ts5_fatal(
"ts5_alloc_sample: could not allocate sample\n");
347 sample->issample = 1;
348 sample->isbuffer = 1;
349 sample->isfilestream = 0;
350 sample->ismemorystream = 0;
351 sample->stream = NULL;
354 unsigned int samples = length * _ts5_status.audio.samplerate;
355 ALLEGRO_CHANNEL_CONF channels = 0;
357 if (_ts5_status.audio.channels==TS5_MONO) {
358 channels=ALLEGRO_CHANNEL_CONF_1;
360 else if (_ts5_status.audio.channels==TS5_STEREO) {
361 channels=ALLEGRO_CHANNEL_CONF_2;
364 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
365 "unknown channel configuration requested");
368 unsigned int sample_size =
369 al_get_channel_count(channels) *
370 al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH_INT16);
372 unsigned int bytes = samples * sample_size;
374 sample->start_time = 0.0;
377 sample->buffer = al_malloc(bytes);
378 if (!sample->buffer) {
379 ts5_fatal(
"ts5_alloc_sample: could not allocate sample buffer\n");
382 sample->buffer_end = sample->buffer + samples * _ts5_status.audio.channels;
383 sample->buffer_recorder_position = sample->buffer;
384 sample->buffer_voicekey_position = sample->buffer;
387 sample->sample = al_create_sample(sample->buffer, samples,
388 _ts5_status.audio.samplerate,
389 ALLEGRO_AUDIO_DEPTH_INT16, channels, 1);
391 if (!sample->sample) {
392 ts5_fatal(
"ts5_alloc_sample: could not create sample\n");
397 sample->instance = al_create_sample_instance(NULL);
399 if (!sample->instance) {
400 ts5_fatal(
"ts5_alloc_sample: could not create sample instance\n");
403 if (!al_set_sample(sample->instance, sample->sample)) {
404 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
405 "could not attach sample to sample instance");
408 if (!al_attach_sample_instance_to_mixer
409 (sample->instance, _ts5_data.audio.mixer)) {
410 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
411 "could not attach sample instance to mixer");
414 al_set_sample_instance_playing(sample->instance, 0);
417 int nslices = length * 1000;
418 sample->voicekey = (
double *)al_malloc(nslices *
sizeof(
double));
419 sample->voicekey_position = sample->voicekey;
420 sample->voicekey_end = sample->voicekey + nslices;
421 sample->voicekey_num_samples = (
int *)al_malloc(nslices *
sizeof(
int));
422 sample->last_state_toggle_time = -1000;
423 sample->previous_state = 0;
443 ts5_log(TS5_LOGLEVEL_2,
"ts5_read_sample(%s)\n", file);
445 TS5_SAMPLE *sample = NULL;
446 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
449 ts5_fatal(
"ts5_read_sample: could not allocate sample\n");
452 sample->issample = 1;
453 sample->isbuffer = 0;
454 sample->isfilestream = 0;
455 sample->ismemorystream = 0;
457 sample->sample = NULL;
458 sample->sample = al_load_sample(file);
460 if (!sample->sample) {
461 ts5_fatal(
"ts5_read_sample: could not read sample\n");
464 sample->instance = NULL;
465 sample->instance = al_create_sample_instance(NULL);
467 if (!sample->instance) {
468 ts5_fatal(
"ts5_read_sample: could not create sample instance\n");
471 if (!al_set_sample(sample->instance, sample->sample)) {
473 "could not attach sample to sample instance");
476 if (!al_attach_sample_instance_to_mixer
477 (sample->instance, _ts5_data.audio.mixer)) {
479 "could not attach sample instance to mixer");
482 al_set_sample_instance_playing(sample->instance, 0);
484 sample->stream = NULL;
486 sample->start_time = 0.0;
488 sample->buffer = NULL;
489 sample->buffer_end = NULL;
490 sample->buffer_recorder_position = NULL;
491 sample->buffer_voicekey_position = NULL;
494 sample->voicekey = NULL;
495 sample->voicekey_position = NULL;
496 sample->voicekey_end = NULL;
497 sample->voicekey_num_samples = NULL;
501 if (al_get_sample_depth(sample->sample) == ALLEGRO_AUDIO_DEPTH_INT16) {
503 sample->isbuffer = 1;
505 sample->buffer = (int16_t *)al_get_sample_data(sample->sample);
506 sample->buffer_end = sample->buffer +
507 al_get_sample_length(sample->sample) *
510 sample->buffer_recorder_position = sample->buffer_end;
511 sample->buffer_voicekey_position = sample->buffer;
513 nslices = al_get_sample_length(sample->sample) * 1000;
514 sample->voicekey = (
double *)al_malloc(nslices *
sizeof(
double));
515 sample->voicekey_position = sample->voicekey;
516 sample->voicekey_end = sample->voicekey + nslices;
517 sample->voicekey_num_samples = (
int *)al_malloc(nslices *
sizeof(
int));
518 sample->last_state_toggle_time = -1000;
519 sample->previous_state = 0;
540 ts5_log(TS5_LOGLEVEL_2,
"ts5_read_long_sample(%s)\n", file);
542 TS5_SAMPLE *sample = NULL;
543 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
546 ts5_fatal(
"ts5_read_long_sample: could not allocate sample\n");
549 sample->issample = 0;
550 sample->isbuffer = 0;
551 sample->isfilestream = 1;
552 sample->ismemorystream = 0;
554 sample->sample = NULL;
555 sample->instance = NULL;
556 sample->stream = NULL;
557 sample->stream = al_load_audio_stream(file, 4, 2048);
559 if (!sample->stream) {
560 ts5_fatal(
"ts5_read_long_sample: could not read sample\n");
563 if (!al_attach_audio_stream_to_mixer
564 (sample->stream, _ts5_data.audio.mixer)) {
565 ts5_fatal(
"%s: %s\n",
"ts5_read_long_sample",
566 "could not attach sample stream to mixer");
569 al_set_audio_stream_playing(sample->stream, 0);
570 al_set_audio_stream_playmode(sample->stream, ALLEGRO_PLAYMODE_ONCE);
573 sample->start_time = 0.0;
576 sample->buffer = NULL;
577 sample->buffer_end = NULL;
578 sample->buffer_recorder_position = NULL;
579 sample->buffer_voicekey_position = NULL;
582 sample->voicekey = NULL;
583 sample->voicekey_position = NULL;
584 sample->voicekey_end = NULL;
585 sample->voicekey_num_samples = NULL;
602 ts5_log(TS5_LOGLEVEL_2,
"ts5_write_sample(%s,%p)\n", file, sample);
604 if (!sample->issample) {
605 ts5_fatal(
"%s: %s\n",
"ts5_write_sample",
606 "writing of streams is not implemented yet\n");
609 if (!al_save_sample(file, sample->sample)) {
610 ts5_fatal(
"ts5_write_sample: could not write sample\n");
626 ts5_log(TS5_LOGLEVEL_2,
"ts5_free_sample(%p)\n", sample);
628 if (sample->issample) {
629 al_set_sample(sample->instance, NULL);
630 al_destroy_sample(sample->sample);
632 al_detach_sample_instance(sample->instance);
633 al_destroy_sample_instance(sample->instance);
635 al_free(sample->voicekey);
636 al_free(sample->voicekey_num_samples);
638 else if (sample->isfilestream) {
639 al_detach_audio_stream(sample->stream);
640 al_destroy_audio_stream(sample->stream);
642 else if (sample->ismemorystream) {
643 ts5_fatal(
"ts5_free_sample: memory streams not implemented yet\n");
674 ts5_log(TS5_LOGLEVEL_5,
"ts5_play_sample(%p)\n", sample);
677 ts5_fatal(
"ts5_play_sample: sample pointer is null\n");
680 if (sample->issample) {
682 if (!al_set_sample_instance_playing(sample->instance, 1)) {
683 ts5_fatal(
"ts5_play_sample: could not play sample\n");
686 else if (sample->isfilestream) {
688 if (!al_set_audio_stream_playing(sample->stream, 1)) {
689 ts5_fatal(
"ts5_play_sample: could not play sample\n");
692 else if (sample->ismemorystream) {
693 ts5_fatal(
"ts5_play_sample: memory streams not implemented yet\n");
706 ts5_log(TS5_LOGLEVEL_5,
"ts5_pause_sample(%p)\n", sample);
709 ts5_fatal(
"ts5_pause_sample: sample pointer is null\n");
712 if (sample->issample) {
714 if (!al_set_sample_instance_playing(sample->instance, 0)) {
715 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
718 else if (sample->isfilestream) {
720 if (!al_set_audio_stream_playing(sample->stream, 0)) {
721 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
724 else if (sample->ismemorystream) {
725 ts5_fatal(
"memory streams not implemented yet\n");
738 ts5_log(TS5_LOGLEVEL_5,
"ts5_stop_sample(%p)\n", sample);
741 ts5_fatal(
"ts5_stop_sample: sample pointer is null\n");
744 if (sample->issample) {
746 if (!al_set_sample_instance_playing(sample->instance, 0)) {
747 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
750 if (!al_set_sample_instance_position(sample->instance, 0)) {
751 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
754 else if (sample->isfilestream) {
756 al_drain_audio_stream(sample->stream);
758 if (!al_rewind_audio_stream(sample->stream)) {
759 ts5_fatal(
"ts5_stop_sample: could not rewind sample\n");
762 else if (sample->ismemorystream) {
763 ts5_fatal(
"ts5_stop_sample: memory streams not implemented yet\n");
778 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_sample_status(%p)\n", sample);
781 ts5_fatal(
"ts5_get_sample_status: sample pointer is null\n");
786 if (sample->issample) {
787 retval = al_get_sample_instance_playing(sample->instance);
789 else if (sample->isfilestream) {
790 retval = al_get_audio_stream_playing(sample->stream);
792 else if (sample->ismemorystream) {
793 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_status",
794 "memory streams not implemented yet");
797 ts5_fatal(
"ts5_get_sample_status: sample type unknown\n");
839 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_sample_data_pointer(%p)\n", sample);
842 ts5_fatal(
"ts5_get_sample_data_pointer: sample pointer is null\n");
848 if (sample->issample) {
849 retval = al_get_sample_data(sample->sample);
851 else if (sample->isfilestream) {
852 ts5_fatal(
"ts5_get_sample_data_pointer: file streams not implemented yet\n");
854 else if (sample->ismemorystream) {
855 ts5_fatal(
"ts5_get_sample_data_pointer: memory streams not implemented yet\n");
905 if (!al_start_audio_recorder(_ts5_data.audio.recorder)) {
906 ts5_fatal(
"ts5_start_audio_recorder: could not start audio recorder\n");
922 al_stop_audio_recorder(_ts5_data.audio.recorder);
935 al_flush_event_queue(_ts5_data.audio.recorder_queue);
950 sample->start_time = al_get_time();
952 int depth = al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH_INT16);
959 sample->buffer_recorder_position = sample->buffer;
964 al_wait_for_event(_ts5_data.audio.recorder_queue, &event);
965 }
while(event.type != ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT);
966 ALLEGRO_AUDIO_RECORDER_EVENT *recorder_event =
967 al_get_audio_recorder_event(&event);
970 double fragment_onset =
event.any.timestamp - recorder_event->samples / samplerate;
971 int64_t samples_to_skip = (sample->start_time - fragment_onset) * samplerate;
973 if (samples_to_skip < 0) {
978 int64_t samples_to_copy = channels * (recorder_event->samples - samples_to_skip);
980 if (samples_to_copy > sample->buffer_end - sample->buffer_recorder_position) {
981 samples_to_copy = sample->buffer_end - sample->buffer_recorder_position;
984 if (samples_to_copy < 0) {
989 memcpy(sample->buffer_recorder_position, recorder_event->buffer + samples_to_skip * channels,
990 (uint64_t)samples_to_copy * depth);
993 sample->buffer_recorder_position += samples_to_copy;
1009 if (sample->buffer_recorder_position == sample->buffer) {
1010 ts5_fatal(
"ts5_get_sample_fragments: audio recording not started yet\n");
1014 int depth = al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH_INT16);
1018 ALLEGRO_EVENT event;
1019 while (!full && al_get_next_event(_ts5_data.audio.recorder_queue, &event)) {
1021 if (event.type==ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT) {
1023 ALLEGRO_AUDIO_RECORDER_EVENT *recorder_event =
1024 al_get_audio_recorder_event(&event);
1027 int64_t samples_to_copy = channels * recorder_event->samples;
1028 if (samples_to_copy > sample->buffer_end - sample->buffer_recorder_position) {
1029 samples_to_copy = sample->buffer_end - sample->buffer_recorder_position;
1034 memcpy(sample->buffer_recorder_position, recorder_event->buffer,
1035 (uint64_t)samples_to_copy * depth);
1038 sample->buffer_recorder_position += samples_to_copy;
1082 ts5_log(TS5_LOGLEVEL_3,
"ts5_define_voicekey_button(%d)\n", button);
1084 if (abs(button)>_ts5_status.timer.voicekey.num_buttons) {
1085 ts5_fatal(
"%s: %s %d, %s %d is %d\n",
"ts5_define_voicekey_button",
1086 "button argument is", button,
1087 "number of voicekey buttons",
1088 _ts5_status.timer.voicekey.num_buttons);
1091 if (button>0 && _ts5_status.timer.voicekey
1092 .button_press_defined[button-1]!=0) {
1093 ts5_fatal(
"%s: %s %d %s\n",
"ts5_define_voicekey_button",
1094 "button press", button,
"is already defined");
1097 if (button<0 && _ts5_status.timer.voicekey
1098 .button_release_defined[-button-1]!=0) {
1099 ts5_fatal(
"%s: %s %d %s\n",
"ts5_define_voicekey_button",
1100 "button release", button,
"is already defined");
1103 _ts5_status.timer.voicekey_is_response_device = 1;
1104 _ts5_status.timer.num_defined_buttons++;
1105 _ts5_status.timer.num_active_buttons++;
1106 _ts5_status.timer.voicekey.num_defined_buttons++;
1107 _ts5_status.timer.voicekey.num_active_buttons++;
1110 _ts5_status.timer.voicekey
1111 .button_press_defined[button-1] =
1112 _ts5_status.timer.num_defined_buttons;
1114 _ts5_status.timer.voicekey
1115 .button_press_active[button-1] =
1116 _ts5_status.timer.num_defined_buttons;
1119 _ts5_status.timer.voicekey
1120 .button_release_defined[-button-1] =
1121 _ts5_status.timer.num_defined_buttons;
1123 _ts5_status.timer.voicekey
1124 .button_release_active[-button-1] =
1125 _ts5_status.timer.num_defined_buttons;
1128 return _ts5_status.timer.num_defined_buttons;
1142 ts5_log(TS5_LOGLEVEL_4,
"ts5_detect_voice_onsets(%p)\n", sample);
1145 int samplerate = al_get_sample_frequency(sample->sample);
1148 int64_t start_sample =
1149 sample->buffer_voicekey_position - sample->buffer;
1151 int64_t stop_sample =
1152 sample->buffer_recorder_position - sample->buffer;
1155 int64_t start_slice = start_sample * 1000 / samplerate / channels;
1156 int64_t stop_slice = stop_sample * 1000 / samplerate / channels;
1159 for(sample_idx = start_sample; sample_idx < stop_sample; sample_idx++) {
1161 slice_idx = sample_idx * 1000 / samplerate / channels;
1162 sample->voicekey_num_samples[slice_idx]++;
1163 sample->voicekey[slice_idx] +=
1164 (sample->buffer[sample_idx] * sample->buffer[sample_idx]);
1169 for(slice_idx = start_slice; slice_idx < stop_slice; slice_idx++) {
1170 sample->voicekey[slice_idx] =
1171 sqrt(sample->voicekey[slice_idx]/sample->voicekey_num_samples[slice_idx]) / max;
1175 for(slice_idx = start_slice; slice_idx < stop_slice; slice_idx++) {
1177 if(sample->voicekey[slice_idx] > _ts5_status.timer.voicekey.treshold) {
1178 sample->voicekey[slice_idx] = 1.0;
1181 sample->voicekey[slice_idx] = 0.0;
1188 for(slice_idx = start_slice; slice_idx < stop_slice; slice_idx++) {
1190 if(sample->voicekey[slice_idx] > _ts5_status.timer.voicekey.treshold) {
1197 if(current_state != sample->previous_state) {
1199 int64_t diff = slice_idx - sample->last_state_toggle_time;
1200 int rise = current_state && diff > _ts5_status.timer.voicekey.rise_delay * 1000;
1201 int drop = (!current_state) && diff > _ts5_status.timer.voicekey.drop_delay * 1000;
1205 ALLEGRO_EVENT voicekey_event;
1207 voicekey_event.user.type = TS5_EVENT_VOICEKEY_BUTTON_DOWN;
1211 voicekey_event.user.type = TS5_EVENT_VOICEKEY_BUTTON_UP;
1214 voicekey_event.user.data1 = 1;
1215 voicekey_event.user.data2 = 1;
1219 voicekey_event.user.data3 =
1220 (intptr_t)(slice_idx*1000 + sample->start_time*1000000.0);
1222 sample->previous_state = current_state;
1223 sample->last_state_toggle_time = slice_idx;
1226 &_ts5_data.timer.voicekey_response_event_source,
1227 &voicekey_event, NULL);
1245 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_treshold(%f)\n", treshold);
1247 if (treshold < 0.0) {
1248 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_treshold",
1249 "treshold should be positive", treshold);
1252 if (treshold > 1.0) {
1253 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_treshold",
1254 "treshold should be smaller than 1.0", treshold);
1258 _ts5_status.timer.voicekey.treshold;
1260 _ts5_status.timer.voicekey.treshold = treshold;
1262 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1263 "ts5_set_voicekey_treshold",
1264 "set voice key treshold",
1265 _ts5_status.timer.voicekey.treshold,
1280 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_treshold\n");
1282 return _ts5_status.timer.voicekey.treshold;
1297 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_rise_delay(%f)\n", rise_delay);
1299 if (rise_delay < 0.0) {
1300 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_rise_delay",
1301 "rise_delay should be positive", rise_delay);
1304 double retval = _ts5_status.timer.voicekey.rise_delay;
1306 _ts5_status.timer.voicekey.rise_delay = rise_delay;
1308 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1309 "ts5_set_voicekey_rise_delay",
1310 "set voice key rise_delay",
1311 _ts5_status.timer.voicekey.rise_delay,
1326 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_rise_delay\n");
1328 return _ts5_status.timer.voicekey.rise_delay;
1344 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_drop_delay(%f)\n", drop_delay);
1346 if (drop_delay < 0.0) {
1347 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_drop_delay",
1348 "drop_delay should be positive", drop_delay);
1351 double retval = _ts5_status.timer.voicekey.drop_delay;
1353 _ts5_status.timer.voicekey.drop_delay = drop_delay;
1355 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1356 "ts5_set_voicekey_drop_delay",
1357 "set voice key drop_delay",
1358 _ts5_status.timer.voicekey.drop_delay,
1373 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_drop_delay\n");
1375 return _ts5_status.timer.voicekey.drop_delay;
1408 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_samplerate(%p)\n", sample);
1411 ts5_fatal(
"ts5_get_sample_samplerate: sample pointer is null\n");
1414 unsigned int retval = 0;
1416 if (sample->issample) {
1417 retval = al_get_sample_frequency(sample->sample);
1419 else if (sample->isfilestream) {
1420 retval = al_get_audio_stream_frequency(sample->stream);
1422 else if (sample->ismemorystream) {
1423 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_samplerate",
1424 "memory streams not implemented yet");
1441 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_channels(%p)\n", sample);
1444 ts5_fatal(
"ts5_get_sample_channels: sample pointer is null\n");
1447 ALLEGRO_CHANNEL_CONF channels = 0;
1449 if (sample->issample) {
1450 channels = al_get_sample_channels(sample->sample);
1452 else if (sample->isfilestream) {
1453 channels = al_get_audio_stream_channels(sample->stream);
1455 else if (sample->ismemorystream) {
1456 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
1457 "memory streams not implemented yet");
1460 unsigned int retval = 0;
1462 if (channels == ALLEGRO_CHANNEL_CONF_1) {
1465 else if (channels == ALLEGRO_CHANNEL_CONF_2) {
1466 retval = TS5_STEREO;
1469 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
1470 "got an unknown number of channels");
1487 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_depth(%p)\n", sample);
1490 ts5_fatal(
"ts5_get_sample_depth: sample pointer is null\n");
1493 ALLEGRO_AUDIO_DEPTH depth = 0;
1495 if (sample->issample) {
1496 depth = al_get_sample_depth(sample->sample);
1498 else if (sample->isfilestream) {
1499 depth = al_get_audio_stream_depth(sample->stream);
1501 else if (sample->ismemorystream) {
1502 ts5_fatal(
"ts5_get_sample_depth: memory streams not implemented yet\n");
1507 if (depth == ALLEGRO_AUDIO_DEPTH_INT16) {
1508 retval = TS5_INTEGER;
1510 else if (depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) {
1514 ts5_fatal(
"ts5_get_audio_depth: got an unknown sample depth\n");
1531 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_length(%p)\n", sample);
1534 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
1537 double retval = 0.0;
1539 if (sample->issample) {
1540 double freq = al_get_sample_frequency(sample->sample);
1541 retval = (double)al_get_sample_length(sample->sample) / freq;
1543 else if (sample->isfilestream) {
1544 retval = al_get_audio_stream_length_secs(sample->stream);
1546 else if (sample->ismemorystream) {
1547 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_length",
1548 "memory streams not implemented yet");
1567 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_position(%p,%u)\n",
1571 ts5_fatal(
"ts5_set_sample_position: sample pointer is null\n");
1574 double retval = 0.0;
1576 if (sample->issample) {
1578 double freq = al_get_sample_frequency(sample->sample);
1579 double max = al_get_sample_length(sample->sample) / freq;
1581 if (position > max) {
1582 ts5_fatal(
"ts5_set_sample_position: position should be",
1583 " <= the length of the sample (%f)\n", max);
1586 retval = al_get_sample_instance_position(sample->instance) / freq;
1588 if (!(al_set_sample_instance_position(sample->instance, position*freq))) {
1589 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1590 "could not change sample position");
1593 else if (sample->isfilestream) {
1595 unsigned int max = al_get_audio_stream_length_secs(sample->stream);
1597 if (position > max) {
1598 ts5_fatal(
"ts5_set_sample_position: position should be",
1599 " <= the length of the sample (%f)\n", max);
1602 retval = al_get_audio_stream_position_secs(sample->stream);
1604 if (!(al_seek_audio_stream_secs(sample->stream, position))) {
1605 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1606 "could not change sample position");
1609 else if (sample->ismemorystream) {
1610 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1611 "memory streams not implemented yet");
1628 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_position(%p)\n", sample);
1631 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
1634 double retval = 0.0;
1636 if (sample->issample) {
1637 double freq = al_get_sample_frequency(sample->sample);
1638 retval = al_get_sample_instance_position(sample->instance) / freq;
1640 else if (sample->isfilestream) {
1641 retval = al_get_audio_stream_position_secs(sample->stream);
1643 else if (sample->ismemorystream) {
1644 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_position",
1645 "memory streams not implemented yet");
1663 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_speed(%p,%f)\n", sample, speed);
1666 ts5_fatal(
"ts5_set_sample_speed: sample pointer is null\n");
1670 ts5_fatal(
"ts5_set_sample_speed: speed should be >0 (is %f)\n", speed);
1673 double retval = 0.0;
1675 if (sample->issample) {
1677 retval = al_get_sample_instance_speed(sample->instance);
1679 if (!(al_set_sample_instance_speed(sample->instance, speed))) {
1680 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1681 "could not change sample speed", speed);
1684 else if (sample->isfilestream) {
1686 retval = al_get_audio_stream_speed(sample->stream);
1688 if (!(al_set_audio_stream_speed(sample->stream, speed))) {
1689 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1690 "could not change sample speed", speed);
1693 else if (sample->ismemorystream) {
1694 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_speed",
1695 "memory streams not implemented yet");
1712 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_speed(%p)\n", sample);
1715 ts5_fatal(
"ts5_get_sample_speed: sample pointer is null\n");
1718 double retval = 0.0;
1720 if (sample->issample) {
1721 retval = al_get_sample_instance_speed(sample->instance);
1723 else if (sample->isfilestream) {
1724 retval = al_get_audio_stream_speed(sample->stream);
1726 else if (sample->ismemorystream) {
1727 ts5_fatal(
"ts5_get_sample_speed: memory streams not implemented yet\n");
1745 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_gain(%p,%f)\n", sample, gain);
1748 ts5_fatal(
"ts5_set_sample_gain: sample pointer is null\n");
1752 ts5_fatal(
"ts5_set_sample_gain: gain should be >0 (is %f)\n", gain);
1755 double retval = 0.0;
1757 if (sample->issample) {
1759 retval = al_get_sample_instance_gain(sample->instance);
1761 if (!(al_set_sample_instance_gain(sample->instance, gain))) {
1762 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1763 "could not change sample gain", gain);
1766 else if (sample->isfilestream) {
1768 retval = al_get_audio_stream_gain(sample->stream);
1770 if (!(al_set_audio_stream_gain(sample->stream, gain))) {
1771 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1772 "could not change sample gain", gain);
1775 else if (sample->ismemorystream) {
1776 ts5_fatal(
"ts5_set_sample_gain: memory streams not implemented yet\n");
1793 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_gain(%p)\n", sample);
1796 ts5_fatal(
"ts5_get_sample_gain: sample pointer is null\n");
1799 double retval = 0.0;
1801 if (sample->issample) {
1802 retval = al_get_sample_instance_gain(sample->instance);
1804 else if (sample->isfilestream) {
1805 retval = al_get_audio_stream_gain(sample->stream);
1807 else if (sample->ismemorystream) {
1808 ts5_fatal(
"ts5_get_sample_gain: memory streams not implemented yet\n");
1827 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_pan(%p,%f)\n", sample, pan);
1830 ts5_fatal(
"ts5_set_sample_pan: sample pointer is null\n");
1833 if (pan < -1.0 || pan > 1) {
1834 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_sample_pan",
1835 "pan should be between -1.0 and 1.0", pan);
1838 double retval = 0.0;
1840 if (sample->issample) {
1842 retval = al_get_sample_instance_pan(sample->instance);
1844 if (!(al_set_sample_instance_pan(sample->instance, pan))) {
1845 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1846 "could not change sample pan", pan);
1849 else if (sample->isfilestream) {
1851 retval = al_get_audio_stream_pan(sample->stream);
1853 if (!(al_set_audio_stream_pan(sample->stream, pan))) {
1854 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1855 "could not change sample pan", pan);
1858 else if (sample->ismemorystream) {
1859 ts5_fatal(
"ts5_set_sample_pan: memory streams not implemented yet\n");
1876 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_pan(%p)\n", sample);
1879 ts5_fatal(
"ts5_get_sample_pan: sample pointer is null\n");
1882 double retval = 0.0;
1884 if (sample->issample) {
1885 retval = al_get_sample_instance_pan(sample->instance);
1887 else if (sample->isfilestream) {
1888 retval = al_get_audio_stream_pan(sample->stream);
1890 else if (sample->ismemorystream) {
1891 ts5_fatal(
"memory streams not implemented yet\n");
1909 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_playmode(%p,%d)\n",
1913 ts5_fatal(
"ts5_set_sample_playmode: sample pointer is null\n");
1916 if (playmode != TS5_PLAY_ONCE && playmode != TS5_PLAY_LOOP) {
1917 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1918 "playmode should be TS5_PLAY_ONCE or TS5_PLAY_LOOP");
1923 if (sample->issample) {
1925 retval = al_get_sample_instance_playmode(sample->instance);
1927 if (!(al_set_sample_instance_playmode(sample->instance, playmode))) {
1928 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1929 "could not change sample playmode");
1932 else if (sample->isfilestream) {
1934 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1936 if (!(al_set_audio_stream_playmode(sample->stream, playmode))) {
1937 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1938 "could not change sample playmode");
1941 else if (sample->ismemorystream) {
1942 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1943 "memory streams not implemented yet");
1960 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_playmode(%p)\n", sample);
1963 ts5_fatal(
"ts5_get_sample_playmode: sample pointer is null\n");
1968 if (sample->issample) {
1969 retval = al_get_sample_instance_playmode(sample->instance);
1971 else if (sample->isfilestream) {
1972 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1974 else if (sample->ismemorystream) {
1975 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_playmode",
1976 "memory streams not implemented yet");
unsigned int ts5_get_audio_channels()
Get the number of channels of the audio system.
int ts5_get_sample_playmode(TS5_SAMPLE *sample)
Get the playmode of a sample.
void ts5_record_sample(TS5_SAMPLE *sample)
Start recording a sample.
int _ts5_is_tscope5_installed
Is Tscope5 installed?
double ts5_set_voicekey_rise_delay(double rise_delay)
Set the voice key rise delay.
void ts5_flush_audio_recorder()
Flush the audio recorder buffer.
double ts5_get_sample_speed(TS5_SAMPLE *sample)
Get the playback speed of a sample.
void ts5_write_sample(const char *file, TS5_SAMPLE *sample)
Write a sample.
unsigned int ts5_get_sample_channels(TS5_SAMPLE *sample)
Get the number of channels of a sample.
void ts5_detect_voice_onsets(TS5_SAMPLE *sample)
Detect voice onsets in a sample.
double ts5_get_voicekey_treshold()
Get the voice key treshold.
double ts5_set_sample_speed(TS5_SAMPLE *sample, double speed)
Set the playback speed of a sample.
unsigned int ts5_set_audio_samplerate(unsigned int samplerate)
Set the requested samplerate for the audio system.
int _ts5_is_audio_recorder_recording
Is the audio recorder recording?
int ts5_get_sample_fragments(TS5_SAMPLE *sample)
Update the sample buffer when recording.
double ts5_get_voicekey_drop_delay()
Get the voice key drop delay.
unsigned int ts5_get_sample_samplerate(TS5_SAMPLE *sample)
Get the sample rate of a sample.
void * ts5_get_sample_data_pointer(TS5_SAMPLE *sample)
Get acces to a sample's data.
void ts5_stop_audio_recorder()
Stop the audio recorder.
void ts5_check_audio_recorder(char *calling_function)
Do some checks at the start of each audio recorder function.
void ts5_start_audio_recorder()
Start the audio recorder.
double ts5_get_sample_length(TS5_SAMPLE *sample)
Get the length of a sample.
double ts5_get_sample_position(TS5_SAMPLE *sample)
Get the playback position of a sample.
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
int ts5_set_audio_depth(int depth)
Set the sample depth for the audio system.
unsigned int ts5_get_audio_samplerate()
Get the sample rate of the audio system.
double ts5_get_voicekey_rise_delay()
Get the voice key rise delay.
int ts5_get_sample_status(TS5_SAMPLE *sample)
Query whether a sample is playing.
double ts5_get_sample_pan(TS5_SAMPLE *sample)
Get the playback pan of a sample.
double ts5_set_voicekey_treshold(double treshold)
Set the voice key treshold.
void ts5_install_tscope5(char *calling_function)
Install Tscope5.
void ts5_stop_sample(TS5_SAMPLE *sample)
Stop playing a sample.
double ts5_get_sample_gain(TS5_SAMPLE *sample)
Get the playback gain of a sample.
void ts5_play_sample(TS5_SAMPLE *sample)
Start playing a sample.
int ts5_set_sample_playmode(TS5_SAMPLE *sample, int playmode)
Set the playmode of a sample.
int ts5_define_voicekey_button(int button)
Define the software voice key as a response button.
void ts5_check_voicekey(char *calling_function)
Do some checks at the start of each voicekey function.
int ts5_get_sample_depth(TS5_SAMPLE *sample)
Get the sample depth of a sample.
void ts5_check_audio_recorder2(char *calling_function)
Do some checks at the start of each audio recorder function.
TS5_SAMPLE * ts5_alloc_sample(double length)
Create an empty sample.
void ts5_free_sample(TS5_SAMPLE *sample)
Free the memory used by a sample.
double ts5_get_audio_gain()
Get the gain of the audio system.
void ts5_pause_sample(TS5_SAMPLE *sample)
Pause playing a sample.
void ts5_fatal(const char *format,...)
Exit safely with an error message.
double ts5_set_sample_gain(TS5_SAMPLE *sample, double gain)
Set the playback gain of a sample.
void ts5_check_audio_recorder3(char *calling_function, TS5_SAMPLE *sample)
Do some checks at the start of each audio recorder function.
double ts5_set_sample_position(TS5_SAMPLE *sample, double position)
Set the playback position of a sample.
unsigned int ts5_set_audio_channels(unsigned int channels)
Set the requested number of channels for the audio system.
double ts5_set_sample_pan(TS5_SAMPLE *sample, double pan)
Set the playback pan of a sample.
int ts5_get_audio_depth()
Get the sample depth of the audio system.
double ts5_set_audio_gain(double gain)
Set the gain (amplification factor) of the audio system.
double ts5_set_voicekey_drop_delay(double drop_delay)
Set the voice key drop delay.
void ts5_check_audio(char *calling_function)
Do some checks at the start of each audio function.
TS5_SAMPLE * ts5_read_long_sample(const char *file)
Open a long sample from a file.
TS5_SAMPLE * ts5_read_sample(const char *file)
Open a sample from a file.