1/* 2** Copyright (C) 2002-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#include "sfconfig.h" 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <fcntl.h> 24#include <string.h> 25#include <ctype.h> 26#include <math.h> 27 28#include "sndfile.h" 29#include "sfendian.h" 30#include "common.h" 31 32/*------------------------------------------------------------------------------ 33*/ 34 35#define SDS_DATA_OFFSET 0x15 36#define SDS_BLOCK_SIZE 127 37 38#define SDS_AUDIO_BYTES_PER_BLOCK 120 39 40#define SDS_3BYTE_TO_INT_DECODE(x) (((x) & 0x7F) | (((x) & 0x7F00) >> 1) | (((x) & 0x7F0000) >> 2)) 41#define SDS_INT_TO_3BYTE_ENCODE(x) (((x) & 0x7F) | (((x) << 1) & 0x7F00) | (((x) << 2) & 0x7F0000)) 42 43/*------------------------------------------------------------------------------ 44** Typedefs. 45*/ 46 47typedef struct tag_SDS_PRIVATE 48{ int bitwidth, frames ; 49 int samplesperblock, total_blocks ; 50 51 int (*reader) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ; 52 int (*writer) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ; 53 54 int read_block, read_count ; 55 unsigned char read_data [SDS_BLOCK_SIZE] ; 56 int read_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */ 57 58 int write_block, write_count ; 59 int total_written ; 60 unsigned char write_data [SDS_BLOCK_SIZE] ; 61 int write_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */ 62} SDS_PRIVATE ; 63 64/*------------------------------------------------------------------------------ 65** Private static functions. 66*/ 67 68static int sds_close (SF_PRIVATE *psf) ; 69 70static int sds_write_header (SF_PRIVATE *psf, int calc_length) ; 71static int sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 72 73static int sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 74 75static sf_count_t sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; 76static sf_count_t sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; 77static sf_count_t sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; 78static sf_count_t sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; 79 80static sf_count_t sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; 81static sf_count_t sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; 82static sf_count_t sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; 83static sf_count_t sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; 84 85static sf_count_t sds_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ; 86static int sds_byterate (SF_PRIVATE * psf) ; 87 88static int sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 89static int sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 90static int sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 91 92static int sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *iptr, int readcount) ; 93 94static int sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 95static int sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 96static int sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ; 97 98static int sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *iptr, int writecount) ; 99 100/*------------------------------------------------------------------------------ 101** Public function. 102*/ 103 104int 105sds_open (SF_PRIVATE *psf) 106{ SDS_PRIVATE *psds ; 107 int error = 0 ; 108 109 /* Hmmmm, need this here to pass update_header_test. */ 110 psf->sf.frames = 0 ; 111 112 if (! (psds = calloc (1, sizeof (SDS_PRIVATE)))) 113 return SFE_MALLOC_FAILED ; 114 psf->codec_data = psds ; 115 116 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) 117 { if ((error = sds_read_header (psf, psds))) 118 return error ; 119 } ; 120 121 if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SDS) 122 return SFE_BAD_OPEN_FORMAT ; 123 124 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 125 { if (sds_write_header (psf, SF_FALSE)) 126 return psf->error ; 127 128 psf->write_header = sds_write_header ; 129 130 psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ; 131 } ; 132 133 if ((error = sds_init (psf, psds)) != 0) 134 return error ; 135 136 psf->container_close = sds_close ; 137 psf->seek = sds_seek ; 138 psf->byterate = sds_byterate ; 139 140 psf->blockwidth = 0 ; 141 142 return error ; 143} /* sds_open */ 144 145/*------------------------------------------------------------------------------ 146*/ 147 148static int 149sds_close (SF_PRIVATE *psf) 150{ 151 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 152 { SDS_PRIVATE *psds ; 153 154 if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL) 155 { psf_log_printf (psf, "*** Bad psf->codec_data ptr.\n") ; 156 return SFE_INTERNAL ; 157 } ; 158 159 if (psds->write_count > 0) 160 { memset (&(psds->write_data [psds->write_count]), 0, (psds->samplesperblock - psds->write_count) * sizeof (int)) ; 161 psds->writer (psf, psds) ; 162 } ; 163 164 sds_write_header (psf, SF_TRUE) ; 165 } ; 166 167 return 0 ; 168} /* sds_close */ 169 170static int 171sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds) 172{ 173 if (psds->bitwidth < 8 || psds->bitwidth > 28) 174 return (psf->error = SFE_SDS_BAD_BIT_WIDTH) ; 175 176 if (psds->bitwidth < 14) 177 { psds->reader = sds_2byte_read ; 178 psds->writer = sds_2byte_write ; 179 psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 2 ; 180 } 181 else if (psds->bitwidth < 21) 182 { psds->reader = sds_3byte_read ; 183 psds->writer = sds_3byte_write ; 184 psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 3 ; 185 } 186 else 187 { psds->reader = sds_4byte_read ; 188 psds->writer = sds_4byte_write ; 189 psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 4 ; 190 } ; 191 192 if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR) 193 { psf->read_short = sds_read_s ; 194 psf->read_int = sds_read_i ; 195 psf->read_float = sds_read_f ; 196 psf->read_double = sds_read_d ; 197 198 /* Read first block. */ 199 psds->reader (psf, psds) ; 200 } ; 201 202 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 203 { psf->write_short = sds_write_s ; 204 psf->write_int = sds_write_i ; 205 psf->write_float = sds_write_f ; 206 psf->write_double = sds_write_d ; 207 } ; 208 209 return 0 ; 210} /* sds_init */ 211 212static int 213sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds) 214{ unsigned char channel, bitwidth, loop_type, byte ; 215 unsigned short sample_no, marker ; 216 unsigned int samp_period, data_length, sustain_loop_start, sustain_loop_end ; 217 int bytesread, blockcount ; 218 219 /* Set position to start of file to begin reading header. */ 220 bytesread = psf_binheader_readf (psf, "pE211", 0, &marker, &channel, &byte) ; 221 222 if (marker != 0xF07E || byte != 0x01) 223 return SFE_SDS_NOT_SDS ; 224 225 bytesread += psf_binheader_readf (psf, "e2", &sample_no) ; 226 sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ; 227 228 psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n" 229 " Midi Channel : %d\n Sample Number : %d\n", 230 channel, sample_no) ; 231 232 bytesread += psf_binheader_readf (psf, "e13", &bitwidth, &samp_period) ; 233 234 samp_period = SDS_3BYTE_TO_INT_DECODE (samp_period) ; 235 236 psds->bitwidth = bitwidth ; 237 238 if (psds->bitwidth > 1) 239 psf_log_printf (psf, " Bit Width : %d\n", psds->bitwidth) ; 240 else 241 { psf_log_printf (psf, " Bit Width : %d (should be > 1)\n", psds->bitwidth) ; 242 return SFE_SDS_BAD_BIT_WIDTH ; 243 } ; 244 245 if (samp_period > 0) 246 { psf->sf.samplerate = 1000000000 / samp_period ; 247 248 psf_log_printf (psf, " Sample Period : %d\n" 249 " Sample Rate : %d\n", 250 samp_period, psf->sf.samplerate) ; 251 } 252 else 253 { psf->sf.samplerate = 16000 ; 254 255 psf_log_printf (psf, " Sample Period : %d (should be > 0)\n" 256 " Sample Rate : %d (guessed)\n", 257 samp_period, psf->sf.samplerate) ; 258 } ; 259 260 bytesread += psf_binheader_readf (psf, "e3331", &data_length, &sustain_loop_start, &sustain_loop_end, &loop_type) ; 261 262 data_length = SDS_3BYTE_TO_INT_DECODE (data_length) ; 263 264 psf->sf.frames = psds->frames = data_length ; 265 266 sustain_loop_start = SDS_3BYTE_TO_INT_DECODE (sustain_loop_start) ; 267 sustain_loop_end = SDS_3BYTE_TO_INT_DECODE (sustain_loop_end) ; 268 269 psf_log_printf (psf, " Sustain Loop\n" 270 " Start : %d\n" 271 " End : %d\n" 272 " Loop Type : %d\n", 273 sustain_loop_start, sustain_loop_end, loop_type) ; 274 275 psf->dataoffset = SDS_DATA_OFFSET ; 276 psf->datalength = psf->filelength - psf->dataoffset ; 277 278 bytesread += psf_binheader_readf (psf, "1", &byte) ; 279 if (byte != 0xF7) 280 psf_log_printf (psf, "bad end : %X\n", byte & 0xFF) ; 281 282 for (blockcount = 0 ; bytesread < psf->filelength ; blockcount++) 283 { 284 bytesread += (int) psf_fread (&marker, 1, 2, psf) ; 285 286 if (marker == 0) 287 break ; 288 289 psf_fseek (psf, SDS_BLOCK_SIZE - 2, SEEK_CUR) ; 290 bytesread += SDS_BLOCK_SIZE - 2 ; 291 } ; 292 293 psf_log_printf (psf, "\nBlocks : %d\n", blockcount) ; 294 psds->total_blocks = blockcount ; 295 296 psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / ((psds->bitwidth + 6) / 7) ; 297 psf_log_printf (psf, "Samples/Block : %d\n", psds->samplesperblock) ; 298 299 psf_log_printf (psf, "Frames : %d\n", blockcount * psds->samplesperblock) ; 300 301 /* Always Mono */ 302 psf->sf.channels = 1 ; 303 psf->sf.sections = 1 ; 304 305 /* 306 ** Lie to the user about PCM bit width. Always round up to 307 ** the next multiple of 8. 308 */ 309 switch ((psds->bitwidth + 7) / 8) 310 { case 1 : 311 psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_S8 ; 312 break ; 313 314 case 2 : 315 psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_16 ; 316 break ; 317 318 case 3 : 319 psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_24 ; 320 break ; 321 322 case 4 : 323 psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_32 ; 324 break ; 325 326 default : 327 psf_log_printf (psf, "*** Weird byte width (%d)\n", (psds->bitwidth + 7) / 8) ; 328 return SFE_SDS_BAD_BIT_WIDTH ; 329 } ; 330 331 psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ; 332 333 return 0 ; 334} /* sds_read_header */ 335 336static int 337sds_write_header (SF_PRIVATE *psf, int calc_length) 338{ SDS_PRIVATE *psds ; 339 sf_count_t current ; 340 int samp_period, data_length, sustain_loop_start, sustain_loop_end ; 341 unsigned char loop_type = 0 ; 342 343 if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL) 344 { psf_log_printf (psf, "*** Bad psf->codec_data ptr.\n") ; 345 return SFE_INTERNAL ; 346 } ; 347 348 if (psf->pipeoffset > 0) 349 return 0 ; 350 351 current = psf_ftell (psf) ; 352 353 if (calc_length) 354 psf->sf.frames = psds->total_written ; 355 356 if (psds->write_count > 0) 357 { int current_count = psds->write_count ; 358 int current_block = psds->write_block ; 359 360 psds->writer (psf, psds) ; 361 362 psf_fseek (psf, -1 * SDS_BLOCK_SIZE, SEEK_CUR) ; 363 364 psds->write_count = current_count ; 365 psds->write_block = current_block ; 366 } ; 367 368 /* Reset the current header length to zero. */ 369 psf->header.ptr [0] = 0 ; 370 psf->header.indx = 0 ; 371 372 if (psf->is_pipe == SF_FALSE) 373 psf_fseek (psf, 0, SEEK_SET) ; 374 375 psf_binheader_writef (psf, "E211", BHW2 (0xF07E), BHW1 (0), BHW1 (1)) ; 376 377 switch (SF_CODEC (psf->sf.format)) 378 { case SF_FORMAT_PCM_S8 : 379 psds->bitwidth = 8 ; 380 break ; 381 case SF_FORMAT_PCM_16 : 382 psds->bitwidth = 16 ; 383 break ; 384 case SF_FORMAT_PCM_24 : 385 psds->bitwidth = 24 ; 386 break ; 387 default: 388 return SFE_SDS_BAD_BIT_WIDTH ; 389 } ; 390 391 samp_period = SDS_INT_TO_3BYTE_ENCODE (1000000000 / psf->sf.samplerate) ; 392 393 psf_binheader_writef (psf, "e213", BHW2 (0), BHW1 (psds->bitwidth), BHW3 (samp_period)) ; 394 395 data_length = SDS_INT_TO_3BYTE_ENCODE (psds->total_written) ; 396 sustain_loop_start = SDS_INT_TO_3BYTE_ENCODE (0) ; 397 sustain_loop_end = SDS_INT_TO_3BYTE_ENCODE (0) ; 398 399 psf_binheader_writef (psf, "e33311", BHW3 (data_length), BHW3 (sustain_loop_start), BHW3 (sustain_loop_end), BHW1 (loop_type), BHW1 (0xF7)) ; 400 401 /* Header construction complete so write it out. */ 402 psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; 403 404 if (psf->error) 405 return psf->error ; 406 407 psf->dataoffset = psf->header.indx ; 408 psf->datalength = psds->write_block * SDS_BLOCK_SIZE ; 409 410 if (current > 0) 411 psf_fseek (psf, current, SEEK_SET) ; 412 413 return psf->error ; 414} /* sds_write_header */ 415 416 417/*------------------------------------------------------------------------------ 418*/ 419 420static int 421sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) 422{ unsigned char *ucptr, checksum ; 423 unsigned int sample ; 424 int k ; 425 426 psds->read_block ++ ; 427 psds->read_count = 0 ; 428 429 if (psds->read_block * psds->samplesperblock > psds->frames) 430 { memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ; 431 return 1 ; 432 } ; 433 434 if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 435 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 436 437 if (psds->read_data [0] != 0xF0) 438 { printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ; 439 } ; 440 441 checksum = psds->read_data [1] ; 442 if (checksum != 0x7E) 443 { printf ("Error 1 : %02X\n", checksum & 0xFF) ; 444 } 445 446 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 447 checksum ^= psds->read_data [k] ; 448 449 checksum &= 0x7F ; 450 451 if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2]) 452 { psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ; 453 } ; 454 455 ucptr = psds->read_data + 5 ; 456 for (k = 0 ; k < 120 ; k += 2) 457 { sample = arith_shift_left (ucptr [k], 25) + arith_shift_left (ucptr [k + 1], 18) ; 458 psds->read_samples [k / 2] = (int) (sample - 0x80000000) ; 459 } ; 460 461 return 1 ; 462} /* sds_2byte_read */ 463 464static int 465sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) 466{ unsigned char *ucptr, checksum ; 467 unsigned int sample ; 468 int k ; 469 470 psds->read_block ++ ; 471 psds->read_count = 0 ; 472 473 if (psds->read_block * psds->samplesperblock > psds->frames) 474 { memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ; 475 return 1 ; 476 } ; 477 478 if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 479 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 480 481 if (psds->read_data [0] != 0xF0) 482 { printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ; 483 } ; 484 485 checksum = psds->read_data [1] ; 486 if (checksum != 0x7E) 487 { printf ("Error 1 : %02X\n", checksum & 0xFF) ; 488 } 489 490 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 491 checksum ^= psds->read_data [k] ; 492 493 checksum &= 0x7F ; 494 495 if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2]) 496 { psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ; 497 } ; 498 499 ucptr = psds->read_data + 5 ; 500 for (k = 0 ; k < 120 ; k += 3) 501 { sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) ; 502 psds->read_samples [k / 3] = (int) (sample - 0x80000000) ; 503 } ; 504 505 return 1 ; 506} /* sds_3byte_read */ 507 508static int 509sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) 510{ unsigned char *ucptr, checksum ; 511 uint32_t sample ; 512 int k ; 513 514 psds->read_block ++ ; 515 psds->read_count = 0 ; 516 517 if (psds->read_block * psds->samplesperblock > psds->frames) 518 { memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ; 519 return 1 ; 520 } ; 521 522 if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 523 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 524 525 if (psds->read_data [0] != 0xF0) 526 { printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ; 527 } ; 528 529 checksum = psds->read_data [1] ; 530 if (checksum != 0x7E) 531 { printf ("Error 1 : %02X\n", checksum & 0xFF) ; 532 } 533 534 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 535 checksum ^= psds->read_data [k] ; 536 537 checksum &= 0x7F ; 538 539 if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2]) 540 { psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ; 541 } ; 542 543 ucptr = psds->read_data + 5 ; 544 for (k = 0 ; k < 120 ; k += 4) 545 { sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) + (ucptr [k + 3] << 4) ; 546 psds->read_samples [k / 4] = (int) (sample - 0x80000000) ; 547 } ; 548 549 return 1 ; 550} /* sds_4byte_read */ 551 552 553static sf_count_t 554sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) 555{ BUF_UNION ubuf ; 556 SDS_PRIVATE *psds ; 557 int *iptr ; 558 int k, bufferlen, readcount, count ; 559 sf_count_t total = 0 ; 560 561 if (psf->codec_data == NULL) 562 return 0 ; 563 psds = (SDS_PRIVATE*) psf->codec_data ; 564 565 iptr = ubuf.ibuf ; 566 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 567 while (len > 0) 568 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 569 count = sds_read (psf, psds, iptr, readcount) ; 570 for (k = 0 ; k < readcount ; k++) 571 ptr [total + k] = iptr [k] >> 16 ; 572 total += count ; 573 len -= readcount ; 574 } ; 575 576 return total ; 577} /* sds_read_s */ 578 579static sf_count_t 580sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) 581{ SDS_PRIVATE *psds ; 582 int total ; 583 584 if (psf->codec_data == NULL) 585 return 0 ; 586 psds = (SDS_PRIVATE*) psf->codec_data ; 587 588 total = sds_read (psf, psds, ptr, len) ; 589 590 return total ; 591} /* sds_read_i */ 592 593static sf_count_t 594sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) 595{ BUF_UNION ubuf ; 596 SDS_PRIVATE *psds ; 597 int *iptr ; 598 int k, bufferlen, readcount, count ; 599 sf_count_t total = 0 ; 600 float normfact ; 601 602 if (psf->codec_data == NULL) 603 return 0 ; 604 psds = (SDS_PRIVATE*) psf->codec_data ; 605 606 if (psf->norm_float == SF_TRUE) 607 normfact = 1.0 / 0x80000000 ; 608 else 609 normfact = 1.0 / (1 << psds->bitwidth) ; 610 611 iptr = ubuf.ibuf ; 612 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 613 while (len > 0) 614 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 615 count = sds_read (psf, psds, iptr, readcount) ; 616 for (k = 0 ; k < readcount ; k++) 617 ptr [total + k] = normfact * iptr [k] ; 618 total += count ; 619 len -= readcount ; 620 } ; 621 622 return total ; 623} /* sds_read_f */ 624 625static sf_count_t 626sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) 627{ BUF_UNION ubuf ; 628 SDS_PRIVATE *psds ; 629 int *iptr ; 630 int k, bufferlen, readcount, count ; 631 sf_count_t total = 0 ; 632 double normfact ; 633 634 if (psf->codec_data == NULL) 635 return 0 ; 636 psds = (SDS_PRIVATE*) psf->codec_data ; 637 638 if (psf->norm_double == SF_TRUE) 639 normfact = 1.0 / 0x80000000 ; 640 else 641 normfact = 1.0 / (1 << psds->bitwidth) ; 642 643 iptr = ubuf.ibuf ; 644 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 645 while (len > 0) 646 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 647 count = sds_read (psf, psds, iptr, readcount) ; 648 for (k = 0 ; k < readcount ; k++) 649 ptr [total + k] = normfact * iptr [k] ; 650 total += count ; 651 len -= readcount ; 652 } ; 653 654 return total ; 655} /* sds_read_d */ 656 657static int 658sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *ptr, int len) 659{ int count, total = 0 ; 660 661 while (total < len) 662 { if (psds->read_block * psds->samplesperblock >= psds->frames) 663 { memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ; 664 return total ; 665 } ; 666 667 if (psds->read_count >= psds->samplesperblock) 668 psds->reader (psf, psds) ; 669 670 count = (psds->samplesperblock - psds->read_count) ; 671 count = (len - total > count) ? count : len - total ; 672 673 memcpy (&(ptr [total]), &(psds->read_samples [psds->read_count]), count * sizeof (int)) ; 674 total += count ; 675 psds->read_count += count ; 676 } ; 677 678 return total ; 679} /* sds_read */ 680 681/*============================================================================== 682*/ 683 684static sf_count_t 685sds_seek (SF_PRIVATE *psf, int mode, sf_count_t seek_from_start) 686{ SDS_PRIVATE *psds ; 687 sf_count_t file_offset ; 688 int newblock, newsample ; 689 690 if ((psds = psf->codec_data) == NULL) 691 { psf->error = SFE_INTERNAL ; 692 return PSF_SEEK_ERROR ; 693 } ; 694 695 if (psf->datalength < 0 || psf->dataoffset < 0) 696 { psf->error = SFE_BAD_SEEK ; 697 return PSF_SEEK_ERROR ; 698 } ; 699 700 if (seek_from_start < 0 || seek_from_start > psf->sf.frames) 701 { psf->error = SFE_BAD_SEEK ; 702 return PSF_SEEK_ERROR ; 703 } ; 704 705 if (mode == SFM_READ && psds->write_count > 0) 706 psds->writer (psf, psds) ; 707 708 newblock = seek_from_start / psds->samplesperblock ; 709 newsample = seek_from_start % psds->samplesperblock ; 710 711 switch (mode) 712 { case SFM_READ : 713 if (newblock > psds->total_blocks) 714 { psf->error = SFE_BAD_SEEK ; 715 return PSF_SEEK_ERROR ; 716 } ; 717 718 file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ; 719 720 if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset) 721 { psf->error = SFE_SEEK_FAILED ; 722 return PSF_SEEK_ERROR ; 723 } ; 724 725 psds->read_block = newblock ; 726 psds->reader (psf, psds) ; 727 psds->read_count = newsample ; 728 break ; 729 730 case SFM_WRITE : 731 if (newblock > psds->total_blocks) 732 { psf->error = SFE_BAD_SEEK ; 733 return PSF_SEEK_ERROR ; 734 } ; 735 736 file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ; 737 738 if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset) 739 { psf->error = SFE_SEEK_FAILED ; 740 return PSF_SEEK_ERROR ; 741 } ; 742 743 psds->write_block = newblock ; 744 psds->reader (psf, psds) ; 745 psds->write_count = newsample ; 746 break ; 747 748 default : 749 psf->error = SFE_BAD_SEEK ; 750 return PSF_SEEK_ERROR ; 751 break ; 752 } ; 753 754 return seek_from_start ; 755} /* sds_seek */ 756 757static int 758sds_byterate (SF_PRIVATE * psf) 759{ 760 if (psf->file.mode == SFM_READ) 761 return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ; 762 763 return -1 ; 764} /* sds_byterate */ 765 766/*============================================================================== 767*/ 768 769static int 770sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) 771{ unsigned char *ucptr, checksum ; 772 unsigned int sample ; 773 int k ; 774 775 psds->write_data [0] = 0xF0 ; 776 psds->write_data [1] = 0x7E ; 777 psds->write_data [2] = 0 ; /* Channel number */ 778 psds->write_data [3] = 2 ; 779 psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */ 780 781 ucptr = psds->write_data + 5 ; 782 for (k = 0 ; k < 120 ; k += 2) 783 { sample = psds->write_samples [k / 2] ; 784 sample += 0x80000000 ; 785 ucptr [k] = (sample >> 25) & 0x7F ; 786 ucptr [k + 1] = (sample >> 18) & 0x7F ; 787 } ; 788 789 checksum = psds->write_data [1] ; 790 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 791 checksum ^= psds->write_data [k] ; 792 checksum &= 0x7F ; 793 794 psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ; 795 psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ; 796 797 if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 798 psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 799 800 psds->write_block ++ ; 801 psds->write_count = 0 ; 802 803 if (psds->write_block > psds->total_blocks) 804 psds->total_blocks = psds->write_block ; 805 psds->frames = psds->total_blocks * psds->samplesperblock ; 806 807 return 1 ; 808} /* sds_2byte_write */ 809 810static int 811sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) 812{ unsigned char *ucptr, checksum ; 813 unsigned int sample ; 814 int k ; 815 816 psds->write_data [0] = 0xF0 ; 817 psds->write_data [1] = 0x7E ; 818 psds->write_data [2] = 0 ; /* Channel number */ 819 psds->write_data [3] = 2 ; 820 psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */ 821 822 ucptr = psds->write_data + 5 ; 823 for (k = 0 ; k < 120 ; k += 3) 824 { sample = psds->write_samples [k / 3] ; 825 sample += 0x80000000 ; 826 ucptr [k] = (sample >> 25) & 0x7F ; 827 ucptr [k + 1] = (sample >> 18) & 0x7F ; 828 ucptr [k + 2] = (sample >> 11) & 0x7F ; 829 } ; 830 831 checksum = psds->write_data [1] ; 832 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 833 checksum ^= psds->write_data [k] ; 834 checksum &= 0x7F ; 835 836 psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ; 837 psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ; 838 839 if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 840 psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 841 842 psds->write_block ++ ; 843 psds->write_count = 0 ; 844 845 if (psds->write_block > psds->total_blocks) 846 psds->total_blocks = psds->write_block ; 847 psds->frames = psds->total_blocks * psds->samplesperblock ; 848 849 return 1 ; 850} /* sds_3byte_write */ 851 852static int 853sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) 854{ unsigned char *ucptr, checksum ; 855 unsigned int sample ; 856 int k ; 857 858 psds->write_data [0] = 0xF0 ; 859 psds->write_data [1] = 0x7E ; 860 psds->write_data [2] = 0 ; /* Channel number */ 861 psds->write_data [3] = 2 ; 862 psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */ 863 864 ucptr = psds->write_data + 5 ; 865 for (k = 0 ; k < 120 ; k += 4) 866 { sample = psds->write_samples [k / 4] ; 867 sample += 0x80000000 ; 868 ucptr [k] = (sample >> 25) & 0x7F ; 869 ucptr [k + 1] = (sample >> 18) & 0x7F ; 870 ucptr [k + 2] = (sample >> 11) & 0x7F ; 871 ucptr [k + 3] = (sample >> 4) & 0x7F ; 872 } ; 873 874 checksum = psds->write_data [1] ; 875 for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++) 876 checksum ^= psds->write_data [k] ; 877 checksum &= 0x7F ; 878 879 psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ; 880 psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ; 881 882 if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE) 883 psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ; 884 885 psds->write_block ++ ; 886 psds->write_count = 0 ; 887 888 if (psds->write_block > psds->total_blocks) 889 psds->total_blocks = psds->write_block ; 890 psds->frames = psds->total_blocks * psds->samplesperblock ; 891 892 return 1 ; 893} /* sds_4byte_write */ 894 895static sf_count_t 896sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) 897{ BUF_UNION ubuf ; 898 SDS_PRIVATE *psds ; 899 int *iptr ; 900 int k, bufferlen, writecount, count ; 901 sf_count_t total = 0 ; 902 903 if (psf->codec_data == NULL) 904 return 0 ; 905 psds = (SDS_PRIVATE*) psf->codec_data ; 906 psds->total_written += len ; 907 908 iptr = ubuf.ibuf ; 909 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 910 while (len > 0) 911 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 912 for (k = 0 ; k < writecount ; k++) 913 iptr [k] = arith_shift_left (ptr [total + k], 16) ; 914 count = sds_write (psf, psds, iptr, writecount) ; 915 total += count ; 916 len -= writecount ; 917 } ; 918 919 return total ; 920} /* sds_write_s */ 921 922static sf_count_t 923sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) 924{ SDS_PRIVATE *psds ; 925 int total ; 926 927 if (psf->codec_data == NULL) 928 return 0 ; 929 psds = (SDS_PRIVATE*) psf->codec_data ; 930 psds->total_written += len ; 931 932 total = sds_write (psf, psds, ptr, len) ; 933 934 return total ; 935} /* sds_write_i */ 936 937static sf_count_t 938sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) 939{ BUF_UNION ubuf ; 940 SDS_PRIVATE *psds ; 941 int *iptr ; 942 int k, bufferlen, writecount, count ; 943 sf_count_t total = 0 ; 944 float normfact ; 945 946 if (psf->codec_data == NULL) 947 return 0 ; 948 psds = (SDS_PRIVATE*) psf->codec_data ; 949 psds->total_written += len ; 950 951 if (psf->norm_float == SF_TRUE) 952 normfact = 1.0 * 0x80000000 ; 953 else 954 normfact = 1.0 * (1 << psds->bitwidth) ; 955 956 iptr = ubuf.ibuf ; 957 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 958 while (len > 0) 959 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 960 for (k = 0 ; k < writecount ; k++) 961 iptr [k] = normfact * ptr [total + k] ; 962 count = sds_write (psf, psds, iptr, writecount) ; 963 total += count ; 964 len -= writecount ; 965 } ; 966 967 return total ; 968} /* sds_write_f */ 969 970static sf_count_t 971sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) 972{ BUF_UNION ubuf ; 973 SDS_PRIVATE *psds ; 974 int *iptr ; 975 int k, bufferlen, writecount, count ; 976 sf_count_t total = 0 ; 977 double normfact ; 978 979 if (psf->codec_data == NULL) 980 return 0 ; 981 psds = (SDS_PRIVATE*) psf->codec_data ; 982 psds->total_written += len ; 983 984 if (psf->norm_double == SF_TRUE) 985 normfact = 1.0 * 0x80000000 ; 986 else 987 normfact = 1.0 * (1 << psds->bitwidth) ; 988 989 iptr = ubuf.ibuf ; 990 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 991 while (len > 0) 992 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 993 for (k = 0 ; k < writecount ; k++) 994 iptr [k] = normfact * ptr [total + k] ; 995 count = sds_write (psf, psds, iptr, writecount) ; 996 total += count ; 997 len -= writecount ; 998 } ; 999 1000 return total ; 1001} /* sds_write_d */ 1002 1003static int 1004sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *ptr, int len) 1005{ int count, total = 0 ; 1006 1007 while (total < len) 1008 { count = psds->samplesperblock - psds->write_count ; 1009 if (count > len - total) 1010 count = len - total ; 1011 1012 memcpy (&(psds->write_samples [psds->write_count]), &(ptr [total]), count * sizeof (int)) ; 1013 total += count ; 1014 psds->write_count += count ; 1015 1016 if (psds->write_count >= psds->samplesperblock) 1017 psds->writer (psf, psds) ; 1018 } ; 1019 1020 return total ; 1021} /* sds_write */ 1022 1023