annotate src/libsndfile-1.0.25/src/mat5.c @ 50:37d53a7e8262

Headers for KJ/Capnp Win32
author Chris Cannam
date Wed, 26 Oct 2016 13:18:45 +0100
parents c7265573341e
children
rev   line source
Chris@0 1 /*
Chris@0 2 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@0 3 **
Chris@0 4 ** This program is free software; you can redistribute it and/or modify
Chris@0 5 ** it under the terms of the GNU Lesser General Public License as published by
Chris@0 6 ** the Free Software Foundation; either version 2.1 of the License, or
Chris@0 7 ** (at your option) any later version.
Chris@0 8 **
Chris@0 9 ** This program is distributed in the hope that it will be useful,
Chris@0 10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 ** GNU Lesser General Public License for more details.
Chris@0 13 **
Chris@0 14 ** You should have received a copy of the GNU Lesser General Public License
Chris@0 15 ** along with this program; if not, write to the Free Software
Chris@0 16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Chris@0 17 */
Chris@0 18
Chris@0 19 #include "sfconfig.h"
Chris@0 20
Chris@0 21 #include <stdio.h>
Chris@0 22 #include <fcntl.h>
Chris@0 23 #include <string.h>
Chris@0 24 #include <ctype.h>
Chris@0 25 #include <math.h>
Chris@0 26
Chris@0 27 #include "sndfile.h"
Chris@0 28 #include "sfendian.h"
Chris@0 29 #include "common.h"
Chris@0 30
Chris@0 31 /*------------------------------------------------------------------------------
Chris@0 32 ** Information on how to decode and encode this file was obtained in a PDF
Chris@0 33 ** file which I found on http://www.wotsit.org/.
Chris@0 34 ** Also did a lot of testing with GNU Octave but do not have access to
Chris@0 35 ** Matlab (tm) and so could not test it there.
Chris@0 36 */
Chris@0 37
Chris@0 38 /*------------------------------------------------------------------------------
Chris@0 39 ** Macros to handle big/little endian issues.
Chris@0 40 */
Chris@0 41
Chris@0 42 #define MATL_MARKER (MAKE_MARKER ('M', 'A', 'T', 'L'))
Chris@0 43
Chris@0 44 #define IM_MARKER (('I' << 8) + 'M')
Chris@0 45 #define MI_MARKER (('M' << 8) + 'I')
Chris@0 46
Chris@0 47 /*------------------------------------------------------------------------------
Chris@0 48 ** Enums and typedefs.
Chris@0 49 */
Chris@0 50
Chris@0 51 enum
Chris@0 52 { MAT5_TYPE_SCHAR = 0x1,
Chris@0 53 MAT5_TYPE_UCHAR = 0x2,
Chris@0 54 MAT5_TYPE_INT16 = 0x3,
Chris@0 55 MAT5_TYPE_UINT16 = 0x4,
Chris@0 56 MAT5_TYPE_INT32 = 0x5,
Chris@0 57 MAT5_TYPE_UINT32 = 0x6,
Chris@0 58 MAT5_TYPE_FLOAT = 0x7,
Chris@0 59 MAT5_TYPE_DOUBLE = 0x9,
Chris@0 60 MAT5_TYPE_ARRAY = 0xE,
Chris@0 61
Chris@0 62 MAT5_TYPE_COMP_USHORT = 0x00020004,
Chris@0 63 MAT5_TYPE_COMP_UINT = 0x00040006
Chris@0 64 } ;
Chris@0 65
Chris@0 66 typedef struct
Chris@0 67 { sf_count_t size ;
Chris@0 68 int rows, cols ;
Chris@0 69 char name [32] ;
Chris@0 70 } MAT5_MATRIX ;
Chris@0 71
Chris@0 72 /*------------------------------------------------------------------------------
Chris@0 73 ** Private static functions.
Chris@0 74 */
Chris@0 75
Chris@0 76 static int mat5_close (SF_PRIVATE *psf) ;
Chris@0 77
Chris@0 78 static int mat5_write_header (SF_PRIVATE *psf, int calc_length) ;
Chris@0 79 static int mat5_read_header (SF_PRIVATE *psf) ;
Chris@0 80
Chris@0 81 /*------------------------------------------------------------------------------
Chris@0 82 ** Public function.
Chris@0 83 */
Chris@0 84
Chris@0 85 int
Chris@0 86 mat5_open (SF_PRIVATE *psf)
Chris@0 87 { int subformat, error = 0 ;
Chris@0 88
Chris@0 89 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
Chris@0 90 { if ((error = mat5_read_header (psf)))
Chris@0 91 return error ;
Chris@0 92 } ;
Chris@0 93
Chris@0 94 if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_MAT5)
Chris@0 95 return SFE_BAD_OPEN_FORMAT ;
Chris@0 96
Chris@0 97 subformat = SF_CODEC (psf->sf.format) ;
Chris@0 98
Chris@0 99 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
Chris@0 100 { if (psf->is_pipe)
Chris@0 101 return SFE_NO_PIPE_WRITE ;
Chris@0 102
Chris@0 103 psf->endian = SF_ENDIAN (psf->sf.format) ;
Chris@0 104 if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
Chris@0 105 psf->endian = SF_ENDIAN_LITTLE ;
Chris@0 106 else if (CPU_IS_BIG_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
Chris@0 107 psf->endian = SF_ENDIAN_BIG ;
Chris@0 108
Chris@0 109 if ((error = mat5_write_header (psf, SF_FALSE)))
Chris@0 110 return error ;
Chris@0 111
Chris@0 112 psf->write_header = mat5_write_header ;
Chris@0 113 } ;
Chris@0 114
Chris@0 115 psf->container_close = mat5_close ;
Chris@0 116
Chris@0 117 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
Chris@0 118
Chris@0 119 switch (subformat)
Chris@0 120 { case SF_FORMAT_PCM_U8 :
Chris@0 121 case SF_FORMAT_PCM_16 :
Chris@0 122 case SF_FORMAT_PCM_32 :
Chris@0 123 error = pcm_init (psf) ;
Chris@0 124 break ;
Chris@0 125
Chris@0 126 case SF_FORMAT_FLOAT :
Chris@0 127 error = float32_init (psf) ;
Chris@0 128 break ;
Chris@0 129
Chris@0 130 case SF_FORMAT_DOUBLE :
Chris@0 131 error = double64_init (psf) ;
Chris@0 132 break ;
Chris@0 133
Chris@0 134 default : break ;
Chris@0 135 } ;
Chris@0 136
Chris@0 137 return error ;
Chris@0 138 } /* mat5_open */
Chris@0 139
Chris@0 140 /*------------------------------------------------------------------------------
Chris@0 141 */
Chris@0 142
Chris@0 143 static int
Chris@0 144 mat5_close (SF_PRIVATE *psf)
Chris@0 145 {
Chris@0 146 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
Chris@0 147 mat5_write_header (psf, SF_TRUE) ;
Chris@0 148
Chris@0 149 return 0 ;
Chris@0 150 } /* mat5_close */
Chris@0 151
Chris@0 152 /*------------------------------------------------------------------------------
Chris@0 153 */
Chris@0 154
Chris@0 155 static int
Chris@0 156 mat5_write_header (SF_PRIVATE *psf, int calc_length)
Chris@0 157 { static const char *filename = "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", " ;
Chris@0 158 static const char *sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ;
Chris@0 159 static const char *wd_name = "wavedata\0" ;
Chris@0 160 sf_count_t current, datasize ;
Chris@0 161 int encoding ;
Chris@0 162
Chris@0 163 current = psf_ftell (psf) ;
Chris@0 164
Chris@0 165 if (calc_length)
Chris@0 166 { psf_fseek (psf, 0, SEEK_END) ;
Chris@0 167 psf->filelength = psf_ftell (psf) ;
Chris@0 168 psf_fseek (psf, 0, SEEK_SET) ;
Chris@0 169
Chris@0 170 psf->datalength = psf->filelength - psf->dataoffset ;
Chris@0 171 if (psf->dataend)
Chris@0 172 psf->datalength -= psf->filelength - psf->dataend ;
Chris@0 173
Chris@0 174 psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
Chris@0 175 } ;
Chris@0 176
Chris@0 177 switch (SF_CODEC (psf->sf.format))
Chris@0 178 { case SF_FORMAT_PCM_U8 :
Chris@0 179 encoding = MAT5_TYPE_UCHAR ;
Chris@0 180 break ;
Chris@0 181
Chris@0 182 case SF_FORMAT_PCM_16 :
Chris@0 183 encoding = MAT5_TYPE_INT16 ;
Chris@0 184 break ;
Chris@0 185
Chris@0 186 case SF_FORMAT_PCM_32 :
Chris@0 187 encoding = MAT5_TYPE_INT32 ;
Chris@0 188 break ;
Chris@0 189
Chris@0 190 case SF_FORMAT_FLOAT :
Chris@0 191 encoding = MAT5_TYPE_FLOAT ;
Chris@0 192 break ;
Chris@0 193
Chris@0 194 case SF_FORMAT_DOUBLE :
Chris@0 195 encoding = MAT5_TYPE_DOUBLE ;
Chris@0 196 break ;
Chris@0 197
Chris@0 198 default :
Chris@0 199 return SFE_BAD_OPEN_FORMAT ;
Chris@0 200 } ;
Chris@0 201
Chris@0 202 /* Reset the current header length to zero. */
Chris@0 203 psf->header [0] = 0 ;
Chris@0 204 psf->headindex = 0 ;
Chris@0 205 psf_fseek (psf, 0, SEEK_SET) ;
Chris@0 206
Chris@0 207 psf_get_date_str (psf->u.cbuf, sizeof (psf->u.scbuf)) ;
Chris@0 208 psf_binheader_writef (psf, "bb", filename, strlen (filename), psf->u.cbuf, strlen (psf->u.cbuf) + 1) ;
Chris@0 209
Chris@0 210 memset (psf->u.scbuf, ' ', 124 - psf->headindex) ;
Chris@0 211 psf_binheader_writef (psf, "b", psf->u.scbuf, make_size_t (124 - psf->headindex)) ;
Chris@0 212
Chris@0 213 psf->rwf_endian = psf->endian ;
Chris@0 214
Chris@0 215 if (psf->rwf_endian == SF_ENDIAN_BIG)
Chris@0 216 psf_binheader_writef (psf, "2b", 0x0100, "MI", make_size_t (2)) ;
Chris@0 217 else
Chris@0 218 psf_binheader_writef (psf, "2b", 0x0100, "IM", make_size_t (2)) ;
Chris@0 219
Chris@0 220 psf_binheader_writef (psf, "444444", MAT5_TYPE_ARRAY, 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
Chris@0 221 psf_binheader_writef (psf, "4444", MAT5_TYPE_INT32, 8, 1, 1) ;
Chris@0 222 psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (sr_name), sr_name, make_size_t (16)) ;
Chris@0 223
Chris@0 224 if (psf->sf.samplerate > 0xFFFF)
Chris@0 225 psf_binheader_writef (psf, "44", MAT5_TYPE_COMP_UINT, psf->sf.samplerate) ;
Chris@0 226 else
Chris@0 227 { unsigned short samplerate = psf->sf.samplerate ;
Chris@0 228
Chris@0 229 psf_binheader_writef (psf, "422", MAT5_TYPE_COMP_USHORT, samplerate, 0) ;
Chris@0 230 } ;
Chris@0 231
Chris@0 232 datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;
Chris@0 233
Chris@0 234 psf_binheader_writef (psf, "t484444", MAT5_TYPE_ARRAY, datasize + 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
Chris@0 235 psf_binheader_writef (psf, "t4448", MAT5_TYPE_INT32, 8, psf->sf.channels, psf->sf.frames) ;
Chris@0 236 psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (wd_name), wd_name, strlen (wd_name)) ;
Chris@0 237
Chris@0 238 datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;
Chris@0 239 if (datasize > 0x7FFFFFFF)
Chris@0 240 datasize = 0x7FFFFFFF ;
Chris@0 241
Chris@0 242 psf_binheader_writef (psf, "t48", encoding, datasize) ;
Chris@0 243
Chris@0 244 /* Header construction complete so write it out. */
Chris@0 245 psf_fwrite (psf->header, psf->headindex, 1, psf) ;
Chris@0 246
Chris@0 247 if (psf->error)
Chris@0 248 return psf->error ;
Chris@0 249
Chris@0 250 psf->dataoffset = psf->headindex ;
Chris@0 251
Chris@0 252 if (current > 0)
Chris@0 253 psf_fseek (psf, current, SEEK_SET) ;
Chris@0 254
Chris@0 255 return psf->error ;
Chris@0 256 } /* mat5_write_header */
Chris@0 257
Chris@0 258 static int
Chris@0 259 mat5_read_header (SF_PRIVATE *psf)
Chris@0 260 { char name [32] ;
Chris@0 261 short version, endian ;
Chris@0 262 int type, flags1, flags2, rows, cols ;
Chris@0 263 unsigned size ;
Chris@0 264
Chris@0 265 psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, 124) ;
Chris@0 266
Chris@0 267 psf->u.scbuf [125] = 0 ;
Chris@0 268
Chris@0 269 if (strlen (psf->u.cbuf) >= 124)
Chris@0 270 return SFE_UNIMPLEMENTED ;
Chris@0 271
Chris@0 272 if (strstr (psf->u.cbuf, "MATLAB 5.0 MAT-file") == psf->u.cbuf)
Chris@0 273 psf_log_printf (psf, "%s\n", psf->u.scbuf) ;
Chris@0 274
Chris@0 275
Chris@0 276 psf_binheader_readf (psf, "E22", &version, &endian) ;
Chris@0 277
Chris@0 278 if (endian == MI_MARKER)
Chris@0 279 { psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
Chris@0 280 if (CPU_IS_LITTLE_ENDIAN) version = ENDSWAP_SHORT (version) ;
Chris@0 281 }
Chris@0 282 else if (endian == IM_MARKER)
Chris@0 283 { psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
Chris@0 284 if (CPU_IS_BIG_ENDIAN) version = ENDSWAP_SHORT (version) ;
Chris@0 285 }
Chris@0 286 else
Chris@0 287 return SFE_MAT5_BAD_ENDIAN ;
Chris@0 288
Chris@0 289 if ((CPU_IS_LITTLE_ENDIAN && endian == IM_MARKER) ||
Chris@0 290 (CPU_IS_BIG_ENDIAN && endian == MI_MARKER))
Chris@0 291 version = ENDSWAP_SHORT (version) ;
Chris@0 292
Chris@0 293 psf_log_printf (psf, "Version : 0x%04X\n", version) ;
Chris@0 294 psf_log_printf (psf, "Endian : 0x%04X => %s\n", endian,
Chris@0 295 (psf->endian == SF_ENDIAN_LITTLE) ? "Little" : "Big") ;
Chris@0 296
Chris@0 297 /*========================================================*/
Chris@0 298 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 299 psf_log_printf (psf, "Block\n Type : %X Size : %d\n", type, size) ;
Chris@0 300
Chris@0 301 if (type != MAT5_TYPE_ARRAY)
Chris@0 302 return SFE_MAT5_NO_BLOCK ;
Chris@0 303
Chris@0 304 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 305 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 306
Chris@0 307 if (type != MAT5_TYPE_UINT32)
Chris@0 308 return SFE_MAT5_NO_BLOCK ;
Chris@0 309
Chris@0 310 psf_binheader_readf (psf, "44", &flags1, &flags2) ;
Chris@0 311 psf_log_printf (psf, " Flg1 : %X Flg2 : %d\n", flags1, flags2) ;
Chris@0 312
Chris@0 313 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 314 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 315
Chris@0 316 if (type != MAT5_TYPE_INT32)
Chris@0 317 return SFE_MAT5_NO_BLOCK ;
Chris@0 318
Chris@0 319 psf_binheader_readf (psf, "44", &rows, &cols) ;
Chris@0 320 psf_log_printf (psf, " Rows : %X Cols : %d\n", rows, cols) ;
Chris@0 321
Chris@0 322 if (rows != 1 || cols != 1)
Chris@0 323 return SFE_MAT5_SAMPLE_RATE ;
Chris@0 324
Chris@0 325 psf_binheader_readf (psf, "4", &type) ;
Chris@0 326
Chris@0 327 if (type == MAT5_TYPE_SCHAR)
Chris@0 328 { psf_binheader_readf (psf, "4", &size) ;
Chris@0 329 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 330 if (size > SIGNED_SIZEOF (name) - 1)
Chris@0 331 { psf_log_printf (psf, "Error : Bad name length.\n") ;
Chris@0 332 return SFE_MAT5_NO_BLOCK ;
Chris@0 333 } ;
Chris@0 334
Chris@0 335 psf_binheader_readf (psf, "bj", name, size, (8 - (size % 8)) % 8) ;
Chris@0 336 name [size] = 0 ;
Chris@0 337 }
Chris@0 338 else if ((type & 0xFFFF) == MAT5_TYPE_SCHAR)
Chris@0 339 { size = type >> 16 ;
Chris@0 340 if (size > 4)
Chris@0 341 { psf_log_printf (psf, "Error : Bad name length.\n") ;
Chris@0 342 return SFE_MAT5_NO_BLOCK ;
Chris@0 343 } ;
Chris@0 344
Chris@0 345 psf_log_printf (psf, " Type : %X\n", type) ;
Chris@0 346 psf_binheader_readf (psf, "4", &name) ;
Chris@0 347 name [size] = 0 ;
Chris@0 348 }
Chris@0 349 else
Chris@0 350 return SFE_MAT5_NO_BLOCK ;
Chris@0 351
Chris@0 352 psf_log_printf (psf, " Name : %s\n", name) ;
Chris@0 353
Chris@0 354 /*-----------------------------------------*/
Chris@0 355
Chris@0 356 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 357
Chris@0 358 switch (type)
Chris@0 359 { case MAT5_TYPE_DOUBLE :
Chris@0 360 { double samplerate ;
Chris@0 361
Chris@0 362 psf_binheader_readf (psf, "d", &samplerate) ;
Chris@0 363 snprintf (name, sizeof (name), "%f\n", samplerate) ;
Chris@0 364 psf_log_printf (psf, " Val : %s\n", name) ;
Chris@0 365
Chris@0 366 psf->sf.samplerate = lrint (samplerate) ;
Chris@0 367 } ;
Chris@0 368 break ;
Chris@0 369
Chris@0 370 case MAT5_TYPE_COMP_USHORT :
Chris@0 371 { unsigned short samplerate ;
Chris@0 372
Chris@0 373 psf_binheader_readf (psf, "j2j", -4, &samplerate, 2) ;
Chris@0 374 psf_log_printf (psf, " Val : %u\n", samplerate) ;
Chris@0 375 psf->sf.samplerate = samplerate ;
Chris@0 376 }
Chris@0 377 break ;
Chris@0 378
Chris@0 379 case MAT5_TYPE_COMP_UINT :
Chris@0 380 psf_log_printf (psf, " Val : %u\n", size) ;
Chris@0 381 psf->sf.samplerate = size ;
Chris@0 382 break ;
Chris@0 383
Chris@0 384 default :
Chris@0 385 psf_log_printf (psf, " Type : %X Size : %d ***\n", type, size) ;
Chris@0 386 return SFE_MAT5_SAMPLE_RATE ;
Chris@0 387 } ;
Chris@0 388
Chris@0 389 /*-----------------------------------------*/
Chris@0 390
Chris@0 391
Chris@0 392 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 393 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 394
Chris@0 395 if (type != MAT5_TYPE_ARRAY)
Chris@0 396 return SFE_MAT5_NO_BLOCK ;
Chris@0 397
Chris@0 398 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 399 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 400
Chris@0 401 if (type != MAT5_TYPE_UINT32)
Chris@0 402 return SFE_MAT5_NO_BLOCK ;
Chris@0 403
Chris@0 404 psf_binheader_readf (psf, "44", &flags1, &flags2) ;
Chris@0 405 psf_log_printf (psf, " Flg1 : %X Flg2 : %d\n", flags1, flags2) ;
Chris@0 406
Chris@0 407 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 408 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 409
Chris@0 410 if (type != MAT5_TYPE_INT32)
Chris@0 411 return SFE_MAT5_NO_BLOCK ;
Chris@0 412
Chris@0 413 psf_binheader_readf (psf, "44", &rows, &cols) ;
Chris@0 414 psf_log_printf (psf, " Rows : %X Cols : %d\n", rows, cols) ;
Chris@0 415
Chris@0 416 psf_binheader_readf (psf, "4", &type) ;
Chris@0 417
Chris@0 418 if (type == MAT5_TYPE_SCHAR)
Chris@0 419 { psf_binheader_readf (psf, "4", &size) ;
Chris@0 420 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 421 if (size > SIGNED_SIZEOF (name) - 1)
Chris@0 422 { psf_log_printf (psf, "Error : Bad name length.\n") ;
Chris@0 423 return SFE_MAT5_NO_BLOCK ;
Chris@0 424 } ;
Chris@0 425
Chris@0 426 psf_binheader_readf (psf, "bj", name, size, (8 - (size % 8)) % 8) ;
Chris@0 427 name [size] = 0 ;
Chris@0 428 }
Chris@0 429 else if ((type & 0xFFFF) == MAT5_TYPE_SCHAR)
Chris@0 430 { size = type >> 16 ;
Chris@0 431 if (size > 4)
Chris@0 432 { psf_log_printf (psf, "Error : Bad name length.\n") ;
Chris@0 433 return SFE_MAT5_NO_BLOCK ;
Chris@0 434 } ;
Chris@0 435
Chris@0 436 psf_log_printf (psf, " Type : %X\n", type) ;
Chris@0 437 psf_binheader_readf (psf, "4", &name) ;
Chris@0 438 name [size] = 0 ;
Chris@0 439 }
Chris@0 440 else
Chris@0 441 return SFE_MAT5_NO_BLOCK ;
Chris@0 442
Chris@0 443 psf_log_printf (psf, " Name : %s\n", name) ;
Chris@0 444
Chris@0 445 psf_binheader_readf (psf, "44", &type, &size) ;
Chris@0 446 psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
Chris@0 447
Chris@0 448 /*++++++++++++++++++++++++++++++++++++++++++++++++++*/
Chris@0 449
Chris@0 450 if (rows == 0 && cols == 0)
Chris@0 451 { psf_log_printf (psf, "*** Error : zero channel count.\n") ;
Chris@0 452 return SFE_CHANNEL_COUNT_ZERO ;
Chris@0 453 } ;
Chris@0 454
Chris@0 455 psf->sf.channels = rows ;
Chris@0 456 psf->sf.frames = cols ;
Chris@0 457
Chris@0 458 psf->sf.format = psf->endian | SF_FORMAT_MAT5 ;
Chris@0 459
Chris@0 460 switch (type)
Chris@0 461 { case MAT5_TYPE_DOUBLE :
Chris@0 462 psf_log_printf (psf, "Data type : double\n") ;
Chris@0 463 psf->sf.format |= SF_FORMAT_DOUBLE ;
Chris@0 464 psf->bytewidth = 8 ;
Chris@0 465 break ;
Chris@0 466
Chris@0 467 case MAT5_TYPE_FLOAT :
Chris@0 468 psf_log_printf (psf, "Data type : float\n") ;
Chris@0 469 psf->sf.format |= SF_FORMAT_FLOAT ;
Chris@0 470 psf->bytewidth = 4 ;
Chris@0 471 break ;
Chris@0 472
Chris@0 473 case MAT5_TYPE_INT32 :
Chris@0 474 psf_log_printf (psf, "Data type : 32 bit PCM\n") ;
Chris@0 475 psf->sf.format |= SF_FORMAT_PCM_32 ;
Chris@0 476 psf->bytewidth = 4 ;
Chris@0 477 break ;
Chris@0 478
Chris@0 479 case MAT5_TYPE_INT16 :
Chris@0 480 psf_log_printf (psf, "Data type : 16 bit PCM\n") ;
Chris@0 481 psf->sf.format |= SF_FORMAT_PCM_16 ;
Chris@0 482 psf->bytewidth = 2 ;
Chris@0 483 break ;
Chris@0 484
Chris@0 485 case MAT5_TYPE_UCHAR :
Chris@0 486 psf_log_printf (psf, "Data type : unsigned 8 bit PCM\n") ;
Chris@0 487 psf->sf.format |= SF_FORMAT_PCM_U8 ;
Chris@0 488 psf->bytewidth = 1 ;
Chris@0 489 break ;
Chris@0 490
Chris@0 491 default :
Chris@0 492 psf_log_printf (psf, "*** Error : Bad marker %08X\n", type) ;
Chris@0 493 return SFE_UNIMPLEMENTED ;
Chris@0 494 } ;
Chris@0 495
Chris@0 496 psf->dataoffset = psf_ftell (psf) ;
Chris@0 497 psf->datalength = psf->filelength - psf->dataoffset ;
Chris@0 498
Chris@0 499 return 0 ;
Chris@0 500 } /* mat5_read_header */
Chris@0 501