diff options
Diffstat (limited to 'src/lingot-audio.c')
| -rw-r--r-- | src/lingot-audio.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/lingot-audio.c b/src/lingot-audio.c new file mode 100644 index 0000000..7e81ab1 --- /dev/null +++ b/src/lingot-audio.c @@ -0,0 +1,208 @@ +/* + * lingot, a musical instrument tuner. + * + * Copyright (C) 2004-2011 Ibán Cereijo Graña, Jairo Chapela Martínez. + * + * This file is part of lingot. + * + * lingot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * lingot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with lingot; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "lingot-defs.h" +#include "lingot-audio.h" + +#include "lingot-core.h" +#include "lingot-audio-oss.h" +#include "lingot-audio-alsa.h" +#include "lingot-audio-jack.h" + +LingotAudioHandler* lingot_audio_new(audio_system_t audio_system, char* device, + int sample_rate, LingotAudioProcessCallback process_callback, + void *process_callback_arg) { + + LingotAudioHandler* result = NULL; + + switch (audio_system) { + case AUDIO_SYSTEM_OSS: + result = lingot_audio_oss_new(device, sample_rate); + break; + case AUDIO_SYSTEM_ALSA: + result = lingot_audio_alsa_new(device, sample_rate); + break; + case AUDIO_SYSTEM_JACK: + result = lingot_audio_jack_new(device, sample_rate); + break; + } + + if (result != NULL) { + // audio source read in floating point format. + result->flt_read_buffer + = malloc(result->read_buffer_size * sizeof(FLT)); + memset(result->flt_read_buffer, 0, result->read_buffer_size + * sizeof(FLT)); + result->process_callback = process_callback; + result->process_callback_arg = process_callback_arg; + result->interrupted = 0; + result->running = 0; + } + + return result; +} + +void lingot_audio_destroy(LingotAudioHandler* audio) { + if (audio != NULL) { + + free(audio->flt_read_buffer); + + switch (audio->audio_system) { + case AUDIO_SYSTEM_OSS: + lingot_audio_oss_destroy(audio); + break; + case AUDIO_SYSTEM_ALSA: + lingot_audio_alsa_destroy(audio); + break; + case AUDIO_SYSTEM_JACK: + lingot_audio_jack_destroy(audio); + break; + default: + perror("unknown audio system\n"); + break; + } + + free(audio); + } +} + +int lingot_audio_read(LingotAudioHandler* audio) { + int result = -1; + + if (audio != NULL) + switch (audio->audio_system) { + case AUDIO_SYSTEM_OSS: + result = lingot_audio_oss_read(audio); + break; + case AUDIO_SYSTEM_ALSA: + result = lingot_audio_alsa_read(audio); + break; + // case AUDIO_SYSTEM_JACK: + // result = lingot_audio_jack_read(audio); + // break; + default: + perror("unknown audio system\n"); + result = -1; + break; + } + + return result; +} + +LingotAudioSystemProperties* lingot_audio_get_audio_system_properties( + audio_system_t audio_system) { + LingotAudioSystemProperties* result; + + switch (audio_system) { + case AUDIO_SYSTEM_OSS: + result = lingot_audio_oss_get_audio_system_properties(audio_system); + break; + case AUDIO_SYSTEM_ALSA: + result = lingot_audio_alsa_get_audio_system_properties(audio_system); + break; + case AUDIO_SYSTEM_JACK: + result = lingot_audio_jack_get_audio_system_properties(audio_system); + break; + default: + perror("unknown audio system\n"); + result = NULL; + break; + } + + return result; +} + +void lingot_audio_audio_system_properties_destroy( + LingotAudioSystemProperties* properties) { + + int i; + for (i = 0; i < properties->n_devices; i++) { + free(properties->devices[i]); + } + + if (properties->sample_rates != NULL) + free(properties->sample_rates); + if (properties->devices != NULL) + free(properties->devices); +} + +void lingot_audio_run_reading_thread(LingotAudioHandler* audio) { + + int read_status = 0; + + while (audio->running) { + // process new data block. + read_status = lingot_audio_read(audio); + + if (read_status == 0) { + audio->process_callback(audio->flt_read_buffer, + audio->read_buffer_size, audio->process_callback_arg); + } else { + audio->running = 0; + audio->interrupted = 1; + } + } +} + +int lingot_audio_start(LingotAudioHandler* audio) { + + int result = 0; + + if (audio->audio_system != AUDIO_SYSTEM_JACK) { + pthread_attr_init(&audio->thread_input_read_attr); + + // detached thread. + // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&audio->thread_input_read, + &audio->thread_input_read_attr, + (void* (*)(void*)) lingot_audio_run_reading_thread, audio); + } else { + result = lingot_audio_jack_start(audio); + } + + if (result == 0) { + audio->running = 1; + } + + return result; +} + +void lingot_audio_stop(LingotAudioHandler* audio) { + void* thread_result; + + if (audio->running == 1) { + audio->running = 0; + // thread cancellation + if (audio->audio_system != AUDIO_SYSTEM_JACK) { + pthread_cancel(audio->thread_input_read); + pthread_join(audio->thread_input_read, &thread_result); + pthread_attr_destroy(&audio->thread_input_read_attr); + } else { + lingot_audio_jack_stop(audio); + } + } +} + |
