📄 wav.c
字号:
return error ; break ; case acid_MARKER : parsestage |= HAVE_other ; psf_binheader_readf (psf, "e4", &dword) ; psf_log_printf (psf, "acid : %u\n", dword) ; if ((error = wav_read_acid_chunk (psf, dword))) return error ; break ; case INFO_MARKER : case LIST_MARKER : parsestage |= HAVE_other ; if ((error = wav_subchunk_parse (psf, marker)) != 0) return error ; break ; case strc_MARKER : /* Multiple of 32 bytes. */ case afsp_MARKER : case bext_MARKER : case clm_MARKER : case plst_MARKER : case DISP_MARKER : case MEXT_MARKER : case PAD_MARKER : parsestage |= HAVE_other ; psf_binheader_readf (psf, "e4", &dword) ; psf_log_printf (psf, "%M : %u\n", marker, dword) ; dword += (dword & 1) ; 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 (psf_ftell (psf) & 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) ; done = SF_TRUE ; break ; } ; /* switch (dword) */ if (! psf->sf.seekable && (parsestage & HAVE_data)) break ; if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (dword)) { psf_log_printf (psf, "End\n") ; break ; } ; if (psf->logindex >= SIGNED_SIZEOF (psf->logbuffer) - 2) return SFE_LOG_OVERRUN ; } ; /* while (1) */ if (! psf->dataoffset) return SFE_WAV_NO_DATA ; psf->endian = SF_ENDIAN_LITTLE ; /* All WAV files are little endian. */ psf_fseek (psf, psf->dataoffset, SEEK_SET) ; if (psf->is_pipe == 0) { /* ** Check for 'wvpk' at the start of the DATA section. Not able to ** handle this. */ psf_binheader_readf (psf, "e4", &marker) ; if (marker == wvpk_MARKER || marker == OggS_MARKER) return SFE_WAV_WVPK_DATA ; } ; /* Seek to start of DATA section. */ psf_fseek (psf, psf->dataoffset, SEEK_SET) ; psf->close = wav_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_EXTENSIBLE : /* compare GUIDs for known ones */ if (wavex_write_guid_equal (&wav_fmt.ext.esf, &MSGUID_SUBTYPE_PCM)) psf->sf.format = SF_FORMAT_WAVEX | u_bitwidth_to_subformat (psf->bytewidth * 8) ; else if (wavex_write_guid_equal (&wav_fmt.ext.esf, &MSGUID_SUBTYPE_MS_ADPCM)) { psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM) ; *blockalign = wav_fmt.msadpcm.blockalign ; *framesperblock = wav_fmt.msadpcm.samplesperblock ; } else if (wavex_write_guid_equal (&wav_fmt.ext.esf, &MSGUID_SUBTYPE_IEEE_FLOAT)) psf->sf.format = SF_FORMAT_WAVEX | ((psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT) ; else if (wavex_write_guid_equal (&wav_fmt.ext.esf, &MSGUID_SUBTYPE_ALAW)) psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ALAW) ; else if (wavex_write_guid_equal (&wav_fmt.ext.esf, &MSGUID_SUBTYPE_MULAW)) psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ULAW) ; else return SFE_UNIMPLEMENTED ; break ; case WAVE_FORMAT_PCM : psf->sf.format = SF_FORMAT_WAV | u_bitwidth_to_subformat (psf->bytewidth * 8) ; break ; case WAVE_FORMAT_MULAW : case IBM_FORMAT_MULAW : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ; break ; case WAVE_FORMAT_ALAW : case IBM_FORMAT_ALAW : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ; break ; case WAVE_FORMAT_MS_ADPCM : psf->sf.format = (SF_FORMAT_WAV | 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_WAV | SF_FORMAT_IMA_ADPCM) ; *blockalign = wav_fmt.ima.blockalign ; *framesperblock = wav_fmt.ima.samplesperblock ; break ; case WAVE_FORMAT_GSM610 : psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ; break ; case WAVE_FORMAT_IEEE_FLOAT : psf->sf.format = SF_FORMAT_WAV ; psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* wav_read_header */static intwav_write_header (SF_PRIVATE *psf, int calc_length){ sf_count_t current ; int fmt_size, k, 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 > 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) ; /* RIFF marker, length, WAVE and 'fmt ' markers. */ if (psf->filelength < 8) psf_binheader_writef (psf, "etm8", RIFF_MARKER, 8) ; else psf_binheader_writef (psf, "etm8", RIFF_MARKER, psf->filelength - 8) ; /* WAVE and 'fmt ' markers. */ psf_binheader_writef (psf, "emm", WAVE_MARKER, fmt_MARKER) ; subformat = psf->sf.format & SF_FORMAT_SUBMASK ; switch (subformat) { case SF_FORMAT_PCM_U8 : case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e4224", 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 = 2 + 2 + 4 + 4 + 2 + 2 ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e4224", 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 = 2 + 2 + 4 + 4 + 2 + 2 ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e4224", 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 = 2 + 2 + 4 + 4 + 2 + 2 ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e4224", 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 = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; /* fmt : size, WAV format type, channels, samplerate, bytespersec */ psf_binheader_writef (psf, "e42244", fmt_size, WAVE_FORMAT_IMA_ADPCM, psf->sf.channels, 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 = 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ; /* fmt : size, WAV format type, channels. */ psf_binheader_writef (psf, "e422", 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 blockalign, framesperblock, bytespersec ; blockalign = WAV_W64_GSM610_BLOCKSIZE ; framesperblock = WAV_W64_GSM610_SAMPLES ; bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; /* fmt chunk. */ fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; /* fmt : size, WAV format type, channels. */ psf_binheader_writef (psf, "e422", 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", blockalign, 0, 2, framesperblock) ; } ; add_fact_chunk = SF_TRUE ; break ; default : return SFE_UNIMPLEMENTED ; } ; if (add_fact_chunk) psf_binheader_writef (psf, "etm48", fact_MARKER, 4, psf->sf.frames) ; if (psf->str_flags & SF_STR_LOCATE_START) wav_write_strings (psf, SF_STR_LOCATE_START) ; if (psf->has_peak && psf->peak_loc == SF_PEAK_START) { psf_binheader_writef (psf, "em4", PEAK_MARKER, sizeof (PEAK_CHUNK) + psf->sf.channels * sizeof (PEAK_POS)) ; psf_binheader_writef (psf, "e44", 1, time (NULL)) ; for (k = 0 ; k < psf->sf.channels ; k++) psf_binheader_writef (psf, "ef4", psf->pchunk->peaks [k].value, psf->pchunk->peaks [k].position) ; } ; psf_binheader_writef (psf, "etm8", data_MARKER, psf->datalength) ; 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 ;} /* wav_write_header */static intwavex_write_guid_equal (const EXT_SUBFORMAT * first, const EXT_SUBFORMAT * second){ return !memcmp (first, second, sizeof (EXT_SUBFORMAT)) ;} /* wavex_write_guid_equal */static voidwavex_write_guid (SF_PRIVATE *psf, const EXT_SUBFORMAT * subformat){ psf_binheader_writef (psf, "e422b", subformat->esf_field1, subformat->esf_field2, subformat->esf_field3, subformat->esf_field4, 8) ;} /* wavex_write_guid */static intwavex_write_header (SF_PRIVATE *psf, int calc_length){ sf_count_t current ; int fmt_size, k, 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 > 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) ; /* RIFF marker, length, WAVE and 'fmt ' markers. */ if (psf->filelength < 8) psf_binheader_writef (psf, "etm8", RIFF_MARKER, 8) ; else psf_binheader_writef (psf, "etm8", RIFF_MARKER, psf->filelength - 8) ; /* WAVE and 'fmt ' markers. */ psf_binheader_writef (psf, "emm", WAVE_MARKER, fmt_MARKER) ; subformat = psf->sf.format & SF_FORMAT_SUBMASK ; /* initial section (same for all, it appears) */ switch (subformat) { case SF_FORMAT_PCM_U8 : case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : case SF_FORMAT_FLOAT : case SF_FORMAT_DOUBLE : case SF_FORMAT_ULAW : case SF_FORMAT_ALAW : fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 4 + 2 + 2 + 8 ; /* fmt : format, channels, samplerate */ psf_binheader_writef (psf, "e4224", fmt_size, WAVE_FORMAT_EXTENSIBLE, 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) ; /* cbSize 22 is sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX) */ psf_binheader_writef (psf, "e2", 22) ; /* wValidBitsPerSample, for our use same as bitwidth as we use it fully */ psf_binheader_writef (psf, "e2", psf->bytewidth * 8) ; if (psf->sf.channels == 2) psf_binheader_writef (psf, "e4", 0x1 | 0x2 ) ; /* dwChannelMask front left and right */ else psf_binheader_writef (psf, "e4", 0) ; /* dwChannelMask = 0 when in doubt */ break ; case SF_FORMAT_MS_ADPCM : /* todo, GUID exists might have different header as per wav_write_header */ default : return SFE_UNIMPLEMENTED ; } ; /* GUI section, different for each */ switch (subformat) { case SF_FORMAT_PCM_U8 : case SF_FORMAT_PCM_16 : case SF_FORMAT_PCM_24 : case SF_FORMAT_PCM_32 : wavex_write_guid (psf, &MSGUID_SUBTYPE_PCM) ; break ; case SF_FORMAT_FLOAT : case SF_FORMAT_DOUBLE : wavex_write_guid (psf, &MSGUID_SUBTYPE_IEEE_FLOAT) ; add_fact_chunk = SF_TRUE ; break ; case SF_FORMAT_ULAW : wavex_write_guid (psf, &MSGUID_SUBTYPE_MULAW) ; add_fact_chunk = SF_TRUE ; break ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -