htk.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:7k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU Lesser General Public License as published by
  6. ** the Free Software Foundation; either version 2.1 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU Lesser General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU Lesser General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <fcntl.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include "sndfile.h"
  24. #include "sfendian.h"
  25. #include "common.h"
  26. /*------------------------------------------------------------------------------
  27. ** Macros to handle big/little endian issues.
  28. */
  29. #define SFE_HTK_BAD_FILE_LEN  1666
  30. #define SFE_HTK_NOT_WAVEFORM 1667
  31. /*------------------------------------------------------------------------------
  32. ** Private static functions.
  33. */
  34. static int htk_close (SF_PRIVATE *psf) ;
  35. static int htk_write_header (SF_PRIVATE *psf, int calc_length) ;
  36. static int htk_read_header (SF_PRIVATE *psf) ;
  37. /*------------------------------------------------------------------------------
  38. ** Public function.
  39. */
  40. int
  41. htk_open (SF_PRIVATE *psf)
  42. { int subformat ;
  43. int error = 0 ;
  44. if (psf->is_pipe)
  45. return SFE_HTK_NO_PIPE ;
  46. if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
  47. { if ((error = htk_read_header (psf)))
  48. return error ;
  49. } ;
  50. subformat = SF_CODEC (psf->sf.format) ;
  51. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  52. { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_HTK)
  53. return SFE_BAD_OPEN_FORMAT ;
  54. psf->endian = SF_ENDIAN_BIG ;
  55. if (htk_write_header (psf, SF_FALSE))
  56. return psf->error ;
  57. psf->write_header = htk_write_header ;
  58. } ;
  59. psf->container_close = htk_close ;
  60. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  61. switch (subformat)
  62. { case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
  63. error = pcm_init (psf) ;
  64. break ;
  65. default : break ;
  66. } ;
  67. return error ;
  68. } /* htk_open */
  69. /*------------------------------------------------------------------------------
  70. */
  71. static int
  72. htk_close (SF_PRIVATE *psf)
  73. {
  74. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  75. htk_write_header (psf, SF_TRUE) ;
  76. return 0 ;
  77. } /* htk_close */
  78. static int
  79. htk_write_header (SF_PRIVATE *psf, int calc_length)
  80. { sf_count_t current ;
  81. int sample_count, sample_period ;
  82. current = psf_ftell (psf) ;
  83. if (calc_length)
  84. psf->filelength = psf_get_filelen (psf) ;
  85. /* Reset the current header length to zero. */
  86. psf->header [0] = 0 ;
  87. psf->headindex = 0 ;
  88. psf_fseek (psf, 0, SEEK_SET) ;
  89. if (psf->filelength > 12)
  90. sample_count = (psf->filelength - 12) / 2 ;
  91. else
  92. sample_count = 0 ;
  93. sample_period = 10000000 / psf->sf.samplerate ;
  94. psf_binheader_writef (psf, "E444", sample_count, sample_period, 0x20000) ;
  95. /* Header construction complete so write it out. */
  96. psf_fwrite (psf->header, psf->headindex, 1, psf) ;
  97. if (psf->error)
  98. return psf->error ;
  99. psf->dataoffset = psf->headindex ;
  100. if (current > 0)
  101. psf_fseek (psf, current, SEEK_SET) ;
  102. return psf->error ;
  103. } /* htk_write_header */
  104. /*
  105. ** Found the following info in a comment block within Bill Schottstaedt's
  106. ** sndlib library.
  107. **
  108. ** HTK format files consist of a contiguous sequence of samples preceded by a
  109. ** header. Each sample is a vector of either 2-byte integers or 4-byte floats.
  110. ** 2-byte integers are used for compressed forms as described below and for
  111. ** vector quantised data as described later in section 5.11. HTK format data
  112. ** files can also be used to store speech waveforms as described in section 5.8.
  113. **
  114. ** The HTK file format header is 12 bytes long and contains the following data
  115. **   nSamples   -- number of samples in file (4-byte integer)
  116. **   sampPeriod -- sample period in 100ns units (4-byte integer)
  117. **   sampSize   -- number of bytes per sample (2-byte integer)
  118. **   parmKind   -- a code indicating the sample kind (2-byte integer)
  119. **
  120. ** The parameter kind  consists of a 6 bit code representing the basic
  121. ** parameter kind plus additional bits for each of the possible qualifiers.
  122. ** The basic parameter kind codes are
  123. **
  124. **  0    WAVEFORM    sampled waveform
  125. **  1    LPC         linear prediction filter coefficients
  126. **  2    LPREFC      linear prediction reflection coefficients
  127. **  3    LPCEPSTRA   LPC cepstral coefficients
  128. **  4    LPDELCEP    LPC cepstra plus delta coefficients
  129. **  5    IREFC       LPC reflection coef in 16 bit integer format
  130. **  6    MFCC        mel-frequency cepstral coefficients
  131. **  7    FBANK       log mel-filter bank channel outputs
  132. **  8    MELSPEC     linear mel-filter bank channel outputs
  133. **  9    USER        user defined sample kind
  134. **  10   DISCRETE    vector quantised data
  135. **
  136. ** and the bit-encoding for the qualifiers (in octal) is
  137. **   _E   000100      has energy
  138. **   _N   000200      absolute energy suppressed
  139. **   _D   000400      has delta coefficients
  140. **   _A   001000      has acceleration coefficients
  141. **   _C   002000      is compressed
  142. **   _Z   004000      has zero mean static coef.
  143. **   _K   010000      has CRC checksum
  144. **   _O   020000      has 0'th cepstral coef.
  145. */
  146. static int
  147. htk_read_header (SF_PRIVATE *psf)
  148. { int sample_count, sample_period, marker ;
  149. psf_binheader_readf (psf, "pE444", 0, &sample_count, &sample_period, &marker) ;
  150. if (2 * sample_count + 12 != psf->filelength)
  151. return SFE_HTK_BAD_FILE_LEN ;
  152. if (marker != 0x20000)
  153. return SFE_HTK_NOT_WAVEFORM ;
  154. psf->sf.channels = 1 ;
  155. if (sample_period > 0)
  156. { psf->sf.samplerate = 10000000 / sample_period ;
  157. psf_log_printf (psf, "HTK Waveform filen  Sample Count  : %dn  Sample Period : %d => %d Hzn",
  158. sample_count, sample_period, psf->sf.samplerate) ;
  159. }
  160. else
  161. { psf->sf.samplerate = 16000 ;
  162. psf_log_printf (psf, "HTK Waveform filen  Sample Count  : %dn  Sample Period : %d (should be > 0) => Guessed sample rate %d Hzn",
  163. sample_count, sample_period, psf->sf.samplerate) ;
  164. } ;
  165. psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
  166. psf->bytewidth = 2 ;
  167. /* HTK always has a 12 byte header. */
  168. psf->dataoffset = 12 ;
  169. psf->endian = SF_ENDIAN_BIG ;
  170. psf->datalength = psf->filelength - psf->dataoffset ;
  171. psf->blockwidth = psf->sf.channels * psf->bytewidth ;
  172. if (! psf->sf.frames && psf->blockwidth)
  173. psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
  174. return 0 ;
  175. } /* htk_read_header */