2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
20 ** Some of the information used to read NIST files was gleaned from
21 ** reading the code of Bill Schottstaedt's sndlib library
22 ** ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz
23 ** However, no code from that package was used.
37 /*------------------------------------------------------------------------------
40 #define NIST_HEADER_LENGTH 1024
42 /*------------------------------------------------------------------------------
43 ** Private static functions.
46 static int nist_close (SF_PRIVATE
*psf
) ;
47 static int nist_write_header (SF_PRIVATE
*psf
, int calc_length
) ;
48 static int nist_read_header (SF_PRIVATE
*psf
) ;
50 /*------------------------------------------------------------------------------
54 nist_open (SF_PRIVATE
*psf
)
57 if (psf
->file
.mode
== SFM_READ
|| (psf
->file
.mode
== SFM_RDWR
&& psf
->filelength
> 0))
58 { if ((error
= nist_read_header (psf
)))
62 if (psf
->file
.mode
== SFM_WRITE
|| psf
->file
.mode
== SFM_RDWR
)
64 return SFE_NO_PIPE_WRITE
;
66 if ((SF_CONTAINER (psf
->sf
.format
)) != SF_FORMAT_NIST
)
67 return SFE_BAD_OPEN_FORMAT
;
69 psf
->endian
= SF_ENDIAN (psf
->sf
.format
) ;
70 if (psf
->endian
== 0 || psf
->endian
== SF_ENDIAN_CPU
)
71 psf
->endian
= (CPU_IS_BIG_ENDIAN
) ? SF_ENDIAN_BIG
: SF_ENDIAN_LITTLE
;
73 psf
->blockwidth
= psf
->bytewidth
* psf
->sf
.channels
;
76 if ((error
= nist_write_header (psf
, SF_FALSE
)))
79 psf
->write_header
= nist_write_header
;
82 psf
->container_close
= nist_close
;
84 switch (SF_CODEC (psf
->sf
.format
))
85 { case SF_FORMAT_PCM_S8
:
86 error
= pcm_init (psf
) ;
89 case SF_FORMAT_PCM_16
:
90 case SF_FORMAT_PCM_24
:
91 case SF_FORMAT_PCM_32
:
92 error
= pcm_init (psf
) ;
96 error
= ulaw_init (psf
) ;
100 error
= alaw_init (psf
) ;
103 default : error
= SFE_UNIMPLEMENTED
;
110 /*------------------------------------------------------------------------------
113 static char bad_header
[] =
114 { 'N', 'I', 'S', 'T', '_', '1', 'A', 0x0d, 0x0a,
115 ' ', ' ', ' ', '1', '0', '2', '4', 0x0d, 0x0a,
120 nist_read_header (SF_PRIVATE
*psf
)
122 int bitwidth
= 0, count
, encoding
;
124 char str
[64], *cptr
;
127 psf_header
= psf
->u
.cbuf
;
129 if (sizeof (psf
->header
) <= NIST_HEADER_LENGTH
)
130 return SFE_INTERNAL
;
132 /* Go to start of file and read in the whole header. */
133 psf_binheader_readf (psf
, "pb", 0, psf_header
, NIST_HEADER_LENGTH
) ;
135 /* Header is a string, so make sure it is null terminated. */
136 psf_header
[NIST_HEADER_LENGTH
] = 0 ;
138 /* Now trim the header after the end marker. */
139 if ((cptr
= strstr (psf_header
, "end_head")))
140 { cptr
+= strlen ("end_head") + 1 ;
144 if (strstr (psf_header
, bad_header
) == psf_header
)
145 return SFE_NIST_CRLF_CONVERISON
;
147 /* Make sure its a NIST file. */
148 if (strstr (psf_header
, "NIST_1A\n") != psf_header
)
149 { psf_log_printf (psf
, "Not a NIST file.\n") ;
150 return SFE_NIST_BAD_HEADER
;
153 if (sscanf (psf_header
, "NIST_1A\n%d\n", &count
) == 1)
154 psf
->dataoffset
= count
;
156 { psf_log_printf (psf
, "*** Suspicious header length.\n") ;
157 psf
->dataoffset
= NIST_HEADER_LENGTH
;
160 /* Determine sample encoding, start by assuming PCM. */
161 encoding
= SF_FORMAT_PCM_U8
;
162 if ((cptr
= strstr (psf_header
, "sample_coding -s")))
163 { sscanf (cptr
, "sample_coding -s%d %63s", &count
, str
) ;
165 if (strcmp (str
, "pcm") == 0)
166 { /* Correct this later when we find out the bitwidth. */
167 encoding
= SF_FORMAT_PCM_U8
;
169 else if (strcmp (str
, "alaw") == 0)
170 encoding
= SF_FORMAT_ALAW
;
171 else if ((strcmp (str
, "ulaw") == 0) || (strcmp (str
, "mu-law") == 0))
172 encoding
= SF_FORMAT_ULAW
;
174 { psf_log_printf (psf
, "*** Unknown encoding : %s\n", str
) ;
179 if ((cptr
= strstr (psf_header
, "channel_count -i ")) != NULL
)
180 sscanf (cptr
, "channel_count -i %d", &(psf
->sf
.channels
)) ;
182 if ((cptr
= strstr (psf_header
, "sample_rate -i ")) != NULL
)
183 sscanf (cptr
, "sample_rate -i %d", &(psf
->sf
.samplerate
)) ;
185 if ((cptr
= strstr (psf_header
, "sample_count -i ")) != NULL
)
186 { sscanf (cptr
, "sample_count -i %ld", &samples
) ;
187 psf
->sf
.frames
= samples
;
190 if ((cptr
= strstr (psf_header
, "sample_n_bytes -i ")) != NULL
)
191 sscanf (cptr
, "sample_n_bytes -i %d", &(psf
->bytewidth
)) ;
193 /* Default endian-ness (for 8 bit, u-law, A-law. */
194 psf
->endian
= (CPU_IS_BIG_ENDIAN
) ? SF_ENDIAN_BIG
: SF_ENDIAN_LITTLE
;
196 /* This is where we figure out endian-ness. */
197 if ((cptr
= strstr (psf_header
, "sample_byte_format -s"))
198 && sscanf (cptr
, "sample_byte_format -s%u %8s", &bytes
, str
) == 2)
200 if (bytes
!= strlen (str
))
201 psf_log_printf (psf
, "Weird sample_byte_format : strlen '%s' != %d\n", str
, bytes
) ;
204 { if (psf
->bytewidth
== 0)
205 psf
->bytewidth
= bytes
;
206 else if (psf
->bytewidth
- bytes
!= 0)
207 { psf_log_printf (psf
, "psf->bytewidth (%d) != bytes (%d)\n", psf
->bytewidth
, bytes
) ;
208 return SFE_NIST_BAD_ENCODING
;
211 if (strcmp (str
, "01") == 0)
212 psf
->endian
= SF_ENDIAN_LITTLE
;
213 else if (strcmp (str
, "10") == 0)
214 psf
->endian
= SF_ENDIAN_BIG
;
216 { psf_log_printf (psf
, "Weird endian-ness : %s\n", str
) ;
217 return SFE_NIST_BAD_ENCODING
;
221 psf
->sf
.format
|= psf
->endian
;
224 if ((cptr
= strstr (psf_header
, "sample_sig_bits -i ")))
225 sscanf (cptr
, "sample_sig_bits -i %d", &bitwidth
) ;
227 if (strstr (psf_header
, "channels_interleaved -s5 FALSE"))
228 { psf_log_printf (psf
, "Non-interleaved data unsupported.\n", str
) ;
229 return SFE_NIST_BAD_ENCODING
;
232 psf
->blockwidth
= psf
->sf
.channels
* psf
->bytewidth
;
233 psf
->datalength
= psf
->filelength
- psf
->dataoffset
;
235 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
237 if (encoding
== SF_FORMAT_PCM_U8
)
238 { switch (psf
->bytewidth
)
240 psf
->sf
.format
|= SF_FORMAT_PCM_S8
;
244 psf
->sf
.format
|= SF_FORMAT_PCM_16
;
248 psf
->sf
.format
|= SF_FORMAT_PCM_24
;
252 psf
->sf
.format
|= SF_FORMAT_PCM_32
;
258 else if (encoding
!= 0)
259 psf
->sf
.format
|= encoding
;
261 return SFE_UNIMPLEMENTED
;
263 /* Sanitize psf->sf.format. */
264 switch (SF_CODEC (psf
->sf
.format
))
265 { case SF_FORMAT_ULAW
:
266 case SF_FORMAT_ALAW
:
267 case SF_FORMAT_PCM_U8
:
268 /* Blank out endian bits. */
269 psf
->sf
.format
= SF_FORMAT_NIST
| SF_CODEC (psf
->sf
.format
) ;
277 } /* nist_read_header */
280 nist_close (SF_PRIVATE
*psf
)
282 if (psf
->file
.mode
== SFM_WRITE
|| psf
->file
.mode
== SFM_RDWR
)
283 nist_write_header (psf
, SF_TRUE
) ;
288 /*=========================================================================
292 nist_write_header (SF_PRIVATE
*psf
, int calc_length
)
293 { const char *end_str
;
297 current
= psf_ftell (psf
) ;
300 { psf
->filelength
= psf_get_filelen (psf
) ;
302 psf
->datalength
= psf
->filelength
- psf
->dataoffset
;
305 psf
->datalength
-= psf
->filelength
- psf
->dataend
;
307 if (psf
->bytewidth
> 0)
308 psf
->sf
.frames
= psf
->datalength
/ (psf
->bytewidth
* psf
->sf
.channels
) ;
311 if (psf
->endian
== SF_ENDIAN_BIG
)
313 else if (psf
->endian
== SF_ENDIAN_LITTLE
)
318 /* Clear the whole header. */
319 memset (psf
->header
, 0, sizeof (psf
->header
)) ;
322 psf_fseek (psf
, 0, SEEK_SET
) ;
324 psf_asciiheader_printf (psf
, "NIST_1A\n 1024\n") ;
325 psf_asciiheader_printf (psf
, "channel_count -i %d\n", psf
->sf
.channels
) ;
326 psf_asciiheader_printf (psf
, "sample_rate -i %d\n", psf
->sf
.samplerate
) ;
328 switch (SF_CODEC (psf
->sf
.format
))
329 { case SF_FORMAT_PCM_S8
:
330 psf_asciiheader_printf (psf
, "sample_coding -s3 pcm\n") ;
331 psf_asciiheader_printf (psf
, "sample_n_bytes -i 1\n"
332 "sample_sig_bits -i 8\n") ;
335 case SF_FORMAT_PCM_16
:
336 case SF_FORMAT_PCM_24
:
337 case SF_FORMAT_PCM_32
:
338 psf_asciiheader_printf (psf
, "sample_n_bytes -i %d\n", psf
->bytewidth
) ;
339 psf_asciiheader_printf (psf
, "sample_sig_bits -i %d\n", psf
->bytewidth
* 8) ;
340 psf_asciiheader_printf (psf
, "sample_coding -s3 pcm\n"
341 "sample_byte_format -s%d %s\n", psf
->bytewidth
, end_str
) ;
344 case SF_FORMAT_ALAW
:
345 psf_asciiheader_printf (psf
, "sample_coding -s4 alaw\n") ;
346 psf_asciiheader_printf (psf
, "sample_n_bytes -s1 1\n") ;
349 case SF_FORMAT_ULAW
:
350 psf_asciiheader_printf (psf
, "sample_coding -s4 ulaw\n") ;
351 psf_asciiheader_printf (psf
, "sample_n_bytes -s1 1\n") ;
354 default : return SFE_UNIMPLEMENTED
;
357 psf
->dataoffset
= NIST_HEADER_LENGTH
;
360 samples
= psf
->sf
.frames
;
361 psf_asciiheader_printf (psf
, "sample_count -i %ld\n", samples
) ;
362 psf_asciiheader_printf (psf
, "end_head\n") ;
364 /* Zero fill to dataoffset. */
365 psf_binheader_writef (psf
, "z", (size_t) (NIST_HEADER_LENGTH
- psf
->headindex
)) ;
367 psf_fwrite (psf
->header
, psf
->headindex
, 1, psf
) ;
373 psf_fseek (psf
, current
, SEEK_SET
) ;
376 } /* nist_write_header */