#include #include #include #include "audio.h" #include "audio_internal.h" AudioPipelineStatus audio_pipeline_start(AudioPipeline *pipeline) { AudioPipelineStatus result = pipeline->source->start(pipeline->source); pipeline->status = result; if (pipeline->statusCallback != NULL) { pipeline->statusCallback(pipeline, result); } return result; } AudioPipelineStatus audio_pipeline_reset(AudioPipeline *pipeline) { AudioPipelineStatus result = pipeline->source->reset(pipeline->source); pipeline->status = result; if (pipeline->statusCallback != NULL) { pipeline->statusCallback(pipeline, result); } return result; } AudioPipelineStatus audio_pipeline_stop(AudioPipeline *pipeline) { AudioPipelineStatus result = pipeline->source->stop(pipeline->source); pipeline->status = result; if (pipeline->statusCallback != NULL) { pipeline->statusCallback(pipeline, result); } return result; } AudioPipeline *audio_pipeline_assemble(AudioPipelineElement *source, ...) { va_list list, list_backup; AudioPipelineElement *item, *last; AudioPipeline *pipeline = malloc(sizeof(AudioPipeline)); pipeline->start = audio_pipeline_start; pipeline->reset = audio_pipeline_reset; pipeline->stop = audio_pipeline_stop; pipeline->source = source; pipeline->status = PipelineStopped; pipeline->statusCallback = NULL; va_start(list, source); va_copy(list_backup, list); if (source == NULL) { fprintf(stderr, "ERROR: Source did not initialize, giving up!\n"); goto fail; } source->pipeline = pipeline; last = source; item = va_arg(list, AudioPipelineElement *); while (item != NULL) { if (item->type == AudioElementSource) { fprintf(stderr, "ERROR: You cannot have a source in the middle of the pipeline, offending element: %s\n", item->describe(item)); goto fail; } AudioPipelineStatus result = item->link(item, last); if (result != PipelineStopped) { fprintf(stderr, "ERROR: Could not link audio pipeline elements %s and %s\n", last->describe(last), item->describe(item)); goto fail; } item->pipeline = pipeline; last = item; if (item->type == AudioElementSink) { break; } item = va_arg(list, AudioPipelineElement *); } if (last->type != AudioElementSink) { fprintf(stderr, "ERROR: Pipeline has no sink!\n"); goto fail; } pipeline->sink = last; va_end(list); va_end(list_backup); return pipeline; fail: va_end(list); item = va_arg(list_backup, AudioPipelineElement *); while (item != NULL) { item->destroy(item); item = va_arg(list_backup, AudioPipelineElement *); } if (pipeline->source != NULL) { pipeline->source->destroy(pipeline->source); } free(pipeline); va_end(list_backup); return NULL; } void audio_pipeline_destroy(AudioPipeline *pipeline) { pipeline->stop(pipeline); AudioPipelineElement *item = pipeline->source->next; while (item != NULL) { AudioPipelineElement *next = item->next; item->destroy(item); item = next; } pipeline->source->destroy(pipeline->source); free(pipeline); } AudioBuffer *alloc_audio_buffer(uint32_t size) { AudioBuffer *buffer = malloc(sizeof(AudioBuffer)); if (buffer == NULL) { return NULL; } buffer->buf_size = size; if (size > 0) { buffer->data = calloc(1, size); if (buffer->data == NULL) { free(buffer); return NULL; } } else { buffer->data = NULL; } return buffer; } void free_audio_buffer(AudioBuffer *buffer) { if (buffer == NULL) { return; } if (buffer->data != NULL) { free(buffer->data); } free(buffer); }