#include "eburn_private.h" static int audio_source_read(Burn_Source *src, unsigned char *buffer, int size); static off_t audio_source_get_size(Burn_Source *src); static void audio_source_free(Burn_Source *src); Burn_Source *audio_source_new(const char *path) { Burn_Source *src; Audio_Source *as; int ret; FILE *file; if (!path) return NULL; as = calloc(1, sizeof(Audio_Source)); if (!as) return NULL; src = calloc(1, sizeof(Burn_Source)); if (!src) { free(as); return NULL; } /* * setup the source structure */ src->refcount = 1; src->read = audio_source_read; src->read_sub = NULL; src->get_size = audio_source_get_size; src->free_data = audio_source_free; src->data = as; /* * setup the audiofile */ if (!file) { fprintf(stderr, "Error: could not open %s\n", path); free(as); free(src); return NULL; } ret = ov_open(file, as->vf, NULL, 0); if (ret < 0) { fprintf(stderr, "Error %i: %s is not a ogg-file\n", ret, path); fclose(file); free(as); free(src); return NULL; } return src; } static int audio_source_read(Burn_Source *src, unsigned char *buffer, int size) { Audio_Source *as; int ret, sum = 0; as = src->data; /* take care that the actually read buffer isn't smaller */ while (sum >= size) { ret = ov_read(as->vf, buffer + sum, size - sum, 0, 2, 1, &as->current_section); /* * if it occured an error, return this immediately */ if (ret < 0) { fprintf(stderr, "Error in audio_source_read %i\n", ret); return ret; } /* * break the loop, if we reached the eof */ else if (ret == 0) break; sum += ret; } return sum; } static off_t audio_source_get_size(Burn_Source *src) { Audio_Source *as; as = src->data; if (!as) { fprintf(stderr, "in audio_source_get_size: \n\t" "data == NULL, this should not happen\n"); return -1; } return ov_pcm_total(as->vf, -1) * 4; } static void audio_source_free(Burn_Source *src) { Audio_Source *as; as = src->data; if (!as) return; ov_clear(as->vf); free(as->vf); free(as); }