int ca_sound_file_open(ca_sound_file **_f, const char *fn) { FILE *file; ca_sound_file *f; int ret; ca_return_val_if_fail(_f, CA_ERROR_INVALID); ca_return_val_if_fail(fn, CA_ERROR_INVALID); if (!(f = ca_new0(ca_sound_file, 1))) return CA_ERROR_OOM; if (!(f->filename = ca_strdup(fn))) { ret = CA_ERROR_OOM; goto fail; } if (!(file = fopen(fn, "r"))) { ret = errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; goto fail; } if ((ret = ca_wav_open(&f->wav, file)) == CA_SUCCESS) { f->nchannels = ca_wav_get_nchannels(f->wav); f->rate = ca_wav_get_rate(f->wav); f->type = ca_wav_get_sample_type(f->wav); *_f = f; return CA_SUCCESS; } if (ret == CA_ERROR_CORRUPT) { if (fseek(file, 0, SEEK_SET) < 0) { ret = CA_ERROR_SYSTEM; goto fail; } if ((ret = ca_vorbis_open(&f->vorbis, file)) == CA_SUCCESS) { f->nchannels = ca_vorbis_get_nchannels(f->vorbis); f->rate = ca_vorbis_get_rate(f->vorbis); f->type = CA_SAMPLE_S16NE; *_f = f; return CA_SUCCESS; } } fail: ca_free(f->filename); ca_free(f); return ret; }
int ca_vorbis_open(ca_vorbis **_v, FILE *f) { int ret, or; ca_vorbis *v; int64_t n; ca_return_val_if_fail(_v, CA_ERROR_INVALID); ca_return_val_if_fail(f, CA_ERROR_INVALID); if (!(v = ca_new0(ca_vorbis, 1))) return CA_ERROR_OOM; if ((or = ov_open(f, &v->ovf, NULL, 0)) < 0) { ret = convert_error(or); goto fail; } if ((n = ov_pcm_total(&v->ovf, -1)) < 0) { ret = convert_error(or); ov_clear(&v->ovf); goto fail; } if (((off_t) n * (off_t) sizeof(int16_t)) > FILE_SIZE_MAX) { ret = CA_ERROR_TOOBIG; ov_clear(&v->ovf); goto fail; } v->size = (off_t) n * (off_t) sizeof(int16_t) * ca_vorbis_get_nchannels(v); *_v = v; return CA_SUCCESS; fail: ca_free(v); return ret; }
int ca_context_create(ca_context **_c) { ca_context *c; int ret; const char *d; ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); ca_return_val_if_fail(_c, CA_ERROR_INVALID); if (!(c = ca_new0(ca_context, 1))) return CA_ERROR_OOM; if (!(c->mutex = ca_mutex_new())) { ca_context_destroy(c); return CA_ERROR_OOM; } if ((ret = ca_proplist_create(&c->props)) < 0) { ca_context_destroy(c); return ret; } if ((d = getenv("CANBERRA_DRIVER"))) { if ((ret = ca_context_set_driver(c, d)) < 0) { ca_context_destroy(c); return ret; } } if ((d = getenv("CANBERRA_DEVICE"))) { if ((ret = ca_context_change_device(c, d)) < 0) { ca_context_destroy(c); return ret; } } *_c = c; return CA_SUCCESS; }