1/* 2** Copyright (C) 1999-2017 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/* 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. 24*/ 25 26#include "sfconfig.h" 27 28#include <stdio.h> 29#include <fcntl.h> 30#include <string.h> 31#include <ctype.h> 32 33#include "sndfile.h" 34#include "sfendian.h" 35#include "common.h" 36 37/*------------------------------------------------------------------------------ 38*/ 39 40#define NIST_HEADER_LENGTH 1024 41 42/*------------------------------------------------------------------------------ 43** Private static functions. 44*/ 45 46static int nist_close (SF_PRIVATE *psf) ; 47static int nist_write_header (SF_PRIVATE *psf, int calc_length) ; 48static int nist_read_header (SF_PRIVATE *psf) ; 49 50/*------------------------------------------------------------------------------ 51*/ 52 53int 54nist_open (SF_PRIVATE *psf) 55{ int error ; 56 57 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) 58 { if ((error = nist_read_header (psf))) 59 return error ; 60 } ; 61 62 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 63 { if (psf->is_pipe) 64 return SFE_NO_PIPE_WRITE ; 65 66 if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_NIST) 67 return SFE_BAD_OPEN_FORMAT ; 68 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 ; 72 73 psf->blockwidth = psf->bytewidth * psf->sf.channels ; 74 psf->sf.frames = 0 ; 75 76 if ((error = nist_write_header (psf, SF_FALSE))) 77 return error ; 78 79 psf->write_header = nist_write_header ; 80 } ; 81 82 psf->container_close = nist_close ; 83 84 switch (SF_CODEC (psf->sf.format)) 85 { case SF_FORMAT_PCM_S8 : 86 error = pcm_init (psf) ; 87 break ; 88 89 case SF_FORMAT_PCM_16 : 90 case SF_FORMAT_PCM_24 : 91 case SF_FORMAT_PCM_32 : 92 error = pcm_init (psf) ; 93 break ; 94 95 case SF_FORMAT_ULAW : 96 error = ulaw_init (psf) ; 97 break ; 98 99 case SF_FORMAT_ALAW : 100 error = alaw_init (psf) ; 101 break ; 102 103 default : error = SFE_UNIMPLEMENTED ; 104 break ; 105 } ; 106 107 return error ; 108} /* nist_open */ 109 110/*------------------------------------------------------------------------------ 111*/ 112 113static char bad_header [] = 114{ 'N', 'I', 'S', 'T', '_', '1', 'A', 0x0d, 0x0a, 115 ' ', ' ', ' ', '1', '0', '2', '4', 0x0d, 0x0a, 116 0 117} ; 118 119 static int 120nist_read_header (SF_PRIVATE *psf) 121{ char psf_header [NIST_HEADER_LENGTH + 2] ; 122 int bitwidth = 0, count, encoding ; 123 unsigned bytes = 0 ; 124 char str [64], *cptr ; 125 long samples ; 126 127 /* Go to start of file and read in the whole header. */ 128 psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ; 129 130 /* Header is a string, so make sure it is null terminated. */ 131 psf_header [NIST_HEADER_LENGTH] = 0 ; 132 133 /* Now trim the header after the end marker. */ 134 if ((cptr = strstr (psf_header, "end_head"))) 135 { cptr += strlen ("end_head") + 1 ; 136 cptr [0] = 0 ; 137 } ; 138 139 if (strstr (psf_header, bad_header) == psf_header) 140 return SFE_NIST_CRLF_CONVERISON ; 141 142 /* Make sure its a NIST file. */ 143 if (strstr (psf_header, "NIST_1A\n") != psf_header) 144 { psf_log_printf (psf, "Not a NIST file.\n") ; 145 return SFE_NIST_BAD_HEADER ; 146 } ; 147 148 if (sscanf (psf_header, "NIST_1A\n%d\n", &count) == 1) 149 psf->dataoffset = count ; 150 else 151 { psf_log_printf (psf, "*** Suspicious header length.\n") ; 152 psf->dataoffset = NIST_HEADER_LENGTH ; 153 } ; 154 155 /* Determine sample encoding, start by assuming PCM. */ 156 encoding = SF_FORMAT_PCM_U8 ; 157 if ((cptr = strstr (psf_header, "sample_coding -s"))) 158 { sscanf (cptr, "sample_coding -s%d %63s", &count, str) ; 159 160 if (strcmp (str, "pcm") == 0) 161 { /* Correct this later when we find out the bitwidth. */ 162 encoding = SF_FORMAT_PCM_U8 ; 163 } 164 else if (strcmp (str, "alaw") == 0) 165 encoding = SF_FORMAT_ALAW ; 166 else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0)) 167 encoding = SF_FORMAT_ULAW ; 168 else 169 { psf_log_printf (psf, "*** Unknown encoding : %s\n", str) ; 170 encoding = 0 ; 171 } ; 172 } ; 173 174 if ((cptr = strstr (psf_header, "channel_count -i ")) != NULL) 175 sscanf (cptr, "channel_count -i %d", &(psf->sf.channels)) ; 176 177 if ((cptr = strstr (psf_header, "sample_rate -i ")) != NULL) 178 sscanf (cptr, "sample_rate -i %d", &(psf->sf.samplerate)) ; 179 180 if ((cptr = strstr (psf_header, "sample_count -i ")) != NULL) 181 { sscanf (cptr, "sample_count -i %ld", &samples) ; 182 psf->sf.frames = samples ; 183 } ; 184 185 if ((cptr = strstr (psf_header, "sample_n_bytes -i ")) != NULL) 186 sscanf (cptr, "sample_n_bytes -i %d", &(psf->bytewidth)) ; 187 188 /* Default endian-ness (for 8 bit, u-law, A-law. */ 189 psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ; 190 191 /* This is where we figure out endian-ness. */ 192 if ((cptr = strstr (psf_header, "sample_byte_format -s")) 193 && sscanf (cptr, "sample_byte_format -s%u %8s", &bytes, str) == 2) 194 { 195 if (bytes != strlen (str)) 196 psf_log_printf (psf, "Weird sample_byte_format : strlen '%s' != %d\n", str, bytes) ; 197 198 if (bytes > 1) 199 { if (psf->bytewidth == 0) 200 psf->bytewidth = bytes ; 201 else if (psf->bytewidth - bytes != 0) 202 { psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ; 203 return SFE_NIST_BAD_ENCODING ; 204 } ; 205 206 if (strcmp (str, "01") == 0) 207 psf->endian = SF_ENDIAN_LITTLE ; 208 else if (strcmp (str, "10") == 0) 209 psf->endian = SF_ENDIAN_BIG ; 210 else 211 { psf_log_printf (psf, "Weird endian-ness : %s\n", str) ; 212 return SFE_NIST_BAD_ENCODING ; 213 } ; 214 } ; 215 216 psf->sf.format |= psf->endian ; 217 } ; 218 219 if ((cptr = strstr (psf_header, "sample_sig_bits -i "))) 220 sscanf (cptr, "sample_sig_bits -i %d", &bitwidth) ; 221 222 if (strstr (psf_header, "channels_interleaved -s5 FALSE")) 223 { psf_log_printf (psf, "Non-interleaved data unsupported.\n", str) ; 224 return SFE_NIST_BAD_ENCODING ; 225 } ; 226 227 psf->blockwidth = psf->sf.channels * psf->bytewidth ; 228 psf->datalength = psf->filelength - psf->dataoffset ; 229 230 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 231 232 if (encoding == SF_FORMAT_PCM_U8) 233 { switch (psf->bytewidth) 234 { case 1 : 235 psf->sf.format |= SF_FORMAT_PCM_S8 ; 236 break ; 237 238 case 2 : 239 psf->sf.format |= SF_FORMAT_PCM_16 ; 240 break ; 241 242 case 3 : 243 psf->sf.format |= SF_FORMAT_PCM_24 ; 244 break ; 245 246 case 4 : 247 psf->sf.format |= SF_FORMAT_PCM_32 ; 248 break ; 249 250 default : break ; 251 } ; 252 } 253 else if (encoding != 0) 254 psf->sf.format |= encoding ; 255 else 256 return SFE_UNIMPLEMENTED ; 257 258 /* Sanitize psf->sf.format. */ 259 switch (SF_CODEC (psf->sf.format)) 260 { case SF_FORMAT_ULAW : 261 case SF_FORMAT_ALAW : 262 case SF_FORMAT_PCM_U8 : 263 /* Blank out endian bits. */ 264 psf->sf.format = SF_FORMAT_NIST | SF_CODEC (psf->sf.format) ; 265 break ; 266 267 default : 268 break ; 269 } ; 270 271 return 0 ; 272} /* nist_read_header */ 273 274static int 275nist_close (SF_PRIVATE *psf) 276{ 277 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 278 nist_write_header (psf, SF_TRUE) ; 279 280 return 0 ; 281} /* nist_close */ 282 283/*========================================================================= 284*/ 285 286static int 287nist_write_header (SF_PRIVATE *psf, int calc_length) 288{ const char *end_str ; 289 long samples ; 290 sf_count_t current ; 291 292 current = psf_ftell (psf) ; 293 294 if (calc_length) 295 { psf->filelength = psf_get_filelen (psf) ; 296 297 psf->datalength = psf->filelength - psf->dataoffset ; 298 299 if (psf->dataend) 300 psf->datalength -= psf->filelength - psf->dataend ; 301 302 if (psf->bytewidth > 0) 303 psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; 304 } ; 305 306 if (psf->endian == SF_ENDIAN_BIG) 307 end_str = "10" ; 308 else if (psf->endian == SF_ENDIAN_LITTLE) 309 end_str = "01" ; 310 else 311 end_str = "error" ; 312 313 /* Clear the whole header. */ 314 memset (psf->header.ptr, 0, psf->header.len) ; 315 psf->header.indx = 0 ; 316 317 psf_fseek (psf, 0, SEEK_SET) ; 318 319 psf_asciiheader_printf (psf, "NIST_1A\n 1024\n") ; 320 psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ; 321 psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ; 322 323 switch (SF_CODEC (psf->sf.format)) 324 { case SF_FORMAT_PCM_S8 : 325 psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ; 326 psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n" 327 "sample_sig_bits -i 8\n") ; 328 break ; 329 330 case SF_FORMAT_PCM_16 : 331 case SF_FORMAT_PCM_24 : 332 case SF_FORMAT_PCM_32 : 333 psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ; 334 psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ; 335 psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n" 336 "sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ; 337 break ; 338 339 case SF_FORMAT_ALAW : 340 psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ; 341 psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; 342 break ; 343 344 case SF_FORMAT_ULAW : 345 psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ; 346 psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ; 347 break ; 348 349 default : return SFE_UNIMPLEMENTED ; 350 } ; 351 352 psf->dataoffset = NIST_HEADER_LENGTH ; 353 354 /* Fix this */ 355 samples = psf->sf.frames ; 356 psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ; 357 psf_asciiheader_printf (psf, "end_head\n") ; 358 359 /* Zero fill to dataoffset. */ 360 psf_binheader_writef (psf, "z", BHWz ((size_t) (NIST_HEADER_LENGTH - psf->header.indx))) ; 361 362 psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; 363 364 if (psf->error) 365 return psf->error ; 366 367 if (current > 0) 368 psf_fseek (psf, current, SEEK_SET) ; 369 370 return psf->error ; 371} /* nist_write_header */ 372 373