audiolib/audio/audio_sink_file.c

72 lines
1.9 KiB
C

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "audio.h"
#include "audio_internal.h"
typedef struct _SinkFileContext {
FILE *fp;
} SinkFileContext;
AudioPipelineStatus sink_file_push(AudioPipelineElement *self, AudioBuffer *buffer) {
SinkFileContext *context = (SinkFileContext *)self->ctx;
size_t bytes = fwrite(buffer->data, 1, buffer->buf_size, context->fp);
return (bytes != buffer->buf_size) ? PipelineError : PipelineRunning;
}
AudioPipelineStatus sink_file_link(AudioPipelineElement *self, AudioPipelineElement *source) {
SinkFileContext *context = (SinkFileContext *)self->ctx;
if (context->fp != NULL) {
fseek(context->fp, 0, SEEK_SET);
if (ftruncate(fileno(context->fp), 0) != 0) {
fprintf(stderr, "WARN: ftruncate failed with %d\n", errno);
}
}
source->next = self;
return PipelineStopped;
}
char *sink_file_describe(AudioPipelineElement *self) {
return "file sink";
}
void sink_file_destroy(AudioPipelineElement *self) {
SinkFileContext *context = (SinkFileContext *)self->ctx;
fclose(context->fp);
free(self->ctx);
free(self);
}
AudioPipelineElement *audio_sink_file(char *filename) {
AudioPipelineElement *self = calloc(1, sizeof(AudioPipelineElement));
SinkFileContext *context = calloc(1, sizeof(SinkFileContext));
context->fp = fopen(filename, "wb");
if (context->fp == NULL) {
fprintf(stderr, "ERROR: Cannot open file %s, errno=%d", filename, errno);
free(context);
free(self);
return NULL;
}
self->ctx = context;
self->describe = sink_file_describe;
self->start = sink_nop;
self->reset = sink_nop;
self->stop = sink_nop;
self->push = sink_file_push;
self->link = sink_file_link;
self->destroy = sink_file_destroy;
self->type = AudioElementSink;
return self;
}