📄 aiff.c
字号:
done = 1 ; break ; } ; /* switch (marker) */ if (ferror (psf->file)) { psf_sprintf (psf, "*** Error on file handle. ***\n") ; clearerr (psf->file) ; break ; } ; if (ftell (psf->file) >= (off_t) (psf->filelength - (2 * sizeof (dword)))) break ; } ; /* while (1) */ if (! psf->dataoffset) return SFE_AIFF_NO_DATA ; psf->current = 0 ; psf->endian = SF_ENDIAN_BIG ; /* All AIF* files are big endian. */ psf->sf.seekable = SF_TRUE ; psf->bytewidth = BITWIDTH2BYTES (psf->sf.pcmbitwidth) ; psf->blockwidth = psf->sf.channels * psf->bytewidth ; fseek (psf->file, psf->dataoffset, SEEK_SET) ; psf->close = (func_close) aiff_close ; switch (psf->bytewidth) { case 1 : psf->read_short = (func_short) pcm_read_sc2s ; psf->read_int = (func_int) pcm_read_sc2i ; psf->read_double = (func_double) pcm_read_sc2d ; break ; case 2 : psf->read_short = (func_short) pcm_read_bes2s ; psf->read_int = (func_int) pcm_read_bes2i ; psf->read_double = (func_double) pcm_read_bes2d ; break ; case 3 : psf->read_short = (func_short) pcm_read_bet2s ; psf->read_int = (func_int) pcm_read_bet2i ; psf->read_double = (func_double) pcm_read_bet2d ; break ; case 4 : psf->read_short = (func_short) pcm_read_bei2s ; psf->read_int = (func_int) pcm_read_bei2i ; psf->read_double = (func_double) pcm_read_bei2d ; break ; default : /* printf ("Weird bytewidth (%d)\n", psf->bytewidth) ; */ return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* aiff_open_read *//*------------------------------------------------------------------------------ */int aiff_open_write (SF_PRIVATE *psf){ COMM_CHUNK comm_fmt ; SSND_CHUNK ssnd_fmt ; unsigned int dword, FORMsize ; if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AIFF) return SFE_BAD_OPEN_FORMAT ; if ((psf->sf.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM) return SFE_BAD_OPEN_FORMAT ; psf->endian = SF_ENDIAN_BIG ; /* All AIF* files are big endian. */ psf->sf.seekable = SF_TRUE ; psf->bytewidth = BITWIDTH2BYTES (psf->sf.pcmbitwidth) ; psf->blockwidth = psf->bytewidth * psf->sf.channels ; psf->dataoffset = 5 * sizeof (dword) + REAL_COMM_SIZE + 4 * sizeof (dword) ; psf->datalength = psf->blockwidth * psf->sf.samples ; psf->filelength = psf->datalength + psf->dataoffset ; psf->error = 0 ; FORMsize = 0x7FFFFFFF ; /* Correct this when closing file. */ comm_fmt.numChannels = psf->sf.channels ; comm_fmt.numSampleFrames = psf->sf.samples ; comm_fmt.sampleSize = psf->sf.pcmbitwidth ; uint2tenbytefloat (psf->sf.samplerate, comm_fmt.sampleRate) ; if (CPU_IS_LITTLE_ENDIAN) endswap_comm_fmt (&comm_fmt) ; ssnd_fmt.offset = 0 ; ssnd_fmt.blocksize = 0 ; /* Not normally used. */ if (CPU_IS_LITTLE_ENDIAN) endswap_ssnd_fmt (&ssnd_fmt) ; dword = FORM_MARKER ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = H2BE_INT (FORMsize) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = AIFF_MARKER ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = COMM_MARKER ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = H2BE_INT (REAL_COMM_SIZE) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; fwrite (&(comm_fmt.numChannels), sizeof (comm_fmt.numChannels), 1, psf->file) ; fwrite (&(comm_fmt.numSampleFrames), sizeof (comm_fmt.numSampleFrames), 1, psf->file) ; fwrite (&(comm_fmt.sampleSize), sizeof (comm_fmt.sampleSize), 1, psf->file) ; fwrite (&(comm_fmt.sampleRate), sizeof (comm_fmt.sampleRate), 1, psf->file) ; dword = SSND_MARKER ; fwrite (&dword, sizeof (dword), 1, psf->file) ; dword = H2BE_INT (psf->datalength + sizeof (SSND_CHUNK)) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; fwrite (&ssnd_fmt, sizeof (ssnd_fmt), 1, psf->file) ; psf->close = (func_close) aiff_close ; switch (psf->bytewidth) { case 1 : psf->write_short = (func_short) pcm_write_s2sc ; psf->write_int = (func_int) pcm_write_i2sc ; psf->write_double = (func_double) pcm_write_d2sc ; break ; case 2 : psf->write_short = (func_short) pcm_write_s2bes ; psf->write_int = (func_int) pcm_write_i2bes ; psf->write_double = (func_double) pcm_write_d2bes ; break ; case 3 : psf->write_short = (func_short) pcm_write_s2bet ; psf->write_int = (func_int) pcm_write_i2bet ; psf->write_double = (func_double) pcm_write_d2bet ; break ; case 4 : psf->write_short = (func_short) pcm_write_s2bei ; psf->write_int = (func_int) pcm_write_i2bei ; psf->write_double = (func_double) pcm_write_d2bei ; break ; default : return SFE_UNIMPLEMENTED ; } ; return 0 ;} /* aiff_open_write *//*------------------------------------------------------------------------------ */int aiff_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 FORM, COMM and SSND chunks. */ fseek (psf->file, 0, SEEK_END) ; psf->filelength = ftell (psf->file) ; dword = psf->filelength - 2 * sizeof (dword) ; fseek (psf->file, sizeof (dword), SEEK_SET) ; dword = H2BE_INT (dword) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; /* FORM */ fseek (psf->file, psf->dataoffset - (long)((sizeof (SSND_CHUNK) + sizeof (dword))), SEEK_SET) ; psf->datalength = psf->filelength - psf->dataoffset ; dword = H2BE_INT (psf->datalength + sizeof (SSND_CHUNK)) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; /* SSND */ fseek (psf->file, 5 * sizeof (dword) + sizeof (short), SEEK_SET) ; dword = psf->datalength / (psf->bytewidth * psf->sf.channels) ; dword = H2BE_INT (dword) ; fwrite (&dword, sizeof (dword), 1, psf->file) ; /* COMM.numSampleFrames */ } ; if (psf->fdata) free (psf->fdata) ; psf->fdata = NULL ; return 0 ;} /* aiff_close *//*==========================================================================================** Rough hack at converting from 80 bit IEEE float in AIFF header to an int and** back again. It assumes that all sample rates are between 1 and 800MHz, which ** should be OK as other sound file formats use a 32 bit integer to store sample ** rate.** There is another (probably better) version in the source code to the SoX but it** has a copyright which probably prevents it from being allowable as GPL/LGPL.*/staticint tenbytefloat2int (unsigned char *bytes){ int val = 3 ; if (bytes [0] & 0x80) /* Negative number. */ return 0 ; if (bytes [0] <= 0x3F) /* Less than 1. */ return 1 ; if (bytes [0] > 0x40) /* Way too big. */ return 0x4000000 ; if (bytes [0] == 0x40 && bytes [1] > 0x1C) /* Too big. */ return 800000000 ; /* Ok, can handle it. */ val = (bytes [2] << 23) | (bytes [3] << 15) | (bytes [4] << 7) | (bytes [5] >> 1) ; val >>= (29 - bytes [1]) ; return val ;} /* tenbytefloat2int */staticvoid uint2tenbytefloat (unsigned int num, unsigned char *bytes){ int count, mask = 0x40000000 ; memset (bytes, 0, 10) ; if (num <= 1) { bytes [0] = 0x3F ; bytes [1] = 0xFF ; bytes [2] = 0x80 ; return ; } ; bytes [0] = 0x40 ; if (num >= mask) { bytes [1] = 0x1D ; return ; } ; for (count = 0 ; count <= 32 ; count ++) { if (num & mask) break ; mask >>= 1 ; } ; num <<= count + 1 ; bytes [1] = 29 - count ; bytes [2] = (num >> 24) & 0xFF ; bytes [3] = (num >> 16) & 0xFF ; bytes [4] = (num >> 8) & 0xFF ; bytes [5] = num & 0xFF ; } /* uint2tenbytefloat */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -