📄 aiff.c
字号:
} else psf_log_printf (psf, " SSND : %u\n", SSNDsize) ; /* Only set dataend if there really is data at the end. */ if (psf->datalength + psf->dataoffset < psf->filelength) psf->dataend = psf->datalength + psf->dataoffset ; psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ; psf_log_printf (psf, " Block Size : %u\n", ssnd_fmt.blocksize) ; found_chunk |= HAVE_SSND ; if (! psf->sf.seekable) break ; /* Seek to end of SSND chunk. */ psf_fseek (psf, psf->dataoffset + psf->datalength + (SSNDsize & 1), SEEK_SET) ; break ; case c_MARKER : psf_binheader_readf (psf, "E4", &dword) ; if (dword == 0) break ; if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1) { psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ; return SFE_INTERNAL ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, dword) ; cptr [dword] = 0 ; psf_log_printf (psf, " %M : %s\n", marker, cptr) ; psf_store_string (psf, SF_STR_COPYRIGHT, cptr) ; break ; case AUTH_MARKER : psf_binheader_readf (psf, "E4", &dword) ; dword += (dword & 1) ; if (dword == 0) break ; if (dword > SIGNED_SIZEOF (psf->u.scbuf)) { psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ; return SFE_INTERNAL ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, dword) ; cptr [dword - 1] = 0 ; psf_log_printf (psf, " %M : %s\n", marker, cptr) ; psf_store_string (psf, SF_STR_ARTIST, cptr) ; break ; case COMT_MARKER : { unsigned short count, id, len ; unsigned int timestamp ; psf_binheader_readf (psf, "E42", &dword, &count) ; psf_log_printf (psf, " %M : %d\n count : %d\n", marker, dword, count) ; dword += (dword & 1) ; if (dword == 0) break ; for (k = 0 ; k < count ; k++) { psf_binheader_readf (psf, "E422", ×tamp, &id, &len) ; psf_log_printf (psf, " time : 0x%x\n marker : %x\n length : %d\n", timestamp, id, len) ; if (len + 1 > SIGNED_SIZEOF (psf->u.scbuf)) { psf_log_printf (psf, "\nError : string length (%d) too big.\n", len) ; return SFE_INTERNAL ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, len) ; cptr [len] = 0 ; psf_log_printf (psf, " string : %s\n", cptr) ; } ; } ; break ; case APPL_MARKER : psf_binheader_readf (psf, "E4", &dword) ; dword += (dword & 1) ; if (dword == 0) break ; if (dword >= SIGNED_SIZEOF (psf->u.scbuf)) { psf_log_printf (psf, " %M : %d (too big, skipping)\n", marker, dword) ; psf_binheader_readf (psf, "j", dword) ; break ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, dword) ; cptr [dword - 1] = 0 ; for (k = 0 ; k < dword ; k++) if (! isprint (cptr [k])) { cptr [k] = 0 ; break ; } ; psf_log_printf (psf, " %M : %s\n", marker, cptr) ; psf_store_string (psf, SF_STR_SOFTWARE, cptr) ; break ; case NAME_MARKER : psf_binheader_readf (psf, "E4", &dword) ; dword += (dword & 1) ; if (dword == 0) break ; if (dword > SIGNED_SIZEOF (psf->u.scbuf)) { psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ; return SFE_INTERNAL ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, dword) ; cptr [dword - 1] = 0 ; psf_log_printf (psf, " %M : %s\n", marker, cptr) ; psf_store_string (psf, SF_STR_TITLE, cptr) ; break ; case ANNO_MARKER : psf_binheader_readf (psf, "E4", &dword) ; if (dword == 0) break ; if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1) { psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ; return SFE_INTERNAL ; } ; cptr = psf->u.scbuf ; psf_binheader_readf (psf, "b", cptr, dword) ; cptr [dword] = 0 ; psf_log_printf (psf, " %M : %s\n", marker, cptr) ; psf_store_string (psf, SF_STR_COMMENT, cptr) ; break ; case INST_MARKER : psf_binheader_readf (psf, "E4", &dword) ; if (dword != SIZEOF_INST_CHUNK) { psf_log_printf (psf, " %M : %d (should be %d)\n", marker, dword, SIZEOF_INST_CHUNK) ; psf_binheader_readf (psf, "j", dword) ; break ; } ; psf_log_printf (psf, " %M : %d\n", marker, dword) ; { unsigned char bytes [6] ; short gain ; psf_binheader_readf (psf, "b", bytes, 6) ; psf_log_printf (psf, " Base Note : %u\n Detune : %u\n" " Low Note : %u\n High Note : %u\n" " Low Vel. : %u\n High Vel. : %u\n", bytes [0], bytes [1], bytes [2], bytes [3], bytes [4], bytes [5]) ; psf_binheader_readf (psf, "E2", &gain) ; psf_log_printf (psf, " Gain (dB) : %d\n", gain) ; } ; { short mode ; /* 0 - no loop, 1 - forward looping, 2 - backward looping */ const char *loop_mode ; unsigned short begin, end ; psf_binheader_readf (psf, "E222", &mode, &begin, &end) ; loop_mode = get_loop_mode_str (mode) ; psf_log_printf (psf, " Sustain\n mode : %d => %s\n begin : %u\n end : %u\n", mode, loop_mode, begin, end) ; psf_binheader_readf (psf, "E222", &mode, &begin, &end) ; loop_mode = get_loop_mode_str (mode) ; psf_log_printf (psf, " Release\n mode : %d => %s\n begin : %u\n end : %u\n", mode, loop_mode, begin, end) ; } ; break ; case basc_MARKER : psf_binheader_readf (psf, "E4", &dword) ; if (dword != SIZEOF_basc_CHUNK) { psf_log_printf (psf, " %M : %d (should be %d)\n", marker, dword, SIZEOF_basc_CHUNK) ; psf_binheader_readf (psf, "j", dword) ; break ; } ; psf_log_printf (psf, " basc : %u\n", dword) ; if ((error = aiff_read_basc_chunk (psf))) return error ; break ; case MARK_MARKER : psf_binheader_readf (psf, "E4", &dword) ; psf_log_printf (psf, " %M : %d\n", marker, dword) ; { unsigned short mark_count, mark_id ; unsigned char pstr_len ; unsigned int position ; bytesread = psf_binheader_readf (psf, "E2", &mark_count) ; psf_log_printf (psf, " Count : %d\n", mark_count) ; while (mark_count && bytesread < dword) { bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &pstr_len) ; psf_log_printf (psf, " Mark ID : %u\n Position : %u\n", mark_id, position) ; pstr_len += (pstr_len & 1) + 1 ; /* fudgy, fudgy, hack, hack */ bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ; psf_log_printf (psf, " Name : %s\n", psf->u.scbuf) ; mark_count -- ; } ; } ; psf_binheader_readf (psf, "j", dword - bytesread) ; break ; case FVER_MARKER : case SFX_MARKER : psf_binheader_readf (psf, "E4", &dword) ; psf_log_printf (psf, " %M : %d\n", marker, dword) ; psf_binheader_readf (psf, "j", dword) ; break ; case NONE_MARKER : /* Fix for broken AIFC files with incorrect COMM chunk length. */ psf_binheader_readf (psf, "1", &byte) ; dword = byte ; psf_binheader_readf (psf, "j", dword) ; break ; default : if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF) && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF)) { psf_binheader_readf (psf, "E4", &dword) ; psf_log_printf (psf, " %M : %d (unknown marker)\n", marker, dword) ; psf_binheader_readf (psf, "j", dword) ; break ; } ; if ((dword = psf_ftell (psf)) & 0x03) { psf_log_printf (psf, " Unknown chunk marker %X at position %d. Resyncing.\n", marker, dword - 4) ; psf_binheader_readf (psf, "j", -3) ; break ; } ; psf_log_printf (psf, "*** Unknown chunk marker %X at position %D. Exiting parser.\n", marker, psf_ftell (psf)) ; done = 1 ; break ; } ; /* switch (marker) */ if ((! psf->sf.seekable) && (found_chunk & HAVE_SSND)) break ; if (psf_ftell (psf) >= psf->filelength - (2 * SIGNED_SIZEOF (dword))) break ; if (psf->logindex >= SIGNED_SIZEOF (psf->logbuffer) - 2) return SFE_LOG_OVERRUN ; } ; /* while (1) */ if (! (found_chunk & HAVE_FORM)) return SFE_AIFF_NO_FORM ; if (! (found_chunk & HAVE_AIFF)) return SFE_AIFF_COMM_NO_FORM ; if (! (found_chunk & HAVE_COMM)) return SFE_AIFF_SSND_NO_COMM ; if (! psf->dataoffset) return SFE_AIFF_NO_DATA ; return 0 ;} /* aiff_read_header */static intaiff_close (SF_PRIVATE *psf){ if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { aiff_write_tailer (psf) ; aiff_write_header (psf, SF_TRUE) ; } ; return 0 ;} /* aiff_close */static intaiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt){ int error = 0, bytesread, subformat ; psf->u.scbuf [0] = 0 ; bytesread = psf_binheader_readf (psf, "E4", &(comm_fmt->size)) ; /* The COMM chunk has an int aligned to an odd word boundary. Some ** procesors are not able to deal with this (ie bus fault) so we have ** to take special care. */ comm_fmt->size += comm_fmt->size & 1 ; bytesread += psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames), &(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ; if (comm_fmt->size == SIZEOF_AIFF_COMM) comm_fmt->encoding = NONE_MARKER ; else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN) bytesread += psf_binheader_readf (psf, "Em", &(comm_fmt->encoding)) ; else if (comm_fmt->size >= SIZEOF_AIFC_COMM) { unsigned char encoding_len ; bytesread += psf_binheader_readf (psf, "Em1", &(comm_fmt->encoding), &encoding_len) ; memset (psf->u.scbuf, 0, comm_fmt->size) ; bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, comm_fmt->size - SIZEOF_AIFC_COMM + 1) ; psf->u.scbuf [encoding_len] = 0 ; } ; psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ; psf_log_printf (psf, " Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ; psf_log_printf (psf, " Frames : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 100) ? " (Should not be 0)" : "") ; psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ; /* Found some broken 'fl32' files with comm.samplesize == 16. Fix it here. */ if ((comm_fmt->encoding == fl32_MARKER || comm_fmt->encoding == FL32_MARKER) && comm_fmt->sampleSize != 32) { psf_log_printf (psf, " Sample Size : %d (should be 32)\n", comm_fmt->sampleSize) ; comm_fmt->sampleSize = 32 ; } else if ((comm_fmt->encoding == fl64_MARKER || comm_fmt->encoding == FL64_MARKER) && comm_fmt->sampleSize != 64) { psf_log_printf (psf, " Sample Size : %d (should be 64)\n", comm_fmt->sampleSize) ; comm_fmt->sampleSize = 64 ; } else psf_log_printf (psf, " Sample Size : %d\n", comm_fmt->sampleSize) ; subformat = s_bitwidth_to_subformat (comm_fmt->sampleSize) ; psf->endian = SF_ENDIAN_BIG ; switch (comm_fmt->encoding) { case NONE_MARKER : psf->sf.format = (SF_FORMAT_AIFF | subformat) ; break ; case twos_MARKER : case in32_MARKER : psf->sf.format = (SF_ENDIAN_BIG | SF_FORMAT_AIFF | subformat) ; break ; case sowt_MARKER : case ni32_MARKER : psf->endian = SF_ENDIAN_LITTLE ; psf->sf.format = (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | subformat) ; break ; case fl32_MARKER : case FL32_MARKER : psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ; break ; case ulaw_MARKER : case ULAW_MARKER : psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_ULAW) ; break ; case alaw_MARKER : case ALAW_MARKER : psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_ALAW) ; break ; case fl64_MARKER : case FL64_MARKER : psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_DOUBLE) ; break ; case raw_MARKER : psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_PCM_U8) ; break ; case DWVW_MARKER : psf->sf.format = SF_FORMAT_AIFF ; switch (comm_fmt->sampleSize) { case 12 : psf->sf.format |= SF_FORMAT_DWVW_12 ; break ; case 16 : psf->sf.format |= SF_FORMAT_DWVW_16 ; break ; case 24 : psf->sf.format |= SF_FORMAT_DWVW_24 ; break ; default : psf->sf.format |= SF_FORMAT_DWVW_N ; break ; } ; break ; case GSM_MARKER : psf->sf.format = SF_FORMAT_AIFF ; psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_GSM610) ; break ; case ima4_MARKER : psf->endian = SF_ENDIAN_BIG ; psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM) ; break ; default : psf_log_printf (psf, "AIFC : Unimplemented format : %M\n", comm_fmt->encoding) ; error = SFE_UNIMPLEMENTED ; } ; if (! psf->u.scbuf [0]) psf_log_printf (psf, " Encoding : %M\n", comm_fmt->encoding) ; else psf_log_printf (psf, " Encoding : %M => %s\n", comm_fmt->encoding, psf->u.scbuf) ; return error ;} /* aiff_read_comm_chunk */static intaiff_write_header (SF_PRIVATE *psf, int calc_length){ sf_count_t current ; unsigned char comm_sample_rate [10], comm_zero_bytes [2] = { 0, 0 } ; unsigned int comm_type, comm_size, comm_encoding, comm_frames ; int k, endian ; short bit_width ; 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->mode == SFM_RDWR && psf->dataoffset > 0) { /* Assuming here that the header has already been written and just
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -