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;
}
Exemple #2
0
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;
}