📄 wav.c
字号:
break ; } ; if (ftell (psf->file) & 0x03) { 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) ; break ; } ; /* switch (dword) */ if (! psf->sf.seekable && (parsestage & HAVE_data)) break ; if (ferror (psf->file)) { psf_log_printf (psf, "*** Error on file handle. ***\n", marker) ; clearerr (psf->file) ; break ; } ; if (ftell (psf->file) >= (int) (psf->filelength - (2 * sizeof (dword)))) break ; } ; /* while (1) */ if (! psf->dataoffset) return SFE_WAV_NO_DATA ; psf->current = 0 ; psf->endian = SF_ENDIAN_LITTLE ; /* All WAV files are little endian. */ psf->sf.sections = 1 ; fseek (psf->file, psf->dataoffset, SEEK_SET) ; psf->close = (func_close) wav_close ; if (psf->blockwidth) { if (psf->filelength - psf->dataoffset < psf->datalength) psf->sf.samples = (psf->filelength - psf->dataoffset) / psf->blockwidth ; else psf->sf.samples = psf->datalength / psf->blockwidth ; } ; switch (format) { case WAVE_FORMAT_PCM : case WAVE_FORMAT_EXTENSIBLE : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_PCM) ; if (psf->bytewidth == 1) psf->chars = SF_CHARS_UNSIGNED ; if ((error = pcm_read_init (psf))) return error ; return 0 ; case WAVE_FORMAT_MULAW : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ; ulaw_read_init (psf) ; return 0 ; case WAVE_FORMAT_ALAW : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ; alaw_read_init (psf) ; return 0 ; case WAVE_FORMAT_MS_ADPCM : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ; if ((error = wav_msadpcm_reader_init (psf, &wav_fmt))) return error ; return 0 ; case WAVE_FORMAT_IMA_ADPCM : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ; if ((error = wav_ima_reader_init (psf, &wav_fmt))) return error ; return 0 ; case WAVE_FORMAT_GSM610 : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ; if ((error = wav_gsm610_reader_init (psf, &wav_fmt))) return error ; return 0 ; case WAVE_FORMAT_IEEE_FLOAT : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_FLOAT) ; float32_read_init (psf) ; return 0 ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* wav_open_read *//*------------------------------------------------------------------------------ */intwav_open_write (SF_PRIVATE *psf){ unsigned int subformat ; int error ; if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_WAV) return SFE_BAD_OPEN_FORMAT ; psf->endian = SF_ENDIAN_LITTLE ; /* All WAV files are little endian. */ psf->sf.seekable = SF_TRUE ; psf->error = 0 ; subformat = psf->sf.format & SF_FORMAT_SUBMASK ; if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW) psf->bytewidth = 1 ; else psf->bytewidth = BITWIDTH2BYTES (psf->sf.pcmbitwidth) ; psf->blockwidth = psf->bytewidth * psf->sf.channels ; /* Set sample count artifically high and fix later. */ psf->sf.samples = 0x7FFFFFFF / psf->blockwidth ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = 0x7FFFFFFF ; /* Set standard wav_close and write_header now, may be overridden in wav_write_header. */ psf->close = (func_close) wav_close ; psf->write_header = (func_wr_hdr) wav_write_header ; if ((error = wav_write_header (psf))) return error ; return 0 ;} /* wav_open_write *//*------------------------------------------------------------------------------ */static int wav_close (SF_PRIVATE *psf){ if (psf->mode == SF_MODE_WRITE) { /* Now we know for certain the length of the file we can * re-write correct values for the RIFF and data chunks. */ fseek (psf->file, 0, SEEK_END) ; psf->tailstart = ftell (psf->file) ; wav_write_tailer (psf) ; fseek (psf->file, 0, SEEK_END) ; psf->filelength = ftell (psf->file) ; fseek (psf->file, 0, SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset - (psf->filelength - psf->tailstart) ; psf->sf.samples = psf->datalength / (psf->bytewidth * psf->sf.channels) ; wav_write_header (psf) ; } ; if (psf->fdata) free (psf->fdata) ; psf->fdata = NULL ; return 0 ;} /* wav_close *//*=========================================================================** Private functions.*/static intread_fmt_chunk (SF_PRIVATE *psf, WAV_FMT *wav_fmt){ unsigned int bytesread, k, structsize, bytespersec = 0 ; memset (wav_fmt, 0, sizeof (WAV_FMT)) ; psf_binheader_readf (psf, "l", &structsize) ; psf_log_printf (psf, "fmt : %d\n", structsize) ; if (structsize < 16) return SFE_WAV_FMT_SHORT ; if (structsize > sizeof (WAV_FMT)) return SFE_WAV_FMT_TOO_BIG ; /* Read the minimal WAV file header here. */ bytesread = psf_binheader_readf (psf, "wwllww", &(wav_fmt->format), &(wav_fmt->min.channels), &(wav_fmt->min.samplerate), &(wav_fmt->min.bytespersec), &(wav_fmt->min.blockalign), &(wav_fmt->min.bitwidth)) ; psf_log_printf (psf, " Format : 0x%X => %s\n", wav_fmt->format, wav_format_str (wav_fmt->format)) ; psf_log_printf (psf, " Channels : %d\n", wav_fmt->min.channels) ; psf_log_printf (psf, " Sample Rate : %d\n", wav_fmt->min.samplerate) ; psf_log_printf (psf, " Block Align : %d\n", wav_fmt->min.blockalign) ; if (wav_fmt->format == WAVE_FORMAT_GSM610 && wav_fmt->min.bitwidth != 0) psf_log_printf (psf, " Bit Width : %d (should be 0)\n", wav_fmt->min.bitwidth) ; else psf_log_printf (psf, " Bit Width : %d\n", wav_fmt->min.bitwidth) ; psf->sf.samplerate = wav_fmt->min.samplerate ; psf->sf.samples = 0 ; /* Correct this when reading data chunk. */ psf->sf.channels = wav_fmt->min.channels ; switch (wav_fmt->format) { case WAVE_FORMAT_PCM : case WAVE_FORMAT_IEEE_FLOAT : bytespersec = wav_fmt->min.samplerate * wav_fmt->min.blockalign ; if (wav_fmt->min.bytespersec != bytespersec) psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ; else psf_log_printf (psf, " Bytes/sec : %d\n", wav_fmt->min.bytespersec) ; psf->sf.pcmbitwidth = wav_fmt->min.bitwidth ; psf->bytewidth = BITWIDTH2BYTES (wav_fmt->min.bitwidth) ; break ; case WAVE_FORMAT_ALAW : case WAVE_FORMAT_MULAW : if (wav_fmt->min.bytespersec / wav_fmt->min.blockalign != wav_fmt->min.samplerate) psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->min.bytespersec, wav_fmt->min.samplerate * wav_fmt->min.blockalign) ; else psf_log_printf (psf, " Bytes/sec : %d\n", wav_fmt->min.bytespersec) ; psf->sf.pcmbitwidth = 16 ; psf->bytewidth = 1 ; if (structsize >= 18) { bytesread += psf_binheader_readf (psf, "w", &(wav_fmt->size20.extrabytes)) ; psf_log_printf (psf, " Extra Bytes : %d\n", wav_fmt->size20.extrabytes) ; } ; break ; case WAVE_FORMAT_IMA_ADPCM : if (wav_fmt->min.bitwidth != 4) return SFE_WAV_ADPCM_NOT4BIT ; if (wav_fmt->min.channels < 1 || wav_fmt->min.channels > 2) return SFE_WAV_ADPCM_CHANNELS ; bytesread += psf_binheader_readf (psf, "ww", &(wav_fmt->ima.extrabytes), &(wav_fmt->ima.samplesperblock)) ; bytespersec = (wav_fmt->ima.samplerate * wav_fmt->ima.blockalign) / wav_fmt->ima.samplesperblock ; if (wav_fmt->ima.bytespersec != bytespersec) psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->ima.bytespersec, bytespersec) ; else psf_log_printf (psf, " Bytes/sec : %d\n", wav_fmt->ima.bytespersec) ; psf->sf.pcmbitwidth = 16 ; psf->bytewidth = 2 ; psf_log_printf (psf, " Extra Bytes : %d\n", wav_fmt->ima.extrabytes) ; psf_log_printf (psf, " Samples/Block : %d\n", wav_fmt->ima.samplesperblock) ; break ; case WAVE_FORMAT_MS_ADPCM : if (wav_fmt->msadpcm.bitwidth != 4) return SFE_WAV_ADPCM_NOT4BIT ; if (wav_fmt->msadpcm.channels < 1 || wav_fmt->msadpcm.channels > 2) return SFE_WAV_ADPCM_CHANNELS ; bytesread += psf_binheader_readf (psf, "www", &(wav_fmt->msadpcm.extrabytes), &(wav_fmt->msadpcm.samplesperblock), &(wav_fmt->msadpcm.numcoeffs)) ; bytespersec = (wav_fmt->min.samplerate * wav_fmt->min.blockalign) / wav_fmt->msadpcm.samplesperblock ; if (wav_fmt->min.bytespersec == bytespersec) psf_log_printf (psf, " Bytes/sec : %d\n", wav_fmt->min.bytespersec) ; else if (wav_fmt->min.bytespersec == (wav_fmt->min.samplerate / wav_fmt->msadpcm.samplesperblock) * wav_fmt->min.blockalign) psf_log_printf (psf, " Bytes/sec : %d (should be %d (MS BUG!))\n", wav_fmt->min.bytespersec, bytespersec) ; else psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ; psf->sf.pcmbitwidth = 16 ; psf->bytewidth = 2 ; psf_log_printf (psf, " Extra Bytes : %d\n", wav_fmt->msadpcm.extrabytes) ; psf_log_printf (psf, " Samples/Block : %d\n", wav_fmt->msadpcm.samplesperblock) ; if (wav_fmt->msadpcm.numcoeffs > sizeof (MS_ADPCM_WAV_FMT) / sizeof (int)) { psf_log_printf (psf, " No. of Coeffs : %d ****\n", wav_fmt->msadpcm.numcoeffs) ; wav_fmt->msadpcm.numcoeffs = sizeof (MS_ADPCM_WAV_FMT) / sizeof (int) ; } else psf_log_printf (psf, " No. of Coeffs : %d\n", wav_fmt->msadpcm.numcoeffs) ; psf_log_printf (psf, " Index Coeffs1 Coeffs2\n") ; for (k = 0 ; k < wav_fmt->msadpcm.numcoeffs ; k++) { bytesread += psf_binheader_readf (psf, "ww", &(wav_fmt->msadpcm.coeffs [k].coeff1), &(wav_fmt->msadpcm.coeffs [k].coeff2)) ; snprintf ((char*) psf->buffer, sizeof (psf->buffer), " %2d %7d %7d\n", k, wav_fmt->msadpcm.coeffs [k].coeff1, wav_fmt->msadpcm.coeffs [k].coeff2) ; psf_log_printf (psf, (char*) psf->buffer) ; } ; break ; case WAVE_FORMAT_GSM610 : if (wav_fmt->gsm610.channels != 1 || wav_fmt->gsm610.blockalign != 65) return SFE_WAV_GSM610_FORMAT ; bytesread += psf_binheader_readf (psf, "ww", &(wav_fmt->gsm610.extrabytes), &(wav_fmt->gsm610.samplesperblock)) ; if (wav_fmt->gsm610.samplesperblock != 320) return SFE_WAV_GSM610_FORMAT ; bytespersec = (wav_fmt->gsm610.samplerate * wav_fmt->gsm610.blockalign) / wav_fmt->gsm610.samplesperblock ; if (wav_fmt->gsm610.bytespersec != bytespersec) psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->gsm610.bytespersec, bytespersec) ; else psf_log_printf (psf, " Bytes/sec : %d\n", wav_fmt->gsm610.bytespersec) ; psf->sf.pcmbitwidth = 16 ; psf->bytewidth = 2 ; psf_log_printf (psf, " Extra Bytes : %d\n", wav_fmt->gsm610.extrabytes) ; psf_log_printf (psf, " Samples/Block : %d\n", wav_fmt->gsm610.samplesperblock) ; break ; case WAVE_FORMAT_EXTENSIBLE : if (wav_fmt->ext.bytespersec / wav_fmt->ext.blockalign != wav_fmt->ext.samplerate)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -