audiolib/audio/audio_source_file.c

103 lines
3 KiB
C

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