📄 adin_sndfile.c
字号:
/** * @file adin_sndfile.c * * <JA> * @brief ファイル掐蜗¨libsndfile を脱いた不兰ファイル粕み哈み * * libsndfile を脱いて不兰ファイルからの掐蜗を乖なう簇眶ですˉ * Microsoft WAVE妨及の不兰ファイル·およびヘッダ痰し∈RAW∷ファイルの戮に, * AU, AND, NIST, ADPCM など屯」な妨及のファイルを粕み哈むことができますˉ * なお·チャンネル眶は1(モノラル)に嘎られますˉまたRAWファイルの眷圭· * デ〖タのバイトオ〖ダ〖は big endian である涩妥がありますˉ * * ファイルのサンプリングレ〖トはシステムの妥滇するサンプリングレ〖ト * ∈adin_standby() で回年される猛∷と办米する涩妥がありますˉ * ファイルのサンプリングレ〖トがこの回年猛と办米しなければエラ〖となりますˉ * RAWファイル掐蜗の眷圭は·ファイルにヘッダ攫鼠が痰く峡不箕の * サンプリングレ〖トが稍汤なため·チェック痰しでファイルの * サンプリングレ〖トが adin_standby() で回年された猛である * と簿年して借妄されますˉ * * 掐蜗ファイル叹は·筛洁掐蜗から粕み哈まれますˉ * ファイル叹を误刁したファイルリストファイルが回年された眷圭· * そのファイルから掐蜗ファイル叹が界肌粕み哈まれますˉ * * libsndfile はconfigure 箕に极瓢浮叫されますˉ浮叫に己窃した眷圭· * ファイル掐蜗には adin_file.c 柒の簇眶が蝗脱されますˉ * * Libsndfile のバ〖ジョンは 1.0.x に滦炳していますˉ * * @sa http://www.mega-nerd.com/libsndfile/ * </JA> * <EN> * @brief Audio input from file using libsndfile library. * * Functions to get input from wave file using libsndfile library. * Many file formats are supported, including Microsoft WAVE format, * and RAW (no header) format, AU, SND, NIST and so on. The channel number * should be 1 (monaural). * 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. * * libsndfile should be installed before compilation. The library and header * will be automatically detected by configure script. When failed to detect, * Julius uses adin_file.c instead for file input. * * This file will work on libsndfile version 1.0.x. * * @sa http://www.mega-nerd.com/libsndfile/ * </EN> * * @author Akinobu LEE * @date Mon Feb 14 12:13:27 2005 * * $Revision: 1.3 $ * *//* * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology * All rights reserved */#include <sent/stddefs.h>#include <sent/speech.h>#include <sent/adin.h>#ifdef HAVE_LIBSNDFILE/* sound header */#include <sndfile.h>static int sfreq; ///< Required sampling frequency in Hzstatic SF_INFO sinfo; ///< Wavefile informationstatic SNDFILE *sp; ///< File handlerstatic boolean from_file; ///< TRUE if reading filename from listfilestatic FILE *fp_list; ///< File pointer used for the listfilestatic char speechfilename[MAXPATHLEN]; ///< Buffer to hold input file name/// Check if the file format is 16bit, monoral.static booleancheck_format(SF_INFO *s){ if ((s->format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { if (s->samplerate != sfreq) { jlog("Error: adin_sndfile: sample rate != %d, it's %d Hz data\n", sfreq, s->samplerate); return FALSE; } } if (s->channels != 1) { jlog("Error: adin_sndfile: channel num != 1, it has %d channels\n", s->channels); return FALSE; }#ifdef HAVE_LIBSNDFILE_VER1 if ((s->format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM_16) { jlog("Error: adin_sndfile: not 16-bit data\n"); return FALSE; }#else if (s->pcmbitwidth != 16) { jlog("Error: adin_sndfile: not 16-bit data, it's %d bit\n", s->pcmbitwidth); return FALSE; }#endif return TRUE;}/// Output format information to stdout (compliant to libsnd-0.0.23)static voidprint_format(SF_INFO *s){ switch(s->format & SF_FORMAT_TYPEMASK) { case SF_FORMAT_WAV: jlog("Stat: adin_sndfile: input format = Microsoft WAV\n"); break; case SF_FORMAT_AIFF: jlog("Stat: adin_sndfile: input format = Apple/SGI AIFF\n"); break; case SF_FORMAT_AU: jlog("Stat: adin_sndfile: input format = Sun/NeXT AU\n"); break;#ifndef HAVE_LIBSNDFILE_VER1 case SF_FORMAT_AULE: jlog("Stat: adin_sndfile: input format = DEC AU\n"); break;#endif case SF_FORMAT_RAW: jlog("Stat: adin_sndfile: input format = RAW\n"); break; case SF_FORMAT_PAF: jlog("Stat: adin_sndfile: input format = Ensoniq PARIS\n"); break; case SF_FORMAT_SVX: jlog("Stat: adin_sndfile: input format = Amiga IFF / SVX8 / SV16\n"); break; case SF_FORMAT_NIST: jlog("Stat: adin_sndfile: input format = Sphere NIST\n"); break;#ifdef HAVE_LIBSNDFILE_VER1 case SF_FORMAT_VOC: jlog("Stat: adin_sndfile: input format = VOC file\n"); break; case SF_FORMAT_IRCAM: jlog("Stat: adin_sndfile: input format = Berkeley/IRCAM/CARL\n"); break; case SF_FORMAT_W64: jlog("Stat: adin_sndfile: input format = Sonic Foundry's 64bit RIFF/WAV\n"); break; case SF_FORMAT_MAT4: jlog("Stat: adin_sndfile: input format = Matlab (tm) V4.2 / GNU Octave 2.0\n"); break; case SF_FORMAT_MAT5: jlog("Stat: adin_sndfile: input format = Matlab (tm) V5.0 / GNU Octave 2.1\n"); break;#endif default: jlog("Stat: adin_sndfile: input format = UNKNOWN TYPE\n"); break; } switch(s->format & SF_FORMAT_SUBMASK) {#ifdef HAVE_LIBSNDFILE_VER1 case SF_FORMAT_PCM_U8: jlog("Stat: adin_sndfile: input type = Unsigned 8 bit PCM\n"); break; case SF_FORMAT_PCM_S8: jlog("Stat: adin_sndfile: input type = Signed 8 bit PCM\n"); break; case SF_FORMAT_PCM_16: jlog("Stat: adin_sndfile: input type = Signed 16 bit PCM\n"); break; case SF_FORMAT_PCM_24: jlog("Stat: adin_sndfile: input type = Signed 24 bit PCM\n"); break; case SF_FORMAT_PCM_32: jlog("Stat: adin_sndfile: input type = Signed 32 bit PCM\n"); break; case SF_FORMAT_FLOAT: jlog("Stat: adin_sndfile: input type = 32bit float\n"); break; case SF_FORMAT_DOUBLE: jlog("Stat: adin_sndfile: input type = 64bit float\n"); break; case SF_FORMAT_ULAW: jlog("Stat: adin_sndfile: input type = U-Law\n"); break; case SF_FORMAT_ALAW: jlog("Stat: adin_sndfile: input type = A-Law\n"); break; case SF_FORMAT_IMA_ADPCM: jlog("Stat: adin_sndfile: input type = IMA ADPCM\n"); break; case SF_FORMAT_MS_ADPCM: jlog("Stat: adin_sndfile: input type = Microsoft ADPCM\n"); break; case SF_FORMAT_GSM610: jlog("Stat: adin_sndfile: input type = GSM 6.10, \n"); break; case SF_FORMAT_G721_32: jlog("Stat: adin_sndfile: input type = 32kbs G721 ADPCM\n"); break; case SF_FORMAT_G723_24: jlog("Stat: adin_sndfile: input type = 24kbs G723 ADPCM\n"); break; case SF_FORMAT_G723_40: jlog("Stat: adin_sndfile: input type = 40kbs G723 ADPCM\n"); break;#else case SF_FORMAT_PCM: jlog("Stat: adin_sndfile: input type = PCM\n"); break; case SF_FORMAT_FLOAT: jlog("Stat: adin_sndfile: input type = floats\n"); break; case SF_FORMAT_ULAW: jlog("Stat: adin_sndfile: input type = U-Law\n"); break; case SF_FORMAT_ALAW: jlog("Stat: adin_sndfile: input type = A-Law\n"); break; case SF_FORMAT_IMA_ADPCM: jlog("Stat: adin_sndfile: input type = IMA ADPCM\n"); break; case SF_FORMAT_MS_ADPCM: jlog("Stat: adin_sndfile: input type = Microsoft ADPCM\n"); break; case SF_FORMAT_PCM_BE: jlog("Stat: adin_sndfile: input type = Big endian PCM\n"); break; case SF_FORMAT_PCM_LE: jlog("Stat: adin_sndfile: input type = Little endian PCM\n"); break; case SF_FORMAT_PCM_S8: jlog("Stat: adin_sndfile: input type = Signed 8 bit PCM\n"); break; case SF_FORMAT_PCM_U8: jlog("Stat: adin_sndfile: input type = Unsigned 8 bit PCM\n"); break; case SF_FORMAT_SVX_FIB: jlog("Stat: adin_sndfile: input type = SVX Fibonacci Delta\n"); break; case SF_FORMAT_SVX_EXP: jlog("Stat: adin_sndfile: input type = SVX Exponential Delta\n"); break; case SF_FORMAT_GSM610: jlog("Stat: adin_sndfile: input type = GSM 6.10, \n"); break; case SF_FORMAT_G721_32: jlog("Stat: adin_sndfile: input type = 32kbs G721 ADPCM\n"); break; case SF_FORMAT_G723_24: jlog("Stat: adin_sndfile: input type = 24kbs G723 ADPCM\n"); break;#endif default: jlog("Stat: adin_sndfile: input type = UNKNOWN SUBTYPE\n"); break; }#ifdef HAVE_LIBSNDFILE_VER1 switch(s->format & SF_FORMAT_ENDMASK) { case SF_ENDIAN_FILE: jlog("Stat: adin_sndfile: endian = file native endian\n"); break; case SF_ENDIAN_LITTLE: jlog("Stat: adin_sndfile: endian = forced little endian\n"); break; case SF_ENDIAN_BIG: jlog("Stat: adin_sndfile: endian = forced big endian\n"); break; case SF_ENDIAN_CPU: jlog("Stat: adin_sndfile: endian = forced CPU native endian\n"); break; } jlog("Stat: adin_sndfile: %d Hz, %d channels\n", s->samplerate, s->channels);#else jlog("Stat: adin_sndfile: %d bit, %d Hz, %d channels\n", s->pcmbitwidth, s->samplerate, s->channels);#endif}/** * Initialization: if listfile is specified, open it here. Else, just store * the required frequency. * * @param freq [in] required sampling frequency * @param arg [in] file name of listfile, or NULL if not use * * @return TRUE on success, FALSE on failure. */booleanadin_sndfile_standby(int freq, void *arg){ char *fname = arg; if (fname != NULL) { /* read input filename from file */ if ((fp_list = fopen(fname, "r")) == NULL) { jlog("Error: adin_sndfile: failed to open %s\n", fname); return(FALSE); } from_file = TRUE; } else { /* read filename from stdin */ from_file = FALSE; } /* store sampling frequency */ sfreq = freq; return(TRUE);}/** * @brief Begin reading audio data from a file. * * If listfile was specified in adin_sndfile_standby(), the next filename * will be read from the listfile. Otherwise, the * filename will be obtained from stdin. Then the file will be opened here. * * @return TRUE on success, FALSE on failure. */booleanadin_sndfile_begin(){ boolean readp; /* ready to read next input */ readp = FALSE; while(readp == FALSE) { if (from_file) { /* read file name from listfile */ do { if (getl_fp(speechfilename, MAXPATHLEN, fp_list) == NULL) { /* end of input */ fclose(fp_list); return(FALSE); /* end of input */ } } while (speechfilename[0] == '#'); /* skip comment */ } else { /* read file name from stdin */ if (get_line_from_stdin(speechfilename, MAXPATHLEN, "enter filename->") == NULL) { return (FALSE); /* end of input */ } } /* open input file */#ifndef HAVE_LIBSNDFILE_VER1 sinfo.samplerate = sfreq; sinfo.pcmbitwidth = 16; sinfo.channels = 1;#endif sinfo.format = 0x0; if ((sp = #ifdef HAVE_LIBSNDFILE_VER1 sf_open(speechfilename, SFM_READ, &sinfo)#else sf_open_read(speechfilename, &sinfo)#endif ) == NULL) { /* retry assuming raw format */ sinfo.samplerate = sfreq; sinfo.channels = 1;#ifdef HAVE_LIBSNDFILE_VER1 sinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_BIG;#else sinfo.pcmbitwidth = 16; sinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_BE;#endif if ((sp =#ifdef HAVE_LIBSNDFILE_VER1 sf_open(speechfilename, SFM_READ, &sinfo)#else sf_open_read(speechfilename, &sinfo)#endif ) == NULL) { sf_perror(sp); jlog("Error: adin_sndfile: failed to open speech data: \"%s\"\n",speechfilename); } } if (sp != NULL) { /* open success */ if (! check_format(&sinfo)) { jlog("Error: adin_sndfile: invalid format: \"%s\"\n",speechfilename); print_format(&sinfo); } else { jlog("Stat: adin_sndfile: input speechfile: %s\n",speechfilename); print_format(&sinfo); readp = TRUE; } } } return TRUE;}/** * Try to read @a sampnum samples and returns actual sample num recorded. * * @param buf [out] samples obtained in this function * @param sampnum [in] wanted number of samples to be read * * @return actural number of read samples, -1 if EOF, -2 if error. */intadin_sndfile_read(SP16 *buf, int sampnum){ int cnt; cnt = sf_read_short(sp, buf, sampnum); if (cnt == 0) { /* EOF */ return -1; } else if (cnt < 0) { /* error */ sf_perror(sp); sf_close(sp); return -2; /* error */ } return cnt;}/** * End recording. * * @return TRUE on success, FALSE on failure. */booleanadin_sndfile_end(){ /* close files */ if (sf_close(sp) != 0) { sf_perror(sp); jlog("Error: adin_sndfile: failed to close\n"); return FALSE; } return TRUE;}/** * * A tiny function to get current input raw speech file name. * * @return string of current input speech file. * */char *adin_sndfile_get_current_filename(){ return(speechfilename);}#endif /* ~HAVE_LIBSNDFILE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -