📄 headers.c
字号:
/* readers/writers for various sound file headers * * -------------------------------- * int mus_header_read (const char *name) * int mus_header_write (const char *name, int type, int in_srate, int in_chans, off_t loc, off_t size_in_samples, int format, const char *comment, int len) * int mus_header_initialize (void) * * Once mus_header_read has been called, the data in it can be accessed through: * * off_t mus_header_samples (void) samples * off_t mus_header_data_location (void) location of data (bytes) * int mus_header_chans (void) channels * int mus_header_srate (void) srate * int mus_header_type (void) header type (i.e. aiff, wave, etc) (see sndlib.h) * int mus_header_format (void) data format (see sndlib.h) * off_t mus_header_comment_start (void) comment start location (if any) (bytes) * off_t mus_header_comment_end (void) comment end location * off_t mus_header_aux_comment_start (int n) if multiple comments, nth start location * off_t mus_header_aux_comment_end (int n) if multiple comments, nth end location * int mus_header_type_specifier (void) original (header-specific) type ID * int mus_header_bits_per_sample (void) sample width in bits * off_t mus_header_true_length (void) true (lseek) file length * int mus_bytes_per_sample (int format) sample width in bytes * bool mus_header_writable(int type, int format) can we write this header * -------------------------------- * * "Linear" below means 2's complement integer. * * Currently supported read/write (in standard data formats): * NeXT/Sun/DEC/AFsp * AIFF/AIFC * RIFF (microsoft wave) * IRCAM (old style) * NIST-sphere * no header * * Currently supported read-only (in selected data formats): * 8SVX (IFF), EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC, CSL, snack "SMP", PVF, * Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I, PSION alaw, MAUD, * Gravis Ultrasound, Comdisco SPW, Goldwave sample, OMF, NVF, * Sonic Foundry, SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample, * Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85 and SY99 (buggy), Yamaha TX16W, * Covox v8, AVI, Kurzweil 2000, Paris Ensoniq, Impulse tracker, Korg, Akai type 4, Maui, * * for a few of these I'm still trying to get documentation -- best sources of info * are ftp.cwi.nl:pub/audio (info files), the AFsp sources, and the SOX sources. * sox and gsm are at ftp.cwi.nl, AFsp is from kabal@Polaris.EE.McGill.CA (Peter Kabal) as * ftp.TSP.EE.McGill.CA:/pub/AFsp/AFsp-V3R2.tar.Z. The Sound Designer formats are described * in the "Developer Documentation" from Digidesign. Other useful sources can be found at * ftp.x.org:/contrib/audio/nas, svr-ftp.eng.cam.ac.uk:/comp.speech/tools, and * at http://www.wotsit.org. I put many of my test cases in * ccrma-ftp.stanford.edu:/pub/Lisp/sf.tar.gz. The RIFF format is described in the * Microsoft Multimedia Programmer's Reference Manual at ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE. * AVI format is described in http://www.rahul.net/jfm/avi.html. * * For a lot of info and examples see http://www.TSP.ECE.McGill.CA/MMSP/Documents/AudioFormats/index.html * * The main problem with compressed sound files is that you can't do reliable * random access to the data, can't easily read backwards, and most of the compression * schemes are proprietary (and appalling), but to translate Mus10/Sam, HCOM, IEEE text, * MIDI sample dumps, various adpcm cases, NIST shortpack files, and AVI see snd-trans.c * in the sound editor (snd-8.tar.gz). * * If anyone has information on any other header or data formats, I would be most interested in it, * but only if it can be included in this file. * * ivc format appears to have 16 bytes of header (-1 5 0 0 0 0 -> mulaw) followed by mulaw or alaw data */#include <mus-config.h>#if USE_SND #include "snd.h"#else #if HAVE_RUBY && (!CLM) #include "xen.h" #endif#endif#include <math.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#if HAVE_STRING_H #include <string.h>#endif#if (defined(HAVE_LIBC_H) && (!defined(HAVE_UNISTD_H))) #include <libc.h>#else #if (!(defined(_MSC_VER))) #include <unistd.h> #endif#endif#include "_sndlib.h"#include "sndlib-strings.h"static bool hdrbuf_is_inited = false;#define HDRBUFSIZ 256static unsigned char *hdrbuf;#define INITIAL_READ_SIZE 32/* AIFF files can have any number of ANNO chunks, so we'll grab at least 4 of them */#define AUX_COMMENTS 4static off_t *aux_comment_start = NULL, *aux_comment_end = NULL;#define LOOPS 2static int *loop_modes = NULL, *loop_starts = NULL, *loop_ends = NULL;static int markers = 0;static int *marker_ids = NULL, *marker_positions = NULL;/* for CLM */void mus_reset_headers_c(void) { hdrbuf_is_inited = false; markers = 0;}int mus_header_initialize(void){ if (!hdrbuf_is_inited) { hdrbuf_is_inited = true; hdrbuf = (unsigned char *)CALLOC(HDRBUFSIZ, sizeof(unsigned char)); aux_comment_start = (off_t *)CALLOC(AUX_COMMENTS, sizeof(off_t)); aux_comment_end = (off_t *)CALLOC(AUX_COMMENTS, sizeof(off_t)); loop_modes = (int *)CALLOC(LOOPS, sizeof(int)); loop_starts = (int *)CALLOC(LOOPS, sizeof(int)); loop_ends = (int *)CALLOC(LOOPS, sizeof(int)); if ((hdrbuf == NULL) || (aux_comment_start == NULL) || (aux_comment_end == NULL) || (loop_modes == NULL) || (loop_starts == NULL) || (loop_ends == NULL)) return(mus_error(MUS_MEMORY_ALLOCATION_FAILED, "mus_header_initialize: buffer allocation failed")); } return(MUS_NO_ERROR);}static const unsigned char I_DSND[4] = {'.','s','n','d'}; /* NeXT/Sun/Dec/SGI/AFsp first word */static const unsigned char I_FORM[4] = {'F','O','R','M'}; /* AIFF first word */static const unsigned char I_AIFF[4] = {'A','I','F','F'}; /* AIFF second word */static const unsigned char I_AIFC[4] = {'A','I','F','C'}; /* ditto but might be compressed data */static const unsigned char I_COMM[4] = {'C','O','M','M'};static const unsigned char I_COMT[4] = {'C','O','M','T'};static const unsigned char I_INFO[4] = {'I','N','F','O'};static const unsigned char I_INST[4] = {'I','N','S','T'};static const unsigned char I_inst[4] = {'i','n','s','t'}; /* RIFF wants lower case, just to be different */static const unsigned char I_MARK[4] = {'M','A','R','K'};static const unsigned char I_SSND[4] = {'S','S','N','D'};static const unsigned char I_FVER[4] = {'F','V','E','R'};static const unsigned char I_NONE[4] = {'N','O','N','E'};static const unsigned char I_ULAW[4] = {'U','L','A','W'}; /* AIFC compression types that we can handle */static const unsigned char I_ulaw[4] = {'u','l','a','w'}; /* or maybe it's lowercase (Apple) ... */static const unsigned char I_ima4[4] = {'i','m','a','4'}; /* AIFC IMA adpcm apparently */static const unsigned char I_raw_[4] = {'r','a','w',' '}; /* AIFC offset binary OS 8.5 (others are 'MAC3' 'MAC6' 'cdx4' 'cdx2' 'str4') */static const unsigned char I_sowt[4] = {'s','o','w','t'}; /* AIFC 16-bit little endian -- used by Mac when extracting CD tracks */static const unsigned char I_in32[4] = {'i','n','3','2'}; /* AIFC */static const unsigned char I_in24[4] = {'i','n','2','4'}; /* AIFC */static const unsigned char I_ni23[4] = {'n','i','2','3'}; /* AIFC */static const unsigned char I_fl32[4] = {'f','l','3','2'}; /* AIFC 32-bit float */static const unsigned char I_FL32[4] = {'F','L','3','2'}; /* AIFC 32-bit float (apparently used by CSound and SoundHack) */static const unsigned char I_fl64[4] = {'f','l','6','4'}; /* AIFC 64-bit float */static const unsigned char I_twos[4] = {'t','w','o','s'}; /* AIFC big endian? */static const unsigned char I_ALAW[4] = {'A','L','A','W'};static const unsigned char I_alaw[4] = {'a','l','a','w'}; /* apple */static const unsigned char I_APPL[4] = {'A','P','P','L'};static const unsigned char I_MUS_[4] = {'C','L','M',' '}; /* I hereby claim this AIFF chunk name */static const unsigned char I_RIFF[4] = {'R','I','F','F'}; /* RIFF first word */static const unsigned char I_RIFX[4] = {'R','I','F','X'}; /* RIFX first word (big-endian RIFF file) */static const unsigned char I_WAVE[4] = {'W','A','V','E'};static const unsigned char I_fmt_[4] = {'f','m','t',' '};static const unsigned char I_data[4] = {'d','a','t','a'};static const unsigned char I_fact[4] = {'f','a','c','t'}; /* used by compressed RIFF files */static const unsigned char I_clm_[4] = {'c','l','m',' '};static const unsigned char I_NIST[4] = {'N','I','S','T'}; /* first word of NIST SPHERE files */static const unsigned char I_8SVX[4] = {'8','S','V','X'}; /* AIFF other choice */static const unsigned char I_16SV[4] = {'1','6','S','V'}; /* hmmm... 16-bit 8svx? */static const unsigned char I_VOC0[4] = {'C','r','e','a'}; /* Actual text is "Creative Voice File" */static const unsigned char I_VOC1[4] = {'t','i','v','e'};static const unsigned char I_SOUN[4] = {'S','O','U','N'}; /* Sound Tools first word="SOUND" -- not unique as SMP files start with "SOUND SAMPLE" */static const unsigned char I_D_SA[4] = {'D',' ','S','A'};static const unsigned char I_MPLE[4] = {'M','P','L','E'};static const unsigned char I_BODY[4] = {'B','O','D','Y'}; /* next 4 for 8svx chunk names */static const unsigned char I_VHDR[4] = {'V','H','D','R'};static const unsigned char I_CHAN[4] = {'C','H','A','N'};static const unsigned char I_ANNO[4] = {'A','N','N','O'};static const unsigned char I_NAME[4] = {'N','A','M','E'};static const unsigned char I_AVR_[4] = {'2','B','I','T'}; /* first word of AVR files */static const unsigned char I_HCOM[4] = {'H','C','O','M'};static const unsigned char I_FSSD[4] = {'F','S','S','D'};static const unsigned char I_SPIB[4] = {'%','/','/','\n'}; /* first word of IEEE spib text sound files */static const unsigned char I_S___[4] = {'%','-','-','-'}; /* first word of other IEEE spib text sound files */static const unsigned char I_ALaw[4] = {'A','L','a','w'}; /* first word of PSION alaw files */static const unsigned char I_Soun[4] = {'S','o','u','n'}; /* second */static const unsigned char I_MAUD[4] = {'M','A','U','D'}; /* MAUD specialization of AIFF */static const unsigned char I_MHDR[4] = {'M','H','D','R'};static const unsigned char I_MDAT[4] = {'M','D','A','T'};static const unsigned char I_mdat[4] = {'m','d','a','t'}; /* quicktime */static const unsigned char I_MThd[4] = {'M','T','h','d'}; /* sigh -- the M word */static const unsigned char I_DECN[4] = {'.','s','d','\0'}; /* first word of DEC files (?) */static const unsigned char I_sfbk[4] = {'s','f','b','k'}; /* SoundFont 2.0 */static const unsigned char I_sdta[4] = {'s','d','t','a'};static const unsigned char I_shdr[4] = {'s','h','d','r'};static const unsigned char I_pdta[4] = {'p','d','t','a'};static const unsigned char I_LIST[4] = {'L','I','S','T'};static const unsigned char I_GF1P[4] = {'G','F','1','P'}; /* first word of Gravis Ultrsound patch files */static const unsigned char I_ATCH[4] = {'A','T','C','H'}; /* second word */static const unsigned char I_DSIG[4] = {'$','S','I','G'}; /* first word of Comdisco SPW file */static const unsigned char I_NAL_[4] = {'N','A','L','_'}; /* second word */static const unsigned char I_GOLD[4] = {'G','O','L','D'}; /* first word Goldwave(?) sample file */static const unsigned char I__WAV[4] = {' ','S','A','M'}; /* second word */static const unsigned char I_SRFS[4] = {'S','R','F','S'}; /* first word Sonic Resource Foundry file(?) */static const unsigned char I_Diam[4] = {'D','i','a','m'}; /* first word DiamondWare file */static const unsigned char I_ondW[4] = {'o','n','d','W'}; /* second word */static const unsigned char I_CSRE[4] = {'C','S','R','E'}; /* adf first word -- second starts with "40" */static const unsigned char I_SND_[4] = {'S','N','D',' '}; /* SBStudio II */static const unsigned char I_SNIN[4] = {'S','N','I','N'};static const unsigned char I_SNNA[4] = {'S','N','N','A'};static const unsigned char I_SNDT[4] = {'S','N','D','T'};static const unsigned char I_DDSF[4] = {'D','D','S','F'}; /* Delusion Digital Sound File */static const unsigned char I_FSMt[4] = {'F','S','M',(unsigned char)'\376'}; /* Farandole Composer WaveSample */static const unsigned char I_SDXc[4] = {'S','D','X',':'}; /* Sample dump exchange format */static const unsigned char I_UWFD[4] = {'U','W','F','D'}; /* Ultratracker Wavesample */static const unsigned char I_LM89[4] = {'L','M','8','9'}; /* Yamaha TX-16 */static const unsigned char I_SY80[4] = {'S','Y','8','0'}; /* Yamaha SY-99 */static const unsigned char I_SY85[4] = {'S','Y','8','5'}; /* Yamaha SY-85 */static const unsigned char I_SCRS[4] = {'S','C','R','S'}; /* Digiplayer ST3 */static const unsigned char I_covox[4] = {(unsigned char)'\377','\125',(unsigned char)'\377',(unsigned char)'\252'};/* static const unsigned char I_DSPL[4] = {'D','S','P','L'}; */ /* Digitracker SPL (now obsolete) */static const unsigned char I_AVI_[4] = {'A','V','I',' '}; /* RIFF AVI */static const unsigned char I_strf[4] = {'s','t','r','f'}; static const unsigned char I_movi[4] = {'m','o','v','i'}; static const unsigned char I_PRAM[4] = {'P','R','A','M'}; /* Kurzweil 2000 */static const unsigned char I_ones[4] = {(unsigned char)'\377',(unsigned char)'\377',(unsigned char)'\377',(unsigned char)'\377'};static const unsigned char I_zeros[4] = {'\0','\0','\0','\0'};static const unsigned char I_asf0[4] = {(unsigned char)'\321','\051',(unsigned char)'\342',(unsigned char)'\326'};static const unsigned char I_asf1[4] = {(unsigned char)'\332','\065',(unsigned char)'\321','\021'};static const unsigned char I_asf2[4] = {(unsigned char)'\220','\064','\000',(unsigned char)'\240'};static const unsigned char I_asf3[4] = {(unsigned char)'\311','\003','\111',(unsigned char)'\276'};static const unsigned char I__PAF[4] = {' ','p','a','f'}; /* Paris Ensoniq */static const unsigned char I_FAP_[4] = {'f','a','p',' '}; /* Paris Ensoniq */static const unsigned char I_DS16[4] = {'D','S','1','6'}; /* CSL */static const unsigned char I_HEDR[4] = {'H','E','D','R'}; static const unsigned char I_HDR8[4] = {'H','D','R','8'}; static const unsigned char I_SDA_[4] = {'S','D','A','_'}; static const unsigned char I_SDAB[4] = {'S','D','A','B'}; static const unsigned char I_SD_B[4] = {'S','D','_','B'}; static const unsigned char I_NOTE[4] = {'N','O','T','E'}; static const unsigned char I_file[4] = {'f','i','l','e'}; /* snack "SMP" */static const unsigned char I__sam[4] = {'=','s','a','m'}; static const unsigned char I_SU7M[4] = {'S','U','7','M'}; static const unsigned char I_SU7R[4] = {'S','U','7','R'}; static const unsigned char I_PVF1[4] = {'P','V','F','1'}; /* portable voice format (mgetty) */static const unsigned char I_PVF2[4] = {'P','V','F','2'};static const unsigned char I_AUTH[4] = {'A','U','T','H'};static const unsigned char I_riff[4] = {'r','i','f','f'}; /* SoundForge */static const unsigned char I_TWIN[4] = {'T','W','I','N'}; /* TwinVQ */static const unsigned char I_IMPS[4] = {'I','M','P','S'}; /* Impulse Tracker */static const unsigned char I_SMP1[4] = {'S','M','P','1'}; /* Korg */static const unsigned char I_Maui[4] = {'M','a','u','i'}; /* Turtle Beach */static const unsigned char I_SDIF[4] = {'S','D','I','F'}; /* IRCAM sdif */static const unsigned char I_NVF_[4] = {'N','V','F',' '}; /* Nomad II Creative NVF */static const unsigned char I_VFMT[4] = {'V','F','M','T'}; /* Nomad II Creative NVF */static const unsigned char I_OggS[4] = {'O','g','g','S'}; /* Ogg-related files, apparently -- ogg123 has "vorbis" instead of "Speex" */static const unsigned char I_fLaC[4] = {'f','L','a','C'}; /* FLAC */static const unsigned char I_ajkg[4] = {'a','j','k','g'}; /* shorten */static const unsigned char I_TTA1[4] = {'T','T','A','1'}; /* ttaenc */static const unsigned char I_wvpk[4] = {'w','v','p','k'}; /* wavpack */#define I_IRCAM_VAX 0x0001a364#define I_IRCAM_SUN 0x0002a364#define I_IRCAM_MIPS 0x0003a364#define I_IRCAM_NEXT 0x0004a364#define NINRS 7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -