/* * audiofile.c * * Scott Wilson * rswilson@ccrma.stanford.edu * last updated: June 15, 2003 * * */ #include "audiofile.h" #include "codec.h" #include "vector.h" int audiofile_fill_fileinfo(SF_INFO *sf_info, codec_fileinfo_t *info); codec_err_t audiofile_open(const char *filename, audiofile_mode_t mode, codec_file_p fp) { SNDFILE* sf; SF_INFO sf_info; if (mode == SFM_WRITE) { // fill sfinfo data structure sf_info.samplerate = fp->info.srate; printf("srate = %d\n", sf_info.samplerate); sf_info.channels = fp->info.channels; // conveniently kept from openign the original file with libsndfile sf_info.format = fp->info.sfformat; /* if (! sf_format_check (&sf_info)) { codec_error("audiofile_open",filename,"bad soundfile format"); return 1; }*/ } if (! (sf = sf_open(filename, mode, &sf_info))) { printf("mode is %d\n",mode); printf("SFM_WRITE is %d\n",SFM_WRITE); codec_error("audiofile_open",filename, sf_strerror(sf)); return 1; } fp->info.filename = filename; if (audiofile_fill_fileinfo(&sf_info, &fp->info)) { /* was a bad file format */ codec_error("audiofile_open", filename, "closing due to bad format"); sf_close(sf); return 1; } fp->ptr.sf_p = sf; return ERR_NONE; } codec_err_t audiofile_close(codec_file_p fp) { int err; if (err = sf_close(fp->ptr.sf_p)) { codec_error("audiofile_close", fp->info.filename, sf_strerror(fp->ptr.sf_p)); return err; } return ERR_NONE; } // vector should be a channels*blocksize nchannel vector (array of ptrs to vectors of codec_float_t) codec_long_t audiofile_read(codec_file_p fp, codec_long_t blocksize, codec_vector_p *vector) { int n,m; sf_count_t count; codec_err_t err; codec_vector_p tmpvector; int chans = fp->info.channels; err = vector_alloc(blocksize*chans, &tmpvector); count = sf_readf_double(fp->ptr.sf_p, tmpvector, blocksize); for (n=0; ninfo.channels; err = vector_alloc(blocksize*chans, &tmpvector); // interleave the samples for (n=0; nptr.sf_p, tmpvector, blocksize); if (count != blocksize) { codec_error("audiofile","write",sf_strerror(fp->ptr.sf_p)); vector_dealloc(tmpvector); return 0; } fp->info.frames += blocksize; vector_dealloc(tmpvector); return blocksize; } codec_err_t audiofile_rewind(codec_file_p fp) { return sf_seek(fp->ptr.sf_p, 0, SEEK_SET); } codec_err_t audiofile_fill_fileinfo(SF_INFO *sf_info, codec_fileinfo_t *info) { info->srate = sf_info->samplerate; info->channels = sf_info->channels; info->sfformat = sf_info->format; info->frames = sf_info->frames; switch (sf_info->format & 0x000f) { case SF_FORMAT_PCM_S8: info->bits_per_sample = 8; info->f_signed = 1; info->f_float = 0; break; case SF_FORMAT_PCM_U8: info->bits_per_sample = 8; info->f_signed = 0; info->f_float = 0; break; case SF_FORMAT_PCM_16: info->bits_per_sample = 16; info->f_signed = 1; info->f_float = 0; break; case SF_FORMAT_PCM_24: info->bits_per_sample = 24; info->f_signed = 1; info->f_float = 0; break; case SF_FORMAT_PCM_32: info->bits_per_sample = 32; info->f_signed = 1; info->f_float = 0; break; case SF_FORMAT_FLOAT: info->bits_per_sample = 32; info->f_signed = 1; info->f_float = 1; break; case SF_FORMAT_DOUBLE: info->bits_per_sample = 64; info->f_signed = 1; info->f_float = 1; break; default: fprintf(stderr, "Error, unknown sound file format\n"); return -1; } return 0; }