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

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 1999-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. /*
  19. ** Some of the information used to read NIST files was gleaned from
  20. ** reading the code of Bill Schottstaedt's sndlib library
  21. ** ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz
  22. ** However, no code from that package was used.
  23. */
  24. #include "sfconfig.h"
  25. #include <stdio.h>
  26. #include <fcntl.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include "sndfile.h"
  30. #include "sfendian.h"
  31. #include "common.h"
  32. /*------------------------------------------------------------------------------
  33. */
  34. #define NIST_HEADER_LENGTH 1024
  35. /*------------------------------------------------------------------------------
  36. ** Private static functions.
  37. */
  38. static int nist_close (SF_PRIVATE *psf) ;
  39. static int nist_write_header (SF_PRIVATE *psf, int calc_length) ;
  40. static int nist_read_header (SF_PRIVATE *psf) ;
  41. /*------------------------------------------------------------------------------
  42. */
  43. int
  44. nist_open (SF_PRIVATE *psf)
  45. { int error ;
  46. if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
  47. { if ((error = nist_read_header (psf)))
  48. return error ;
  49. } ;
  50. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  51. { if (psf->is_pipe)
  52. return SFE_NO_PIPE_WRITE ;
  53. if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_NIST)
  54. return SFE_BAD_OPEN_FORMAT ;
  55. psf->endian = SF_ENDIAN (psf->sf.format) ;
  56. if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)
  57. psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
  58. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  59. psf->sf.frames = 0 ;
  60. if ((error = nist_write_header (psf, SF_FALSE)))
  61. return error ;
  62. psf->write_header = nist_write_header ;
  63. } ;
  64. psf->container_close = nist_close ;
  65. switch (SF_CODEC (psf->sf.format))
  66. { case SF_FORMAT_PCM_S8 :
  67. error = pcm_init (psf) ;
  68. break ;
  69. case SF_FORMAT_PCM_16 :
  70. case SF_FORMAT_PCM_24 :
  71. case SF_FORMAT_PCM_32 :
  72. error = pcm_init (psf) ;
  73. break ;
  74. case SF_FORMAT_ULAW :
  75. error = ulaw_init (psf) ;
  76. break ;
  77. case SF_FORMAT_ALAW :
  78. error = alaw_init (psf) ;
  79. break ;
  80. default : error = SFE_UNIMPLEMENTED ;
  81. break ;
  82. } ;
  83. return error ;
  84. } /* nist_open */
  85. /*------------------------------------------------------------------------------
  86. */
  87. static char bad_header [] =
  88. { 'N', 'I', 'S', 'T', '_', '1', 'A', 0x0d, 0x0a,
  89. ' ', ' ', ' ', '1', '0', '2', '4', 0x0d, 0x0a,
  90. 0
  91. } ;
  92. static int
  93. nist_read_header (SF_PRIVATE *psf)
  94. { char *psf_header ;
  95. int bitwidth = 0, count, encoding ;
  96. unsigned bytes = 0 ;
  97. char  str [64], *cptr ;
  98. long samples ;
  99. psf_header = psf->u.cbuf ;
  100. if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
  101. return SFE_INTERNAL ;
  102. /* Go to start of file and read in the whole header. */
  103. psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ;
  104. /* Header is a string, so make sure it is null terminated. */
  105. psf_header [NIST_HEADER_LENGTH] = 0 ;
  106. /* Now trim the header after the end marker. */
  107. if ((cptr = strstr (psf_header, "end_head")))
  108. { cptr += strlen ("end_head") + 1 ;
  109. cptr [0] = 0 ;
  110. } ;
  111. if (strstr (psf_header, bad_header) == psf_header)
  112. return SFE_NIST_CRLF_CONVERISON ;
  113. /* Make sure its a NIST file. */
  114. if (strstr (psf_header, "NIST_1An") != psf_header)
  115. { psf_log_printf (psf, "Not a NIST file.n") ;
  116. return SFE_NIST_BAD_HEADER ;
  117. } ;
  118. if (sscanf (psf_header, "NIST_1An%dn", &count) == 1)
  119. psf->dataoffset = count ;
  120. else
  121. { psf_log_printf (psf, "*** Suspicious header length.n") ;
  122. psf->dataoffset = NIST_HEADER_LENGTH ;
  123. } ;
  124. /* Determine sample encoding, start by assuming PCM. */
  125. encoding = SF_FORMAT_PCM_U8 ;
  126. if ((cptr = strstr (psf_header, "sample_coding -s")))
  127. { sscanf (cptr, "sample_coding -s%d %63s", &count, str) ;
  128. if (strcmp (str, "pcm") == 0)
  129. { /* Correct this later when we find out the bitwidth. */
  130. encoding = SF_FORMAT_PCM_U8 ;
  131. }
  132. else if (strcmp (str, "alaw") == 0)
  133. encoding = SF_FORMAT_ALAW ;
  134. else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
  135. encoding = SF_FORMAT_ULAW ;
  136. else
  137. { psf_log_printf (psf, "*** Unknown encoding : %sn", str) ;
  138. encoding = 0 ;
  139. } ;
  140. } ;
  141. if ((cptr = strstr (psf_header, "channel_count -i ")) != NULL)
  142. sscanf (cptr, "channel_count -i %d", &(psf->sf.channels)) ;
  143. if ((cptr = strstr (psf_header, "sample_rate -i ")) != NULL)
  144. sscanf (cptr, "sample_rate -i %d", &(psf->sf.samplerate)) ;
  145. if ((cptr = strstr (psf_header, "sample_count -i ")) != NULL)
  146. { sscanf (cptr, "sample_count -i %ld", &samples) ;
  147. psf->sf.frames = samples ;
  148. } ;
  149. if ((cptr = strstr (psf_header, "sample_n_bytes -i ")) != NULL)
  150. sscanf (cptr, "sample_n_bytes -i %d", &(psf->bytewidth)) ;
  151. /* Default endian-ness (for 8 bit, u-law, A-law. */
  152. psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
  153. /* This is where we figure out endian-ness. */
  154. if ((cptr = strstr (psf_header, "sample_byte_format -s"))
  155. && sscanf (cptr, "sample_byte_format -s%u %8s", &bytes, str) == 2)
  156. {
  157. if (bytes != strlen (str))
  158. psf_log_printf (psf, "Weird sample_byte_format : strlen '%s' != %dn", str, bytes) ;
  159. if (bytes > 1)
  160. { if (strcmp (str, "01") == 0)
  161. psf->endian = SF_ENDIAN_LITTLE ;
  162. else if (strcmp (str, "10") == 0)
  163. psf->endian = SF_ENDIAN_BIG ;
  164. else
  165. { psf_log_printf (psf, "Weird endian-ness : %sn", str) ;
  166. return SFE_NIST_BAD_ENCODING ;
  167. } ;
  168. } ;
  169. psf->sf.format |= psf->endian ;
  170. } ;
  171. if ((cptr = strstr (psf_header, "sample_sig_bits -i ")))
  172. sscanf (cptr, "sample_sig_bits -i %d", &bitwidth) ;
  173. if (strstr (psf_header, "channels_interleaved -s5 FALSE"))
  174. { psf_log_printf (psf, "Non-interleaved data unsupported.n", str) ;
  175. return SFE_NIST_BAD_ENCODING ;
  176. } ;
  177. psf->blockwidth = psf->sf.channels * psf->bytewidth ;
  178. psf->datalength = psf->filelength - psf->dataoffset ;
  179. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  180. if (encoding == SF_FORMAT_PCM_U8)
  181. { switch (psf->bytewidth)
  182. { case 1 :
  183. psf->sf.format |= SF_FORMAT_PCM_S8 ;
  184. break ;
  185. case 2 :
  186. psf->sf.format |= SF_FORMAT_PCM_16 ;
  187. break ;
  188. case 3 :
  189. psf->sf.format |= SF_FORMAT_PCM_24 ;
  190. break ;
  191. case 4 :
  192. psf->sf.format |= SF_FORMAT_PCM_32 ;
  193. break ;
  194. default : break ;
  195. } ;
  196. }
  197. else if (encoding != 0)
  198. psf->sf.format |= encoding ;
  199. else
  200. return SFE_UNIMPLEMENTED ;
  201. /* Sanitize psf->sf.format. */
  202. switch (SF_CODEC (psf->sf.format))
  203. { case SF_FORMAT_ULAW :
  204. case SF_FORMAT_ALAW :
  205. case SF_FORMAT_PCM_U8 :
  206. /* Blank out endian bits. */
  207. psf->sf.format = SF_FORMAT_NIST | SF_CODEC (psf->sf.format) ;
  208. break ;
  209. default :
  210. break ;
  211. } ;
  212. return 0 ;
  213. } /* nist_read_header */
  214. static int
  215. nist_close (SF_PRIVATE *psf)
  216. {
  217. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  218. nist_write_header (psf, SF_TRUE) ;
  219. return 0 ;
  220. } /* nist_close */
  221. /*=========================================================================
  222. */
  223. static int
  224. nist_write_header (SF_PRIVATE *psf, int calc_length)
  225. { const char *end_str ;
  226. long samples ;
  227. sf_count_t current ;
  228. current = psf_ftell (psf) ;
  229. if (calc_length)
  230. { psf->filelength = psf_get_filelen (psf) ;
  231. psf->datalength = psf->filelength - psf->dataoffset ;
  232. if (psf->dataend)
  233. psf->datalength -= psf->filelength - psf->dataend ;
  234. if (psf->bytewidth > 0)
  235. psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
  236. } ;
  237. if (psf->endian == SF_ENDIAN_BIG)
  238. end_str = "10" ;
  239. else if (psf->endian == SF_ENDIAN_LITTLE)
  240. end_str = "01" ;
  241. else
  242. end_str = "error" ;
  243. /* Clear the whole header. */
  244. memset (psf->header, 0, sizeof (psf->header)) ;
  245. psf->headindex = 0 ;
  246. psf_fseek (psf, 0, SEEK_SET) ;
  247. psf_asciiheader_printf (psf, "NIST_1An   1024n") ;
  248. psf_asciiheader_printf (psf, "channel_count -i %dn", psf->sf.channels) ;
  249. psf_asciiheader_printf (psf, "sample_rate -i %dn", psf->sf.samplerate) ;
  250. switch (SF_CODEC (psf->sf.format))
  251. { case SF_FORMAT_PCM_S8 :
  252. psf_asciiheader_printf (psf, "sample_coding -s3 pcmn") ;
  253. psf_asciiheader_printf (psf, "sample_n_bytes -i 1n"
  254. "sample_sig_bits -i 8n") ;
  255. break ;
  256. case SF_FORMAT_PCM_16 :
  257. case SF_FORMAT_PCM_24 :
  258. case SF_FORMAT_PCM_32 :
  259. psf_asciiheader_printf (psf, "sample_n_bytes -i %dn", psf->bytewidth) ;
  260. psf_asciiheader_printf (psf, "sample_sig_bits -i %dn", psf->bytewidth * 8) ;
  261. psf_asciiheader_printf (psf, "sample_coding -s3 pcmn"
  262. "sample_byte_format -s%d %sn", psf->bytewidth, end_str) ;
  263. break ;
  264. case SF_FORMAT_ALAW :
  265. psf_asciiheader_printf (psf, "sample_coding -s4 alawn") ;
  266. psf_asciiheader_printf (psf, "sample_n_bytes -s1 1n") ;
  267. break ;
  268. case SF_FORMAT_ULAW :
  269. psf_asciiheader_printf (psf, "sample_coding -s4 ulawn") ;
  270. psf_asciiheader_printf (psf, "sample_n_bytes -s1 1n") ;
  271. break ;
  272. default : return SFE_UNIMPLEMENTED ;
  273. } ;
  274. psf->dataoffset = NIST_HEADER_LENGTH ;
  275. /* Fix this */
  276. samples = psf->sf.frames ;
  277. psf_asciiheader_printf (psf, "sample_count -i %ldn", samples) ;
  278. psf_asciiheader_printf (psf, "end_headn") ;
  279. /* Zero fill to dataoffset. */
  280. psf_binheader_writef (psf, "z", (size_t) (NIST_HEADER_LENGTH - psf->headindex)) ;
  281. psf_fwrite (psf->header, psf->headindex, 1, psf) ;
  282. if (psf->error)
  283. return psf->error ;
  284. if (current > 0)
  285. psf_fseek (psf, current, SEEK_SET) ;
  286. return psf->error ;
  287. } /* nist_write_header */