📄 wav.c
字号:
psf->read_int = (func_int) wav_read_x86f2i ; psf->read_double = (func_double) wav_read_x86f2d ; } ; return 0 ; default : return SFE_UNIMPLEMENTED ; } ; psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_PCM) ; switch (psf->bytewidth) { case 1 : psf->read_short = (func_short) pcm_read_uc2s ; psf->read_int = (func_int) pcm_read_uc2i ; psf->read_double = (func_double) pcm_read_uc2d ; break ; case 2 : psf->read_short = (func_short) pcm_read_les2s ; psf->read_int = (func_int) pcm_read_les2i ; psf->read_double = (func_double) pcm_read_les2d ; break ; case 3 : psf->read_short = (func_short) pcm_read_let2s ; psf->read_int = (func_int) pcm_read_let2i ; psf->read_double = (func_double) pcm_read_let2d ; break ; case 4 : psf->read_short = (func_short) pcm_read_lei2s ; psf->read_int = (func_int) pcm_read_lei2i ; psf->read_double = (func_double) pcm_read_lei2d ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* wav_open_read *//*------------------------------------------------------------------------------ */int wav_open_write (SF_PRIVATE *psf){ WAV_FMT wav_fmt ; unsigned int dword, 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 ; wav_fmt.min.channels = psf->sf.channels ; wav_fmt.min.samplerate = psf->sf.samplerate ; wav_fmt.min.bytespersec = psf->sf.samplerate * psf->bytewidth * psf->sf.channels ; wav_fmt.min.blockalign = psf->bytewidth * psf->sf.channels ; wav_fmt.min.bitwidth = psf->sf.pcmbitwidth ; switch (psf->sf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM : wav_fmt.format = WAVE_FORMAT_PCM ; psf->dataoffset = 7 * sizeof (dword) + sizeof (MIN_WAV_FMT) ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (MIN_WAV_FMT), 0) ; break ; case SF_FORMAT_FLOAT : wav_fmt.format = WAVE_FORMAT_IEEE_FLOAT ; psf->dataoffset = 9 * sizeof (dword) + sizeof (MIN_WAV_FMT) + sizeof (FACT_CHUNK) ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (MIN_WAV_FMT), 1) ; break ; case SF_FORMAT_ULAW : wav_fmt.format = WAVE_FORMAT_MULAW ; wav_fmt.size20.bitwidth = 8 ; wav_fmt.size20.extrabytes = 2 ; wav_fmt.size20.dummy = 0 ; psf->dataoffset = 9 * sizeof (dword) + sizeof (WAV_FMT_SIZE20) + sizeof (FACT_CHUNK) ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (WAV_FMT_SIZE20), 1) ; break ; case SF_FORMAT_ALAW : wav_fmt.format = WAVE_FORMAT_ALAW ; wav_fmt.size20.bitwidth = 8 ; wav_fmt.size20.extrabytes = 2 ; wav_fmt.size20.dummy = 0 ; psf->dataoffset = 9 * sizeof (dword) + sizeof (WAV_FMT_SIZE20) + sizeof (FACT_CHUNK) ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (WAV_FMT_SIZE20), 1) ; break ; case SF_FORMAT_IMA_ADPCM : wav_fmt.format = WAVE_FORMAT_IMA_ADPCM ; if ((error = wav_ima_writer_init (psf, &wav_fmt))) return error ; psf->dataoffset = 9 * sizeof (dword) + sizeof (IMA_ADPCM_WAV_FMT) + sizeof (FACT_CHUNK) ; if (psf->sf.samples % wav_fmt.ima.samplesperblock) psf->datalength = ((psf->sf.samples / wav_fmt.ima.samplesperblock) + 1) * wav_fmt.ima.samplesperblock ; else psf->datalength = psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (IMA_ADPCM_WAV_FMT), 1) ; break ; case SF_FORMAT_MS_ADPCM : wav_fmt.format = WAVE_FORMAT_MS_ADPCM ; msadpcm_writer_init (psf, &wav_fmt) ; psf->dataoffset = 9 * sizeof (dword) + sizeof (MS_ADPCM_WAV_FMT) + sizeof (FACT_CHUNK) ; if (psf->sf.samples % wav_fmt.msadpcm.samplesperblock) psf->datalength = ((psf->sf.samples / wav_fmt.msadpcm.samplesperblock) + 1) * wav_fmt.msadpcm.samplesperblock ; else psf->datalength = psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (MS_ADPCM_WAV_FMT), 1) ; break ; case SF_FORMAT_GSM610 : wav_fmt.format = WAVE_FORMAT_GSM610 ; wav_gsm610_writer_init (psf, &wav_fmt) ; psf->dataoffset = 9 * sizeof (dword) + sizeof (GSM610_WAV_FMT) + sizeof (FACT_CHUNK) ; if (psf->sf.samples % wav_fmt.gsm610.samplesperblock) psf->datalength = ((psf->sf.samples / wav_fmt.gsm610.samplesperblock) + 1) * wav_fmt.gsm610.samplesperblock ; else psf->datalength = psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; write_header (psf, &wav_fmt, sizeof (GSM610_WAV_FMT), 1) ; break ; default : return SFE_UNIMPLEMENTED ; } ; dword = data_MARKER ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = H2LE_INT (psf->datalength) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; psf->close = (func_close) wav_close ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_FLOAT) ; if (CAN_READ_WRITE_x86_IEEE) { psf->write_short = (func_short) pcm_write_s2f ; psf->write_int = (func_int) pcm_write_i2f ; psf->write_double = (func_double) pcm_write_d2f ; } else { psf->write_short = (func_short) wav_write_s2x86f ; psf->write_int = (func_int) wav_write_i2x86f ; psf->write_double = (func_double) wav_write_d2x86f ; } ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_IMA_ADPCM) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ; psf->write_short = (func_short) ima_write_s ; psf->write_int = (func_int) ima_write_i ; psf->write_double = (func_double) ima_write_d ; psf->seek_func = (func_seek) ima_seek ; psf->close = (func_close) wav_ima_close ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_MS_ADPCM) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ; psf->write_short = (func_short) msadpcm_write_s ; psf->write_int = (func_int) msadpcm_write_i ; psf->write_double = (func_double) msadpcm_write_d ; psf->seek_func = (func_seek) msadpcm_seek ; psf->close = (func_close) msadpcm_close ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_GSM610) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ; psf->write_short = (func_short) wav_gsm610_write_s ; psf->write_int = (func_int) wav_gsm610_write_i ; psf->write_double = (func_double) wav_gsm610_write_d ; psf->seek_func = NULL ; /* Not seekable */ psf->close = (func_close) wav_gsm610_close ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_ULAW) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ; psf->write_short = (func_short) ulaw_write_s2ulaw ; psf->write_int = (func_int) ulaw_write_i2ulaw ; psf->write_double = (func_double) ulaw_write_d2ulaw ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_ALAW) { psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ; psf->write_short = (func_short) alaw_write_s2alaw ; psf->write_int = (func_int) alaw_write_i2alaw ; psf->write_double = (func_double) alaw_write_d2alaw ; return 0 ; } ; if ((psf->sf.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM) return SFE_UNIMPLEMENTED ; switch (psf->bytewidth) { case 1 : psf->write_short = (func_short) pcm_write_s2uc ; psf->write_int = (func_int) pcm_write_i2uc ; psf->write_double = (func_double) pcm_write_d2uc ; break ; case 2 : psf->write_short = (func_short) pcm_write_s2les ; psf->write_int = (func_int) pcm_write_i2les ; psf->write_double = (func_double) pcm_write_d2les ; break ; case 3 : psf->write_short = (func_short) pcm_write_s2let ; psf->write_int = (func_int) pcm_write_i2let ; psf->write_double = (func_double) pcm_write_d2let ; break ; case 4 : psf->write_short = (func_short) pcm_write_s2lei ; psf->write_int = (func_int) pcm_write_i2lei ; psf->write_double = (func_double) pcm_write_d2lei ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* wav_open_write *//*------------------------------------------------------------------------------ */int wav_close (SF_PRIVATE *psf){ unsigned int dword ; 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->filelength = ftell (psf->file) ; /* Fix RIFF size. */ dword = H2LE_INT (psf->filelength - 2 * sizeof (dword)) ; fseek (psf->file, sizeof (dword), SEEK_SET) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; psf->datalength = psf->filelength - psf->dataoffset ; psf->sf.samples = psf->datalength / (psf->sf.channels * psf->bytewidth) ; fseek (psf->file, (int) (psf->dataoffset - sizeof (dword)), SEEK_SET) ; dword = H2LE_INT (psf->datalength) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; } ; if (psf->fdata) free (psf->fdata) ; psf->fdata = NULL ; return 0 ;} /* wav_close *//*========================================================================= * Private functions. */staticint read_fmt_chunk (SF_PRIVATE *psf, WAV_FMT *wav_fmt){ unsigned int dword, bytesread, k, structsize, bytespersec = 0 ; memset (wav_fmt, 0, sizeof (WAV_FMT)) ; bytesread = 0 ; fread (&dword, sizeof (dword), 1, psf->file) ; structsize = LE2H_INT (dword) ; psf_sprintf (psf, "fmt : %d\n", structsize) ; if (structsize < 16) return SFE_WAV_FMT_SHORT ; if (structsize > sizeof (WAV_FMT)) return SFE_WAV_FMT_TOO_BIG ; fread (wav_fmt, structsize, 1, psf->file) ; bytesread += structsize ; if (CPU_IS_BIG_ENDIAN) le2h_wav_fmt (wav_fmt) ; psf_sprintf (psf, " Format : 0x%X => %s\n", wav_fmt->format, wav_format_str (wav_fmt->format)) ; psf_sprintf (psf, " Channels : %d\n", wav_fmt->min.channels) ; psf_sprintf (psf, " Sample Rate : %d\n", wav_fmt->min.samplerate) ; psf_sprintf (psf, " Block Align : %d\n", wav_fmt->min.blockalign) ; psf_sprintf (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_sprintf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -