audiolib/audio/audio.c

150 lines
3.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#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);
}