PageRenderTime 88ms CodeModel.GetById 12ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sndfile/src/sds.c

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