📄 adin_file.c
字号:
/** * @file adin_file.c * @author Akinobu LEE * @date Sun Feb 13 13:31:20 2005 * * <JA> * @brief ファイル掐蜗¨WAV/RAWファイルおよび筛洁掐蜗からの粕み哈み * * 不兰ファイルからの掐蜗を乖なう簇眶ですˉサポ〖トしているファイル妨及は * Microsoft WAVE妨及の不兰ファイル·およびヘッダ痰し∈RAW∷ファイルですˉ * オ〖ディオ妨及は·痰暗教PCM·16bit·モノラルに嘎られていますˉ * RAWファイルの眷圭·デ〖タのバイトオ〖ダ〖が big endian であることを * 涟捏としていますので·庙罢してくださいˉ * * ファイルのサンプリングレ〖トはシステムの妥滇するサンプリングレ〖ト * ∈adin_standby() で回年される猛∷と办米する涩妥がありますˉ * WAVE妨及のファイルの眷圭は· * ファイルのサンプリングレ〖トがこの回年猛と办米しなければエラ〖となりますˉ * RAWファイル掐蜗の眷圭は·ファイルにヘッダ攫鼠が痰く峡不箕の * サンプリングレ〖トが稍汤なため·チェック痰しでファイルの * サンプリングレ〖トが adin_standby() で回年された猛である * と簿年して借妄されますˉ * * 掐蜗ファイル叹は·筛洁掐蜗から粕み哈まれますˉ * ファイル叹を误刁したファイルリストファイルが回年された眷圭· * そのファイルから掐蜗ファイル叹が界肌粕み哈まれますˉ * * libsndfile を蝗脱する眷圭·adin_sndfile.c 柒の簇眶が蝗脱されますˉ * この眷圭·このファイルの簇眶は蝗脱されませんˉ * * このファイル柒では int を 4byte, short を 2byte と簿年していますˉ * </JA> * <EN> * @brief Audio input from file or stdin * * Functions to get input from wave file or standard input. * Two file formats are supported, Microsoft WAVE format and RAW (no header) * format. The audio format should be uncompressed PCM, 16bit, monoral. * On RAW file input, the data byte order must be in big endian. * * The sampling rate of input file must be equal to the system requirement * value which is specified by adin_standby() . For WAVE format file, * the sampling rate of the input file described in its header is checked * against the system value, and rejected if not matched. But for RAW format * file, no check will be applied since it has no header information about * the recording sampling rate, so be careful of the sampling rate setting. * * When file input mode, the file name will be read from standard input. * If a filelist file is specified, the file names are read from the file * sequencially instead. * * When compiled with libsndfile support, the functions in adin_sndfile.c * is used for file input instead of functions below. * * In this file, assume sizeof(int)=4, sizeof(short)=2 * </EN> * * $Revision: 1.3 $ * *//* * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology * All rights reserved */#include <sent/stddefs.h>#include <sent/speech.h>#include <sent/adin.h>static FILE *gfp; ///< File pointer of current input filestatic boolean wav_p; ///< TRUE if input is WAVE file, FALSE if RAW filestatic int maxlen; ///< Number of samples, described in the header of WAVE filestatic int nowlen; ///< Current number of read samples/** * When file input, the first 4 bytes of the file are read at first to * identify whether it is WAVE file format. This work area is used to * keep back the 4 bytes if the input is actually a RAW format. */static SP16 pre_data[2];static boolean has_pre; ///< TRUE if pre_data is availablestatic unsigned int sfreq; ///< Sampling frequency in Hz, specified by adin_standby()/* read .wav data with endian conversion *//* (all .wav datas are in little endian) *//** * Read a header value from WAVE file with endian conversion. * If required number of data has not been read, it produces error. * * @param buf [out] Pointer to store read data * @param unitbyte [in] Unit size * @param unitnum [in] Required number of units to read * @param fp [in] File pointer * * @return TRUE on success, FALSE if required number of data has not been read. */static booleanmyread(void *buf, size_t unitbyte, int unitnum, FILE *fp){ int tmp; if ((tmp = myfread(buf, unitbyte, unitnum, fp)) < unitnum) { return(FALSE); }#ifdef WORDS_BIGENDIAN swap_bytes(buf, unitbyte, unitnum);#endif return(TRUE);}/// Abbreviation for header reading#define MYREAD(A,B,C,D) if (!myread(A, B, C, D)) {j_printerr("adin_file: file is corrupted\n"); return -1;}/** * @brief Parse header part of a WAVE file to prepare for data reading * * The audio format will be checked here, and data length is also read from * the header. Then the pointer is moved to the start point of data part. * * When called, the file pointer should be located just after * the first 4 bytes, "RIFF". It also sets @a maxlen and @a nowlen . * * @param fp [in] File pointer * * @return TRUE if check successfully passed, FALSE if an error occured. */static booleansetup_wav(FILE *fp){ char dummy[9]; unsigned int i, len; unsigned short s; /* 4 byte: byte num of rest ( = filesize - 8) */ /* --- just skip them */ MYREAD(dummy, 1, 4, fp); /* first part: WAVE format specifications */ /* 4 byte: "WAVE" */ MYREAD(dummy, 1, 4, fp); if (dummy[0] != 'W' || dummy[1] != 'A' || dummy[2] != 'V' || dummy[3] != 'E') { j_printerr("adin_file: WAVE header not found, file corrupted?\n"); fclose_readfile(fp); return FALSE; } /* format chunk: "fmt " */ MYREAD(dummy, 1, 4, fp); if (dummy[0] != 'f' || dummy[1] != 'm' || dummy[2] != 't' || dummy[3] != ' ') { j_printerr("adin_file: fmt chunk not found, file corrupted?\n"); fclose_readfile(fp); return FALSE; } /* 4byte: byte size of this part */ MYREAD(&len, 4, 1, fp); /* 2byte: data format */ MYREAD(&s, 2, 1, fp); if (s != 1) { j_printerr("adin_file: data format != PCM (id=%d)\n", s); fclose_readfile(fp); return FALSE; } /* 2byte: channel num */ MYREAD(&s, 2, 1, fp); if (s >= 2) { j_printerr("adin_file: channel num != 1 (%d)\n", s); fclose_readfile(fp); return FALSE; } /* 4byte: sampling rate */ MYREAD(&i, 4, 1, fp); if (i != sfreq) { j_printerr("adin_file: sampling rate != %d (%d)\n", sfreq, i); fclose_readfile(fp); return FALSE; } /* 4byte: bytes per second */ MYREAD(&i, 4, 1, fp); if (i != sfreq * sizeof(SP16)) { j_printerr("adin_file: bytes per second != %d (%d)\n", sfreq * sizeof(SP16), i); fclose_readfile(fp); return FALSE; } /* 2bytes: bytes per frame ( = (bytes per sample) x channel ) */ MYREAD(&s, 2, 1, fp); if (s != 2) { j_printerr("adin_file: (bytes per sample) x channel != 2 (%d)\n", s); fclose_readfile(fp); return FALSE; } /* 2bytes: bits per sample */ MYREAD(&s, 2, 1, fp); if (s != 16) { j_printerr("adin_file: bits per sample != 16 (%d)\n", s); fclose_readfile(fp); return FALSE; } /* skip rest */ if (len > 16) { len -= 16; while (len > 0) { if (len > 8) { MYREAD(dummy, 1, 8, fp); len -= 8; } else { MYREAD(dummy, 1, len, fp); len = 0; } } } /* end of fmt part */ /* seek for 'data' part */ while (myread(dummy, 1, 4, fp)) { MYREAD(&len, 4, 1, fp); if (dummy[0] == 'd' && dummy[1] == 'a' && dummy[2] == 't' && dummy[3] == 'a') { break; } for (i=0;i<len;i++) myread(dummy, 1, 1, fp); } /* ready to read in "data" part --- this is speech data */ maxlen = len / sizeof(SP16); nowlen = 0; return TRUE;}/** * @brief Open input file * * Open the file, check the file format, and set the file pointer to @a gfp . * * @param filename [in] file name, or NULL for standard input * * @return TRUE on success, FALSE on failure. */static booleanadin_file_open(char *filename) /* NULL for standard input */{ FILE *fp; char dummy[4]; if (filename != NULL) { if ((fp = fopen_readfile(filename)) == NULL) { j_printerr("failed to open %s\n",filename); return(FALSE); } } else { fp = stdin; } /* check first 4 byte to detect Microsoft WAVE format */ if (myfread(dummy, 1, 4, fp) < 4) { j_printerr("Error: size less than 4 bytes?\n",filename); fclose_readfile(fp); return(FALSE); } if (dummy[0] == 'R' && dummy[1] == 'I' && dummy[2] == 'F' && dummy[3] == 'F') { /* it's a WAVE file */ wav_p = TRUE; has_pre = FALSE; if (setup_wav(fp) == FALSE) { j_printerr("Error: failed to read %s as a wav file\n",filename); fclose_readfile(fp); return(FALSE); } } else { /* read as raw format file */ wav_p = FALSE; memcpy(pre_data, dummy, 4); /* already read (4/sizeof(SP)) samples */ has_pre = TRUE; } gfp = fp; return(TRUE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -