#include #include #include #include "audio.h" #include "audio_internal.h" typedef struct _SourceFileContext { AudioBuffer *buffer; FILE *fp; } SourceFileContext; AudioPipelineStatus source_file_start(AudioPipelineElement *self) { SourceFileContext *context = (SourceFileContext *)self->ctx; while(!feof(context->fp)) { // fprintf(stderr, "INFO: File offset %d, reading %d\n", ftell(context->fp), context->buffer->buf_size); size_t bytes = fread(context->buffer->data, 1, context->buffer->buf_size, context->fp); if (bytes > 0) { uint32_t buf_size = context->buffer->buf_size; context->buffer->buf_size = (uint32_t)bytes; AudioPipelineStatus result = self->next->push(self->next, context->buffer); if ((result != PipelineRunning) && (result != PipelineBuffering)) { self->pipeline->status = result; if (self->pipeline->statusCallback != NULL) { self->pipeline->statusCallback(self->pipeline, result); } return result; } context->buffer->buf_size = buf_size; } } return PipelineFinished; } AudioPipelineStatus source_file_reset(AudioPipelineElement *self) { SourceFileContext *context = (SourceFileContext *)self->ctx; fseek(context->fp, 0, SEEK_SET); return PipelineStopped; } char *source_file_describe(AudioPipelineElement *self) { return "file source"; } void source_file_destroy(AudioPipelineElement *self) { SourceFileContext *context = (SourceFileContext *)self->ctx; free_audio_buffer(context->buffer); fclose(context->fp); free(self->ctx); free(self); } AudioPipelineElement *audio_source_file(char *filename, uint32_t block_size) { AudioPipelineElement *self = calloc(1, sizeof(AudioPipelineElement)); if (self == NULL) { return NULL; } SourceFileContext *context = calloc(1, sizeof(SourceFileContext)); if (context == NULL) { free(self); return NULL; } context->buffer = alloc_audio_buffer(block_size); if (context->buffer == NULL) { fprintf(stderr, "ERROR: Not enough memory for buffer of size %d!\n", block_size); free(context); free(self); return NULL; } context->fp = fopen(filename, "rb"); if (context->fp == NULL) { fprintf(stderr, "ERROR: Could not open file %s\n", filename); free_audio_buffer(context->buffer); free(context); free(self); return NULL; } self->bits_per_sample = 0; self->channels = 0; self->sample_rate = 0; self->ctx = context; self->describe = source_file_describe; self->start = source_file_start; self->reset = source_file_reset; self->stop = source_stop_nop; self->push = NULL; self->link = NULL; self->destroy = source_file_destroy; self->type = AudioElementSource; return self; }