static int mat4_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int encoding ; double samplerate ; current = psf_ftell (psf->filedes) ; if (calc_length) { psf_fseek (psf->filedes, 0, SEEK_END) ; psf->filelength = psf_ftell (psf->filedes) ; psf_fseek (psf->filedes, 0, SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; encoding = mat4_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK, psf->endian) ; if (encoding == -1) return SFE_BAD_OPEN_FORMAT ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf->filedes, 0, SEEK_SET) ; /* Need sample rate as a double for writing to the header. */ samplerate = psf->sf.samplerate ; if (psf->endian == SF_ENDIAN_BIG) { psf_binheader_writef (psf, "Em444", MAT4_BE_DOUBLE, 1, 1, 0) ; psf_binheader_writef (psf, "E4bd", 11, "samplerate", 11, samplerate) ; psf_binheader_writef (psf, "tEm484", encoding, psf->sf.channels, psf->sf.frames, 0) ; psf_binheader_writef (psf, "E4b", 9, "wavedata", 9) ; } else if (psf->endian == SF_ENDIAN_LITTLE) { psf_binheader_writef (psf, "em444", MAT4_LE_DOUBLE, 1, 1, 0) ; psf_binheader_writef (psf, "e4bd", 11, "samplerate", 11, samplerate) ; psf_binheader_writef (psf, "tem484", encoding, psf->sf.channels, psf->sf.frames, 0) ; psf_binheader_writef (psf, "e4b", 9, "wavedata", 9) ; } else return SFE_BAD_OPEN_FORMAT ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf->filedes) ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf->filedes, current, SEEK_SET) ; return 0 ; } /* mat4_write_header */
static int voc_close (SF_PRIVATE *psf) { if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { /* Now we know for certain the length of the file we can re-write ** correct values for the FORM, 8SVX and BODY chunks. */ unsigned byte = VOC_TERMINATOR ; psf_fseek (psf, 0, SEEK_END) ; /* Write terminator */ psf_fwrite (&byte, 1, 1, psf) ; psf->filelength = psf_ftell (psf) ; psf_fseek (psf, 0, SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; voc_write_header (psf, SF_FALSE) ; } ; return 0 ; } /* voc_close */
static int pvf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) { sf_count_t current ; if (psf->pipeoffset > 0) return 0 ; current = psf_ftell (psf) ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; if (psf->is_pipe == SF_FALSE) psf_fseek (psf, 0, SEEK_SET) ; snprintf ((char*) psf->header, sizeof (psf->header), "PVF1\n%d %d %d\n", psf->sf.channels, psf->sf.samplerate, psf->bytewidth * 8) ; psf->headindex = strlen ((char*) psf->header) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* pvf_write_header */
static int mat4_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int encoding ; double samplerate ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; encoding = mat4_format_to_encoding (SF_CODEC (psf->sf.format), psf->endian) ; if (encoding == -1) return SFE_BAD_OPEN_FORMAT ; /* Reset the current header length to zero. */ psf->header.ptr [0] = 0 ; psf->header.indx = 0 ; psf_fseek (psf, 0, SEEK_SET) ; /* Need sample rate as a double for writing to the header. */ samplerate = psf->sf.samplerate ; if (psf->endian == SF_ENDIAN_BIG) { psf_binheader_writef (psf, "Em444", BHWm (MAT4_BE_DOUBLE), BHW4 (1), BHW4 (1), BHW4 (0)) ; psf_binheader_writef (psf, "E4bd", BHW4 (11), BHWv ("samplerate"), BHWz (11), BHWd (samplerate)) ; psf_binheader_writef (psf, "tEm484", BHWm (encoding), BHW4 (psf->sf.channels), BHW8 (psf->sf.frames), BHW4 (0)) ; psf_binheader_writef (psf, "E4b", BHW4 (9), BHWv ("wavedata"), BHWz (9)) ; } else if (psf->endian == SF_ENDIAN_LITTLE) { psf_binheader_writef (psf, "em444", BHWm (MAT4_LE_DOUBLE), BHW4 (1), BHW4 (1), BHW4 (0)) ; psf_binheader_writef (psf, "e4bd", BHW4 (11), BHWv ("samplerate"), BHWz (11), BHWd (samplerate)) ; psf_binheader_writef (psf, "tem484", BHWm (encoding), BHW4 (psf->sf.channels), BHW8 (psf->sf.frames), BHW4 (0)) ; psf_binheader_writef (psf, "e4b", BHW4 (9), BHWv ("wavedata"), BHWz (9)) ; } else return SFE_BAD_OPEN_FORMAT ; /* Header construction complete so write it out. */ psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->header.indx ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* mat4_write_header */
static int avr_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int sign, datalength ; if (psf->pipeoffset > 0) return 0 ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; /* ** Only attempt to seek if we are not writng to a pipe. If we are ** writing to a pipe we shouldn't be here anyway. */ if (psf->is_pipe == SF_FALSE) psf_fseek (psf, 0, SEEK_SET) ; datalength = (int) (psf->datalength & 0x7FFFFFFF) ; psf_binheader_writef (psf, "Emz22", TWOBIT_MARKER, (size_t) 8, psf->sf.channels == 2 ? 0xFFFF : 0, psf->bytewidth * 8) ; sign = ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8) ? 0 : 0xFFFF ; psf_binheader_writef (psf, "E222", sign, 0, 0xFFFF) ; psf_binheader_writef (psf, "E4444", psf->sf.samplerate, psf->sf.frames, 0, 0) ; psf_binheader_writef (psf, "E222zz", 0, 0, 0, (size_t) 20, (size_t) 64) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* avr_write_header */
static int pvf_read_header (SF_PRIVATE *psf) { char buffer [32] ; int marker, channels, samplerate, bitwidth ; psf_binheader_readf (psf, "pmj", 0, &marker, 1) ; psf_log_printf (psf, "%M\n", marker) ; if (marker != PVF1_MARKER) return SFE_PVF_NO_PVF1 ; /* Grab characters up until a newline which is replaced by an EOS. */ psf_binheader_readf (psf, "G", buffer, sizeof (buffer)) ; if (sscanf (buffer, "%d %d %d", &channels, &samplerate, &bitwidth) != 3) return SFE_PVF_BAD_HEADER ; psf_log_printf (psf, " Channels : %d\n Sample rate : %d\n Bit width : %d\n", channels, samplerate, bitwidth) ; psf->sf.channels = channels ; psf->sf.samplerate = samplerate ; switch (bitwidth) { case 8 : psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_S8 ; psf->bytewidth = 1 ; break ; case 16 : psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_16 ; psf->bytewidth = 2 ; break ; case 32 : psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_32 ; psf->bytewidth = 4 ; break ; default : return SFE_PVF_BAD_BITWIDTH ; } ; psf->dataoffset = psf_ftell (psf) ; psf_log_printf (psf, " Data Offset : %D\n", psf->dataoffset) ; psf->endian = SF_ENDIAN_BIG ; psf->datalength = psf->filelength - psf->dataoffset ; psf->blockwidth = psf->sf.channels * psf->bytewidth ; if (! psf->sf.frames && psf->blockwidth) psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; return 0 ; } /* pvf_read_header */
static int ircam_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) { int encoding ; float samplerate ; sf_count_t current ; if (psf->pipeoffset > 0) return 0 ; current = psf_ftell (psf) ; /* This also sets psf->endian. */ encoding = get_encoding (SF_CODEC (psf->sf.format)) ; if (encoding == 0) return SFE_BAD_OPEN_FORMAT ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; if (psf->is_pipe == SF_FALSE) psf_fseek (psf, 0, SEEK_SET) ; samplerate = psf->sf.samplerate ; switch (psf->endian) { case SF_ENDIAN_BIG : psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ; psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ; break ; case SF_ENDIAN_LITTLE : psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ; psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ; break ; default : return SFE_BAD_OPEN_FORMAT ; } ; psf_binheader_writef (psf, "z", (size_t) (IRCAM_DATA_OFFSET - psf->headindex)) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* ircam_write_header */
static void test_tell_or_die (SF_PRIVATE *psf, sf_count_t expected_position, int linenum) { sf_count_t retval ; retval = psf_ftell (psf) ; if (retval != expected_position) { printf ("\n\nLine %d: psf_ftell() failed. Position reported as %" PRId64 " (should be %" PRId64 ").\n\n", linenum, retval, expected_position) ; exit (1) ; } ; }
static int w64_close (SF_PRIVATE *psf) { if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { /* Now we know for certain the length of the file we can * re-write correct values for the riff and data chunks. */ psf_fseek (psf->filedes, 0, SEEK_END) ; psf->dataend = psf_ftell (psf->filedes) ; psf_fseek (psf->filedes, 0, SEEK_END) ; psf->filelength = psf_ftell (psf->filedes) ; psf_fseek (psf->filedes, 0, SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset - (psf->filelength - psf->dataend) ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; w64_write_header (psf, SF_FALSE) ; } ; return 0 ; } /* w64_close */
int ogg_open (SF_PRIVATE *psf) { OGG_PRIVATE* odata = calloc (1, sizeof (OGG_PRIVATE)) ; sf_count_t pos = psf_ftell (psf) ; int error = 0 ; psf->container_data = odata ; psf->container_close = ogg_close ; if (psf->file.mode == SFM_RDWR) return SFE_BAD_MODE_RW ; if (psf->file.mode == SFM_READ) if ((error = ogg_stream_classify (psf, odata)) != 0) return error ; /* Reset everything to an initial state. */ ogg_sync_clear (&odata->osync) ; ogg_stream_clear (&odata->ostream) ; psf_fseek (psf, pos, SEEK_SET) ; switch (psf->sf.format) { case SF_FORMAT_OGG | SF_FORMAT_VORBIS : return ogg_vorbis_open (psf) ; case SF_FORMAT_OGGFLAC : free (psf->container_data) ; psf->container_data = NULL ; psf->container_close = NULL ; return flac_open (psf) ; #if ENABLE_EXPERIMENTAL_CODE case SF_FORMAT_OGG | SF_FORMAT_SPEEX : return ogg_speex_open (psf) ; case SF_FORMAT_OGG | SF_FORMAT_PCM_16 : case SF_FORMAT_OGG | SF_FORMAT_PCM_24 : return ogg_pcm_open (psf) ; #endif default : break ; } ; psf_log_printf (psf, "%s : mode should be SFM_READ or SFM_WRITE.\n", __func__) ; return SFE_INTERNAL ; } /* ogg_open */
static int ircam_write_header (SF_PRIVATE *psf, int calc_length) { int encoding ; float samplerate ; sf_count_t current ; current = psf_ftell (psf) ; calc_length = calc_length ; /* This also sets psf->endian. */ encoding = get_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ; if (! encoding) return SFE_BAD_OPEN_FORMAT ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; samplerate = psf->sf.samplerate ; if (psf->endian == SF_ENDIAN_BIG) { psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ; psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ; } else if (psf->endian == SF_ENDIAN_LITTLE) { psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ; psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ; } else return SFE_BAD_OPEN_FORMAT ; psf_binheader_writef (psf, "z", IRCAM_DATA_OFFSET - psf->headindex) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* ircam_write_header */
static void test_read_or_die (SF_PRIVATE *psf, void *data, sf_count_t bytes, sf_count_t items, sf_count_t new_position, int linenum) { sf_count_t retval ; retval = psf_fread (data, bytes, items, psf) ; if (retval != items) { printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ; exit (1) ; } ; if ((retval = psf_ftell (psf)) != new_position) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ; exit (1) ; } ; return ; } /* test_write_or_die */
static int wve_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; unsigned datalen ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; /* Write header. */ datalen = psf->datalength ; psf_binheader_writef (psf, "Emmmm", ALAW_MARKER, SOUN_MARKER, DFIL_MARKER, ESSN_MARKER) ; psf_binheader_writef (psf, "E2422222", PSION_VERSION, datalen, 0, 0, 0, 0, 0) ; psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->sf.channels != 1) return SFE_CHANNEL_COUNT ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* wve_write_header */
static int caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) { int indx ; sf_count_t pos ; if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0) return SFE_UNKNOWN_CHUNK ; if (chunk_info->data == NULL) return SFE_BAD_CHUNK_DATA_PTR ; chunk_info->id_size = psf->rchunks.chunks [indx].id_size ; memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ; pos = psf_ftell (psf) ; psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ; psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ; psf_fseek (psf, pos, SEEK_SET) ; return SFE_NO_ERROR ; } /* caf_get_chunk_data */
static int nist_close (SF_PRIVATE *psf) { if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { /* Now we know for certain the length of the file we can ** re-write correct values for the datasize header element. */ psf_fseek (psf->filedes, 0, SEEK_END) ; psf->filelength = psf_ftell (psf->filedes) ; psf->dataoffset = NIST_HEADER_LENGTH ; psf->datalength = psf->filelength - psf->dataoffset ; psf->sf.frames = psf->datalength / psf->blockwidth ; nist_write_header (psf, SF_FALSE) ; } ; return 0 ; } /* nist_close */
static int htk_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int sample_count, sample_period ; current = psf_ftell (psf) ; if (calc_length) psf->filelength = psf_get_filelen (psf) ; /* Reset the current header length to zero. */ psf->header.ptr [0] = 0 ; psf->header.indx = 0 ; psf_fseek (psf, 0, SEEK_SET) ; if (psf->filelength > 12) sample_count = (psf->filelength - 12) / 2 ; else sample_count = 0 ; sample_period = 10000000 / psf->sf.samplerate ; psf_binheader_writef (psf, "E444", sample_count, sample_period, 0x20000) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->header.indx ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* htk_write_header */
static int mat4_close (SF_PRIVATE *psf) { if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { /* Now we know for certain the length of the file we can * re-write correct values for the datasize header element. */ psf_fseek (psf->filedes, 0, SEEK_END) ; psf->filelength = psf_ftell (psf->filedes) ; psf->datalength = psf->filelength - psf->dataoffset ; psf_fseek (psf->filedes, 0, SEEK_SET) ; psf->sf.frames = psf->datalength / psf->blockwidth ; mat4_write_header (psf, SF_FALSE) ; } ; if (psf->fdata) free (psf->fdata) ; psf->fdata = NULL ; return 0 ; } /* mat4_close */
static int caf_write_header (SF_PRIVATE *psf, int calc_length) { BUF_UNION ubuf ; CAF_PRIVATE *pcaf ; DESC_CHUNK desc ; sf_count_t current, free_len ; uint32_t uk ; int subformat, append_free_block = SF_TRUE ; if ((pcaf = psf->container_data) == NULL) return SFE_INTERNAL ; memset (&desc, 0, sizeof (desc)) ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; if (psf->bytewidth > 0) psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; /* 'caff' marker, version and flags. */ psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ; /* 'desc' marker and chunk size. */ psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ; double64_be_write (1.0 * psf->sf.samplerate, ubuf.ucbuf) ; psf_binheader_writef (psf, "b", ubuf.ucbuf, make_size_t (8)) ; subformat = SF_CODEC (psf->sf.format) ; psf->endian = SF_ENDIAN (psf->sf.format) ; if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)) psf->endian = SF_ENDIAN_BIG ; else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU)) psf->endian = SF_ENDIAN_LITTLE ; if (psf->endian == SF_ENDIAN_LITTLE) desc.fmt_flags = 2 ; else psf->endian = SF_ENDIAN_BIG ; /* initial section (same for all, it appears) */ switch (subformat) { case SF_FORMAT_PCM_S8 : desc.fmt_id = lpcm_MARKER ; psf->bytewidth = 1 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 8 ; break ; case SF_FORMAT_PCM_16 : desc.fmt_id = lpcm_MARKER ; psf->bytewidth = 2 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 16 ; break ; case SF_FORMAT_PCM_24 : psf->bytewidth = 3 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 24 ; desc.fmt_id = lpcm_MARKER ; break ; case SF_FORMAT_PCM_32 : desc.fmt_id = lpcm_MARKER ; psf->bytewidth = 4 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 32 ; break ; case SF_FORMAT_FLOAT : desc.fmt_id = lpcm_MARKER ; desc.fmt_flags |= 1 ; psf->bytewidth = 4 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 32 ; break ; case SF_FORMAT_DOUBLE : desc.fmt_id = lpcm_MARKER ; desc.fmt_flags |= 1 ; psf->bytewidth = 8 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 64 ; break ; case SF_FORMAT_ALAW : desc.fmt_id = alaw_MARKER ; psf->bytewidth = 1 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 8 ; break ; case SF_FORMAT_ULAW : desc.fmt_id = ulaw_MARKER ; psf->bytewidth = 1 ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.frames_per_packet = 1 ; desc.channels_per_frame = psf->sf.channels ; desc.bits_per_chan = 8 ; break ; case SF_FORMAT_ALAC_16 : case SF_FORMAT_ALAC_20 : case SF_FORMAT_ALAC_24 : case SF_FORMAT_ALAC_32 : desc.fmt_id = alac_MARKER ; desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; desc.channels_per_frame = psf->sf.channels ; alac_get_desc_chunk_items (subformat, &desc.fmt_flags, &desc.frames_per_packet) ; append_free_block = SF_FALSE ; break ; default : return SFE_UNIMPLEMENTED ; } ; psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ; caf_write_strings (psf, SF_STR_LOCATE_START) ; if (psf->peak_info != NULL) { int k ; psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ; for (k = 0 ; k < psf->sf.channels ; k++) psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ; } ; if (psf->channel_map && pcaf->chanmap_tag) psf_binheader_writef (psf, "Em8444", chan_MARKER, (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ; /* Write custom headers. */ for (uk = 0 ; uk < psf->wchunks.used ; uk++) psf_binheader_writef (psf, "m44b", (int) psf->wchunks.chunks [uk].mark32, 0, psf->wchunks.chunks [uk].len, psf->wchunks.chunks [uk].data, make_size_t (psf->wchunks.chunks [uk].len)) ; if (append_free_block) { /* Add free chunk so that the actual audio data starts at a multiple 0x1000. */ free_len = 0x1000 - psf->headindex - 16 - 12 ; while (free_len < 0) free_len += 0x1000 ; psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ; } ; psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength + 4, 0) ; psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current < psf->dataoffset) psf_fseek (psf, psf->dataoffset, SEEK_SET) ; else if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* caf_write_header */
static int avr_read_header (SF_PRIVATE *psf) { AVR_HEADER hdr ; memset (&hdr, 0, sizeof (hdr)) ; psf_binheader_readf (psf, "pmb", 0, &hdr.marker, &hdr.name, sizeof (hdr.name)) ; psf_log_printf (psf, "%M\n", hdr.marker) ; if (hdr.marker != TWOBIT_MARKER) return SFE_AVR_X ; psf_log_printf (psf, " Name : %s\n", hdr.name) ; psf_binheader_readf (psf, "E22222", &hdr.mono, &hdr.rez, &hdr.sign, &hdr.loop, &hdr.midi) ; psf->sf.channels = (hdr.mono & 1) + 1 ; psf_log_printf (psf, " Channels : %d\n Bit width : %d\n Signed : %s\n", (hdr.mono & 1) + 1, hdr.rez, hdr.sign ? "yes" : "no") ; switch ((hdr.rez << 16) + (hdr.sign & 1)) { case ((8 << 16) + 0) : psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_U8 ; psf->bytewidth = 1 ; break ; case ((8 << 16) + 1) : psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_S8 ; psf->bytewidth = 1 ; break ; case ((16 << 16) + 1) : psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_16 ; psf->bytewidth = 2 ; break ; default : psf_log_printf (psf, "Error : bad rez/sign combination.\n") ; return SFE_AVR_X ; } ; psf_binheader_readf (psf, "E4444", &hdr.srate, &hdr.frames, &hdr.lbeg, &hdr.lend) ; psf->sf.frames = hdr.frames ; psf->sf.samplerate = hdr.srate ; psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ; psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ; psf_binheader_readf (psf, "E222", &hdr.res1, &hdr.res2, &hdr.res3) ; psf_binheader_readf (psf, "bb", hdr.ext, sizeof (hdr.ext), hdr.user, sizeof (hdr.user)) ; psf_log_printf (psf, " Ext : %s\n User : %s\n", hdr.ext, hdr.user) ; psf->endian = SF_ENDIAN_BIG ; psf->dataoffset = AVR_HDR_SIZE ; psf->datalength = hdr.frames * (hdr.rez / 8) ; if (psf->fileoffset > 0) psf->filelength = AVR_HDR_SIZE + psf->datalength ; if (psf_ftell (psf) != psf->dataoffset) psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ; psf->blockwidth = psf->sf.channels * psf->bytewidth ; if (psf->sf.frames == 0 && psf->blockwidth) psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; return 0 ; } /* avr_read_header */
static int w64_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t fmt_size, current ; size_t fmt_pad = 0 ; int subformat, add_fact_chunk = SF_FALSE ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; if (psf->bytewidth) psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; /* riff marker, length, wave and 'fmt ' markers. */ psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength, wave_MARKER16, fmt_MARKER16) ; subformat = SF_CODEC (psf->sf.format) ; switch (subformat) { case SF_FORMAT_PCM_U8 : case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_PCM, psf->sf.channels, psf->sf.samplerate) ; /* fmt : bytespersec */ psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ; /* fmt : blockalign, bitwidth */ psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ; break ; case SF_FORMAT_FLOAT : case SF_FORMAT_DOUBLE : fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_IEEE_FLOAT, psf->sf.channels, psf->sf.samplerate) ; /* fmt : bytespersec */ psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ; /* fmt : blockalign, bitwidth */ psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ; add_fact_chunk = SF_TRUE ; break ; case SF_FORMAT_ULAW : fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ; /* fmt : bytespersec */ psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ; /* fmt : blockalign, bitwidth */ psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ; add_fact_chunk = SF_TRUE ; break ; case SF_FORMAT_ALAW : fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ; /* fmt : bytespersec */ psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ; /* fmt : blockalign, bitwidth */ psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ; add_fact_chunk = SF_TRUE ; break ; /* Lite remove start */ case SF_FORMAT_IMA_ADPCM : { int blockalign, framesperblock, bytespersec ; blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ; framesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ; bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; /* fmt chunk. */ fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : size, WAV format type, channels. */ psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_IMA_ADPCM, psf->sf.channels) ; /* fmt : samplerate, bytespersec. */ psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ; /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ psf_binheader_writef (psf, "e2222", blockalign, 4, 2, framesperblock) ; } ; add_fact_chunk = SF_TRUE ; break ; case SF_FORMAT_MS_ADPCM : { int blockalign, framesperblock, bytespersec, extrabytes ; blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ; framesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ; bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; /* fmt chunk. */ extrabytes = 2 + 2 + MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ; fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : size, W64 format type, channels. */ psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_MS_ADPCM, psf->sf.channels) ; /* fmt : samplerate, bytespersec. */ psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ; /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ psf_binheader_writef (psf, "e22222", blockalign, 4, extrabytes, framesperblock, 7) ; msadpcm_write_adapt_coeffs (psf) ; } ; add_fact_chunk = SF_TRUE ; break ; /* Lite remove end */ case SF_FORMAT_GSM610 : { int bytespersec ; bytespersec = (psf->sf.samplerate * WAV_W64_GSM610_BLOCKSIZE) / WAV_W64_GSM610_SAMPLES ; /* fmt chunk. */ fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ; fmt_size += fmt_pad ; /* fmt : size, WAV format type, channels. */ psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ; /* fmt : samplerate, bytespersec. */ psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ; /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ psf_binheader_writef (psf, "e2222", WAV_W64_GSM610_BLOCKSIZE, 0, 2, WAV_W64_GSM610_SAMPLES) ; } ; add_fact_chunk = SF_TRUE ; break ; default : return SFE_UNIMPLEMENTED ; } ; /* Pad to 8 bytes with zeros. */ if (fmt_pad > 0) psf_binheader_writef (psf, "z", fmt_pad) ; if (add_fact_chunk) psf_binheader_writef (psf, "eh88", fact_MARKER16, (sf_count_t) (16 + 8 + 8), psf->sf.frames) ; psf_binheader_writef (psf, "eh8", data_MARKER16, psf->datalength + 24) ; psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* w64_write_header */
static int voc_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int rate_const, subformat ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; subformat = SF_CODEC (psf->sf.format) ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; /* VOC marker and 0x1A byte. */ psf_binheader_writef (psf, "eb1", "Creative Voice File", make_size_t (19), 0x1A) ; /* Data offset, version and other. */ psf_binheader_writef (psf, "e222", 26, 0x0114, 0x111F) ; /* Use same logic as SOX. ** If the file is mono 8 bit data, use VOC_SOUND_DATA. ** If the file is mono 16 bit data, use VOC_EXTENED. ** Otherwise use VOC_EXTENED_2. */ if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 1) { /* samplerate = 1000000 / (256 - rate_const) ; */ rate_const = 256 - 1000000 / psf->sf.samplerate ; /* First type marker, length, rate_const and compression */ psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ; } else if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 2) { /* sample_rate = 128000000 / (65536 - rate_short) ; */ rate_const = 65536 - 128000000 / psf->sf.samplerate ; /* First write the VOC_EXTENDED section ** marker, length, rate_const and compression */ psf_binheader_writef (psf, "e13211", VOC_EXTENDED, 4, rate_const, 0, 1) ; /* samplerate = 1000000 / (256 - rate_const) ; */ rate_const = 256 - 1000000 / psf->sf.samplerate ; /* Now write the VOC_SOUND_DATA section ** marker, length, rate_const and compression */ psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ; } else { int length ; if (psf->sf.channels < 1 || psf->sf.channels > 2) return SFE_CHANNEL_COUNT ; switch (subformat) { case SF_FORMAT_PCM_U8 : psf->bytewidth = 1 ; length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ; /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */ psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ; break ; case SF_FORMAT_PCM_16 : psf->bytewidth = 2 ; length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ; /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */ psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ; break ; case SF_FORMAT_ALAW : psf->bytewidth = 1 ; length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ; psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 6, 0) ; break ; case SF_FORMAT_ULAW : psf->bytewidth = 1 ; length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ; psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 7, 0) ; break ; default : return SFE_UNIMPLEMENTED ; } ; } ; psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* voc_write_header */
static int nist_write_header (SF_PRIVATE *psf, int calc_length) { char *end_str ; long samples ; sf_count_t current ; current = psf_ftell (psf->filedes) ; /* Prevent compiler warning. */ calc_length = calc_length ; if (psf->endian == SF_ENDIAN_BIG) end_str = "10" ; else if (psf->endian == SF_ENDIAN_LITTLE) end_str = "01" ; else end_str = "error" ; /* Clear the whole header. */ memset (psf->header, 0, sizeof (psf->header)) ; psf->headindex = 0 ; psf_fseek (psf->filedes, 0, SEEK_SET) ; psf_asciiheader_printf (psf, "NIST_1A\n 1024\n") ; psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ; psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ; switch (psf->sf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8 : psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n" "sample_sig_bits -i 8\n") ; break ; case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ; psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ; psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n" "sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ; break ; case SF_FORMAT_ALAW : psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; break ; case SF_FORMAT_ULAW : psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; break ; default : return SFE_UNIMPLEMENTED ; } ; psf->dataoffset = NIST_HEADER_LENGTH ; /* Fix this */ samples = psf->sf.frames ; psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ; psf_asciiheader_printf (psf, "end_head\n") ; /* Zero fill to dataoffset. */ psf_binheader_writef (psf, "z", NIST_HEADER_LENGTH - psf->headindex) ; psf_fwrite (psf->header, psf->headindex, 1, psf->filedes) ; if (current > 0) psf_fseek (psf->filedes, current, SEEK_SET) ; return 0 ; } /* nist_write_header */
static int w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) { WAV_PRIVATE *wpriv ; WAV_FMT *wav_fmt ; int dword = 0, marker, format = 0 ; sf_count_t chunk_size, bytesread = 0 ; int parsestage = 0, error, done = 0 ; if ((wpriv = psf->container_data) == NULL) return SFE_INTERNAL ; wav_fmt = &wpriv->wav_fmt ; /* Set position to start of file to begin reading header. */ psf_binheader_readf (psf, "p", 0) ; while (! done) { /* Each new chunk must start on an 8 byte boundary, so jump if needed. */ if (psf->headindex & 0x7) psf_binheader_readf (psf, "j", 8 - (psf->headindex & 0x7)) ; /* Generate hash of 16 byte marker. */ marker = chunk_size = 0 ; bytesread = psf_binheader_readf (psf, "eh8", &marker, &chunk_size) ; if (bytesread == 0) break ; switch (marker) { case riff_HASH16 : if (parsestage) return SFE_W64_NO_RIFF ; if (psf->filelength != chunk_size) psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ; else psf_log_printf (psf, "riff : %D\n", chunk_size) ; parsestage |= HAVE_riff ; bytesread += psf_binheader_readf (psf, "h", &marker) ; if (marker == wave_HASH16) { if ((parsestage & HAVE_riff) != HAVE_riff) return SFE_W64_NO_WAVE ; psf_log_printf (psf, "wave\n") ; parsestage |= HAVE_wave ; } ; chunk_size = 0 ; break ; case ACID_HASH16: psf_log_printf (psf, "Looks like an ACID file. Exiting.\n") ; return SFE_UNIMPLEMENTED ; case fmt_HASH16 : if ((parsestage & (HAVE_riff | HAVE_wave)) != (HAVE_riff | HAVE_wave)) return SFE_WAV_NO_FMT ; psf_log_printf (psf, " fmt : %D\n", chunk_size) ; /* size of 16 byte marker and 8 byte chunk_size value. */ chunk_size -= 24 ; if ((error = wav_w64_read_fmt_chunk (psf, (int) chunk_size))) return error ; if (chunk_size % 8) psf_binheader_readf (psf, "j", 8 - (chunk_size % 8)) ; format = wav_fmt->format ; parsestage |= HAVE_fmt ; chunk_size = 0 ; break ; case fact_HASH16: { sf_count_t frames ; psf_binheader_readf (psf, "e8", &frames) ; psf_log_printf (psf, " fact : %D\n frames : %D\n", chunk_size, frames) ; } ; chunk_size = 0 ; break ; case data_HASH16 : if ((parsestage & (HAVE_riff | HAVE_wave | HAVE_fmt)) != (HAVE_riff | HAVE_wave | HAVE_fmt)) return SFE_W64_NO_DATA ; psf->dataoffset = psf_ftell (psf) ; psf->datalength = SF_MIN (chunk_size - 24, psf->filelength - psf->dataoffset) ; if (chunk_size % 8) chunk_size += 8 - (chunk_size % 8) ; psf_log_printf (psf, "data : %D\n", chunk_size) ; parsestage |= HAVE_data ; if (! psf->sf.seekable) break ; /* Seek past data and continue reading header. */ psf_fseek (psf, chunk_size, SEEK_CUR) ; chunk_size = 0 ; break ; case levl_HASH16 : psf_log_printf (psf, "levl : %D\n", chunk_size) ; chunk_size -= 24 ; break ; case list_HASH16 : psf_log_printf (psf, "list : %D\n", chunk_size) ; chunk_size -= 24 ; break ; case junk_HASH16 : psf_log_printf (psf, "junk : %D\n", chunk_size) ; chunk_size -= 24 ; break ; case bext_MARKER : psf_log_printf (psf, "bext : %D\n", chunk_size) ; chunk_size -= 24 ; break ; case MARKER_HASH16 : psf_log_printf (psf, "marker : %D\n", chunk_size) ; chunk_size -= 24 ; break ; case SUMLIST_HASH16 : psf_log_printf (psf, "summary list : %D\n", chunk_size) ; chunk_size -= 24 ; break ; default : psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %D. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ; done = SF_TRUE ; break ; } ; /* switch (dword) */ if (chunk_size >= psf->filelength) { psf_log_printf (psf, "*** Chunk size %u > file length %D. Exiting parser.\n", chunk_size, psf->filelength) ; break ; } ; if (psf->sf.seekable == 0 && (parsestage & HAVE_data)) break ; if (psf_ftell (psf) >= (psf->filelength - (2 * SIGNED_SIZEOF (dword)))) break ; if (chunk_size > 0 && chunk_size < 0xffff0000) { dword = chunk_size ; psf_binheader_readf (psf, "j", dword - 24) ; } ; } ; /* while (1) */ if (psf->dataoffset <= 0) return SFE_W64_NO_DATA ; if (psf->sf.channels < 1) return SFE_CHANNEL_COUNT_ZERO ; if (psf->sf.channels >= SF_MAX_CHANNELS) return SFE_CHANNEL_COUNT ; psf->endian = SF_ENDIAN_LITTLE ; /* All W64 files are little endian. */ if (psf_ftell (psf) != psf->dataoffset) psf_fseek (psf, psf->dataoffset, SEEK_SET) ; if (psf->blockwidth) { if (psf->filelength - psf->dataoffset < psf->datalength) psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; else psf->sf.frames = psf->datalength / psf->blockwidth ; } ; switch (format) { case WAVE_FORMAT_PCM : case WAVE_FORMAT_EXTENSIBLE : /* extensible might be FLOAT, MULAW, etc as well! */ psf->sf.format = SF_FORMAT_W64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ; break ; case WAVE_FORMAT_MULAW : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ULAW) ; break ; case WAVE_FORMAT_ALAW : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ALAW) ; break ; case WAVE_FORMAT_MS_ADPCM : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM) ; *blockalign = wav_fmt->msadpcm.blockalign ; *framesperblock = wav_fmt->msadpcm.samplesperblock ; break ; case WAVE_FORMAT_IMA_ADPCM : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM) ; *blockalign = wav_fmt->ima.blockalign ; *framesperblock = wav_fmt->ima.samplesperblock ; break ; case WAVE_FORMAT_GSM610 : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_GSM610) ; break ; case WAVE_FORMAT_IEEE_FLOAT : psf->sf.format = SF_FORMAT_W64 ; psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ; } /* w64_read_header */
static int au_read_header (SF_PRIVATE *psf) { AU_FMT au_fmt ; int marker, dword ; memset (&au_fmt, 0, sizeof (au_fmt)) ; psf_binheader_readf (psf, "pm", 0, &marker) ; psf_log_printf (psf, "%M\n", marker) ; if (marker == DOTSND_MARKER) { psf->endian = SF_ENDIAN_BIG ; psf_binheader_readf (psf, "E44444", &(au_fmt.dataoffset), &(au_fmt.datasize), &(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ; } else if (marker == DNSDOT_MARKER) { psf->endian = SF_ENDIAN_LITTLE ; psf_binheader_readf (psf, "e44444", &(au_fmt.dataoffset), &(au_fmt.datasize), &(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ; } else return SFE_AU_NO_DOTSND ; psf_log_printf (psf, " Data Offset : %d\n", au_fmt.dataoffset) ; if (psf->fileoffset > 0 && au_fmt.datasize == -1) { psf_log_printf (psf, " Data Size : -1\n") ; return SFE_AU_EMBED_BAD_LEN ; } ; if (psf->fileoffset > 0) { psf->filelength = au_fmt.dataoffset + au_fmt.datasize ; psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; } else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength) psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength) { psf->filelength = au_fmt.dataoffset + au_fmt.datasize ; psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; } else { dword = psf->filelength - au_fmt.dataoffset ; psf_log_printf (psf, " Data Size : %d (should be %d)\n", au_fmt.datasize, dword) ; au_fmt.datasize = dword ; } ; psf->dataoffset = au_fmt.dataoffset ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf_ftell (psf) < psf->dataoffset) psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ; psf->sf.samplerate = au_fmt.samplerate ; psf->sf.channels = au_fmt.channels ; /* Only fill in type major. */ if (psf->endian == SF_ENDIAN_BIG) psf->sf.format = SF_FORMAT_AU ; else if (psf->endian == SF_ENDIAN_LITTLE) psf->sf.format = SF_ENDIAN_LITTLE | SF_FORMAT_AU ; psf_log_printf (psf, " Encoding : %d => ", au_fmt.encoding) ; psf->sf.format = SF_ENDIAN (psf->sf.format) ; switch (au_fmt.encoding) { case AU_ENCODING_ULAW_8 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ULAW ; psf->bytewidth = 1 ; /* Before decoding */ psf_log_printf (psf, "8-bit ISDN u-law\n") ; break ; case AU_ENCODING_PCM_8 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_S8 ; psf->bytewidth = 1 ; psf_log_printf (psf, "8-bit linear PCM\n") ; break ; case AU_ENCODING_PCM_16 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_16 ; psf->bytewidth = 2 ; psf_log_printf (psf, "16-bit linear PCM\n") ; break ; case AU_ENCODING_PCM_24 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_24 ; psf->bytewidth = 3 ; psf_log_printf (psf, "24-bit linear PCM\n") ; break ; case AU_ENCODING_PCM_32 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_32 ; psf->bytewidth = 4 ; psf_log_printf (psf, "32-bit linear PCM\n") ; break ; case AU_ENCODING_FLOAT : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_FLOAT ; psf->bytewidth = 4 ; psf_log_printf (psf, "32-bit float\n") ; break ; case AU_ENCODING_DOUBLE : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_DOUBLE ; psf->bytewidth = 8 ; psf_log_printf (psf, "64-bit double precision float\n") ; break ; case AU_ENCODING_ALAW_8 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ALAW ; psf->bytewidth = 1 ; /* Before decoding */ psf_log_printf (psf, "8-bit ISDN A-law\n") ; break ; case AU_ENCODING_ADPCM_G721_32 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G721_32 ; psf->bytewidth = 0 ; psf_log_printf (psf, "G721 32kbs ADPCM\n") ; break ; case AU_ENCODING_ADPCM_G723_24 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_24 ; psf->bytewidth = 0 ; psf_log_printf (psf, "G723 24kbs ADPCM\n") ; break ; case AU_ENCODING_ADPCM_G723_40 : psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_40 ; psf->bytewidth = 0 ; psf_log_printf (psf, "G723 40kbs ADPCM\n") ; break ; case AU_ENCODING_ADPCM_G722 : psf_log_printf (psf, "G722 64 kbs ADPCM (unsupported)\n") ; break ; case AU_ENCODING_NEXT : psf_log_printf (psf, "Weird NeXT encoding format (unsupported)\n") ; break ; default : psf_log_printf (psf, "Unknown!!\n") ; break ; } ; psf_log_printf (psf, " Sample Rate : %d\n", au_fmt.samplerate) ; if (au_fmt.channels < 1) { psf_log_printf (psf, " Channels : %d **** should be >= 1\n", au_fmt.channels) ; return SFE_CHANNEL_COUNT_ZERO ; } else if (au_fmt.channels > SF_MAX_CHANNELS) { psf_log_printf (psf, " Channels : %d **** should be <= %d\n", au_fmt.channels, SF_MAX_CHANNELS) ; return SFE_CHANNEL_COUNT ; } ; psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ; psf->blockwidth = psf->sf.channels * psf->bytewidth ; if (! psf->sf.frames && psf->blockwidth) psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; return 0 ; } /* au_read_header */
static int w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) { WAV_FMT wav_fmt ; int dword = 0, marker, format = 0 ; sf_count_t chunk_size, bytesread = 0 ; int parsestage = 0, error, done = 0 ; /* Set position to start of file to begin reading header. */ psf_binheader_readf (psf, "p", 0) ; while (! done) { /* Read the 4 byte marker and jump 12 bytes. */ bytesread += psf_binheader_readf (psf, "h", &marker) ; chunk_size = 0 ; switch (marker) { case riff_HASH16 : if (parsestage) return SFE_W64_NO_RIFF ; bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ; if (psf->filelength < chunk_size) psf_log_printf (psf, "riff : %d (should be %d)\n", chunk_size, psf->filelength) ; else psf_log_printf (psf, "riff : %d\n", chunk_size) ; parsestage |= HAVE_riff ; break ; case ACID_HASH16: psf_log_printf (psf, "Looks like an ACID file. Exiting.\n") ; return SFE_UNIMPLEMENTED ; case wave_HASH16 : if ((parsestage & HAVE_riff) != HAVE_riff) return SFE_W64_NO_WAVE ; psf_log_printf (psf, "wave\n") ; parsestage |= HAVE_wave ; break ; case fmt_HASH16 : if ((parsestage & (HAVE_riff | HAVE_wave)) != (HAVE_riff | HAVE_wave)) return SFE_W64_NO_FMT ; bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ; psf_log_printf (psf, " fmt : %d (0x%X)\n", chunk_size, chunk_size) ; /* size of 16 byte marker and 8 byte chunk_size value. */ chunk_size -= 24 ; if ((error = wav_w64_read_fmt_chunk (psf, &wav_fmt, (int) chunk_size))) return error ; if (chunk_size % 8) psf_binheader_readf (psf, "j", 8 - (chunk_size % 8)) ; format = wav_fmt.format ; parsestage |= HAVE_fmt ; break ; case fact_HASH16: { sf_count_t frames ; psf_binheader_readf (psf, "e88", &chunk_size, &frames) ; psf_log_printf (psf, " fact : 0x%X\n" " frames : %d\n", chunk_size, frames) ; } ; break ; case data_HASH16 : if ((parsestage & (HAVE_riff | HAVE_wave | HAVE_fmt)) != (HAVE_riff | HAVE_wave | HAVE_fmt)) return SFE_W64_NO_DATA ; psf_binheader_readf (psf, "e8", &chunk_size) ; psf->dataoffset = psf_ftell (psf->filedes) ; psf->datalength = chunk_size - 24 ; if (chunk_size % 8) chunk_size += 8 - (chunk_size % 8) ; psf_log_printf (psf, "data : %d (0x%X)\n", chunk_size, psf->datalength) ; parsestage |= HAVE_data ; if (! psf->sf.seekable) break ; /* Seek past data and continue reading header. */ psf_fseek (psf->filedes, chunk_size, SEEK_CUR) ; break ; default : if (psf_ftell (psf->filedes) & 0x0F) { psf_log_printf (psf, " Unknown chunk marker at position %d. Resynching.\n", dword - 4) ; psf_binheader_readf (psf, "j", -3) ; break ; } ; psf_log_printf (psf, "*** Unknown chunk marker : %X. Exiting parser.\n", marker) ; done = SF_TRUE ; break ; } ; /* switch (dword) */ if (! psf->sf.seekable && (parsestage & HAVE_data)) break ; if (psf_ferror (psf->filedes)) { psf_log_printf (psf, "*** Error on file handle. ***\n", marker) ; psf_fclearerr (psf->filedes) ; break ; } ; if (psf_ftell (psf->filedes) >= (int) (psf->filelength - (2 * sizeof (dword)))) break ; if (psf->logindex >= sizeof (psf->logbuffer) - 2) return SFE_LOG_OVERRUN ; } ; /* while (1) */ if (! psf->dataoffset) return SFE_W64_NO_DATA ; psf->endian = SF_ENDIAN_LITTLE ; /* All WAV files are little endian. */ psf_fseek (psf->filedes, psf->dataoffset, SEEK_SET) ; psf->close = w64_close ; if (psf->blockwidth) { if (psf->filelength - psf->dataoffset < psf->datalength) psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; else psf->sf.frames = psf->datalength / psf->blockwidth ; } ; switch (format) { case WAVE_FORMAT_PCM : case WAVE_FORMAT_EXTENSIBLE : psf->sf.format = SF_FORMAT_W64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ; break ; case WAVE_FORMAT_MULAW : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ULAW) ; break ; case WAVE_FORMAT_ALAW : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ALAW) ; break ; case WAVE_FORMAT_MS_ADPCM : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM) ; *blockalign = wav_fmt.msadpcm.blockalign ; *framesperblock = wav_fmt.msadpcm.samplesperblock ; break ; case WAVE_FORMAT_IMA_ADPCM : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM) ; *blockalign = wav_fmt.ima.blockalign ; *framesperblock = wav_fmt.ima.samplesperblock ; break ; case WAVE_FORMAT_GSM610 : psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_GSM610) ; break ; case WAVE_FORMAT_IEEE_FLOAT : psf->sf.format = SF_FORMAT_W64 ; psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ; } /* w64_read_header */
static int au_write_header (SF_PRIVATE *psf, int calc_length) { sf_count_t current ; int encoding, datalength ; if (psf->pipeoffset > 0) return 0 ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; } ; encoding = au_format_to_encoding (SF_CODEC (psf->sf.format)) ; if (! encoding) return (psf->error = SFE_BAD_OPEN_FORMAT) ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; /* ** Only attempt to seek if we are not writng to a pipe. If we are ** writing to a pipe we shouldn't be here anyway. */ if (psf->is_pipe == SF_FALSE) psf_fseek (psf, 0, SEEK_SET) ; /* ** AU format files allow a datalength value of -1 if the datalength ** is not know at the time the header is written. ** Also use this value of -1 if the datalength > 2 gigabytes. */ if (psf->datalength < 0 || psf->datalength > 0x7FFFFFFF) datalength = -1 ; else datalength = (int) (psf->datalength & 0x7FFFFFFF) ; if (psf->endian == SF_ENDIAN_BIG) { psf_binheader_writef (psf, "Em4", DOTSND_MARKER, AU_DATA_OFFSET) ; psf_binheader_writef (psf, "E4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ; } else if (psf->endian == SF_ENDIAN_LITTLE) { psf_binheader_writef (psf, "em4", DNSDOT_MARKER, AU_DATA_OFFSET) ; psf_binheader_writef (psf, "e4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ; } else return (psf->error = SFE_BAD_OPEN_FORMAT) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* au_write_header */
static int mat5_write_header (SF_PRIVATE *psf, int calc_length) { static const char *sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ; static const char *wd_name = "wavedata\0" ; sf_count_t current, datasize ; int encoding ; current = psf_ftell (psf) ; if (calc_length) { psf_fseek (psf, 0, SEEK_END) ; psf->filelength = psf_ftell (psf) ; psf_fseek (psf, 0, SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; switch (psf->sf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_U8 : encoding = MAT5_TYPE_UCHAR ; break ; case SF_FORMAT_PCM_16 : encoding = MAT5_TYPE_INT16 ; break ; case SF_FORMAT_PCM_32 : encoding = MAT5_TYPE_INT32 ; break ; case SF_FORMAT_FLOAT : encoding = MAT5_TYPE_FLOAT ; break ; case SF_FORMAT_DOUBLE : encoding = MAT5_TYPE_DOUBLE ; break ; default : return SFE_BAD_OPEN_FORMAT ; } ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; psf_fseek (psf, 0, SEEK_SET) ; psf_binheader_writef (psf, "S", "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", ") ; psf_get_date_str (psf->u.scbuf, sizeof (psf->u.scbuf)) ; psf_binheader_writef (psf, "jS", -1, psf->u.scbuf) ; memset (psf->u.scbuf, ' ', 124 - psf->headindex) ; psf_binheader_writef (psf, "b", psf->u.scbuf, 124 - psf->headindex) ; psf->rwf_endian = psf->endian ; if (psf->rwf_endian == SF_ENDIAN_BIG) psf_binheader_writef (psf, "2b", 0x0100, "MI", 2) ; else psf_binheader_writef (psf, "2b", 0x0100, "IM", 2) ; psf_binheader_writef (psf, "444444", MAT5_TYPE_ARRAY, 64, MAT5_TYPE_UINT32, 8, 6, 0) ; psf_binheader_writef (psf, "4444", MAT5_TYPE_INT32, 8, 1, 1) ; psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (sr_name), sr_name, 16) ; if (psf->sf.samplerate > 0xFFFF) psf_binheader_writef (psf, "44", MAT5_TYPE_COMP_UINT, psf->sf.samplerate) ; else { unsigned short samplerate = psf->sf.samplerate ; psf_binheader_writef (psf, "422", MAT5_TYPE_COMP_USHORT, samplerate, 0) ; } ; datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ; psf_binheader_writef (psf, "t484444", MAT5_TYPE_ARRAY, datasize + 64, MAT5_TYPE_UINT32, 8, 6, 0) ; psf_binheader_writef (psf, "t4448", MAT5_TYPE_INT32, 8, psf->sf.channels, psf->sf.frames) ; psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (wd_name), wd_name, strlen (wd_name)) ; datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ; if (datasize > 0x7FFFFFFF) datasize = 0x7FFFFFFF ; psf_binheader_writef (psf, "t48", encoding, datasize) ; /* Header construction complete so write it out. */ psf_fwrite (psf->header, psf->headindex, 1, psf) ; if (psf->error) return psf->error ; psf->dataoffset = psf->headindex ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* mat5_write_header */
static int mat4_read_header (SF_PRIVATE *psf) { int marker, rows, cols, imag ; unsigned namesize ; double value ; const char *marker_str ; char name [64] ; psf_binheader_readf (psf, "pm", 0, &marker) ; /* MAT4 file must start with a double for the samplerate. */ if (marker == MAT4_BE_DOUBLE) { psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ; marker_str = "big endian double" ; } else if (marker == MAT4_LE_DOUBLE) { psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ; marker_str = "little endian double" ; } else return SFE_UNIMPLEMENTED ; psf_log_printf (psf, "GNU Octave 2.0 / MATLAB v4.2 format\nMarker : %s\n", marker_str) ; psf_binheader_readf (psf, "444", &rows, &cols, &imag) ; psf_log_printf (psf, " Rows : %d\n Cols : %d\n Imag : %s\n", rows, cols, imag ? "True" : "False") ; psf_binheader_readf (psf, "4", &namesize) ; if (namesize >= SIGNED_SIZEOF (name)) return SFE_MAT4_BAD_NAME ; psf_binheader_readf (psf, "b", name, namesize) ; name [namesize] = 0 ; psf_log_printf (psf, " Name : %s\n", name) ; psf_binheader_readf (psf, "d", &value) ; snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " Value : %f\n", value) ; psf_log_printf (psf, psf->u.cbuf) ; if ((rows != 1) || (cols != 1)) return SFE_MAT4_NO_SAMPLERATE ; psf->sf.samplerate = (int)lrint(value); // kengo: /* Now write out the audio data. */ psf_binheader_readf (psf, "m", &marker) ; psf_log_printf (psf, "Marker : %s\n", mat4_marker_to_str (marker)) ; psf_binheader_readf (psf, "444", &rows, &cols, &imag) ; psf_log_printf (psf, " Rows : %d\n Cols : %d\n Imag : %s\n", rows, cols, imag ? "True" : "False") ; psf_binheader_readf (psf, "4", &namesize) ; if (namesize >= SIGNED_SIZEOF (name)) return SFE_MAT4_BAD_NAME ; psf_binheader_readf (psf, "b", name, namesize) ; name [namesize] = 0 ; psf_log_printf (psf, " Name : %s\n", name) ; psf->dataoffset = psf_ftell (psf) ; if (rows == 0 && cols == 0) { psf_log_printf (psf, "*** Error : zero channel count.\n") ; return SFE_CHANNEL_COUNT_ZERO ; } ; psf->sf.channels = rows ; psf->sf.frames = cols ; psf->sf.format = psf->endian | SF_FORMAT_MAT4 ; switch (marker) { case MAT4_BE_DOUBLE : case MAT4_LE_DOUBLE : psf->sf.format |= SF_FORMAT_DOUBLE ; psf->bytewidth = 8 ; break ; case MAT4_BE_FLOAT : case MAT4_LE_FLOAT : psf->sf.format |= SF_FORMAT_FLOAT ; psf->bytewidth = 4 ; break ; case MAT4_BE_PCM_32 : case MAT4_LE_PCM_32 : psf->sf.format |= SF_FORMAT_PCM_32 ; psf->bytewidth = 4 ; break ; case MAT4_BE_PCM_16 : case MAT4_LE_PCM_16 : psf->sf.format |= SF_FORMAT_PCM_16 ; psf->bytewidth = 2 ; break ; default : psf_log_printf (psf, "*** Error : Bad marker %08X\n", marker) ; return SFE_UNIMPLEMENTED ; } ; if ((psf->filelength - psf->dataoffset) < psf->sf.channels * psf->sf.frames * psf->bytewidth) { psf_log_printf (psf, "*** File seems to be truncated. %D <--> %D\n", psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ; } else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth) psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ; psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ; psf->sf.sections = 1 ; return 0 ; } /* mat4_read_header */
static int nist_write_header (SF_PRIVATE *psf, int calc_length) { const char *end_str ; long samples ; sf_count_t current ; current = psf_ftell (psf) ; if (calc_length) { psf->filelength = psf_get_filelen (psf) ; psf->datalength = psf->filelength - psf->dataoffset ; if (psf->dataend) psf->datalength -= psf->filelength - psf->dataend ; if (psf->bytewidth > 0) psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; } ; if (psf->endian == SF_ENDIAN_BIG) end_str = "10" ; else if (psf->endian == SF_ENDIAN_LITTLE) end_str = "01" ; else end_str = "error" ; /* Clear the whole header. */ memset (psf->header.ptr, 0, psf->header.len) ; psf->header.indx = 0 ; psf_fseek (psf, 0, SEEK_SET) ; psf_asciiheader_printf (psf, "NIST_1A\n 1024\n") ; psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ; psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ; switch (SF_CODEC (psf->sf.format)) { case SF_FORMAT_PCM_S8 : psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n" "sample_sig_bits -i 8\n") ; break ; case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ; psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ; psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n" "sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ; break ; case SF_FORMAT_ALAW : psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; break ; case SF_FORMAT_ULAW : psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ; psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; break ; default : return SFE_UNIMPLEMENTED ; } ; psf->dataoffset = NIST_HEADER_LENGTH ; /* Fix this */ samples = psf->sf.frames ; psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ; psf_asciiheader_printf (psf, "end_head\n") ; /* Zero fill to dataoffset. */ psf_binheader_writef (psf, "z", BHWz ((size_t) (NIST_HEADER_LENGTH - psf->header.indx))) ; psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; if (psf->error) return psf->error ; if (current > 0) psf_fseek (psf, current, SEEK_SET) ; return psf->error ; } /* nist_write_header */
static int caf_read_header (SF_PRIVATE *psf) { CAF_PRIVATE *pcaf ; BUF_UNION ubuf ; DESC_CHUNK desc ; sf_count_t chunk_size ; double srate ; short version, flags ; int marker, k, have_data = 0, error ; if ((pcaf = psf->container_data) == NULL) return SFE_INTERNAL ; memset (&desc, 0, sizeof (desc)) ; /* Set position to start of file to begin reading header. */ psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ; psf_log_printf (psf, "%M\n Version : %d\n Flags : %x\n", marker, version, flags) ; if (marker != caff_MARKER) return SFE_CAF_NOT_CAF ; psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, ubuf.ucbuf, 8) ; srate = double64_be_read (ubuf.ucbuf) ; snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "%5.3f", srate) ; psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, ubuf.cbuf) ; if (marker != desc_MARKER) return SFE_CAF_NO_DESC ; if (chunk_size < SIGNED_SIZEOF (DESC_CHUNK)) { psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ; return SFE_MALFORMED_FILE ; } ; psf->sf.samplerate = lrint (srate) ; psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.frames_per_packet, &desc.channels_per_frame, &desc.bits_per_chan) ; psf_log_printf (psf, " Format id : %M\n Format flags : %x\n Bytes / packet : %u\n" " Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ; if (desc.channels_per_frame > SF_MAX_CHANNELS) { psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ; return SFE_MALFORMED_FILE ; } ; if (chunk_size > SIGNED_SIZEOF (DESC_CHUNK)) psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ; psf->sf.channels = desc.channels_per_frame ; while (1) { marker = 0 ; chunk_size = 0 ; psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ; if (marker == 0) { sf_count_t pos = psf_ftell (psf) ; psf_log_printf (psf, "Have 0 marker at position %D (0x%x).\n", pos, pos) ; break ; } ; if (chunk_size < 0) { psf_log_printf (psf, "%M : %D *** Should be >= 0 ***\n", marker, chunk_size) ; break ; } ; psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ; switch (marker) { case peak_MARKER : psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) { psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ; return SFE_CAF_BAD_PEAK ; } ; if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL) return SFE_MALLOC_FAILED ; /* read in rest of PEAK chunk. */ psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ; psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ; psf_log_printf (psf, " Ch Position Value\n") ; for (k = 0 ; k < psf->sf.channels ; k++) { sf_count_t position ; float value ; psf_binheader_readf (psf, "Ef8", &value, &position) ; psf->peak_info->peaks [k].value = value ; psf->peak_info->peaks [k].position = position ; snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), " %2d %-12" PRId64 " %g\n", k, position, value) ; psf_log_printf (psf, ubuf.cbuf) ; } ; psf->peak_info->peak_loc = SF_PEAK_START ; break ; case chan_MARKER : if (chunk_size < 12) { psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ; psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; break ; } psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; if ((error = caf_read_chanmap (psf, chunk_size))) return error ; break ; case free_MARKER : psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; break ; case data_MARKER : psf_binheader_readf (psf, "E4", &k) ; if (chunk_size == -1) { psf_log_printf (psf, "%M : -1\n") ; chunk_size = psf->filelength - psf->headindex ; } else if (psf->filelength > 0 && chunk_size > psf->filelength - psf->headindex + 10) { psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, psf->filelength - psf->headindex - 8) ; psf->datalength = psf->filelength - psf->headindex - 8 ; } else { psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; /* Subtract the 4 bytes of the 'edit' field above. */ psf->datalength = chunk_size - 4 ; } ; psf_log_printf (psf, " edit : %u\n", k) ; psf->dataoffset = psf->headindex ; if (psf->datalength + psf->dataoffset < psf->filelength) psf->dataend = psf->datalength + psf->dataoffset ; psf_binheader_readf (psf, "j", make_size_t (psf->datalength)) ; have_data = 1 ; break ; case kuki_MARKER : psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ; psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; break ; case pakt_MARKER : if (chunk_size < 24) { psf_log_printf (psf, "%M : %D (should be > 24)\n", marker, chunk_size) ; return SFE_MALFORMED_FILE ; } else if (chunk_size > psf->filelength - psf->headindex) { psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->headindex) ; return SFE_MALFORMED_FILE ; } else psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; psf_binheader_readf (psf, "E8844", &pcaf->alac.packets, &pcaf->alac.valid_frames, &pcaf->alac.priming_frames, &pcaf->alac.remainder_frames) ; psf_log_printf (psf, " Packets : %D\n" " Valid frames : %D\n" " Priming frames : %d\n" " Remainder frames : %d\n", pcaf->alac.packets, pcaf->alac.valid_frames, pcaf->alac.priming_frames, pcaf->alac.remainder_frames ) ; if (pcaf->alac.packets == 0 && pcaf->alac.valid_frames == 0 && pcaf->alac.priming_frames == 0 && pcaf->alac.remainder_frames == 0) psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ; pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ; psf_binheader_readf (psf, "j", make_size_t (chunk_size) - 24) ; break ; case info_MARKER : if (chunk_size < 4) { psf_log_printf (psf, "%M : %D (should be > 4)\n", marker, chunk_size) ; return SFE_MALFORMED_FILE ; } else if (chunk_size > psf->filelength - psf->headindex) { psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->headindex) ; return SFE_MALFORMED_FILE ; } ; psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; caf_read_strings (psf, chunk_size) ; break ; default : psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ; psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; break ; } ; if (marker != data_MARKER && chunk_size >= 0xffffff00) break ; if (! psf->sf.seekable && have_data) break ; if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size)) { psf_log_printf (psf, "End\n") ; break ; } ; } ; if (have_data == 0) { psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ; return SFE_MALFORMED_FILE ; } ; psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ; psf_fseek (psf, psf->dataoffset, SEEK_SET) ; if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0) return SFE_UNSUPPORTED_ENCODING ; if (psf->bytewidth > 0) psf->sf.frames = psf->datalength / psf->bytewidth ; return 0 ; } /* caf_read_header */