libsndfile source files.
[Faustine.git] / interpretor / libsndfile-1.0.25 / src / dwvw.c
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 /*===========================================================================
20 ** Delta Word Variable Width
21 **
22 ** This decoder and encoder were implemented using information found in this
23 ** document : http://home.swbell.net/rubywand/R011SNDFMTS.TXT
24 **
25 ** According to the document, the algorithm "was invented 1991 by Magnus
26 ** Lidstrom and is copyright 1993 by NuEdge Development".
27 */
28
29 #include "sfconfig.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <math.h>
35
36 #include "sndfile.h"
37 #include "sfendian.h"
38 #include "common.h"
39
40 typedef struct
41 { int dwm_maxsize, bit_width, max_delta, span ;
42 int samplecount ;
43 int bit_count, bits, last_delta_width, last_sample ;
44 struct
45 { int index, end ;
46 unsigned char buffer [256] ;
47 } b ;
48 } DWVW_PRIVATE ;
49
50 /*============================================================================================
51 */
52
53 static sf_count_t dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
54 static sf_count_t dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
55 static sf_count_t dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
56 static sf_count_t dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
57
58 static sf_count_t dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
59 static sf_count_t dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
60 static sf_count_t dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
61 static sf_count_t dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
62
63 static sf_count_t dwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
64 static int dwvw_close (SF_PRIVATE *psf) ;
65
66 static int dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;
67 static int dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count) ;
68
69 static int dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len) ;
70 static void dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits) ;
71 static void dwvw_read_reset (DWVW_PRIVATE *pdwvw) ;
72
73 /*============================================================================================
74 ** DWVW initialisation function.
75 */
76
77 int
78 dwvw_init (SF_PRIVATE *psf, int bitwidth)
79 { DWVW_PRIVATE *pdwvw ;
80
81 if (psf->codec_data != NULL)
82 { psf_log_printf (psf, "*** psf->codec_data is not NULL.\n") ;
83 return SFE_INTERNAL ;
84 } ;
85
86 if (bitwidth > 24)
87 return SFE_DWVW_BAD_BITWIDTH ;
88
89 if (psf->file.mode == SFM_RDWR)
90 return SFE_BAD_MODE_RW ;
91
92 if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL)
93 return SFE_MALLOC_FAILED ;
94
95 psf->codec_data = (void*) pdwvw ;
96
97 pdwvw->bit_width = bitwidth ;
98 pdwvw->dwm_maxsize = bitwidth / 2 ;
99 pdwvw->max_delta = 1 << (bitwidth - 1) ;
100 pdwvw->span = 1 << bitwidth ;
101
102 dwvw_read_reset (pdwvw) ;
103
104 if (psf->file.mode == SFM_READ)
105 { psf->read_short = dwvw_read_s ;
106 psf->read_int = dwvw_read_i ;
107 psf->read_float = dwvw_read_f ;
108 psf->read_double = dwvw_read_d ;
109 } ;
110
111 if (psf->file.mode == SFM_WRITE)
112 { psf->write_short = dwvw_write_s ;
113 psf->write_int = dwvw_write_i ;
114 psf->write_float = dwvw_write_f ;
115 psf->write_double = dwvw_write_d ;
116 } ;
117
118 psf->codec_close = dwvw_close ;
119 psf->seek = dwvw_seek ;
120
121 /* FIXME : This is bogus. */
122 psf->sf.frames = SF_COUNT_MAX ;
123 psf->datalength = psf->sf.frames ;
124 /* EMXIF : This is bogus. */
125
126 return 0 ;
127 } /* dwvw_init */
128
129 /*--------------------------------------------------------------------------------------------
130 */
131
132 static int
133 dwvw_close (SF_PRIVATE *psf)
134 { DWVW_PRIVATE *pdwvw ;
135
136 if (psf->codec_data == NULL)
137 return 0 ;
138 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
139
140 if (psf->file.mode == SFM_WRITE)
141 { static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
142
143 /* Write 8 zero samples to fully flush output. */
144 dwvw_encode_data (psf, pdwvw, last_values, 12) ;
145
146 /* Write the last buffer worth of data to disk. */
147 psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
148
149 if (psf->write_header)
150 psf->write_header (psf, SF_TRUE) ;
151 } ;
152
153 return 0 ;
154 } /* dwvw_close */
155
156 static sf_count_t
157 dwvw_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
158 { DWVW_PRIVATE *pdwvw ;
159
160 if (! psf->codec_data)
161 { psf->error = SFE_INTERNAL ;
162 return PSF_SEEK_ERROR ;
163 } ;
164
165 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
166
167 if (offset == 0)
168 { psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
169 dwvw_read_reset (pdwvw) ;
170 return 0 ;
171 } ;
172
173 psf->error = SFE_BAD_SEEK ;
174 return PSF_SEEK_ERROR ;
175 } /* dwvw_seek */
176
177
178 /*==============================================================================
179 */
180
181 static sf_count_t
182 dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
183 { DWVW_PRIVATE *pdwvw ;
184 int *iptr ;
185 int k, bufferlen, readcount = 0, count ;
186 sf_count_t total = 0 ;
187
188 if (! psf->codec_data)
189 return 0 ;
190 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
191
192 iptr = psf->u.ibuf ;
193 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
194 while (len > 0)
195 { readcount = (len >= bufferlen) ? bufferlen : len ;
196 count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
197 for (k = 0 ; k < readcount ; k++)
198 ptr [total + k] = iptr [k] >> 16 ;
199
200 total += count ;
201 len -= readcount ;
202 if (count != readcount)
203 break ;
204 } ;
205
206 return total ;
207 } /* dwvw_read_s */
208
209 static sf_count_t
210 dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
211 { DWVW_PRIVATE *pdwvw ;
212 int readcount, count ;
213 sf_count_t total = 0 ;
214
215 if (! psf->codec_data)
216 return 0 ;
217 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
218
219 while (len > 0)
220 { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
221
222 count = dwvw_decode_data (psf, pdwvw, ptr, readcount) ;
223
224 total += count ;
225 len -= count ;
226
227 if (count != readcount)
228 break ;
229 } ;
230
231 return total ;
232 } /* dwvw_read_i */
233
234 static sf_count_t
235 dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
236 { DWVW_PRIVATE *pdwvw ;
237 int *iptr ;
238 int k, bufferlen, readcount = 0, count ;
239 sf_count_t total = 0 ;
240 float normfact ;
241
242 if (! psf->codec_data)
243 return 0 ;
244 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
245
246 normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
247
248 iptr = psf->u.ibuf ;
249 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
250 while (len > 0)
251 { readcount = (len >= bufferlen) ? bufferlen : len ;
252 count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
253 for (k = 0 ; k < readcount ; k++)
254 ptr [total + k] = normfact * (float) (iptr [k]) ;
255
256 total += count ;
257 len -= readcount ;
258 if (count != readcount)
259 break ;
260 } ;
261
262 return total ;
263 } /* dwvw_read_f */
264
265 static sf_count_t
266 dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
267 { DWVW_PRIVATE *pdwvw ;
268 int *iptr ;
269 int k, bufferlen, readcount = 0, count ;
270 sf_count_t total = 0 ;
271 double normfact ;
272
273 if (! psf->codec_data)
274 return 0 ;
275 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
276
277 normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
278
279 iptr = psf->u.ibuf ;
280 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
281 while (len > 0)
282 { readcount = (len >= bufferlen) ? bufferlen : len ;
283 count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
284 for (k = 0 ; k < readcount ; k++)
285 ptr [total + k] = normfact * (double) (iptr [k]) ;
286
287 total += count ;
288 len -= readcount ;
289 if (count != readcount)
290 break ;
291 } ;
292
293 return total ;
294 } /* dwvw_read_d */
295
296 static int
297 dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len)
298 { int count ;
299 int delta_width_modifier, delta_width, delta_negative, delta, sample ;
300
301 /* Restore state from last decode call. */
302 delta_width = pdwvw->last_delta_width ;
303 sample = pdwvw->last_sample ;
304
305 for (count = 0 ; count < len ; count++)
306 { /* If bit_count parameter is zero get the delta_width_modifier. */
307 delta_width_modifier = dwvw_decode_load_bits (psf, pdwvw, -1) ;
308
309 /* Check for end of input bit stream. Break loop if end. */
310 if (delta_width_modifier < 0)
311 break ;
312
313 if (delta_width_modifier && dwvw_decode_load_bits (psf, pdwvw, 1))
314 delta_width_modifier = - delta_width_modifier ;
315
316 /* Calculate the current word width. */
317 delta_width = (delta_width + delta_width_modifier + pdwvw->bit_width) % pdwvw->bit_width ;
318
319 /* Load the delta. */
320 delta = 0 ;
321 if (delta_width)
322 { delta = dwvw_decode_load_bits (psf, pdwvw, delta_width - 1) | (1 << (delta_width - 1)) ;
323 delta_negative = dwvw_decode_load_bits (psf, pdwvw, 1) ;
324 if (delta == pdwvw->max_delta - 1)
325 delta += dwvw_decode_load_bits (psf, pdwvw, 1) ;
326 if (delta_negative)
327 delta = -delta ;
328 } ;
329
330 /* Calculate the sample */
331 sample += delta ;
332
333 if (sample >= pdwvw->max_delta)
334 sample -= pdwvw->span ;
335 else if (sample < - pdwvw->max_delta)
336 sample += pdwvw->span ;
337
338 /* Store the sample justifying to the most significant bit. */
339 ptr [count] = sample << (32 - pdwvw->bit_width) ;
340
341 if (pdwvw->b.end == 0 && pdwvw->bit_count == 0)
342 break ;
343 } ;
344
345 pdwvw->last_delta_width = delta_width ;
346 pdwvw->last_sample = sample ;
347
348 pdwvw->samplecount += count ;
349
350 return count ;
351 } /* dwvw_decode_data */
352
353 static int
354 dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count)
355 { int output = 0, get_dwm = SF_FALSE ;
356
357 /*
358 ** Depending on the value of parameter bit_count, either get the
359 ** required number of bits (ie bit_count > 0) or the
360 ** delta_width_modifier (otherwise).
361 */
362
363 if (bit_count < 0)
364 { get_dwm = SF_TRUE ;
365 /* modify bit_count to ensure we have enought bits for finding dwm. */
366 bit_count = pdwvw->dwm_maxsize ;
367 } ;
368
369 /* Load bits in bit reseviour. */
370 while (pdwvw->bit_count < bit_count)
371 { if (pdwvw->b.index >= pdwvw->b.end)
372 { pdwvw->b.end = psf_fread (pdwvw->b.buffer, 1, sizeof (pdwvw->b.buffer), psf) ;
373 pdwvw->b.index = 0 ;
374 } ;
375
376 /* Check for end of input stream. */
377 if (bit_count < 8 && pdwvw->b.end == 0)
378 return -1 ;
379
380 pdwvw->bits = (pdwvw->bits << 8) ;
381
382 if (pdwvw->b.index < pdwvw->b.end)
383 { pdwvw->bits |= pdwvw->b.buffer [pdwvw->b.index] ;
384 pdwvw->b.index ++ ;
385 } ;
386 pdwvw->bit_count += 8 ;
387 } ;
388
389 /* If asked to get bits do so. */
390 if (! get_dwm)
391 { output = (pdwvw->bits >> (pdwvw->bit_count - bit_count)) & ((1 << bit_count) - 1) ;
392 pdwvw->bit_count -= bit_count ;
393 return output ;
394 } ;
395
396 /* Otherwise must have been asked to get delta_width_modifier. */
397 while (output < (pdwvw->dwm_maxsize))
398 { pdwvw->bit_count -= 1 ;
399 if (pdwvw->bits & (1 << pdwvw->bit_count))
400 break ;
401 output += 1 ;
402 } ;
403
404 return output ;
405 } /* dwvw_decode_load_bits */
406
407 static void
408 dwvw_read_reset (DWVW_PRIVATE *pdwvw)
409 { pdwvw->samplecount = 0 ;
410 pdwvw->b.index = 0 ;
411 pdwvw->b.end = 0 ;
412 pdwvw->bit_count = 0 ;
413 pdwvw->bits = 0 ;
414 pdwvw->last_delta_width = 0 ;
415 pdwvw->last_sample = 0 ;
416 } /* dwvw_read_reset */
417
418 static void
419 dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits)
420 { int byte ;
421
422 /* Shift the bits into the resevoir. */
423 pdwvw->bits = (pdwvw->bits << new_bits) | (data & ((1 << new_bits) - 1)) ;
424 pdwvw->bit_count += new_bits ;
425
426 /* Transfer bit to buffer. */
427 while (pdwvw->bit_count >= 8)
428 { byte = pdwvw->bits >> (pdwvw->bit_count - 8) ;
429 pdwvw->bit_count -= 8 ;
430 pdwvw->b.buffer [pdwvw->b.index] = byte & 0xFF ;
431 pdwvw->b.index ++ ;
432 } ;
433
434 if (pdwvw->b.index > SIGNED_SIZEOF (pdwvw->b.buffer) - 4)
435 { psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
436 pdwvw->b.index = 0 ;
437 } ;
438
439 return ;
440 } /* dwvw_encode_store_bits */
441
442 #if 0
443 /* Debigging routine. */
444 static void
445 dump_bits (DWVW_PRIVATE *pdwvw)
446 { int k, mask ;
447
448 for (k = 0 ; k < 10 && k < pdwvw->b.index ; k++)
449 { mask = 0x80 ;
450 while (mask)
451 { putchar (mask & pdwvw->b.buffer [k] ? '1' : '0') ;
452 mask >>= 1 ;
453 } ;
454 putchar (' ') ;
455 }
456
457 for (k = pdwvw->bit_count - 1 ; k >= 0 ; k --)
458 putchar (pdwvw->bits & (1 << k) ? '1' : '0') ;
459
460 putchar ('\n') ;
461 } /* dump_bits */
462 #endif
463
464 #define HIGHEST_BIT(x,count) \
465 { int y = x ; \
466 (count) = 0 ; \
467 while (y) \
468 { (count) ++ ; \
469 y >>= 1 ; \
470 } ; \
471 } ;
472
473 static int
474 dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len)
475 { int count ;
476 int delta_width_modifier, delta, delta_negative, delta_width, extra_bit ;
477
478 for (count = 0 ; count < len ; count++)
479 { delta = (ptr [count] >> (32 - pdwvw->bit_width)) - pdwvw->last_sample ;
480
481 /* Calculate extra_bit if needed. */
482 extra_bit = -1 ;
483 delta_negative = 0 ;
484 if (delta < -pdwvw->max_delta)
485 delta = pdwvw->max_delta + (delta % pdwvw->max_delta) ;
486 else if (delta == -pdwvw->max_delta)
487 { extra_bit = 1 ;
488 delta_negative = 1 ;
489 delta = pdwvw->max_delta - 1 ;
490 }
491 else if (delta > pdwvw->max_delta)
492 { delta_negative = 1 ;
493 delta = pdwvw->span - delta ;
494 delta = abs (delta) ;
495 }
496 else if (delta == pdwvw->max_delta)
497 { extra_bit = 1 ;
498 delta = pdwvw->max_delta - 1 ;
499 }
500 else if (delta < 0)
501 { delta_negative = 1 ;
502 delta = abs (delta) ;
503 } ;
504
505 if (delta == pdwvw->max_delta - 1 && extra_bit == -1)
506 extra_bit = 0 ;
507
508 /* Find width in bits of delta */
509 HIGHEST_BIT (delta, delta_width) ;
510
511 /* Calculate the delta_width_modifier */
512 delta_width_modifier = (delta_width - pdwvw->last_delta_width) % pdwvw->bit_width ;
513 if (delta_width_modifier > pdwvw->dwm_maxsize)
514 delta_width_modifier -= pdwvw->bit_width ;
515 if (delta_width_modifier < -pdwvw->dwm_maxsize)
516 delta_width_modifier += pdwvw->bit_width ;
517
518 /* Write delta_width_modifier zeros, followed by terminating '1'. */
519 dwvw_encode_store_bits (psf, pdwvw, 0, abs (delta_width_modifier)) ;
520 if (abs (delta_width_modifier) != pdwvw->dwm_maxsize)
521 dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
522
523 /* Write delta_width_modifier sign. */
524 if (delta_width_modifier < 0)
525 dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
526 if (delta_width_modifier > 0)
527 dwvw_encode_store_bits (psf, pdwvw, 0, 1) ;
528
529 /* Write delta and delta sign bit. */
530 if (delta_width)
531 { dwvw_encode_store_bits (psf, pdwvw, delta, abs (delta_width) - 1) ;
532 dwvw_encode_store_bits (psf, pdwvw, (delta_negative ? 1 : 0), 1) ;
533 } ;
534
535 /* Write extra bit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
536 if (extra_bit >= 0)
537 dwvw_encode_store_bits (psf, pdwvw, extra_bit, 1) ;
538
539 pdwvw->last_sample = ptr [count] >> (32 - pdwvw->bit_width) ;
540 pdwvw->last_delta_width = delta_width ;
541 } ;
542
543 pdwvw->samplecount += count ;
544
545 return count ;
546 } /* dwvw_encode_data */
547
548 static sf_count_t
549 dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
550 { DWVW_PRIVATE *pdwvw ;
551 int *iptr ;
552 int k, bufferlen, writecount = 0, count ;
553 sf_count_t total = 0 ;
554
555 if (! psf->codec_data)
556 return 0 ;
557 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
558
559 iptr = psf->u.ibuf ;
560 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
561 while (len > 0)
562 { writecount = (len >= bufferlen) ? bufferlen : len ;
563 for (k = 0 ; k < writecount ; k++)
564 iptr [k] = ptr [total + k] << 16 ;
565 count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
566
567 total += count ;
568 len -= writecount ;
569 if (count != writecount)
570 break ;
571 } ;
572
573 return total ;
574 } /* dwvw_write_s */
575
576 static sf_count_t
577 dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
578 { DWVW_PRIVATE *pdwvw ;
579 int writecount, count ;
580 sf_count_t total = 0 ;
581
582 if (! psf->codec_data)
583 return 0 ;
584 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
585
586 while (len > 0)
587 { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
588
589 count = dwvw_encode_data (psf, pdwvw, ptr, writecount) ;
590
591 total += count ;
592 len -= count ;
593
594 if (count != writecount)
595 break ;
596 } ;
597
598 return total ;
599 } /* dwvw_write_i */
600
601 static sf_count_t
602 dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
603 { DWVW_PRIVATE *pdwvw ;
604 int *iptr ;
605 int k, bufferlen, writecount = 0, count ;
606 sf_count_t total = 0 ;
607 float normfact ;
608
609 if (! psf->codec_data)
610 return 0 ;
611 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
612
613 normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
614
615 iptr = psf->u.ibuf ;
616 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
617 while (len > 0)
618 { writecount = (len >= bufferlen) ? bufferlen : len ;
619 for (k = 0 ; k < writecount ; k++)
620 iptr [k] = lrintf (normfact * ptr [total + k]) ;
621 count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
622
623 total += count ;
624 len -= writecount ;
625 if (count != writecount)
626 break ;
627 } ;
628
629 return total ;
630 } /* dwvw_write_f */
631
632 static sf_count_t
633 dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
634 { DWVW_PRIVATE *pdwvw ;
635 int *iptr ;
636 int k, bufferlen, writecount = 0, count ;
637 sf_count_t total = 0 ;
638 double normfact ;
639
640 if (! psf->codec_data)
641 return 0 ;
642 pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
643
644 normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
645
646 iptr = psf->u.ibuf ;
647 bufferlen = ARRAY_LEN (psf->u.ibuf) ;
648 while (len > 0)
649 { writecount = (len >= bufferlen) ? bufferlen : len ;
650 for (k = 0 ; k < writecount ; k++)
651 iptr [k] = lrint (normfact * ptr [total + k]) ;
652 count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
653
654 total += count ;
655 len -= writecount ;
656 if (count != writecount)
657 break ;
658 } ;
659
660 return total ;
661 } /* dwvw_write_d */
662