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;
378 sample->buffer = NULL;
379 sample->buffer = al_malloc(bytes);
380 sample->buffer_pos = sample->buffer;
381 sample->buffer_end = sample->buffer + samples * _ts5_status.audio.channels;
382 if (!sample->buffer) {
383 ts5_fatal(
"ts5_alloc_sample: could not allocate sample buffer\n");
388 sample->sample = al_create_sample(sample->buffer, samples,
389 _ts5_status.audio.samplerate,
390 ALLEGRO_AUDIO_DEPTH_INT16, channels, 1);
392 if (!sample->sample) {
393 ts5_fatal(
"ts5_alloc_sample: could not create sample\n");
398 sample->instance = al_create_sample_instance(NULL);
400 if (!sample->instance) {
401 ts5_fatal(
"ts5_alloc_sample: could not create sample instance\n");
404 if (!al_set_sample(sample->instance, sample->sample)) {
405 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
406 "could not attach sample to sample instance");
409 if (!al_attach_sample_instance_to_mixer
410 (sample->instance, _ts5_data.audio.mixer)) {
411 ts5_fatal(
"%s: %s\n",
"ts5_alloc_sample",
412 "could not attach sample instance to mixer");
415 al_set_sample_instance_playing(sample->instance, 0);
419 int ntimeslices = length * 1000;
420 sample->rms_num_samples = (
int *)al_malloc(ntimeslices *
sizeof(
int));
421 sample->rms = (
double *)al_malloc(ntimeslices *
sizeof(
double));
422 sample->rms_pos = sample->rms;
423 sample->rms_end = sample->rms + ntimeslices;
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_pos = NULL;
490 sample->buffer_end = NULL;
493 sample->rms_num_samples = NULL;
495 sample->rms_pos = NULL;
496 sample->rms_end = NULL;
500 if (al_get_sample_depth(sample->sample) == ALLEGRO_AUDIO_DEPTH_INT16) {
502 sample->buffer = (int16_t *)al_get_sample_data(sample->sample);
504 sample->buffer_pos = sample->buffer +
505 al_get_sample_length(sample->sample) *
508 sample->buffer_end = sample->buffer_pos;
510 ntimeslices = al_get_sample_length(sample->sample) * 1000;
511 sample->rms_num_samples = (
int *)al_malloc(ntimeslices *
sizeof(
int));
512 sample->rms = (
double *)al_malloc(ntimeslices *
sizeof(
double));
513 sample->rms_pos = sample->rms;
514 sample->rms_end = sample->rms + ntimeslices;
535 ts5_log(TS5_LOGLEVEL_2,
"ts5_read_long_sample(%s)\n", file);
537 TS5_SAMPLE *sample = NULL;
538 sample = (TS5_SAMPLE *)al_malloc(
sizeof(TS5_SAMPLE));
541 ts5_fatal(
"ts5_read_long_sample: could not allocate sample\n");
544 sample->issample = 0;
545 sample->isbuffer = 0;
546 sample->isfilestream = 1;
547 sample->ismemorystream = 0;
549 sample->sample = NULL;
550 sample->instance = NULL;
551 sample->stream = NULL;
552 sample->stream = al_load_audio_stream(file, 4, 2048);
554 if (!sample->stream) {
555 ts5_fatal(
"ts5_read_long_sample: could not read sample\n");
558 if (!al_attach_audio_stream_to_mixer
559 (sample->stream, _ts5_data.audio.mixer)) {
560 ts5_fatal(
"%s: %s\n",
"ts5_read_long_sample",
561 "could not attach sample stream to mixer");
564 al_set_audio_stream_playing(sample->stream, 0);
565 al_set_audio_stream_playmode(sample->stream, ALLEGRO_PLAYMODE_ONCE);
568 sample->start_time = 0.0;
571 sample->buffer = NULL;
572 sample->buffer_pos = NULL;
573 sample->buffer_end = NULL;
574 sample->start_time = 0.0;
577 sample->rms_num_samples = NULL;
579 sample->rms_pos = NULL;
580 sample->rms_end = NULL;
598 ts5_log(TS5_LOGLEVEL_2,
"ts5_write_sample(%s,%p)\n", file, sample);
600 if (!sample->issample) {
601 ts5_fatal(
"%s: %s\n",
"ts5_write_sample",
602 "writing of streams is not implemented yet\n");
605 if (!al_save_sample(file, sample->sample)) {
606 ts5_fatal(
"ts5_write_sample: could not write sample\n");
622 ts5_log(TS5_LOGLEVEL_2,
"ts5_free_sample(%p)\n", sample);
624 if (sample->issample) {
625 al_set_sample(sample->instance, NULL);
626 al_destroy_sample(sample->sample);
628 al_detach_sample_instance(sample->instance);
629 al_destroy_sample_instance(sample->instance);
631 al_free(sample->rms_num_samples);
632 al_free(sample->rms);
634 else if (sample->isfilestream) {
635 al_detach_audio_stream(sample->stream);
636 al_destroy_audio_stream(sample->stream);
638 else if (sample->ismemorystream) {
639 ts5_fatal(
"ts5_free_sample: memory streams not implemented yet\n");
670 ts5_log(TS5_LOGLEVEL_5,
"ts5_play_sample(%p)\n", sample);
673 ts5_fatal(
"ts5_play_sample: sample pointer is null\n");
676 if (sample->issample) {
678 if (!al_set_sample_instance_playing(sample->instance, 1)) {
679 ts5_fatal(
"ts5_play_sample: could not play sample\n");
682 else if (sample->isfilestream) {
684 if (!al_set_audio_stream_playing(sample->stream, 1)) {
685 ts5_fatal(
"ts5_play_sample: could not play sample\n");
688 else if (sample->ismemorystream) {
689 ts5_fatal(
"ts5_play_sample: memory streams not implemented yet\n");
702 ts5_log(TS5_LOGLEVEL_5,
"ts5_pause_sample(%p)\n", sample);
705 ts5_fatal(
"ts5_pause_sample: sample pointer is null\n");
708 if (sample->issample) {
710 if (!al_set_sample_instance_playing(sample->instance, 0)) {
711 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
714 else if (sample->isfilestream) {
716 if (!al_set_audio_stream_playing(sample->stream, 0)) {
717 ts5_fatal(
"ts5_pause_sample: could not pause sample\n");
720 else if (sample->ismemorystream) {
721 ts5_fatal(
"memory streams not implemented yet\n");
734 ts5_log(TS5_LOGLEVEL_5,
"ts5_stop_sample(%p)\n", sample);
737 ts5_fatal(
"ts5_stop_sample: sample pointer is null\n");
740 if (sample->issample) {
742 if (!al_set_sample_instance_playing(sample->instance, 0)) {
743 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
746 if (!al_set_sample_instance_position(sample->instance, 0)) {
747 ts5_fatal(
"ts5_stop_sample: could not stop sample\n");
750 else if (sample->isfilestream) {
752 al_drain_audio_stream(sample->stream);
754 if (!al_rewind_audio_stream(sample->stream)) {
755 ts5_fatal(
"ts5_stop_sample: could not rewind sample\n");
758 else if (sample->ismemorystream) {
759 ts5_fatal(
"ts5_stop_sample: memory streams not implemented yet\n");
774 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_sample_status(%p)\n", sample);
777 ts5_fatal(
"ts5_get_sample_status: sample pointer is null\n");
782 if (sample->issample) {
783 retval = al_get_sample_instance_playing(sample->instance);
785 else if (sample->isfilestream) {
786 retval = al_get_audio_stream_playing(sample->stream);
788 else if (sample->ismemorystream) {
789 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_status",
790 "memory streams not implemented yet");
793 ts5_fatal(
"ts5_get_sample_status: sample type unknown\n");
834 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_sample_data_pointer(%p)\n", sample);
837 ts5_fatal(
"ts5_get_sample_data_pointer: sample pointer is null\n");
843 if (sample->issample) {
844 retval = al_get_sample_data(sample->sample);
846 else if (sample->isfilestream) {
847 ts5_fatal(
"ts5_get_sample_data_pointer: file streams not implemented yet\n");
849 else if (sample->ismemorystream) {
850 ts5_fatal(
"ts5_get_sample_data_pointer: memory streams not implemented yet\n");
899 if (!al_start_audio_recorder(_ts5_data.audio.recorder)) {
900 ts5_fatal(
"ts5_start_audio_recorder: could not start audio recorder\n");
916 al_stop_audio_recorder(_ts5_data.audio.recorder);
929 al_flush_event_queue(_ts5_data.audio.recorder_queue);
944 sample->start_time = al_get_time();
946 int depth = al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH_INT16);
953 sample->buffer_pos = sample->buffer;
958 al_wait_for_event(_ts5_data.audio.recorder_queue, &event);
959 }
while(event.type != ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT);
960 ALLEGRO_AUDIO_RECORDER_EVENT *recorder_event =
961 al_get_audio_recorder_event(&event);
964 double fragment_onset =
event.any.timestamp - recorder_event->samples / samplerate;
965 int64_t samples_to_skip = (sample->start_time - fragment_onset) * samplerate;
967 if (samples_to_skip < 0) {
972 int64_t samples_to_copy = channels * (recorder_event->samples - samples_to_skip);
974 if (samples_to_copy > sample->buffer_end - sample->buffer_pos) {
975 samples_to_copy = sample->buffer_end - sample->buffer_pos;
978 if (samples_to_copy < 0) {
983 memcpy(sample->buffer_pos, recorder_event->buffer + samples_to_skip * channels,
984 (uint64_t)samples_to_copy * depth);
987 sample->buffer_pos += samples_to_copy;
1004 if (sample->buffer_pos == sample->buffer) {
1005 ts5_fatal(
"ts5_get_sample_fragments: audio recording not started yet\n");
1009 int depth = al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH_INT16);
1013 ALLEGRO_EVENT event;
1014 while (!full && al_get_next_event(_ts5_data.audio.recorder_queue, &event)) {
1016 if (event.type==ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT) {
1018 ALLEGRO_AUDIO_RECORDER_EVENT *recorder_event =
1019 al_get_audio_recorder_event(&event);
1022 int64_t samples_to_copy = channels * recorder_event->samples;
1023 if (samples_to_copy > sample->buffer_end - sample->buffer_pos) {
1024 samples_to_copy = sample->buffer_end - sample->buffer_pos;
1029 memcpy(sample->buffer_pos, recorder_event->buffer,
1030 (uint64_t)samples_to_copy * depth);
1033 sample->buffer_pos += samples_to_copy;
1076 ts5_log(TS5_LOGLEVEL_3,
"ts5_define_voicekey_button(%d)\n", button);
1078 if (abs(button)>_ts5_status.timer.voicekey.num_buttons) {
1079 ts5_fatal(
"%s: %s %d, %s %d is %d\n",
"ts5_define_voicekey_button",
1080 "button argument is", button,
1081 "number of voicekey buttons",
1082 _ts5_status.timer.voicekey.num_buttons);
1085 if (button>0 && _ts5_status.timer.voicekey
1086 .button_press_defined[button-1]!=0) {
1087 ts5_fatal(
"%s: %s %d %s\n",
"ts5_define_voicekey_button",
1088 "button press", button,
"is already defined");
1091 if (button<0 && _ts5_status.timer.voicekey
1092 .button_release_defined[-button-1]!=0) {
1093 ts5_fatal(
"%s: %s %d %s\n",
"ts5_define_voicekey_button",
1094 "button release", button,
"is already defined");
1097 _ts5_status.timer.voicekey_is_response_device = 1;
1098 _ts5_status.timer.num_defined_buttons++;
1099 _ts5_status.timer.num_active_buttons++;
1100 _ts5_status.timer.voicekey.num_defined_buttons++;
1101 _ts5_status.timer.voicekey.num_active_buttons++;
1104 _ts5_status.timer.voicekey
1105 .button_press_defined[button-1] =
1106 _ts5_status.timer.num_defined_buttons;
1108 _ts5_status.timer.voicekey
1109 .button_press_active[button-1] =
1110 _ts5_status.timer.num_defined_buttons;
1113 _ts5_status.timer.voicekey
1114 .button_release_defined[-button-1] =
1115 _ts5_status.timer.num_defined_buttons;
1117 _ts5_status.timer.voicekey
1118 .button_release_active[-button-1] =
1119 _ts5_status.timer.num_defined_buttons;
1122 return _ts5_status.timer.num_defined_buttons;
1134 ts5_log(TS5_LOGLEVEL_4,
"ts5_detect_voice_onsets(%p)\n", sample);
1137 ts5_fatal(
"ts5_detect_voice_onsets: sample pointer is null\n");
1140 if (sample->isfilestream) {
1141 ts5_fatal(
"ts5_detect_voice_onsets: file streams not implemented yet\n");
1144 if (sample->ismemorystream) {
1145 ts5_fatal(
"ts5_detect_voice_onsets: memory streams not implemented yet\n");
1148 if (al_get_sample_depth(sample->sample) != ALLEGRO_AUDIO_DEPTH_INT16) {
1149 ts5_fatal(
"ts5_detect_voice_onsets: floating point samples not implemented\n");
1153 int samplerate = al_get_sample_frequency(sample->sample);
1154 int64_t nsamples = sample->buffer_pos - sample->buffer;
1158 int64_t timeslice = 0;
1159 for(sample_idx=0; sample_idx<nsamples; sample_idx++) {
1160 timeslice = sample_idx * 1000 / samplerate / channels;
1161 sample->rms_num_samples[timeslice]++;
1162 sample->rms[timeslice] +=
1163 (sample->buffer[sample_idx] * sample->buffer[sample_idx]);
1169 for(timeslice=0; timeslice<ntimeslices; timeslice++) {
1170 sample->rms[timeslice] =
1171 sqrt(sample->rms[timeslice]/sample->rms_num_samples[timeslice]) / max;
1175 for(timeslice=0; timeslice<ntimeslices; timeslice++) {
1177 if(sample->rms[timeslice] > _ts5_status.timer.voicekey.treshold) {
1178 sample->rms[timeslice] = 1.0;
1181 sample->rms[timeslice] = 0.0;
1186 int current_state, previous_state=0;
1187 int64_t last_state_toggle_time=0;
1189 for(timeslice=0; timeslice<ntimeslices; timeslice++) {
1191 if(sample->rms[timeslice] > _ts5_status.timer.voicekey.treshold) {
1198 if(current_state != previous_state) {
1200 int diff = timeslice - last_state_toggle_time;
1201 int rise = current_state && diff > _ts5_status.timer.voicekey.rise_delay * 1000;
1202 int drop = (!current_state) && diff > _ts5_status.timer.voicekey.drop_delay * 1000;
1206 ALLEGRO_EVENT voicekey_event;
1208 voicekey_event.user.type = TS5_EVENT_VOICEKEY_BUTTON_DOWN;
1212 voicekey_event.user.type = TS5_EVENT_VOICEKEY_BUTTON_UP;
1215 voicekey_event.user.data1 = 1;
1216 voicekey_event.user.data2 = 1;
1220 voicekey_event.user.data3 =
1221 (intptr_t)(timeslice*1000 - sample->start_time*1000000.0);
1223 previous_state = current_state;
1224 last_state_toggle_time = timeslice;
1227 &_ts5_data.timer.voicekey_response_event_source,
1228 &voicekey_event, NULL);
1247 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_treshold(%f)\n", treshold);
1249 if (treshold < 0.0) {
1250 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_treshold",
1251 "treshold should be positive", treshold);
1254 if (treshold > 1.0) {
1255 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_treshold",
1256 "treshold should be smaller than 1.0", treshold);
1260 _ts5_status.timer.voicekey.treshold;
1262 _ts5_status.timer.voicekey.treshold = treshold;
1264 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1265 "ts5_set_voicekey_treshold",
1266 "set voice key treshold",
1267 _ts5_status.timer.voicekey.treshold,
1282 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_treshold\n");
1284 return _ts5_status.timer.voicekey.treshold;
1299 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_rise_delay(%f)\n", rise_delay);
1301 if (rise_delay < 0.0) {
1302 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_rise_delay",
1303 "rise_delay should be positive", rise_delay);
1306 double retval = _ts5_status.timer.voicekey.rise_delay;
1308 _ts5_status.timer.voicekey.rise_delay = rise_delay;
1310 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1311 "ts5_set_voicekey_rise_delay",
1312 "set voice key rise_delay",
1313 _ts5_status.timer.voicekey.rise_delay,
1328 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_rise_delay\n");
1330 return _ts5_status.timer.voicekey.rise_delay;
1346 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_voicekey_drop_delay(%f)\n", drop_delay);
1348 if (drop_delay < 0.0) {
1349 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_voicekey_drop_delay",
1350 "drop_delay should be positive", drop_delay);
1353 double retval = _ts5_status.timer.voicekey.drop_delay;
1355 _ts5_status.timer.voicekey.drop_delay = drop_delay;
1357 ts5_log(TS5_LOGLEVEL_4,
"%s: %s to %f (was %f)\n",
1358 "ts5_set_voicekey_drop_delay",
1359 "set voice key drop_delay",
1360 _ts5_status.timer.voicekey.drop_delay,
1375 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_voicekey_drop_delay\n");
1377 return _ts5_status.timer.voicekey.drop_delay;
1410 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_samplerate(%p)\n", sample);
1413 ts5_fatal(
"ts5_get_sample_samplerate: sample pointer is null\n");
1416 unsigned int retval = 0;
1418 if (sample->issample) {
1419 retval = al_get_sample_frequency(sample->sample);
1421 else if (sample->isfilestream) {
1422 retval = al_get_audio_stream_frequency(sample->stream);
1424 else if (sample->ismemorystream) {
1425 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_samplerate",
1426 "memory streams not implemented yet");
1443 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_channels(%p)\n", sample);
1446 ts5_fatal(
"ts5_get_sample_channels: sample pointer is null\n");
1449 ALLEGRO_CHANNEL_CONF channels = 0;
1451 if (sample->issample) {
1452 channels = al_get_sample_channels(sample->sample);
1454 else if (sample->isfilestream) {
1455 channels = al_get_audio_stream_channels(sample->stream);
1457 else if (sample->ismemorystream) {
1458 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
1459 "memory streams not implemented yet");
1462 unsigned int retval = 0;
1464 if (channels == ALLEGRO_CHANNEL_CONF_1) {
1467 else if (channels == ALLEGRO_CHANNEL_CONF_2) {
1468 retval = TS5_STEREO;
1471 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_channels",
1472 "got an unknown number of channels");
1489 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_depth(%p)\n", sample);
1492 ts5_fatal(
"ts5_get_sample_depth: sample pointer is null\n");
1495 ALLEGRO_AUDIO_DEPTH depth = 0;
1497 if (sample->issample) {
1498 depth = al_get_sample_depth(sample->sample);
1500 else if (sample->isfilestream) {
1501 depth = al_get_audio_stream_depth(sample->stream);
1503 else if (sample->ismemorystream) {
1504 ts5_fatal(
"ts5_get_sample_depth: memory streams not implemented yet\n");
1509 if (depth == ALLEGRO_AUDIO_DEPTH_INT16) {
1510 retval = TS5_INTEGER;
1512 else if (depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) {
1516 ts5_fatal(
"ts5_get_audio_depth: got an unknown sample depth\n");
1533 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_length(%p)\n", sample);
1536 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
1539 double retval = 0.0;
1541 if (sample->issample) {
1542 double freq = al_get_sample_frequency(sample->sample);
1543 retval = (double)al_get_sample_length(sample->sample) / freq;
1545 else if (sample->isfilestream) {
1546 retval = al_get_audio_stream_length_secs(sample->stream);
1548 else if (sample->ismemorystream) {
1549 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_length",
1550 "memory streams not implemented yet");
1569 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_position(%p,%u)\n",
1573 ts5_fatal(
"ts5_set_sample_position: sample pointer is null\n");
1576 double retval = 0.0;
1578 if (sample->issample) {
1580 double freq = al_get_sample_frequency(sample->sample);
1581 double max = al_get_sample_length(sample->sample) / freq;
1583 if (position > max) {
1584 ts5_fatal(
"ts5_set_sample_position: position should be",
1585 " <= the length of the sample (%f)\n", max);
1588 retval = al_get_sample_instance_position(sample->instance) / freq;
1590 if (!(al_set_sample_instance_position(sample->instance, position*freq))) {
1591 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1592 "could not change sample position");
1595 else if (sample->isfilestream) {
1597 unsigned int max = al_get_audio_stream_length_secs(sample->stream);
1599 if (position > max) {
1600 ts5_fatal(
"ts5_set_sample_position: position should be",
1601 " <= the length of the sample (%f)\n", max);
1604 retval = al_get_audio_stream_position_secs(sample->stream);
1606 if (!(al_seek_audio_stream_secs(sample->stream, position))) {
1607 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1608 "could not change sample position");
1611 else if (sample->ismemorystream) {
1612 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_position",
1613 "memory streams not implemented yet");
1630 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_position(%p)\n", sample);
1633 ts5_fatal(
"ts5_get_sample_length: sample pointer is null\n");
1636 double retval = 0.0;
1638 if (sample->issample) {
1639 double freq = al_get_sample_frequency(sample->sample);
1640 retval = al_get_sample_instance_position(sample->instance) / freq;
1642 else if (sample->isfilestream) {
1643 retval = al_get_audio_stream_position_secs(sample->stream);
1645 else if (sample->ismemorystream) {
1646 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_position",
1647 "memory streams not implemented yet");
1665 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_speed(%p,%f)\n", sample, speed);
1668 ts5_fatal(
"ts5_set_sample_speed: sample pointer is null\n");
1672 ts5_fatal(
"ts5_set_sample_speed: speed should be >0 (is %f)\n", speed);
1675 double retval = 0.0;
1677 if (sample->issample) {
1679 retval = al_get_sample_instance_speed(sample->instance);
1681 if (!(al_set_sample_instance_speed(sample->instance, speed))) {
1682 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1683 "could not change sample speed", speed);
1686 else if (sample->isfilestream) {
1688 retval = al_get_audio_stream_speed(sample->stream);
1690 if (!(al_set_audio_stream_speed(sample->stream, speed))) {
1691 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_speed",
1692 "could not change sample speed", speed);
1695 else if (sample->ismemorystream) {
1696 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_speed",
1697 "memory streams not implemented yet");
1714 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_speed(%p)\n", sample);
1717 ts5_fatal(
"ts5_get_sample_speed: sample pointer is null\n");
1720 double retval = 0.0;
1722 if (sample->issample) {
1723 retval = al_get_sample_instance_speed(sample->instance);
1725 else if (sample->isfilestream) {
1726 retval = al_get_audio_stream_speed(sample->stream);
1728 else if (sample->ismemorystream) {
1729 ts5_fatal(
"ts5_get_sample_speed: memory streams not implemented yet\n");
1747 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_gain(%p,%f)\n", sample, gain);
1750 ts5_fatal(
"ts5_set_sample_gain: sample pointer is null\n");
1754 ts5_fatal(
"ts5_set_sample_gain: gain should be >0 (is %f)\n", gain);
1757 double retval = 0.0;
1759 if (sample->issample) {
1761 retval = al_get_sample_instance_gain(sample->instance);
1763 if (!(al_set_sample_instance_gain(sample->instance, gain))) {
1764 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1765 "could not change sample gain", gain);
1768 else if (sample->isfilestream) {
1770 retval = al_get_audio_stream_gain(sample->stream);
1772 if (!(al_set_audio_stream_gain(sample->stream, gain))) {
1773 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_gain",
1774 "could not change sample gain", gain);
1777 else if (sample->ismemorystream) {
1778 ts5_fatal(
"ts5_set_sample_gain: memory streams not implemented yet\n");
1795 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_gain(%p)\n", sample);
1798 ts5_fatal(
"ts5_get_sample_gain: sample pointer is null\n");
1801 double retval = 0.0;
1803 if (sample->issample) {
1804 retval = al_get_sample_instance_gain(sample->instance);
1806 else if (sample->isfilestream) {
1807 retval = al_get_audio_stream_gain(sample->stream);
1809 else if (sample->ismemorystream) {
1810 ts5_fatal(
"ts5_get_sample_gain: memory streams not implemented yet\n");
1829 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_pan(%p,%f)\n", sample, pan);
1832 ts5_fatal(
"ts5_set_sample_pan: sample pointer is null\n");
1835 if (pan < -1.0 || pan > 1) {
1836 ts5_fatal(
"%s: %s (is %f)\n",
"ts5_set_sample_pan",
1837 "pan should be between -1.0 and 1.0", pan);
1840 double retval = 0.0;
1842 if (sample->issample) {
1844 retval = al_get_sample_instance_pan(sample->instance);
1846 if (!(al_set_sample_instance_pan(sample->instance, pan))) {
1847 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1848 "could not change sample pan", pan);
1851 else if (sample->isfilestream) {
1853 retval = al_get_audio_stream_pan(sample->stream);
1855 if (!(al_set_audio_stream_pan(sample->stream, pan))) {
1856 ts5_fatal(
"%s: %s (%f)\n",
"ts5_set_sample_pan",
1857 "could not change sample pan", pan);
1860 else if (sample->ismemorystream) {
1861 ts5_fatal(
"ts5_set_sample_pan: memory streams not implemented yet\n");
1878 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_pan(%p)\n", sample);
1881 ts5_fatal(
"ts5_get_sample_pan: sample pointer is null\n");
1884 double retval = 0.0;
1886 if (sample->issample) {
1887 retval = al_get_sample_instance_pan(sample->instance);
1889 else if (sample->isfilestream) {
1890 retval = al_get_audio_stream_pan(sample->stream);
1892 else if (sample->ismemorystream) {
1893 ts5_fatal(
"memory streams not implemented yet\n");
1911 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_sample_playmode(%p,%d)\n",
1915 ts5_fatal(
"ts5_set_sample_playmode: sample pointer is null\n");
1918 if (playmode != TS5_PLAY_ONCE && playmode != TS5_PLAY_LOOP) {
1919 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1920 "playmode should be TS5_PLAY_ONCE or TS5_PLAY_LOOP");
1925 if (sample->issample) {
1927 retval = al_get_sample_instance_playmode(sample->instance);
1929 if (!(al_set_sample_instance_playmode(sample->instance, playmode))) {
1930 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1931 "could not change sample playmode");
1934 else if (sample->isfilestream) {
1936 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1938 if (!(al_set_audio_stream_playmode(sample->stream, playmode))) {
1939 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1940 "could not change sample playmode");
1943 else if (sample->ismemorystream) {
1944 ts5_fatal(
"%s: %s\n",
"ts5_set_sample_playmode",
1945 "memory streams not implemented yet");
1962 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_sample_playmode(%p)\n", sample);
1965 ts5_fatal(
"ts5_get_sample_playmode: sample pointer is null\n");
1970 if (sample->issample) {
1971 retval = al_get_sample_instance_playmode(sample->instance);
1973 else if (sample->isfilestream) {
1974 retval = al_get_audio_stream_playmode(sample->stream) - 3;
1976 else if (sample->ismemorystream) {
1977 ts5_fatal(
"%s: %s\n",
"ts5_get_sample_playmode",
1978 "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.