1/* 2** Copyright (C) 1999-2019 Erik de Castro Lopo <erikd@mega-nerd.com> 3** Copyright (C) 2004-2005 David Viens <davidv@plogue.com> 4** 5** This program is free software; you can redistribute it and/or modify 6** it under the terms of the GNU Lesser General Public License as published by 7** the Free Software Foundation; either version 2.1 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU Lesser General Public License for more details. 14** 15** You should have received a copy of the GNU Lesser General Public License 16** along with this program; if not, write to the Free Software 17** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18*/ 19 20#include "sfconfig.h" 21 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <ctype.h> 26#include <time.h> 27#include <inttypes.h> 28 29#include "sndfile.h" 30#include "sfendian.h" 31#include "common.h" 32#include "wavlike.h" 33 34/*------------------------------------------------------------------------------ 35 * Macros to handle big/little endian issues. 36 */ 37 38#define RIFF_MARKER (MAKE_MARKER ('R', 'I', 'F', 'F')) 39#define RIFX_MARKER (MAKE_MARKER ('R', 'I', 'F', 'X')) 40#define WAVE_MARKER (MAKE_MARKER ('W', 'A', 'V', 'E')) 41#define fmt_MARKER (MAKE_MARKER ('f', 'm', 't', ' ')) 42#define fact_MARKER (MAKE_MARKER ('f', 'a', 'c', 't')) 43 44#define cue_MARKER (MAKE_MARKER ('c', 'u', 'e', ' ')) 45#define slnt_MARKER (MAKE_MARKER ('s', 'l', 'n', 't')) 46#define wavl_MARKER (MAKE_MARKER ('w', 'a', 'v', 'l')) 47#define plst_MARKER (MAKE_MARKER ('p', 'l', 's', 't')) 48#define smpl_MARKER (MAKE_MARKER ('s', 'm', 'p', 'l')) 49#define iXML_MARKER (MAKE_MARKER ('i', 'X', 'M', 'L')) 50#define levl_MARKER (MAKE_MARKER ('l', 'e', 'v', 'l')) 51#define MEXT_MARKER (MAKE_MARKER ('M', 'E', 'X', 'T')) 52#define acid_MARKER (MAKE_MARKER ('a', 'c', 'i', 'd')) 53#define strc_MARKER (MAKE_MARKER ('s', 't', 'r', 'c')) 54#define afsp_MARKER (MAKE_MARKER ('a', 'f', 's', 'p')) 55#define clm_MARKER (MAKE_MARKER ('c', 'l', 'm', ' ')) 56#define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o')) 57#define FLLR_MARKER (MAKE_MARKER ('F', 'L', 'L', 'R')) 58 59#define minf_MARKER (MAKE_MARKER ('m', 'i', 'n', 'f')) 60#define elm1_MARKER (MAKE_MARKER ('e', 'l', 'm', '1')) 61#define regn_MARKER (MAKE_MARKER ('r', 'e', 'g', 'n')) 62#define ovwf_MARKER (MAKE_MARKER ('o', 'v', 'w', 'f')) 63#define umid_MARKER (MAKE_MARKER ('u', 'm', 'i', 'd')) 64#define SyLp_MARKER (MAKE_MARKER ('S', 'y', 'L', 'p')) 65#define Cr8r_MARKER (MAKE_MARKER ('C', 'r', '8', 'r')) 66#define JUNK_MARKER (MAKE_MARKER ('J', 'U', 'N', 'K')) 67#define PMX_MARKER (MAKE_MARKER ('_', 'P', 'M', 'X')) 68#define inst_MARKER (MAKE_MARKER ('i', 'n', 's', 't')) 69#define AFAn_MARKER (MAKE_MARKER ('A', 'F', 'A', 'n')) 70 71 72/* Weird WAVPACK marker which can show up at the start of the DATA section. */ 73#define wvpk_MARKER (MAKE_MARKER ('w', 'v', 'p', 'k')) 74#define OggS_MARKER (MAKE_MARKER ('O', 'g', 'g', 'S')) 75 76/* ID3v1 trailer which can show up at the end and erronerously look like a chunk. */ 77#define TAG__MARKER (MAKE_MARKER ('T', 'A', 'G', 0)) 78#define TAG__MARKER_MASK (MAKE_MARKER (0xff, 0xff, 0xff, 0)) 79 80#define WAVLIKE_PEAK_CHUNK_SIZE(ch) (2 * sizeof (int) + ch * (sizeof (float) + sizeof (int))) 81 82 83enum 84{ HAVE_RIFF = 1 << 0, 85 HAVE_WAVE = 1 << 1, 86 HAVE_fmt = 1 << 2, 87 HAVE_fact = 1 << 3, 88 HAVE_PEAK = 1 << 4, 89 HAVE_data = 1 << 5, 90 HAVE_other = 1 << 6 91} ; 92 93 94/* known WAVEFORMATEXTENSIBLE GUIDS */ 95static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM = 96{ 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 97} ; 98 99#if 0 100static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM = 101{ 0x00000002, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 102} ; 103#endif 104 105static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT = 106{ 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 107} ; 108 109static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW = 110{ 0x00000006, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 111} ; 112 113static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW = 114{ 0x00000007, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 115} ; 116 117/* 118** the next two are from 119** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html 120*/ 121static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM = 122{ 0x00000001, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 } 123} ; 124 125static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT = 126{ 0x00000003, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 } 127} ; 128 129 130#if 0 131/* maybe interesting one day to read the following through sf_read_raw */ 132/* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */ 133static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX = 134{ 0x8312B9C2, 0x2E6E, 0x11d4, { 0xA8, 0x24, 0xDE, 0x5B, 0x96, 0xC3, 0xAB, 0x21 } 135} ; 136#endif 137 138/*------------------------------------------------------------------------------ 139** Private static functions. 140*/ 141 142static int wav_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ; 143static int wav_write_header (SF_PRIVATE *psf, int calc_length) ; 144 145static int wav_write_tailer (SF_PRIVATE *psf) ; 146static int wav_command (SF_PRIVATE *psf, int command, void *data, int datasize) ; 147static int wav_close (SF_PRIVATE *psf) ; 148 149static int wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen) ; 150static int wav_read_acid_chunk (SF_PRIVATE *psf, uint32_t chunklen) ; 151 152static int wav_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ; 153static SF_CHUNK_ITERATOR * wav_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) ; 154static int wav_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ; 155static int wav_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ; 156 157/*------------------------------------------------------------------------------ 158** Public function. 159*/ 160 161int 162wav_open (SF_PRIVATE *psf) 163{ WAVLIKE_PRIVATE * wpriv ; 164 int format, subformat, error, blockalign = 0, framesperblock = 0 ; 165 166 if ((wpriv = calloc (1, sizeof (WAVLIKE_PRIVATE))) == NULL) 167 return SFE_MALLOC_FAILED ; 168 psf->container_data = wpriv ; 169 170 wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ; 171 psf->strings.flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ; 172 173 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) 174 { if ((error = wav_read_header (psf, &blockalign, &framesperblock))) 175 return error ; 176 177 psf->next_chunk_iterator = wav_next_chunk_iterator ; 178 psf->get_chunk_size = wav_get_chunk_size ; 179 psf->get_chunk_data = wav_get_chunk_data ; 180 } ; 181 182 subformat = SF_CODEC (psf->sf.format) ; 183 184 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 185 { if (psf->is_pipe) 186 return SFE_NO_PIPE_WRITE ; 187 188 wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ; 189 190 format = SF_CONTAINER (psf->sf.format) ; 191 if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX) 192 return SFE_BAD_OPEN_FORMAT ; 193 194 psf->blockwidth = psf->bytewidth * psf->sf.channels ; 195 196 /* RIFF WAVs are little-endian, RIFX WAVs are big-endian, default to little */ 197 psf->endian = SF_ENDIAN (psf->sf.format) ; 198 if (CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_CPU) 199 psf->endian = SF_ENDIAN_BIG ; 200 else if (psf->endian != SF_ENDIAN_BIG) 201 psf->endian = SF_ENDIAN_LITTLE ; 202 203 if (psf->file.mode != SFM_RDWR || psf->filelength < 44) 204 { psf->filelength = 0 ; 205 psf->datalength = 0 ; 206 psf->dataoffset = 0 ; 207 psf->sf.frames = 0 ; 208 } ; 209 210#if (ENABLE_EXPERIMENTAL_CODE == 0) 211 /* For now, don't support writing MPEGLAYER3 WAVs, as we can't guarentee that 212 ** such a file written by libsndfile would have the same length when opened again. 213 */ 214 if (subformat == SF_FORMAT_MPEG_LAYER_III) 215 return SFE_UNSUPPORTED_ENCODING ; 216#endif 217 218 if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM) 219 { blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ; 220 framesperblock = -1 ; /* Corrected later. */ 221 } ; 222 223 /* By default, add the peak chunk to floating point files. Default behaviour 224 ** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE). 225 */ 226 if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)) 227 { if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL) 228 return SFE_MALLOC_FAILED ; 229 psf->peak_info->peak_loc = SF_PEAK_START ; 230 } ; 231 232 psf->write_header = wav_write_header ; 233 psf->set_chunk = wav_set_chunk ; 234 } ; 235 236 psf->container_close = wav_close ; 237 psf->command = wav_command ; 238 239 switch (subformat) 240 { case SF_FORMAT_PCM_U8 : 241 case SF_FORMAT_PCM_16 : 242 case SF_FORMAT_PCM_24 : 243 case SF_FORMAT_PCM_32 : 244 error = pcm_init (psf) ; 245 break ; 246 247 case SF_FORMAT_ULAW : 248 error = ulaw_init (psf) ; 249 break ; 250 251 case SF_FORMAT_ALAW : 252 error = alaw_init (psf) ; 253 break ; 254 255 /* Lite remove start */ 256 case SF_FORMAT_FLOAT : 257 error = float32_init (psf) ; 258 break ; 259 260 case SF_FORMAT_DOUBLE : 261 error = double64_init (psf) ; 262 break ; 263 264 case SF_FORMAT_IMA_ADPCM : 265 error = wavlike_ima_init (psf, blockalign, framesperblock) ; 266 break ; 267 268 case SF_FORMAT_MS_ADPCM : 269 error = wavlike_msadpcm_init (psf, blockalign, framesperblock) ; 270 break ; 271 272 case SF_FORMAT_G721_32 : 273 error = g72x_init (psf) ; 274 break ; 275 276 case SF_FORMAT_NMS_ADPCM_16 : 277 case SF_FORMAT_NMS_ADPCM_24 : 278 case SF_FORMAT_NMS_ADPCM_32 : 279 error = nms_adpcm_init (psf) ; 280 break ; 281 282 /* Lite remove end */ 283 284 case SF_FORMAT_GSM610 : 285 error = gsm610_init (psf) ; 286 break ; 287 288 case SF_FORMAT_MPEG_LAYER_III : 289 error = mpeg_init (psf, SF_BITRATE_MODE_CONSTANT, SF_FALSE) ; 290 break ; 291 292 default : return SFE_UNIMPLEMENTED ; 293 } ; 294 295 if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0)) 296 return psf->write_header (psf, SF_FALSE) ; 297 298 return error ; 299} /* wav_open */ 300 301/*========================================================================= 302** Private functions. 303*/ 304 305static int 306wav_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) 307{ WAVLIKE_PRIVATE *wpriv ; 308 WAV_FMT *wav_fmt ; 309 FACT_CHUNK fact_chunk ; 310 uint32_t marker, chunk_size = 0, RIFFsize = 0, done = 0 ; 311 int parsestage = 0, error, format = 0 ; 312 313 if (psf->is_pipe == 0 && psf->filelength > 0xFFFFFFFFLL) 314 psf_log_printf (psf, "Warning : filelength > 0xffffffff. This is bad!!!!\n") ; 315 316 if ((wpriv = psf->container_data) == NULL) 317 return SFE_INTERNAL ; 318 wav_fmt = &wpriv->wav_fmt ; 319 320 /* Set position to start of file to begin reading header. */ 321 psf_binheader_readf (psf, "pmj", 0, &marker, -4) ; 322 psf->header.indx = 0 ; 323 324 /* RIFX signifies big-endian format for all header and data to prevent 325 ** lots of code copying here, we'll set the psf->rwf_endian flag once here, 326 ** and never specify endian-ness for all other header ops/ 327 */ 328 psf->rwf_endian = (marker == RIFF_MARKER) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ; 329 330 while (! done) 331 { size_t jump = chunk_size & 1 ; 332 333 marker = chunk_size = 0 ; 334 psf_binheader_readf (psf, "jm4", jump, &marker, &chunk_size) ; 335 if (marker == 0) 336 { sf_count_t pos = psf_ftell (psf) ; 337 psf_log_printf (psf, "Have 0 marker at position %D (0x%x).\n", pos, pos) ; 338 break ; 339 } ; 340 341 psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ; 342 343 switch (marker) 344 { case RIFF_MARKER : 345 case RIFX_MARKER : 346 if (parsestage) 347 return SFE_WAV_NO_RIFF ; 348 349 parsestage |= HAVE_RIFF ; 350 351 RIFFsize = chunk_size ; 352 353 if (psf->fileoffset > 0 && psf->filelength > RIFFsize + 8) 354 { /* Set file length. */ 355 psf->filelength = RIFFsize + 8 ; 356 if (marker == RIFF_MARKER) 357 psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ; 358 else 359 psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ; 360 } 361 else if (psf->filelength < RIFFsize + 2 * SIGNED_SIZEOF (marker)) 362 { if (marker == RIFF_MARKER) 363 psf_log_printf (psf, "RIFF : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (marker)) ; 364 else 365 psf_log_printf (psf, "RIFX : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (marker)) ; 366 367 RIFFsize = psf->filelength - 2 * SIGNED_SIZEOF (RIFFsize) ; 368 } 369 else 370 { if (marker == RIFF_MARKER) 371 psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ; 372 else 373 psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ; 374 } ; 375 376 psf_binheader_readf (psf, "m", &marker) ; 377 if (marker != WAVE_MARKER) 378 return SFE_WAV_NO_WAVE ; 379 parsestage |= HAVE_WAVE ; 380 psf_log_printf (psf, "WAVE\n") ; 381 chunk_size = 0 ; 382 break ; 383 384 case fmt_MARKER : 385 if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE)) 386 return SFE_WAV_NO_FMT ; 387 388 /* If this file has a SECOND fmt chunk, I don't want to know about it. */ 389 if (parsestage & HAVE_fmt) 390 break ; 391 392 parsestage |= HAVE_fmt ; 393 394 psf_log_printf (psf, "fmt : %d\n", chunk_size) ; 395 396 if ((error = wavlike_read_fmt_chunk (psf, chunk_size))) 397 return error ; 398 399 format = wav_fmt->format ; 400 break ; 401 402 case data_MARKER : 403 if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) 404 return SFE_WAV_NO_DATA ; 405 406 if (psf->file.mode == SFM_RDWR && (parsestage & HAVE_other) != 0) 407 return SFE_RDWR_BAD_HEADER ; 408 409 parsestage |= HAVE_data ; 410 411 psf->datalength = chunk_size ; 412 if (psf->datalength & 1) 413 psf_log_printf (psf, "*** 'data' chunk should be an even number of bytes in length.\n") ; 414 415 psf->dataoffset = psf_ftell (psf) ; 416 417 if (psf->dataoffset > 0) 418 { if (chunk_size == 0 && RIFFsize == 8 && psf->filelength > 44) 419 { psf_log_printf (psf, "*** Looks like a WAV file which wasn't closed properly. Fixing it.\n") ; 420 psf->datalength = psf->filelength - psf->dataoffset ; 421 } ; 422 423 if (psf->datalength > psf->filelength - psf->dataoffset) 424 { psf_log_printf (psf, "data : %D (should be %D)\n", psf->datalength, psf->filelength - psf->dataoffset) ; 425 psf->datalength = psf->filelength - psf->dataoffset ; 426 } 427 else 428 psf_log_printf (psf, "data : %D\n", psf->datalength) ; 429 430 /* Only set dataend if there really is data at the end. */ 431 if (psf->datalength + psf->dataoffset < psf->filelength) 432 psf->dataend = psf->datalength + psf->dataoffset ; 433 434 psf->datalength += chunk_size & 1 ; 435 chunk_size = 0 ; 436 } ; 437 438 if (! psf->sf.seekable || psf->dataoffset < 0) 439 break ; 440 441 /* Seek past data and continue reading header. */ 442 psf_fseek (psf, psf->datalength, SEEK_CUR) ; 443 444 if (psf_ftell (psf) != psf->datalength + psf->dataoffset) 445 psf_log_printf (psf, "*** psf_fseek past end error ***\n") ; 446 break ; 447 448 case fact_MARKER : 449 if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE)) 450 return SFE_WAV_BAD_FACT ; 451 452 parsestage |= HAVE_fact ; 453 454 if ((parsestage & HAVE_fmt) != HAVE_fmt) 455 psf_log_printf (psf, "*** Should have 'fmt ' chunk before 'fact'\n") ; 456 457 psf_binheader_readf (psf, "4", & (fact_chunk.frames)) ; 458 459 if (chunk_size > SIGNED_SIZEOF (fact_chunk)) 460 psf_binheader_readf (psf, "j", (int) (chunk_size - SIGNED_SIZEOF (fact_chunk))) ; 461 462 if (chunk_size) 463 psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ; 464 else 465 psf_log_printf (psf, "%M : %u (should not be zero)\n", marker, chunk_size) ; 466 467 psf_log_printf (psf, " frames : %d\n", fact_chunk.frames) ; 468 break ; 469 470 case PEAK_MARKER : 471 if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) 472 return SFE_WAV_PEAK_B4_FMT ; 473 474 parsestage |= HAVE_PEAK ; 475 476 psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ; 477 if ((error = wavlike_read_peak_chunk (psf, chunk_size)) != 0) 478 return error ; 479 psf->peak_info->peak_loc = ((parsestage & HAVE_data) == 0) ? SF_PEAK_START : SF_PEAK_END ; 480 break ; 481 482 case cue_MARKER : 483 parsestage |= HAVE_other ; 484 485 { uint32_t thisread, bytesread, cue_count, position, offset ; 486 int id, chunk_id, chunk_start, block_start, cue_index ; 487 488 bytesread = psf_binheader_readf (psf, "4", &cue_count) ; 489 psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ; 490 491 if (cue_count > 2500) /* 2500 is close to the largest number of cues possible because of block sizes */ 492 { psf_log_printf (psf, " Count : %u (skipping)\n", cue_count) ; 493 psf_binheader_readf (psf, "j", chunk_size - bytesread) ; 494 break ; 495 } ; 496 497 psf_log_printf (psf, " Count : %d\n", cue_count) ; 498 499 if (psf->cues) 500 { free (psf->cues) ; 501 psf->cues = NULL ; 502 } ; 503 504 if ((psf->cues = psf_cues_alloc (cue_count)) == NULL) 505 return SFE_MALLOC_FAILED ; 506 507 cue_index = 0 ; 508 509 while (cue_count) 510 { 511 if ((thisread = psf_binheader_readf (psf, "e44m444", &id, &position, &chunk_id, &chunk_start, &block_start, &offset)) == 0) 512 break ; 513 bytesread += thisread ; 514 515 if (cue_index < 10) /* avoid swamping log buffer with cues */ 516 psf_log_printf (psf, " Cue ID : %2d" 517 " Pos : %5u Chunk : %M" 518 " Chk Start : %d Blk Start : %d" 519 " Offset : %5d\n", 520 id, position, chunk_id, chunk_start, block_start, offset) ; 521 else if (cue_index == 10) 522 psf_log_printf (psf, " (Skipping)\n") ; 523 524 psf->cues->cue_points [cue_index].indx = id ; 525 psf->cues->cue_points [cue_index].position = position ; 526 psf->cues->cue_points [cue_index].fcc_chunk = chunk_id ; 527 psf->cues->cue_points [cue_index].chunk_start = chunk_start ; 528 psf->cues->cue_points [cue_index].block_start = block_start ; 529 psf->cues->cue_points [cue_index].sample_offset = offset ; 530 psf->cues->cue_points [cue_index].name [0] = '\0' ; 531 cue_count -- ; 532 cue_index ++ ; 533 } ; 534 535 if (bytesread != chunk_size) 536 { psf_log_printf (psf, "**** Chunk size weirdness (%d != %d)\n", chunk_size, bytesread) ; 537 psf_binheader_readf (psf, "j", chunk_size - bytesread) ; 538 } ; 539 } ; 540 break ; 541 542 case smpl_MARKER : 543 parsestage |= HAVE_other ; 544 545 psf_log_printf (psf, "smpl : %u\n", chunk_size) ; 546 547 if ((error = wav_read_smpl_chunk (psf, chunk_size))) 548 return error ; 549 break ; 550 551 case acid_MARKER : 552 parsestage |= HAVE_other ; 553 554 psf_log_printf (psf, "acid : %u\n", chunk_size) ; 555 556 if ((error = wav_read_acid_chunk (psf, chunk_size))) 557 return error ; 558 break ; 559 560 case INFO_MARKER : 561 case LIST_MARKER : 562 parsestage |= HAVE_other ; 563 564 if ((error = wavlike_subchunk_parse (psf, marker, chunk_size)) != 0) 565 return error ; 566 break ; 567 568 case bext_MARKER : 569 /* 570 The 'bext' chunk can actually be updated, so don't need to set this. 571 parsestage |= HAVE_other ; 572 */ 573 if ((error = wavlike_read_bext_chunk (psf, chunk_size))) 574 return error ; 575 break ; 576 577 case PAD_MARKER : 578 /* 579 We can eat into a 'PAD ' chunk if we need to. 580 parsestage |= HAVE_other ; 581 */ 582 psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ; 583 psf_binheader_readf (psf, "j", chunk_size) ; 584 break ; 585 586 case cart_MARKER: 587 if ((error = wavlike_read_cart_chunk (psf, chunk_size))) 588 return error ; 589 break ; 590 591 case iXML_MARKER : /* See http://en.wikipedia.org/wiki/IXML */ 592 case strc_MARKER : /* Multiple of 32 bytes. */ 593 case afsp_MARKER : 594 case clm_MARKER : 595 case elmo_MARKER : 596 case levl_MARKER : 597 case plst_MARKER : 598 case minf_MARKER : 599 case elm1_MARKER : 600 case regn_MARKER : 601 case ovwf_MARKER : 602 case inst_MARKER : 603 case AFAn_MARKER : 604 case umid_MARKER : 605 case SyLp_MARKER : 606 case Cr8r_MARKER : 607 case JUNK_MARKER : 608 case PMX_MARKER : 609 case DISP_MARKER : 610 case MEXT_MARKER : 611 case FLLR_MARKER : 612 psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ; 613 psf_binheader_readf (psf, "j", chunk_size) ; 614 break ; 615 616 default : 617 if (chunk_size >= 0xffff0000) 618 { done = SF_TRUE ; 619 psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %u. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ; 620 break ; 621 } ; 622 623 if ((marker & TAG__MARKER_MASK) == TAG__MARKER && 624 psf_ftell (psf) - 8 + 128 == psf->filelength) 625 { psf_log_printf (psf, "*** Hit ID3v1 trailer. Exiting parser.\n") ; 626 chunk_size = 128 ; 627 done = SF_TRUE ; 628 parsestage |= HAVE_other ; 629 break ; 630 } ; 631 632 if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF) 633 && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF)) 634 { psf_log_printf (psf, "*** %M : %u (unknown marker)\n", marker, chunk_size) ; 635 psf_binheader_readf (psf, "j", chunk_size) ; 636 break ; 637 } ; 638 if (psf_ftell (psf) & 0x03) 639 { psf_log_printf (psf, " Unknown chunk marker at position %D. Resynching.\n", psf_ftell (psf) - 8) ; 640 psf_binheader_readf (psf, "j", -3) ; 641 /* File is too messed up so we prevent editing in RDWR mode here. */ 642 parsestage |= HAVE_other ; 643 break ; 644 } ; 645 psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 8) ; 646 done = SF_TRUE ; 647 break ; 648 } ; /* switch (marker) */ 649 650 if (chunk_size >= psf->filelength) 651 { psf_log_printf (psf, "*** Chunk size %u > file length %D. Exiting parser.\n", chunk_size, psf->filelength) ; 652 break ; 653 } ; 654 655 if (! psf->sf.seekable && (parsestage & HAVE_data)) 656 break ; 657 658 if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size)) 659 { psf_log_printf (psf, "End\n") ; 660 break ; 661 } ; 662 } ; /* while (1) */ 663 664 if (psf->dataoffset <= 0) 665 return SFE_WAV_NO_DATA ; 666 667 if (psf->sf.channels < 1) 668 return SFE_CHANNEL_COUNT_ZERO ; 669 670 if (psf->sf.channels > SF_MAX_CHANNELS) 671 return SFE_CHANNEL_COUNT ; 672 673 if (format != WAVE_FORMAT_PCM && (parsestage & HAVE_fact) == 0) 674 psf_log_printf (psf, "**** All non-PCM format files should have a 'fact' chunk.\n") ; 675 676 /* WAVs can be little or big endian */ 677 psf->endian = psf->rwf_endian ; 678 679 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 680 681 if (psf->is_pipe == 0) 682 { /* 683 ** Check for 'wvpk' at the start of the DATA section. Not able to 684 ** handle this. 685 */ 686 psf_binheader_readf (psf, "4", &marker) ; 687 if (marker == wvpk_MARKER || marker == OggS_MARKER) 688 return SFE_WAV_WVPK_DATA ; 689 } ; 690 691 /* Seek to start of DATA section. */ 692 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 693 694 if (psf->blockwidth) 695 { if (psf->filelength - psf->dataoffset < psf->datalength) 696 psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; 697 else 698 psf->sf.frames = psf->datalength / psf->blockwidth ; 699 } ; 700 701 switch (format) 702 { case WAVE_FORMAT_EXTENSIBLE : 703 if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM)) 704 { *blockalign = wav_fmt->msadpcm.blockalign ; 705 *framesperblock = wav_fmt->msadpcm.samplesperblock ; 706 } ; 707 break ; 708 709 case WAVE_FORMAT_NMS_VBXADPCM : 710 switch (wav_fmt->min.bitwidth) 711 { case 2 : 712 psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16 ; 713 break ; 714 case 3 : 715 psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24 ; 716 break ; 717 case 4 : 718 psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32 ; 719 break ; 720 721 default : 722 return SFE_UNIMPLEMENTED ; 723 } 724 break ; 725 726 case WAVE_FORMAT_PCM : 727 psf->sf.format = SF_FORMAT_WAV | u_bitwidth_to_subformat (psf->bytewidth * 8) ; 728 break ; 729 730 case WAVE_FORMAT_MULAW : 731 case IBM_FORMAT_MULAW : 732 psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ; 733 break ; 734 735 case WAVE_FORMAT_ALAW : 736 case IBM_FORMAT_ALAW : 737 psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ; 738 break ; 739 740 case WAVE_FORMAT_MS_ADPCM : 741 psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ; 742 *blockalign = wav_fmt->msadpcm.blockalign ; 743 *framesperblock = wav_fmt->msadpcm.samplesperblock ; 744 break ; 745 746 case WAVE_FORMAT_IMA_ADPCM : 747 psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ; 748 *blockalign = wav_fmt->ima.blockalign ; 749 *framesperblock = wav_fmt->ima.samplesperblock ; 750 break ; 751 752 case WAVE_FORMAT_GSM610 : 753 psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ; 754 break ; 755 756 case WAVE_FORMAT_IEEE_FLOAT : 757 psf->sf.format = SF_FORMAT_WAV ; 758 psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ; 759 break ; 760 761 case WAVE_FORMAT_G721_ADPCM : 762 psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_G721_32 ; 763 break ; 764 765 case WAVE_FORMAT_MPEGLAYER3 : 766 psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_MPEG_LAYER_III ; 767 if (parsestage & HAVE_fact) 768 psf->sf.frames = fact_chunk.frames ; 769 break ; 770 771 default : return SFE_UNIMPLEMENTED ; 772 } ; 773 774 if (wpriv->fmt_is_broken) 775 wavlike_analyze (psf) ; 776 777 /* Only set the format endian-ness if its non-standard big-endian. */ 778 if (psf->endian == SF_ENDIAN_BIG) 779 psf->sf.format |= SF_ENDIAN_BIG ; 780 781 return 0 ; 782} /* wav_read_header */ 783 784static int 785wav_write_fmt_chunk (SF_PRIVATE *psf) 786{ int subformat, fmt_size, add_fact_chunk = 0 ; 787 788 subformat = SF_CODEC (psf->sf.format) ; 789 790 switch (subformat) 791 { case SF_FORMAT_PCM_U8 : 792 case SF_FORMAT_PCM_16 : 793 case SF_FORMAT_PCM_24 : 794 case SF_FORMAT_PCM_32 : 795 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ; 796 797 /* fmt : format, channels, samplerate */ 798 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_PCM), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 799 /* fmt : bytespersec */ 800 psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ; 801 /* fmt : blockalign, bitwidth */ 802 psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ; 803 break ; 804 805 case SF_FORMAT_FLOAT : 806 case SF_FORMAT_DOUBLE : 807 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ; 808 809 /* fmt : format, channels, samplerate */ 810 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_IEEE_FLOAT), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 811 /* fmt : bytespersec */ 812 psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ; 813 /* fmt : blockalign, bitwidth */ 814 psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ; 815 816 add_fact_chunk = SF_TRUE ; 817 break ; 818 819 case SF_FORMAT_ULAW : 820 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ; 821 822 /* fmt : format, channels, samplerate */ 823 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MULAW), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 824 /* fmt : bytespersec */ 825 psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ; 826 /* fmt : blockalign, bitwidth, extrabytes */ 827 psf_binheader_writef (psf, "222", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (8), BHW2 (0)) ; 828 829 add_fact_chunk = SF_TRUE ; 830 break ; 831 832 case SF_FORMAT_ALAW : 833 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ; 834 835 /* fmt : format, channels, samplerate */ 836 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_ALAW), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 837 /* fmt : bytespersec */ 838 psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ; 839 /* fmt : blockalign, bitwidth, extrabytes */ 840 psf_binheader_writef (psf, "222", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (8), BHW2 (0)) ; 841 842 add_fact_chunk = SF_TRUE ; 843 break ; 844 845 /* Lite remove start */ 846 case SF_FORMAT_IMA_ADPCM : 847 { int blockalign, framesperblock, bytespersec ; 848 849 blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ; 850 framesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ; 851 bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; 852 853 /* fmt chunk. */ 854 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; 855 856 /* fmt : size, WAV format type, channels, samplerate, bytespersec */ 857 psf_binheader_writef (psf, "42244", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_IMA_ADPCM), 858 BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ; 859 860 /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ 861 psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (4), BHW2 (2), BHW2 (framesperblock)) ; 862 } ; 863 864 add_fact_chunk = SF_TRUE ; 865 break ; 866 867 case SF_FORMAT_MS_ADPCM : 868 { int blockalign, framesperblock, bytespersec, extrabytes ; 869 870 blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ; 871 framesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ; 872 bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; 873 874 /* fmt chunk. */ 875 extrabytes = 2 + 2 + WAVLIKE_MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ; 876 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ; 877 878 /* fmt : size, WAV format type, channels. */ 879 psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MS_ADPCM), BHW2 (psf->sf.channels)) ; 880 881 /* fmt : samplerate, bytespersec. */ 882 psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ; 883 884 /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ 885 psf_binheader_writef (psf, "22222", BHW2 (blockalign), BHW2 (4), BHW2 (extrabytes), BHW2 (framesperblock), BHW2 (7)) ; 886 887 wavlike_msadpcm_write_adapt_coeffs (psf) ; 888 } ; 889 890 add_fact_chunk = SF_TRUE ; 891 break ; 892 893 894 case SF_FORMAT_G721_32 : 895 /* fmt chunk. */ 896 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; 897 898 /* fmt : size, WAV format type, channels, samplerate, bytespersec */ 899 psf_binheader_writef (psf, "42244", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_G721_ADPCM), 900 BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate), BHW4 (psf->sf.samplerate * psf->sf.channels / 2)) ; 901 902 /* fmt : blockalign, bitwidth, extrabytes, auxblocksize. */ 903 psf_binheader_writef (psf, "2222", BHW2 (64), BHW2 (4), BHW2 (2), BHW2 (0)) ; 904 905 add_fact_chunk = SF_TRUE ; 906 break ; 907 908 case SF_FORMAT_NMS_ADPCM_16 : 909 case SF_FORMAT_NMS_ADPCM_24 : 910 case SF_FORMAT_NMS_ADPCM_32 : 911 { int bytespersec, blockalign, bitwidth ; 912 913 bitwidth = subformat == SF_FORMAT_NMS_ADPCM_16 ? 2 : subformat == SF_FORMAT_NMS_ADPCM_24 ? 3 : 4 ; 914 blockalign = 20 * bitwidth + 2 ; 915 bytespersec = psf->sf.samplerate * blockalign / 160 ; 916 917 /* fmt chunk. */ 918 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ; 919 920 /* fmt : format, channels, samplerate */ 921 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_NMS_VBXADPCM), 922 BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 923 /* fmt : bytespersec, blockalign, bitwidth */ 924 psf_binheader_writef (psf, "422", BHW4 (bytespersec), BHW2 (blockalign), BHW2 (bitwidth)) ; 925 926 add_fact_chunk = SF_TRUE ; 927 break ; 928 } 929 930 /* Lite remove end */ 931 932 case SF_FORMAT_GSM610 : 933 { int blockalign, framesperblock, bytespersec ; 934 935 blockalign = WAVLIKE_GSM610_BLOCKSIZE ; 936 framesperblock = WAVLIKE_GSM610_SAMPLES ; 937 bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ; 938 939 /* fmt chunk. */ 940 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; 941 942 /* fmt : size, WAV format type, channels. */ 943 psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_GSM610), BHW2 (psf->sf.channels)) ; 944 945 /* fmt : samplerate, bytespersec. */ 946 psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ; 947 948 /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */ 949 psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (0), BHW2 (2), BHW2 (framesperblock)) ; 950 } ; 951 952 add_fact_chunk = SF_TRUE ; 953 break ; 954 955#if (ENABLE_EXPERIMENTAL_CODE == 0) 956 case SF_FORMAT_MPEG_LAYER_III : 957 { int bytespersec, blockalign, flags, blocksize, samplesperblock, codecdelay ; 958 959 /* Intended to be set as the average sample rate. 960 ** TODO: Maybe re-write this on close with final average 961 ** byterate? */ 962 bytespersec = psf->byterate (psf) ; 963 964 /* Average block size. Info only I think. */ 965 blocksize = (1152 * bytespersec) / psf->sf.samplerate ; 966 967 /* Can be set to block size IFF the block size is 968 ** constant, set to 1 otherwise. Constant sized 969 ** MPEG block streams are uncommon (CBR @ 32kHz and 970 ** 48kHz only. Meh. */ 971 blockalign = 1 ; 972 973 /* TODO: Only flags defined are padding-type. I /think/ 974 ** Lame does ISO style padding by default, which has a 975 ** flag value of 0. 976 */ 977 flags = 0 ; 978 979 /* Should only vary per MPEG 1.0/2.0 vs '2.5'. 980 ** TODO: Move this out to MPEG specific place? */ 981 samplesperblock = psf->sf.samplerate >= 32000 ? 1152 : 576 ; 982 983 /* Set as 0 if unknown. 984 ** TODO: Plumb this cleanly from Lame. 985 */ 986 codecdelay = 0 ; 987 988 /* fmt chunk. */ 989 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 ; 990 991 /* fmt : size, WAV format type, channels. */ 992 psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MPEGLAYER3), BHW2 (psf->sf.channels)) ; 993 994 /* fmt : samplerate, bytespersec. */ 995 psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ; 996 997 /* fmt : blockalign, bitwidth, extrabytes, id. */ 998 psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (0), BHW2 (12), BHW2 (1)) ; 999 1000 /* fmt : flags, blocksize, samplesperblock, codecdelay */ 1001 psf_binheader_writef (psf, "4222", BHW4 (flags), BHW2 (blocksize), BHW2 (samplesperblock), BHW2 (codecdelay)) ; 1002 } ; 1003 1004 add_fact_chunk = SF_TRUE ; 1005 break ; 1006#endif 1007 1008 default : return SFE_UNIMPLEMENTED ; 1009 } ; 1010 1011 if (add_fact_chunk) 1012 psf_binheader_writef (psf, "tm48", BHWm (fact_MARKER), BHW4 (4), BHW8 (psf->sf.frames)) ; 1013 1014 return 0 ; 1015} /* wav_write_fmt_chunk */ 1016 1017static int 1018wavex_write_fmt_chunk (SF_PRIVATE *psf) 1019{ WAVLIKE_PRIVATE *wpriv ; 1020 int subformat, fmt_size ; 1021 1022 if ((wpriv = psf->container_data) == NULL) 1023 return SFE_INTERNAL ; 1024 1025 subformat = SF_CODEC (psf->sf.format) ; 1026 1027 /* initial section (same for all, it appears) */ 1028 switch (subformat) 1029 { case SF_FORMAT_PCM_U8 : 1030 case SF_FORMAT_PCM_16 : 1031 case SF_FORMAT_PCM_24 : 1032 case SF_FORMAT_PCM_32 : 1033 case SF_FORMAT_FLOAT : 1034 case SF_FORMAT_DOUBLE : 1035 case SF_FORMAT_ULAW : 1036 case SF_FORMAT_ALAW : 1037 fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 4 + 2 + 2 + 8 ; 1038 1039 /* fmt : format, channels, samplerate */ 1040 psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_EXTENSIBLE), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ; 1041 /* fmt : bytespersec */ 1042 psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ; 1043 /* fmt : blockalign, bitwidth */ 1044 psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ; 1045 1046 /* cbSize 22 is sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX) */ 1047 psf_binheader_writef (psf, "2", BHW2 (22)) ; 1048 1049 /* wValidBitsPerSample, for our use same as bitwidth as we use it fully */ 1050 psf_binheader_writef (psf, "2", BHW2 (psf->bytewidth * 8)) ; 1051 1052 /* For an Ambisonic file set the channel mask to zero. 1053 ** Otherwise use a default based on the channel count. 1054 */ 1055 if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE) 1056 psf_binheader_writef (psf, "4", BHW4 (0)) ; 1057 else if (wpriv->wavex_channelmask != 0) 1058 psf_binheader_writef (psf, "4", BHW4 (wpriv->wavex_channelmask)) ; 1059 else 1060 { /* 1061 ** Ok some liberty is taken here to use the most commonly used channel masks 1062 ** instead of "no mapping". If you really want to use "no mapping" for 8 channels and less 1063 ** please don't use wavex. (otherwise we'll have to create a new SF_COMMAND) 1064 */ 1065 switch (psf->sf.channels) 1066 { case 1 : /* center channel mono */ 1067 psf_binheader_writef (psf, "4", BHW4 (0x4)) ; 1068 break ; 1069 1070 case 2 : /* front left and right */ 1071 psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2)) ; 1072 break ; 1073 1074 case 4 : /* Quad */ 1075 psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x10 | 0x20)) ; 1076 break ; 1077 1078 case 6 : /* 5.1 */ 1079 psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20)) ; 1080 break ; 1081 1082 case 8 : /* 7.1 */ 1083 psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x80)) ; 1084 break ; 1085 1086 default : /* 0 when in doubt , use direct out, ie NO mapping*/ 1087 psf_binheader_writef (psf, "4", BHW4 (0x0)) ; 1088 break ; 1089 } ; 1090 } ; 1091 break ; 1092 1093 case SF_FORMAT_MS_ADPCM : /* Todo, GUID exists might have different header as per wav_write_header */ 1094 default : 1095 return SFE_UNIMPLEMENTED ; 1096 } ; 1097 1098 /* GUID section, different for each */ 1099 1100 switch (subformat) 1101 { case SF_FORMAT_PCM_U8 : 1102 case SF_FORMAT_PCM_16 : 1103 case SF_FORMAT_PCM_24 : 1104 case SF_FORMAT_PCM_32 : 1105 wavlike_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ? 1106 &MSGUID_SUBTYPE_PCM : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM) ; 1107 break ; 1108 1109 case SF_FORMAT_FLOAT : 1110 case SF_FORMAT_DOUBLE : 1111 wavlike_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ? 1112 &MSGUID_SUBTYPE_IEEE_FLOAT : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT) ; 1113 break ; 1114 1115 case SF_FORMAT_ULAW : 1116 wavlike_write_guid (psf, &MSGUID_SUBTYPE_MULAW) ; 1117 break ; 1118 1119 case SF_FORMAT_ALAW : 1120 wavlike_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ; 1121 break ; 1122 1123#if 0 1124 /* This is dead code due to return in previous switch statement. */ 1125 case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */ 1126 wavlike_write_guid (psf, &MSGUID_SUBTYPE_MS_ADPCM) ; 1127 break ; 1128 return SFE_UNIMPLEMENTED ; 1129#endif 1130 1131 default : return SFE_UNIMPLEMENTED ; 1132 } ; 1133 1134 psf_binheader_writef (psf, "tm48", BHWm (fact_MARKER), BHW4 (4), BHW8 (psf->sf.frames)) ; 1135 1136 return 0 ; 1137} /* wavex_write_fmt_chunk */ 1138 1139 1140static int 1141wav_write_header (SF_PRIVATE *psf, int calc_length) 1142{ sf_count_t current ; 1143 int error, has_data = SF_FALSE ; 1144 1145 current = psf_ftell (psf) ; 1146 1147 if (current > psf->dataoffset) 1148 has_data = SF_TRUE ; 1149 1150 if (calc_length) 1151 { psf->filelength = psf_get_filelen (psf) ; 1152 1153 psf->datalength = psf->filelength - psf->dataoffset ; 1154 1155 if (psf->dataend) 1156 psf->datalength -= psf->filelength - psf->dataend ; 1157 else if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE) 1158 psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ; 1159 } ; 1160 1161 /* Reset the current header length to zero. */ 1162 psf->header.ptr [0] = 0 ; 1163 psf->header.indx = 0 ; 1164 psf_fseek (psf, 0, SEEK_SET) ; 1165 1166 /* 1167 ** RIFX signifies big-endian format for all header and data. 1168 ** To prevent lots of code copying here, we'll set the psf->rwf_endian flag 1169 ** once here, and never specify endian-ness for all other header operations. 1170 */ 1171 1172 /* RIFF/RIFX marker, length, WAVE and 'fmt ' markers. */ 1173 1174 if (psf->endian == SF_ENDIAN_LITTLE) 1175 psf_binheader_writef (psf, "etm8", BHWm (RIFF_MARKER), BHW8 ((psf->filelength < 8) ? 8 : psf->filelength - 8)) ; 1176 else 1177 psf_binheader_writef (psf, "Etm8", BHWm (RIFX_MARKER), BHW8 ((psf->filelength < 8) ? 8 : psf->filelength - 8)) ; 1178 1179 /* WAVE and 'fmt ' markers. */ 1180 psf_binheader_writef (psf, "mm", BHWm (WAVE_MARKER), BHWm (fmt_MARKER)) ; 1181 1182 /* Write the 'fmt ' chunk. */ 1183 switch (SF_CONTAINER (psf->sf.format)) 1184 { case SF_FORMAT_WAV : 1185 if ((error = wav_write_fmt_chunk (psf)) != 0) 1186 return error ; 1187 break ; 1188 1189 case SF_FORMAT_WAVEX : 1190 if ((error = wavex_write_fmt_chunk (psf)) != 0) 1191 return error ; 1192 break ; 1193 1194 default : 1195 return SFE_UNIMPLEMENTED ; 1196 } ; 1197 1198 /* The LIST/INFO chunk. */ 1199 if (psf->strings.flags & SF_STR_LOCATE_START) 1200 wavlike_write_strings (psf, SF_STR_LOCATE_START) ; 1201 1202 if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START) 1203 wavlike_write_peak_chunk (psf) ; 1204 1205 if (psf->broadcast_16k != NULL) 1206 wavlike_write_bext_chunk (psf) ; 1207 1208 if (psf->cart_16k != NULL) 1209 wavlike_write_cart_chunk (psf) ; 1210 1211 if (psf->cues != NULL) 1212 { uint32_t k ; 1213 1214 psf_binheader_writef (psf, "em44", BHWm (cue_MARKER), BHW4 (4 + psf->cues->cue_count * 6 * 4), BHW4 (psf->cues->cue_count)) ; 1215 1216 for (k = 0 ; k < psf->cues->cue_count ; k++) 1217 psf_binheader_writef (psf, "e44m444", BHW4 (psf->cues->cue_points [k].indx), BHW4 (psf->cues->cue_points [k].position), 1218 BHWm (psf->cues->cue_points [k].fcc_chunk), BHW4 (psf->cues->cue_points [k].chunk_start), 1219 BHW4 (psf->cues->cue_points [k].block_start), BHW4 (psf->cues->cue_points [k].sample_offset)) ; 1220 } ; 1221 1222 if (psf->instrument != NULL) 1223 { int tmp ; 1224 double dtune = (double) (0x40000000) / 25.0 ; 1225 1226 psf_binheader_writef (psf, "m4", BHWm (smpl_MARKER), BHW4 (9 * 4 + psf->instrument->loop_count * 6 * 4)) ; 1227 psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* Manufacturer zero is everyone */ 1228 tmp = (int) (1.0e9 / psf->sf.samplerate) ; /* Sample period in nano seconds */ 1229 psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (psf->instrument->basenote)) ; 1230 tmp = (uint32_t) (psf->instrument->detune * dtune + 0.5) ; 1231 psf_binheader_writef (psf, "4", BHW4 (tmp)) ; 1232 psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* SMTPE format */ 1233 psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loop_count), BHW4 (0)) ; 1234 1235 /* Make sure we don't read past the loops array end. */ 1236 if (psf->instrument->loop_count > ARRAY_LEN (psf->instrument->loops)) 1237 psf->instrument->loop_count = ARRAY_LEN (psf->instrument->loops) ; 1238 1239 for (tmp = 0 ; tmp < psf->instrument->loop_count ; tmp++) 1240 { int type ; 1241 1242 type = psf->instrument->loops [tmp].mode ; 1243 type = (type == SF_LOOP_FORWARD ? 0 : type == SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ; 1244 1245 psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (type)) ; 1246 psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loops [tmp].start), BHW4 (psf->instrument->loops [tmp].end - 1)) ; 1247 psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (psf->instrument->loops [tmp].count)) ; 1248 } ; 1249 } ; 1250 1251 /* Write custom headers. */ 1252 if (psf->wchunks.used > 0) 1253 wavlike_write_custom_chunks (psf) ; 1254 1255 if (psf->header.indx + 16 < psf->dataoffset) 1256 { /* Add PAD data if necessary. */ 1257 size_t k = psf->dataoffset - (psf->header.indx + 16) ; 1258 psf_binheader_writef (psf, "m4z", BHWm (PAD_MARKER), BHW4 (k), BHWz (k)) ; 1259 } ; 1260 1261 psf_binheader_writef (psf, "tm8", BHWm (data_MARKER), BHW8 (psf->datalength)) ; 1262 psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; 1263 if (psf->error) 1264 return psf->error ; 1265 1266 if (has_data && psf->dataoffset != psf->header.indx) 1267 { psf_log_printf (psf, "Oooops : has_data && psf->dataoffset != psf->header.indx\n") ; 1268 return psf->error = SFE_INTERNAL ; 1269 } ; 1270 1271 psf->dataoffset = psf->header.indx ; 1272 1273 if (! has_data) 1274 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 1275 else if (current > 0) 1276 psf_fseek (psf, current, SEEK_SET) ; 1277 1278 return psf->error ; 1279} /* wav_write_header */ 1280 1281 1282static int 1283wav_write_tailer (SF_PRIVATE *psf) 1284{ 1285 /* Reset the current header buffer length to zero. */ 1286 psf->header.ptr [0] = 0 ; 1287 psf->header.indx = 0 ; 1288 1289 if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE) 1290 { psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ; 1291 psf->dataend = psf->dataoffset + psf->datalength ; 1292 } ; 1293 1294 if (psf->dataend > 0) 1295 psf_fseek (psf, psf->dataend, SEEK_SET) ; 1296 else 1297 psf->dataend = psf_fseek (psf, 0, SEEK_END) ; 1298 1299 if (psf->dataend & 1) 1300 psf_binheader_writef (psf, "z", BHWz (1)) ; 1301 1302 /* Add a PEAK chunk if requested. */ 1303 if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_END) 1304 wavlike_write_peak_chunk (psf) ; 1305 1306 if (psf->strings.flags & SF_STR_LOCATE_END) 1307 wavlike_write_strings (psf, SF_STR_LOCATE_END) ; 1308 1309 /* Write the tailer. */ 1310 if (psf->header.indx > 0) 1311 psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; 1312 1313 return 0 ; 1314} /* wav_write_tailer */ 1315 1316static int 1317wav_close (SF_PRIVATE *psf) 1318{ 1319 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 1320 { wav_write_tailer (psf) ; 1321 1322 if (psf->file.mode == SFM_RDWR) 1323 { sf_count_t current = psf_ftell (psf) ; 1324 1325 /* 1326 ** If the mode is RDWR and the current position is less than the 1327 ** filelength, truncate the file. 1328 */ 1329 1330 if (current < psf->filelength) 1331 { psf_ftruncate (psf, current) ; 1332 psf->filelength = current ; 1333 } ; 1334 } ; 1335 1336 psf->write_header (psf, SF_TRUE) ; 1337 } ; 1338 1339 return 0 ; 1340} /* wav_close */ 1341 1342static int 1343wav_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize) 1344{ WAVLIKE_PRIVATE *wpriv ; 1345 1346 if ((wpriv = psf->container_data) == NULL) 1347 return SFE_INTERNAL ; 1348 1349 switch (command) 1350 { case SFC_WAVEX_SET_AMBISONIC : 1351 if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAVEX) 1352 { if (datasize == SF_AMBISONIC_NONE) 1353 wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ; 1354 else if (datasize == SF_AMBISONIC_B_FORMAT) 1355 wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ; 1356 else 1357 return 0 ; 1358 } ; 1359 return wpriv->wavex_ambisonic ; 1360 1361 case SFC_WAVEX_GET_AMBISONIC : 1362 return wpriv->wavex_ambisonic ; 1363 1364 case SFC_SET_CHANNEL_MAP_INFO : 1365 wpriv->wavex_channelmask = wavlike_gen_channel_mask (psf->channel_map, psf->sf.channels) ; 1366 return (wpriv->wavex_channelmask != 0) ; 1367 1368 default : 1369 break ; 1370 } ; 1371 1372 return 0 ; 1373} /* wav_command */ 1374 1375static int 1376wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen) 1377{ char buffer [512] ; 1378 uint32_t thisread, bytesread = 0, dword, sampler_data, loop_count, actually_loop_count = 0 ; 1379 uint32_t note, pitch, start, end, type = -1, count ; 1380 int j, k ; 1381 1382 chunklen += (chunklen & 1) ; 1383 1384 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1385 psf_log_printf (psf, " Manufacturer : %X\n", dword) ; 1386 1387 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1388 psf_log_printf (psf, " Product : %u\n", dword) ; 1389 1390 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1391 psf_log_printf (psf, " Period : %u nsec\n", dword) ; 1392 1393 bytesread += psf_binheader_readf (psf, "4", ¬e) ; 1394 psf_log_printf (psf, " Midi Note : %u\n", note) ; 1395 1396 bytesread += psf_binheader_readf (psf, "4", &pitch) ; 1397 if (pitch != 0) 1398 { snprintf (buffer, sizeof (buffer), "%f", 1399 (1.0 * 0x80000000) / ((uint32_t) pitch)) ; 1400 psf_log_printf (psf, " Pitch Fract. : %s\n", buffer) ; 1401 } 1402 else 1403 psf_log_printf (psf, " Pitch Fract. : 0\n") ; 1404 1405 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1406 psf_log_printf (psf, " SMPTE Format : %u\n", dword) ; 1407 1408 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1409 snprintf (buffer, sizeof (buffer), "%02"PRIu32 ":%02"PRIu32 ":%02"PRIu32 1410 " %02"PRIu32 "", (dword >> 24) & 0x7F, (dword >> 16) & 0x7F, 1411 (dword >> 8) & 0x7F, dword & 0x7F) ; 1412 psf_log_printf (psf, " SMPTE Offset : %s\n", buffer) ; 1413 1414 bytesread += psf_binheader_readf (psf, "4", &loop_count) ; 1415 psf_log_printf (psf, " Loop Count : %u\n", loop_count) ; 1416 1417 if (loop_count == 0 && chunklen == bytesread) 1418 return 0 ; 1419 1420 /* Sampler Data holds the number of data bytes after the CUE chunks which 1421 ** is not actually CUE data. Display value after CUE data. 1422 */ 1423 bytesread += psf_binheader_readf (psf, "4", &sampler_data) ; 1424 1425 if (psf->instrument) 1426 { psf_log_printf (psf, " Found more than one SMPL chunk, using last one.\n") ; 1427 free (psf->instrument) ; 1428 psf->instrument = NULL ; 1429 } ; 1430 if ((psf->instrument = psf_instrument_alloc ()) == NULL) 1431 return SFE_MALLOC_FAILED ; 1432 1433 psf->instrument->loop_count = loop_count ; 1434 1435 for (j = 0 ; loop_count > 0 && chunklen - bytesread >= 24 ; j ++) 1436 { if ((thisread = psf_binheader_readf (psf, "4", &dword)) == 0) 1437 break ; 1438 bytesread += thisread ; 1439 psf_log_printf (psf, " Cue ID : %2u", dword) ; 1440 1441 bytesread += psf_binheader_readf (psf, "4", &type) ; 1442 psf_log_printf (psf, " Type : %2u", type) ; 1443 1444 bytesread += psf_binheader_readf (psf, "4", &start) ; 1445 psf_log_printf (psf, " Start : %5u", start) ; 1446 1447 bytesread += psf_binheader_readf (psf, "4", &end) ; 1448 psf_log_printf (psf, " End : %5u", end) ; 1449 1450 bytesread += psf_binheader_readf (psf, "4", &dword) ; 1451 psf_log_printf (psf, " Fraction : %5u", dword) ; 1452 1453 bytesread += psf_binheader_readf (psf, "4", &count) ; 1454 psf_log_printf (psf, " Count : %5u\n", count) ; 1455 1456 if (j < ARRAY_LEN (psf->instrument->loops)) 1457 { psf->instrument->loops [j].start = start ; 1458 psf->instrument->loops [j].end = end + 1 ; 1459 psf->instrument->loops [j].count = count ; 1460 1461 switch (type) 1462 { case 0 : 1463 psf->instrument->loops [j].mode = SF_LOOP_FORWARD ; 1464 break ; 1465 case 1 : 1466 psf->instrument->loops [j].mode = SF_LOOP_ALTERNATING ; 1467 break ; 1468 case 2 : 1469 psf->instrument->loops [j].mode = SF_LOOP_BACKWARD ; 1470 break ; 1471 default: 1472 psf->instrument->loops [j].mode = SF_LOOP_NONE ; 1473 break ; 1474 } ; 1475 } ; 1476 actually_loop_count ++ ; 1477 } ; 1478 1479 if (actually_loop_count > ARRAY_LEN (psf->instrument->loops)) 1480 { 1481 psf_log_printf (psf, "*** Warning, actual Loop Points count exceeds %u, changing Loop Count from %u to %u\n", ARRAY_LEN (psf->instrument->loops), loop_count, ARRAY_LEN (psf->instrument->loops)) ; 1482 psf->instrument->loop_count = ARRAY_LEN (psf->instrument->loops) ; 1483 } 1484 else if (loop_count != actually_loop_count) 1485 { psf_log_printf (psf, "*** Warning, actual Loop Points count != Loop Count, changing Loop Count from %u to %u\n", loop_count, actually_loop_count) ; 1486 psf->instrument->loop_count = actually_loop_count ; 1487 } ; 1488 1489 if (chunklen - bytesread == 0) 1490 { if (sampler_data != 0) 1491 psf_log_printf (psf, " Sampler Data : %u (should be 0)\n", sampler_data) ; 1492 else 1493 psf_log_printf (psf, " Sampler Data : %u\n", sampler_data) ; 1494 } 1495 else 1496 { if (sampler_data != chunklen - bytesread) 1497 { psf_log_printf (psf, " Sampler Data : %u (should have been %u)\n", sampler_data, chunklen - bytesread) ; 1498 sampler_data = chunklen - bytesread ; 1499 } 1500 else 1501 psf_log_printf (psf, " Sampler Data : %u\n", sampler_data) ; 1502 1503 psf_log_printf (psf, " ") ; 1504 for (k = 0 ; k < (int) sampler_data ; k++) 1505 { char ch ; 1506 1507 if (k > 0 && (k % 20) == 0) 1508 psf_log_printf (psf, "\n ") ; 1509 1510 if ((thisread = psf_binheader_readf (psf, "1", &ch)) == 0) 1511 break ; 1512 bytesread += thisread ; 1513 psf_log_printf (psf, "%02X ", ch & 0xFF) ; 1514 } ; 1515 1516 psf_log_printf (psf, "\n") ; 1517 } ; 1518 1519 psf->instrument->basenote = note ; 1520 psf->instrument->detune = (int8_t) (pitch / (0x40000000 / 25.0) + 0.5) ; 1521 psf->instrument->gain = 1 ; 1522 psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ; 1523 psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ; 1524 1525 return 0 ; 1526} /* wav_read_smpl_chunk */ 1527 1528/* 1529** The acid chunk goes a little something like this: 1530** 1531** 4 bytes 'acid' 1532** 4 bytes (int) length of chunk starting at next byte 1533** 1534** 4 bytes (int) type of file: 1535** this appears to be a bit mask,however some combinations 1536** are probably impossible and/or qualified as "errors" 1537** 1538** 0x01 On: One Shot Off: Loop 1539** 0x02 On: Root note is Set Off: No root 1540** 0x04 On: Stretch is On, Off: Strech is OFF 1541** 0x08 On: Disk Based Off: Ram based 1542** 0x10 On: ?????????? Off: ????????? (Acidizer puts that ON) 1543** 1544** 2 bytes (short) root note 1545** if type 0x10 is OFF : [C,C#,(...),B] -> [0x30 to 0x3B] 1546** if type 0x10 is ON : [C,C#,(...),B] -> [0x3C to 0x47] 1547** (both types fit on same MIDI pitch albeit different octaves, so who cares) 1548** 1549** 2 bytes (short) ??? always set to 0x8000 1550** 4 bytes (float) ??? seems to be always 0 1551** 4 bytes (int) number of beats 1552** 2 bytes (short) meter denominator //always 4 in SF/ACID 1553** 2 bytes (short) meter numerator //always 4 in SF/ACID 1554** //are we sure about the order?? usually its num/denom 1555** 4 bytes (float) tempo 1556** 1557*/ 1558 1559static int 1560wav_read_acid_chunk (SF_PRIVATE *psf, uint32_t chunklen) 1561{ char buffer [512] ; 1562 uint32_t bytesread = 0 ; 1563 int beats, flags ; 1564 short rootnote, q1, meter_denom, meter_numer ; 1565 float q2, tempo ; 1566 1567 chunklen += (chunklen & 1) ; 1568 1569 bytesread += psf_binheader_readf (psf, "422f", &flags, &rootnote, &q1, &q2) ; 1570 1571 snprintf (buffer, sizeof (buffer), "%f", q2) ; 1572 1573 psf_log_printf (psf, " Flags : 0x%04x (%s,%s,%s,%s,%s)\n", flags, 1574 (flags & 0x01) ? "OneShot" : "Loop", 1575 (flags & 0x02) ? "RootNoteValid" : "RootNoteInvalid", 1576 (flags & 0x04) ? "StretchOn" : "StretchOff", 1577 (flags & 0x08) ? "DiskBased" : "RAMBased", 1578 (flags & 0x10) ? "??On" : "??Off") ; 1579 1580 psf_log_printf (psf, " Root note : 0x%x\n ???? : 0x%04x\n ???? : %s\n", 1581 rootnote, q1, buffer) ; 1582 1583 bytesread += psf_binheader_readf (psf, "422f", &beats, &meter_denom, &meter_numer, &tempo) ; 1584 snprintf (buffer, sizeof (buffer), "%f", tempo) ; 1585 psf_log_printf (psf, " Beats : %d\n Meter : %d/%d\n Tempo : %s\n", 1586 beats, meter_numer, meter_denom, buffer) ; 1587 1588 psf_binheader_readf (psf, "j", chunklen - bytesread) ; 1589 1590 if (psf->loop_info) 1591 { psf_log_printf (psf, " Found existing loop info, using last one.\n") ; 1592 free (psf->loop_info) ; 1593 psf->loop_info = NULL ; 1594 } ; 1595 if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL) 1596 return SFE_MALLOC_FAILED ; 1597 1598 psf->loop_info->time_sig_num = meter_numer ; 1599 psf->loop_info->time_sig_den = meter_denom ; 1600 psf->loop_info->loop_mode = (flags & 0x01) ? SF_LOOP_NONE : SF_LOOP_FORWARD ; 1601 psf->loop_info->num_beats = beats ; 1602 psf->loop_info->bpm = tempo ; 1603 psf->loop_info->root_key = (flags & 0x02) ? rootnote : -1 ; 1604 1605 return 0 ; 1606} /* wav_read_acid_chunk */ 1607 1608/*============================================================================== 1609*/ 1610 1611static int 1612wav_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) 1613{ return psf_save_write_chunk (&psf->wchunks, chunk_info) ; 1614} /* wav_set_chunk */ 1615 1616static SF_CHUNK_ITERATOR * 1617wav_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) 1618{ return psf_next_chunk_iterator (&psf->rchunks, iterator) ; 1619} /* wav_next_chunk_iterator */ 1620 1621static int 1622wav_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) 1623{ int indx ; 1624 1625 if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0) 1626 return SFE_UNKNOWN_CHUNK ; 1627 1628 chunk_info->datalen = psf->rchunks.chunks [indx].len ; 1629 1630 return SFE_NO_ERROR ; 1631} /* wav_get_chunk_size */ 1632 1633static int 1634wav_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) 1635{ int indx ; 1636 sf_count_t pos ; 1637 1638 if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0) 1639 return SFE_UNKNOWN_CHUNK ; 1640 1641 if (chunk_info->data == NULL) 1642 return SFE_BAD_CHUNK_DATA_PTR ; 1643 1644 chunk_info->id_size = psf->rchunks.chunks [indx].id_size ; 1645 memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ; 1646 1647 pos = psf_ftell (psf) ; 1648 psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ; 1649 psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ; 1650 psf_fseek (psf, pos, SEEK_SET) ; 1651 1652 return SFE_NO_ERROR ; 1653} /* wav_get_chunk_data */ 1654