Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ** Copyright (C) 2003-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 | 239 | #define MAX_XI_SAMPLES 16 |
33 | | |
34 | | /*------------------------------------------------------------------------------ |
35 | | ** Private static functions and tyepdefs. |
36 | | */ |
37 | | |
38 | | typedef struct |
39 | | { /* Warning, this filename is NOT nul terminated. */ |
40 | | char filename [22] ; |
41 | | char software [20] ; |
42 | | char sample_name [22] ; |
43 | | |
44 | | int loop_begin, loop_end ; |
45 | | int sample_flags ; |
46 | | |
47 | | /* Data for encoder and decoder. */ |
48 | | short last_16 ; |
49 | | } XI_PRIVATE ; |
50 | | |
51 | | static int xi_close (SF_PRIVATE *psf) ; |
52 | | static int xi_write_header (SF_PRIVATE *psf, int calc_length) ; |
53 | | static int xi_read_header (SF_PRIVATE *psf) ; |
54 | | static int dpcm_init (SF_PRIVATE *psf) ; |
55 | | |
56 | | |
57 | | static sf_count_t dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ; |
58 | | |
59 | | /*------------------------------------------------------------------------------ |
60 | | ** Public function. |
61 | | */ |
62 | | |
63 | | int |
64 | | xi_open (SF_PRIVATE *psf) |
65 | 263 | { XI_PRIVATE *pxi ; |
66 | 263 | int subformat, error = 0 ; |
67 | | |
68 | 263 | if (psf->is_pipe) |
69 | 0 | return SFE_XI_NO_PIPE ; |
70 | | |
71 | 263 | if (psf->codec_data) |
72 | 0 | pxi = psf->codec_data ; |
73 | 263 | else if ((pxi = calloc (1, sizeof (XI_PRIVATE))) == NULL) |
74 | 0 | return SFE_MALLOC_FAILED ; |
75 | | |
76 | 263 | psf->codec_data = pxi ; |
77 | | |
78 | 263 | if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) |
79 | 263 | { if ((error = xi_read_header (psf))) |
80 | 40 | return error ; |
81 | 263 | } ; |
82 | | |
83 | 223 | subformat = SF_CODEC (psf->sf.format) ; |
84 | | |
85 | 223 | if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) |
86 | 0 | { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_XI) |
87 | 0 | return SFE_BAD_OPEN_FORMAT ; |
88 | | |
89 | 0 | psf->endian = SF_ENDIAN_LITTLE ; |
90 | 0 | psf->sf.channels = 1 ; /* Always mono */ |
91 | 0 | psf->sf.samplerate = 44100 ; /* Always */ |
92 | | |
93 | | /* Set up default instrument and software name. */ |
94 | 0 | memcpy (pxi->filename, "Default Name ", sizeof (pxi->filename)) ; |
95 | 0 | memcpy (pxi->software, PACKAGE_NAME "-" PACKAGE_VERSION " ", sizeof (pxi->software)) ; |
96 | |
|
97 | 0 | memset (pxi->sample_name, 0, sizeof (pxi->sample_name)) ; |
98 | 0 | snprintf (pxi->sample_name, sizeof (pxi->sample_name), "%s", "Sample #1") ; |
99 | |
|
100 | 0 | pxi->sample_flags = (subformat == SF_FORMAT_DPCM_16) ? 16 : 0 ; |
101 | |
|
102 | 0 | if (xi_write_header (psf, SF_FALSE)) |
103 | 0 | return psf->error ; |
104 | | |
105 | 0 | psf->write_header = xi_write_header ; |
106 | 223 | } ; |
107 | | |
108 | 223 | psf->container_close = xi_close ; |
109 | 223 | psf->seek = dpcm_seek ; |
110 | | |
111 | 223 | psf->sf.seekable = SF_FALSE ; |
112 | | |
113 | 223 | psf->blockwidth = psf->bytewidth * psf->sf.channels ; |
114 | | |
115 | 223 | switch (subformat) |
116 | 223 | { case SF_FORMAT_DPCM_8 : /* 8-bit differential PCM. */ |
117 | 207 | case SF_FORMAT_DPCM_16 : /* 16-bit differential PCM. */ |
118 | 207 | error = dpcm_init (psf) ; |
119 | 207 | break ; |
120 | | |
121 | 16 | default : break ; |
122 | 223 | } ; |
123 | | |
124 | 223 | return error ; |
125 | 223 | } /* xi_open */ |
126 | | |
127 | | /*------------------------------------------------------------------------------ |
128 | | */ |
129 | | |
130 | | static int |
131 | | xi_close (SF_PRIVATE * UNUSED (psf)) |
132 | 223 | { |
133 | 223 | return 0 ; |
134 | 223 | } /* xi_close */ |
135 | | |
136 | | /*============================================================================== |
137 | | */ |
138 | | |
139 | | static sf_count_t dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; |
140 | | static sf_count_t dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; |
141 | | static sf_count_t dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; |
142 | | static sf_count_t dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; |
143 | | |
144 | | static sf_count_t dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; |
145 | | static sf_count_t dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; |
146 | | static sf_count_t dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; |
147 | | static sf_count_t dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; |
148 | | |
149 | | static sf_count_t dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; |
150 | | static sf_count_t dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; |
151 | | static sf_count_t dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; |
152 | | static sf_count_t dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; |
153 | | |
154 | | static sf_count_t dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; |
155 | | static sf_count_t dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; |
156 | | static sf_count_t dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; |
157 | | static sf_count_t dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; |
158 | | |
159 | | static int |
160 | | dpcm_init (SF_PRIVATE *psf) |
161 | 207 | { if (psf->bytewidth == 0 || psf->sf.channels == 0) |
162 | 0 | return SFE_INTERNAL ; |
163 | | |
164 | 207 | psf->blockwidth = psf->bytewidth * psf->sf.channels ; |
165 | | |
166 | 207 | if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR) |
167 | 207 | { switch (psf->bytewidth) |
168 | 207 | { case 1 : |
169 | 124 | psf->read_short = dpcm_read_dsc2s ; |
170 | 124 | psf->read_int = dpcm_read_dsc2i ; |
171 | 124 | psf->read_float = dpcm_read_dsc2f ; |
172 | 124 | psf->read_double = dpcm_read_dsc2d ; |
173 | 124 | break ; |
174 | 83 | case 2 : |
175 | 83 | psf->read_short = dpcm_read_dles2s ; |
176 | 83 | psf->read_int = dpcm_read_dles2i ; |
177 | 83 | psf->read_float = dpcm_read_dles2f ; |
178 | 83 | psf->read_double = dpcm_read_dles2d ; |
179 | 83 | break ; |
180 | 0 | default : |
181 | 0 | psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ; |
182 | 0 | return SFE_UNIMPLEMENTED ; |
183 | 207 | } ; |
184 | 207 | } ; |
185 | | |
186 | 207 | if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) |
187 | 0 | { switch (psf->bytewidth) |
188 | 0 | { case 1 : |
189 | 0 | psf->write_short = dpcm_write_s2dsc ; |
190 | 0 | psf->write_int = dpcm_write_i2dsc ; |
191 | 0 | psf->write_float = dpcm_write_f2dsc ; |
192 | 0 | psf->write_double = dpcm_write_d2dsc ; |
193 | 0 | break ; |
194 | 0 | case 2 : |
195 | 0 | psf->write_short = dpcm_write_s2dles ; |
196 | 0 | psf->write_int = dpcm_write_i2dles ; |
197 | 0 | psf->write_float = dpcm_write_f2dles ; |
198 | 0 | psf->write_double = dpcm_write_d2dles ; |
199 | 0 | break ; |
200 | 0 | default : |
201 | 0 | psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ; |
202 | 0 | return SFE_UNIMPLEMENTED ; |
203 | 0 | } ; |
204 | 207 | } ; |
205 | | |
206 | 207 | psf->filelength = psf_get_filelen (psf) ; |
207 | 207 | psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : |
208 | 207 | psf->filelength - psf->dataoffset ; |
209 | 207 | psf->sf.frames = psf->datalength / psf->blockwidth ; |
210 | | |
211 | 207 | return 0 ; |
212 | 207 | } /* dpcm_init */ |
213 | | |
214 | | /*============================================================================== |
215 | | */ |
216 | | |
217 | | static sf_count_t |
218 | | dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) |
219 | 0 | { BUF_UNION ubuf ; |
220 | 0 | XI_PRIVATE *pxi ; |
221 | 0 | int total, bufferlen, len ; |
222 | |
|
223 | 0 | if ((pxi = psf->codec_data) == NULL) |
224 | 0 | return SFE_INTERNAL ; |
225 | | |
226 | 0 | if (psf->datalength < 0 || psf->dataoffset < 0) |
227 | 0 | { psf->error = SFE_BAD_SEEK ; |
228 | 0 | return PSF_SEEK_ERROR ; |
229 | 0 | } ; |
230 | |
|
231 | 0 | if (offset == 0) |
232 | 0 | { psf_fseek (psf, psf->dataoffset, SEEK_SET) ; |
233 | 0 | pxi->last_16 = 0 ; |
234 | 0 | return 0 ; |
235 | 0 | } ; |
236 | |
|
237 | 0 | if (offset < 0 || offset > psf->sf.frames) |
238 | 0 | { psf->error = SFE_BAD_SEEK ; |
239 | 0 | return PSF_SEEK_ERROR ; |
240 | 0 | } ; |
241 | |
|
242 | 0 | if (mode != SFM_READ) |
243 | 0 | { /* What to do about write??? */ |
244 | 0 | psf->error = SFE_BAD_SEEK ; |
245 | 0 | return PSF_SEEK_ERROR ; |
246 | 0 | } ; |
247 | |
|
248 | 0 | psf_fseek (psf, psf->dataoffset, SEEK_SET) ; |
249 | |
|
250 | 0 | if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_DPCM_16) |
251 | 0 | { total = offset ; |
252 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
253 | 0 | while (total > 0) |
254 | 0 | { len = (total > bufferlen) ? bufferlen : total ; |
255 | 0 | total -= (int) dpcm_read_dles2s (psf, ubuf.sbuf, len) ; |
256 | 0 | } ; |
257 | 0 | } |
258 | 0 | else |
259 | 0 | { total = offset ; |
260 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
261 | 0 | while (total > 0) |
262 | 0 | { len = (total > bufferlen) ? bufferlen : total ; |
263 | 0 | total -= (int) dpcm_read_dsc2s (psf, ubuf.sbuf, len) ; |
264 | 0 | } ; |
265 | 0 | } ; |
266 | |
|
267 | 0 | return offset ; |
268 | 0 | } /* dpcm_seek */ |
269 | | |
270 | | |
271 | | static int |
272 | | xi_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) |
273 | 0 | { XI_PRIVATE *pxi ; |
274 | 0 | sf_count_t current ; |
275 | 0 | const char *string ; |
276 | |
|
277 | 0 | if ((pxi = psf->codec_data) == NULL) |
278 | 0 | return SFE_INTERNAL ; |
279 | | |
280 | 0 | current = psf_ftell (psf) ; |
281 | | |
282 | | /* Reset the current header length to zero. */ |
283 | 0 | psf->header.ptr [0] = 0 ; |
284 | 0 | psf->header.indx = 0 ; |
285 | 0 | psf_fseek (psf, 0, SEEK_SET) ; |
286 | |
|
287 | 0 | string = "Extended Instrument: " ; |
288 | 0 | psf_binheader_writef (psf, "b", BHWv (string), BHWz (strlen (string))) ; |
289 | 0 | psf_binheader_writef (psf, "b1", BHWv (pxi->filename), BHWz (sizeof (pxi->filename)), BHW1 (0x1A)) ; |
290 | | |
291 | | /* Write software version and two byte XI version. */ |
292 | 0 | psf_binheader_writef (psf, "eb2", BHWv (pxi->software), BHWz (sizeof (pxi->software)), BHW2 ((1 << 8) + 2)) ; |
293 | | |
294 | | /* |
295 | | ** Jump note numbers (96), volume envelope (48), pan envelope (48), |
296 | | ** volume points (1), pan points (1) |
297 | | */ |
298 | 0 | psf_binheader_writef (psf, "z", BHWz ((size_t) (96 + 48 + 48 + 1 + 1))) ; |
299 | | |
300 | | /* Jump volume loop (3 bytes), pan loop (3), envelope flags (3), vibrato (3) |
301 | | ** fade out (2), 22 unknown bytes, and then write sample_count (2 bytes). |
302 | | */ |
303 | 0 | psf_binheader_writef (psf, "ez2z2", BHWz ((size_t) (4 * 3)), BHW2 (0x1234), BHWz (22), BHW2 (1)) ; |
304 | |
|
305 | 0 | pxi->loop_begin = 0 ; |
306 | 0 | pxi->loop_end = 0 ; |
307 | |
|
308 | 0 | psf_binheader_writef (psf, "et844", BHW8 (psf->sf.frames), BHW4 (pxi->loop_begin), BHW4 (pxi->loop_end)) ; |
309 | | |
310 | | /* volume, fine tune, flags, pan, note, namelen */ |
311 | 0 | psf_binheader_writef (psf, "111111", BHW1 (128), BHW1 (0), BHW1 (pxi->sample_flags), BHW1 (128), BHW1 (0), BHW1 (strlen (pxi->sample_name))) ; |
312 | |
|
313 | 0 | psf_binheader_writef (psf, "b", BHWv (pxi->sample_name), BHWz (sizeof (pxi->sample_name))) ; |
314 | | |
315 | | /* Header construction complete so write it out. */ |
316 | 0 | psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; |
317 | |
|
318 | 0 | if (psf->error) |
319 | 0 | return psf->error ; |
320 | | |
321 | 0 | psf->dataoffset = psf->header.indx ; |
322 | |
|
323 | 0 | if (current > 0) |
324 | 0 | psf_fseek (psf, current, SEEK_SET) ; |
325 | |
|
326 | 0 | return psf->error ; |
327 | 0 | } /* xi_write_header */ |
328 | | |
329 | | static int |
330 | | xi_read_header (SF_PRIVATE *psf) |
331 | 263 | { char buffer [64], name [32] ; |
332 | 263 | short version, fade_out, sample_count ; |
333 | 263 | int k, loop_begin, loop_end ; |
334 | 263 | int sample_sizes [MAX_XI_SAMPLES] ; |
335 | | |
336 | 263 | psf_binheader_readf (psf, "pb", 0, buffer, 21) ; |
337 | | |
338 | 263 | memset (sample_sizes, 0, sizeof (sample_sizes)) ; |
339 | | |
340 | 263 | buffer [20] = 0 ; |
341 | 263 | if (strcmp (buffer, "Extended Instrument:") != 0) |
342 | 23 | return SFE_XI_BAD_HEADER ; |
343 | | |
344 | 240 | memset (buffer, 0, sizeof (buffer)) ; |
345 | 240 | psf_binheader_readf (psf, "b", buffer, 23) ; |
346 | | |
347 | 240 | if (buffer [22] != 0x1A) |
348 | 1 | return SFE_XI_BAD_HEADER ; |
349 | | |
350 | 239 | buffer [22] = 0 ; |
351 | 1.62k | for (k = 21 ; k >= 0 && buffer [k] == ' ' ; k --) |
352 | 1.38k | buffer [k] = 0 ; |
353 | | |
354 | 239 | psf_log_printf (psf, "Extended Instrument : %s\n", buffer) ; |
355 | 239 | psf_store_string (psf, SF_STR_TITLE, buffer) ; |
356 | | |
357 | 239 | psf_binheader_readf (psf, "be2", buffer, 20, &version) ; |
358 | 239 | buffer [19] = 0 ; |
359 | 536 | for (k = 18 ; k >= 0 && buffer [k] == ' ' ; k --) |
360 | 297 | buffer [k] = 0 ; |
361 | | |
362 | 239 | psf_log_printf (psf, "Software : %s\nVersion : %d.%02d\n", buffer, version / 256, version % 256) ; |
363 | 239 | psf_store_string (psf, SF_STR_SOFTWARE, buffer) ; |
364 | | |
365 | | /* Jump note numbers (96), volume envelope (48), pan envelope (48), |
366 | | ** volume points (1), pan points (1) |
367 | | */ |
368 | 239 | psf_binheader_readf (psf, "j", 96 + 48 + 48 + 1 + 1) ; |
369 | | |
370 | 239 | psf_binheader_readf (psf, "b", buffer, 12) ; |
371 | 239 | psf_log_printf (psf, "Volume Loop\n sustain : %u\n begin : %u\n end : %u\n", |
372 | 239 | buffer [0], buffer [1], buffer [2]) ; |
373 | 239 | psf_log_printf (psf, "Pan Loop\n sustain : %u\n begin : %u\n end : %u\n", |
374 | 239 | buffer [3], buffer [4], buffer [5]) ; |
375 | 239 | psf_log_printf (psf, "Envelope Flags\n volume : 0x%X\n pan : 0x%X\n", |
376 | 239 | buffer [6] & 0xFF, buffer [7] & 0xFF) ; |
377 | | |
378 | 239 | psf_log_printf (psf, "Vibrato\n type : %u\n sweep : %u\n depth : %u\n rate : %u\n", |
379 | 239 | buffer [8], buffer [9], buffer [10], buffer [11]) ; |
380 | | |
381 | | /* |
382 | | ** Read fade_out then jump reserved (2 bytes) and ???? (20 bytes) and |
383 | | ** sample_count. |
384 | | */ |
385 | 239 | psf_binheader_readf (psf, "e2j2", &fade_out, 2 + 20, &sample_count) ; |
386 | 239 | psf_log_printf (psf, "Fade out : %d\n", fade_out) ; |
387 | | |
388 | | /* XI file can contain up to 16 samples. */ |
389 | 239 | if (sample_count > MAX_XI_SAMPLES) |
390 | 1 | return SFE_XI_EXCESS_SAMPLES ; |
391 | | |
392 | 238 | if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL) |
393 | 0 | return SFE_MALLOC_FAILED ; |
394 | | |
395 | 238 | psf->instrument->basenote = 0 ; |
396 | | /* Log all data for each sample. */ |
397 | 776 | for (k = 0 ; k < sample_count ; k++) |
398 | 538 | { psf_binheader_readf (psf, "e444", &(sample_sizes [k]), &loop_begin, &loop_end) ; |
399 | | |
400 | | /* Read 5 know bytes, 1 unknown byte and 22 name bytes. */ |
401 | 538 | psf_binheader_readf (psf, "bb", buffer, 6, name, 22) ; |
402 | 538 | name [21] = 0 ; |
403 | | |
404 | 538 | psf_log_printf (psf, "Sample #%d\n name : %s\n", k + 1, name) ; |
405 | | |
406 | 538 | psf_log_printf (psf, " size : %d\n", sample_sizes [k]) ; |
407 | | |
408 | 538 | psf_log_printf (psf, " loop\n begin : %d\n end : %d\n", loop_begin, loop_end) ; |
409 | | |
410 | 538 | psf_log_printf (psf, " volume : %u\n f. tune : %d\n flags : 0x%02X ", |
411 | 538 | buffer [0] & 0xFF, buffer [1] & 0xFF, buffer [2] & 0xFF) ; |
412 | | |
413 | 538 | psf_log_printf (psf, " (") ; |
414 | 538 | if (buffer [2] & 1) |
415 | 146 | psf_log_printf (psf, " Loop") ; |
416 | 538 | if (buffer [2] & 2) |
417 | 140 | psf_log_printf (psf, " PingPong") ; |
418 | 538 | psf_log_printf (psf, (buffer [2] & 16) ? " 16bit" : " 8bit") ; |
419 | 538 | psf_log_printf (psf, " )\n") ; |
420 | | |
421 | 538 | psf_log_printf (psf, " pan : %u\n note : %d\n namelen : %d\n", |
422 | 538 | buffer [3] & 0xFF, buffer [4], buffer [5]) ; |
423 | | |
424 | 538 | psf->instrument->basenote = buffer [4] ; |
425 | 538 | if (buffer [2] & 1) |
426 | 146 | { psf->instrument->loop_count = 1 ; |
427 | 146 | psf->instrument->loops [0].mode = (buffer [2] & 2) ? SF_LOOP_ALTERNATING : SF_LOOP_FORWARD ; |
428 | 146 | psf->instrument->loops [0].start = loop_begin ; |
429 | 146 | psf->instrument->loops [0].end = loop_end ; |
430 | 146 | } ; |
431 | | |
432 | 538 | if (k != 0) |
433 | 316 | continue ; |
434 | | |
435 | 222 | if (buffer [2] & 16) |
436 | 88 | { psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_16 ; |
437 | 88 | psf->bytewidth = 2 ; |
438 | 88 | } |
439 | 134 | else |
440 | 134 | { psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_8 ; |
441 | 134 | psf->bytewidth = 1 ; |
442 | 134 | } ; |
443 | 222 | } ; |
444 | | |
445 | 471 | while (sample_count > 1 && sample_sizes [sample_count - 1] == 0) |
446 | 233 | sample_count -- ; |
447 | | |
448 | | /* Currently, we can only handle 1 sample per file. */ |
449 | | |
450 | 238 | if (sample_count > 2) |
451 | 15 | { psf_log_printf (psf, "*** Sample count is less than 16 but more than 1.\n") ; |
452 | 15 | psf_log_printf (psf, " sample count : %d sample_sizes [%d] : %d\n", |
453 | 15 | sample_count, sample_count - 1, sample_sizes [sample_count - 1]) ; |
454 | 15 | return SFE_XI_EXCESS_SAMPLES ; |
455 | 223 | } ; |
456 | | |
457 | 223 | psf->datalength = sample_sizes [0] ; |
458 | | |
459 | 223 | psf->dataoffset = psf_ftell (psf) ; |
460 | 223 | if (psf->dataoffset < 0) |
461 | 0 | { psf_log_printf (psf, "*** Bad Data Offset : %D\n", psf->dataoffset) ; |
462 | 0 | return SFE_BAD_OFFSET ; |
463 | 223 | } ; |
464 | 223 | psf_log_printf (psf, "Data Offset : %D\n", psf->dataoffset) ; |
465 | | |
466 | 223 | if (psf->dataoffset + psf->datalength > psf->filelength) |
467 | 113 | { psf_log_printf (psf, "*** File seems to be truncated. Should be at least %D bytes long.\n", |
468 | 113 | psf->dataoffset + sample_sizes [0]) ; |
469 | 113 | psf->datalength = psf->filelength - psf->dataoffset ; |
470 | 113 | } ; |
471 | | |
472 | 223 | if (psf_fseek (psf, psf->dataoffset, SEEK_SET) != psf->dataoffset) |
473 | 0 | return SFE_BAD_SEEK ; |
474 | | |
475 | 223 | psf->endian = SF_ENDIAN_LITTLE ; |
476 | 223 | psf->sf.channels = 1 ; /* Always mono */ |
477 | 223 | psf->sf.samplerate = 44100 ; /* Always */ |
478 | | |
479 | 223 | psf->blockwidth = psf->sf.channels * psf->bytewidth ; |
480 | | |
481 | 223 | if (! psf->sf.frames && psf->blockwidth) |
482 | 207 | psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ; |
483 | | |
484 | 223 | psf->instrument->gain = 1 ; |
485 | 223 | psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ; |
486 | 223 | psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ; |
487 | | |
488 | 223 | return 0 ; |
489 | 223 | } /* xi_read_header */ |
490 | | |
491 | | /*============================================================================== |
492 | | */ |
493 | | |
494 | | static void dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest) ; |
495 | | static void dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest) ; |
496 | | static void dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact) ; |
497 | | static void dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact) ; |
498 | | |
499 | | static void dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest) ; |
500 | | static void dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest) ; |
501 | | static void dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact) ; |
502 | | static void dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact) ; |
503 | | |
504 | | static sf_count_t |
505 | | dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) |
506 | 41 | { BUF_UNION ubuf ; |
507 | 41 | XI_PRIVATE *pxi ; |
508 | 41 | int bufferlen, readcount ; |
509 | 41 | sf_count_t total = 0 ; |
510 | | |
511 | 41 | if ((pxi = psf->codec_data) == NULL) |
512 | 0 | return 0 ; |
513 | | |
514 | 41 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
515 | | |
516 | 350 | while (len > 0) |
517 | 350 | { if (len < bufferlen) |
518 | 30 | bufferlen = (int) len ; |
519 | 350 | readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
520 | 350 | dsc2s_array (pxi, ubuf.scbuf, readcount, ptr + total) ; |
521 | 350 | total += readcount ; |
522 | 350 | if (readcount < bufferlen) |
523 | 41 | break ; |
524 | 309 | len -= readcount ; |
525 | 309 | } ; |
526 | | |
527 | 41 | return total ; |
528 | 41 | } /* dpcm_read_dsc2s */ |
529 | | |
530 | | static sf_count_t |
531 | | dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) |
532 | 29 | { BUF_UNION ubuf ; |
533 | 29 | XI_PRIVATE *pxi ; |
534 | 29 | int bufferlen, readcount ; |
535 | 29 | sf_count_t total = 0 ; |
536 | | |
537 | 29 | if ((pxi = psf->codec_data) == NULL) |
538 | 0 | return 0 ; |
539 | | |
540 | 29 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
541 | | |
542 | 340 | while (len > 0) |
543 | 340 | { if (len < bufferlen) |
544 | 22 | bufferlen = (int) len ; |
545 | 340 | readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
546 | 340 | dsc2i_array (pxi, ubuf.scbuf, readcount, ptr + total) ; |
547 | 340 | total += readcount ; |
548 | 340 | if (readcount < bufferlen) |
549 | 29 | break ; |
550 | 311 | len -= readcount ; |
551 | 311 | } ; |
552 | | |
553 | 29 | return total ; |
554 | 29 | } /* dpcm_read_dsc2i */ |
555 | | |
556 | | static sf_count_t |
557 | | dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) |
558 | 0 | { BUF_UNION ubuf ; |
559 | 0 | XI_PRIVATE *pxi ; |
560 | 0 | int bufferlen, readcount ; |
561 | 0 | sf_count_t total = 0 ; |
562 | 0 | float normfact ; |
563 | |
|
564 | 0 | if ((pxi = psf->codec_data) == NULL) |
565 | 0 | return 0 ; |
566 | | |
567 | 0 | normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ; |
568 | |
|
569 | 0 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
570 | |
|
571 | 0 | while (len > 0) |
572 | 0 | { if (len < bufferlen) |
573 | 0 | bufferlen = (int) len ; |
574 | 0 | readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
575 | 0 | dsc2f_array (pxi, ubuf.scbuf, readcount, ptr + total, normfact) ; |
576 | 0 | total += readcount ; |
577 | 0 | if (readcount < bufferlen) |
578 | 0 | break ; |
579 | 0 | len -= readcount ; |
580 | 0 | } ; |
581 | |
|
582 | 0 | return total ; |
583 | 0 | } /* dpcm_read_dsc2f */ |
584 | | |
585 | | static sf_count_t |
586 | | dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) |
587 | 30 | { BUF_UNION ubuf ; |
588 | 30 | XI_PRIVATE *pxi ; |
589 | 30 | int bufferlen, readcount ; |
590 | 30 | sf_count_t total = 0 ; |
591 | 30 | double normfact ; |
592 | | |
593 | 30 | if ((pxi = psf->codec_data) == NULL) |
594 | 0 | return 0 ; |
595 | | |
596 | 30 | normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ; |
597 | | |
598 | 30 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
599 | | |
600 | 468 | while (len > 0) |
601 | 468 | { if (len < bufferlen) |
602 | 23 | bufferlen = (int) len ; |
603 | 468 | readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
604 | 468 | dsc2d_array (pxi, ubuf.scbuf, readcount, ptr + total, normfact) ; |
605 | 468 | total += readcount ; |
606 | 468 | if (readcount < bufferlen) |
607 | 30 | break ; |
608 | 438 | len -= readcount ; |
609 | 438 | } ; |
610 | | |
611 | 30 | return total ; |
612 | 30 | } /* dpcm_read_dsc2d */ |
613 | | |
614 | | /*------------------------------------------------------------------------------ |
615 | | */ |
616 | | |
617 | | static sf_count_t |
618 | | dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) |
619 | 24 | { BUF_UNION ubuf ; |
620 | 24 | XI_PRIVATE *pxi ; |
621 | 24 | int bufferlen, readcount ; |
622 | 24 | sf_count_t total = 0 ; |
623 | | |
624 | 24 | if ((pxi = psf->codec_data) == NULL) |
625 | 0 | return 0 ; |
626 | | |
627 | 24 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
628 | | |
629 | 288 | while (len > 0) |
630 | 288 | { if (len < bufferlen) |
631 | 9 | bufferlen = (int) len ; |
632 | 288 | readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
633 | 288 | dles2s_array (pxi, ubuf.sbuf, readcount, ptr + total) ; |
634 | 288 | total += readcount ; |
635 | 288 | if (readcount < bufferlen) |
636 | 24 | break ; |
637 | 264 | len -= readcount ; |
638 | 264 | } ; |
639 | | |
640 | 24 | return total ; |
641 | 24 | } /* dpcm_read_dles2s */ |
642 | | |
643 | | static sf_count_t |
644 | | dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) |
645 | 27 | { BUF_UNION ubuf ; |
646 | 27 | XI_PRIVATE *pxi ; |
647 | 27 | int bufferlen, readcount ; |
648 | 27 | sf_count_t total = 0 ; |
649 | | |
650 | 27 | if ((pxi = psf->codec_data) == NULL) |
651 | 0 | return 0 ; |
652 | | |
653 | 27 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
654 | | |
655 | 460 | while (len > 0) |
656 | 460 | { if (len < bufferlen) |
657 | 9 | bufferlen = (int) len ; |
658 | 460 | readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
659 | 460 | dles2i_array (pxi, ubuf.sbuf, readcount, ptr + total) ; |
660 | 460 | total += readcount ; |
661 | 460 | if (readcount < bufferlen) |
662 | 27 | break ; |
663 | 433 | len -= readcount ; |
664 | 433 | } ; |
665 | | |
666 | 27 | return total ; |
667 | 27 | } /* dpcm_read_dles2i */ |
668 | | |
669 | | static sf_count_t |
670 | | dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) |
671 | 0 | { BUF_UNION ubuf ; |
672 | 0 | XI_PRIVATE *pxi ; |
673 | 0 | int bufferlen, readcount ; |
674 | 0 | sf_count_t total = 0 ; |
675 | 0 | float normfact ; |
676 | |
|
677 | 0 | if ((pxi = psf->codec_data) == NULL) |
678 | 0 | return 0 ; |
679 | | |
680 | 0 | normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ; |
681 | |
|
682 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
683 | |
|
684 | 0 | while (len > 0) |
685 | 0 | { if (len < bufferlen) |
686 | 0 | bufferlen = (int) len ; |
687 | 0 | readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
688 | 0 | dles2f_array (pxi, ubuf.sbuf, readcount, ptr + total, normfact) ; |
689 | 0 | total += readcount ; |
690 | 0 | if (readcount < bufferlen) |
691 | 0 | break ; |
692 | 0 | len -= readcount ; |
693 | 0 | } ; |
694 | |
|
695 | 0 | return total ; |
696 | 0 | } /* dpcm_read_dles2f */ |
697 | | |
698 | | static sf_count_t |
699 | | dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) |
700 | 27 | { BUF_UNION ubuf ; |
701 | 27 | XI_PRIVATE *pxi ; |
702 | 27 | int bufferlen, readcount ; |
703 | 27 | sf_count_t total = 0 ; |
704 | 27 | double normfact ; |
705 | | |
706 | 27 | if ((pxi = psf->codec_data) == NULL) |
707 | 0 | return 0 ; |
708 | | |
709 | 27 | normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ; |
710 | | |
711 | 27 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
712 | | |
713 | 294 | while (len > 0) |
714 | 294 | { if (len < bufferlen) |
715 | 11 | bufferlen = (int) len ; |
716 | 294 | readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
717 | 294 | dles2d_array (pxi, ubuf.sbuf, readcount, ptr + total, normfact) ; |
718 | 294 | total += readcount ; |
719 | 294 | if (readcount < bufferlen) |
720 | 27 | break ; |
721 | 267 | len -= readcount ; |
722 | 267 | } ; |
723 | | |
724 | 27 | return total ; |
725 | 27 | } /* dpcm_read_dles2d */ |
726 | | |
727 | | /*============================================================================== |
728 | | */ |
729 | | |
730 | | static void s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count) ; |
731 | | static void i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count) ; |
732 | | static void f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact) ; |
733 | | static void d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact) ; |
734 | | |
735 | | static void s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count) ; |
736 | | static void i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count) ; |
737 | | static void f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact) ; |
738 | | static void d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact) ; |
739 | | |
740 | | |
741 | | static sf_count_t |
742 | | dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len) |
743 | 0 | { BUF_UNION ubuf ; |
744 | 0 | XI_PRIVATE *pxi ; |
745 | 0 | int bufferlen, writecount ; |
746 | 0 | sf_count_t total = 0 ; |
747 | |
|
748 | 0 | if ((pxi = psf->codec_data) == NULL) |
749 | 0 | return 0 ; |
750 | | |
751 | 0 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
752 | |
|
753 | 0 | while (len > 0) |
754 | 0 | { if (len < bufferlen) |
755 | 0 | bufferlen = (int) len ; |
756 | 0 | s2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen) ; |
757 | 0 | writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
758 | 0 | total += writecount ; |
759 | 0 | if (writecount < bufferlen) |
760 | 0 | break ; |
761 | 0 | len -= writecount ; |
762 | 0 | } ; |
763 | |
|
764 | 0 | return total ; |
765 | 0 | } /* dpcm_write_s2dsc */ |
766 | | |
767 | | static sf_count_t |
768 | | dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len) |
769 | 0 | { BUF_UNION ubuf ; |
770 | 0 | XI_PRIVATE *pxi ; |
771 | 0 | int bufferlen, writecount ; |
772 | 0 | sf_count_t total = 0 ; |
773 | |
|
774 | 0 | if ((pxi = psf->codec_data) == NULL) |
775 | 0 | return 0 ; |
776 | | |
777 | 0 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
778 | |
|
779 | 0 | while (len > 0) |
780 | 0 | { if (len < bufferlen) |
781 | 0 | bufferlen = (int) len ; |
782 | 0 | i2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen) ; |
783 | 0 | writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
784 | 0 | total += writecount ; |
785 | 0 | if (writecount < bufferlen) |
786 | 0 | break ; |
787 | 0 | len -= writecount ; |
788 | 0 | } ; |
789 | |
|
790 | 0 | return total ; |
791 | 0 | } /* dpcm_write_i2dsc */ |
792 | | |
793 | | static sf_count_t |
794 | | dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len) |
795 | 0 | { BUF_UNION ubuf ; |
796 | 0 | XI_PRIVATE *pxi ; |
797 | 0 | int bufferlen, writecount ; |
798 | 0 | sf_count_t total = 0 ; |
799 | 0 | float normfact ; |
800 | |
|
801 | 0 | if ((pxi = psf->codec_data) == NULL) |
802 | 0 | return 0 ; |
803 | | |
804 | 0 | normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ; |
805 | |
|
806 | 0 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
807 | |
|
808 | 0 | while (len > 0) |
809 | 0 | { if (len < bufferlen) |
810 | 0 | bufferlen = (int) len ; |
811 | 0 | f2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen, normfact) ; |
812 | 0 | writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
813 | 0 | total += writecount ; |
814 | 0 | if (writecount < bufferlen) |
815 | 0 | break ; |
816 | 0 | len -= writecount ; |
817 | 0 | } ; |
818 | |
|
819 | 0 | return total ; |
820 | 0 | } /* dpcm_write_f2dsc */ |
821 | | |
822 | | static sf_count_t |
823 | | dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len) |
824 | 0 | { BUF_UNION ubuf ; |
825 | 0 | XI_PRIVATE *pxi ; |
826 | 0 | int bufferlen, writecount ; |
827 | 0 | sf_count_t total = 0 ; |
828 | 0 | double normfact ; |
829 | |
|
830 | 0 | if ((pxi = psf->codec_data) == NULL) |
831 | 0 | return 0 ; |
832 | | |
833 | 0 | normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ; |
834 | |
|
835 | 0 | bufferlen = ARRAY_LEN (ubuf.ucbuf) ; |
836 | |
|
837 | 0 | while (len > 0) |
838 | 0 | { if (len < bufferlen) |
839 | 0 | bufferlen = (int) len ; |
840 | 0 | d2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen, normfact) ; |
841 | 0 | writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ; |
842 | 0 | total += writecount ; |
843 | 0 | if (writecount < bufferlen) |
844 | 0 | break ; |
845 | 0 | len -= writecount ; |
846 | 0 | } ; |
847 | |
|
848 | 0 | return total ; |
849 | 0 | } /* dpcm_write_d2dsc */ |
850 | | |
851 | | |
852 | | static sf_count_t |
853 | | dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len) |
854 | 0 | { BUF_UNION ubuf ; |
855 | 0 | XI_PRIVATE *pxi ; |
856 | 0 | int bufferlen, writecount ; |
857 | 0 | sf_count_t total = 0 ; |
858 | |
|
859 | 0 | if ((pxi = psf->codec_data) == NULL) |
860 | 0 | return 0 ; |
861 | | |
862 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
863 | |
|
864 | 0 | while (len > 0) |
865 | 0 | { if (len < bufferlen) |
866 | 0 | bufferlen = (int) len ; |
867 | 0 | s2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen) ; |
868 | 0 | writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
869 | 0 | total += writecount ; |
870 | 0 | if (writecount < bufferlen) |
871 | 0 | break ; |
872 | 0 | len -= writecount ; |
873 | 0 | } ; |
874 | |
|
875 | 0 | return total ; |
876 | 0 | } /* dpcm_write_s2dles */ |
877 | | |
878 | | static sf_count_t |
879 | | dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len) |
880 | 0 | { BUF_UNION ubuf ; |
881 | 0 | XI_PRIVATE *pxi ; |
882 | 0 | int bufferlen, writecount ; |
883 | 0 | sf_count_t total = 0 ; |
884 | |
|
885 | 0 | if ((pxi = psf->codec_data) == NULL) |
886 | 0 | return 0 ; |
887 | | |
888 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
889 | |
|
890 | 0 | while (len > 0) |
891 | 0 | { if (len < bufferlen) |
892 | 0 | bufferlen = (int) len ; |
893 | 0 | i2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen) ; |
894 | 0 | writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
895 | 0 | total += writecount ; |
896 | 0 | if (writecount < bufferlen) |
897 | 0 | break ; |
898 | 0 | len -= writecount ; |
899 | 0 | } ; |
900 | |
|
901 | 0 | return total ; |
902 | 0 | } /* dpcm_write_i2dles */ |
903 | | |
904 | | static sf_count_t |
905 | | dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len) |
906 | 0 | { BUF_UNION ubuf ; |
907 | 0 | XI_PRIVATE *pxi ; |
908 | 0 | int bufferlen, writecount ; |
909 | 0 | sf_count_t total = 0 ; |
910 | 0 | float normfact ; |
911 | |
|
912 | 0 | if ((pxi = psf->codec_data) == NULL) |
913 | 0 | return 0 ; |
914 | | |
915 | 0 | normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ; |
916 | |
|
917 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
918 | |
|
919 | 0 | while (len > 0) |
920 | 0 | { if (len < bufferlen) |
921 | 0 | bufferlen = (int) len ; |
922 | 0 | f2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen, normfact) ; |
923 | 0 | writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
924 | 0 | total += writecount ; |
925 | 0 | if (writecount < bufferlen) |
926 | 0 | break ; |
927 | 0 | len -= writecount ; |
928 | 0 | } ; |
929 | |
|
930 | 0 | return total ; |
931 | 0 | } /* dpcm_write_f2dles */ |
932 | | |
933 | | static sf_count_t |
934 | | dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len) |
935 | 0 | { BUF_UNION ubuf ; |
936 | 0 | XI_PRIVATE *pxi ; |
937 | 0 | int bufferlen, writecount ; |
938 | 0 | sf_count_t total = 0 ; |
939 | 0 | double normfact ; |
940 | |
|
941 | 0 | if ((pxi = psf->codec_data) == NULL) |
942 | 0 | return 0 ; |
943 | | |
944 | 0 | normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ; |
945 | |
|
946 | 0 | bufferlen = ARRAY_LEN (ubuf.sbuf) ; |
947 | |
|
948 | 0 | while (len > 0) |
949 | 0 | { if (len < bufferlen) |
950 | 0 | bufferlen = (int) len ; |
951 | 0 | d2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen, normfact) ; |
952 | 0 | writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ; |
953 | 0 | total += writecount ; |
954 | 0 | if (writecount < bufferlen) |
955 | 0 | break ; |
956 | 0 | len -= writecount ; |
957 | 0 | } ; |
958 | |
|
959 | 0 | return total ; |
960 | 0 | } /* dpcm_write_d2dles */ |
961 | | |
962 | | |
963 | | /*============================================================================== |
964 | | */ |
965 | | |
966 | | static void |
967 | | dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest) |
968 | 350 | { signed char last_val ; |
969 | 350 | int k ; |
970 | | |
971 | 350 | last_val = pxi->last_16 >> 8 ; |
972 | | |
973 | 2.63M | for (k = 0 ; k < count ; k++) |
974 | 2.63M | { last_val += src [k] ; |
975 | 2.63M | dest [k] = arith_shift_left (last_val, 8) ; |
976 | 2.63M | } ; |
977 | | |
978 | 350 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
979 | 350 | } /* dsc2s_array */ |
980 | | |
981 | | static void |
982 | | dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest) |
983 | 340 | { signed char last_val ; |
984 | 340 | int k ; |
985 | | |
986 | 340 | last_val = pxi->last_16 >> 8 ; |
987 | | |
988 | 2.60M | for (k = 0 ; k < count ; k++) |
989 | 2.60M | { last_val += src [k] ; |
990 | 2.60M | dest [k] = arith_shift_left (last_val, 24) ; |
991 | 2.60M | } ; |
992 | | |
993 | 340 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
994 | 340 | } /* dsc2i_array */ |
995 | | |
996 | | static void |
997 | | dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact) |
998 | 0 | { signed char last_val ; |
999 | 0 | int k ; |
1000 | |
|
1001 | 0 | last_val = pxi->last_16 >> 8 ; |
1002 | |
|
1003 | 0 | for (k = 0 ; k < count ; k++) |
1004 | 0 | { last_val += src [k] ; |
1005 | 0 | dest [k] = last_val * normfact ; |
1006 | 0 | } ; |
1007 | |
|
1008 | 0 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1009 | 0 | } /* dsc2f_array */ |
1010 | | |
1011 | | static void |
1012 | | dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact) |
1013 | 468 | { signed char last_val ; |
1014 | 468 | int k ; |
1015 | | |
1016 | 468 | last_val = pxi->last_16 >> 8 ; |
1017 | | |
1018 | 3.65M | for (k = 0 ; k < count ; k++) |
1019 | 3.65M | { last_val += src [k] ; |
1020 | 3.65M | dest [k] = last_val * normfact ; |
1021 | 3.65M | } ; |
1022 | | |
1023 | 468 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1024 | 468 | } /* dsc2d_array */ |
1025 | | |
1026 | | /*------------------------------------------------------------------------------ |
1027 | | */ |
1028 | | |
1029 | | static void |
1030 | | s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count) |
1031 | 0 | { signed char last_val, current ; |
1032 | 0 | int k ; |
1033 | |
|
1034 | 0 | last_val = pxi->last_16 >> 8 ; |
1035 | |
|
1036 | 0 | for (k = 0 ; k < count ; k++) |
1037 | 0 | { current = src [k] >> 8 ; |
1038 | 0 | dest [k] = current - last_val ; |
1039 | 0 | last_val = current ; |
1040 | 0 | } ; |
1041 | |
|
1042 | 0 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1043 | 0 | } /* s2dsc_array */ |
1044 | | |
1045 | | static void |
1046 | | i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count) |
1047 | 0 | { signed char last_val, current ; |
1048 | 0 | int k ; |
1049 | |
|
1050 | 0 | last_val = pxi->last_16 >> 8 ; |
1051 | |
|
1052 | 0 | for (k = 0 ; k < count ; k++) |
1053 | 0 | { current = src [k] >> 24 ; |
1054 | 0 | dest [k] = current - last_val ; |
1055 | 0 | last_val = current ; |
1056 | 0 | } ; |
1057 | |
|
1058 | 0 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1059 | 0 | } /* i2dsc_array */ |
1060 | | |
1061 | | static void |
1062 | | f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact) |
1063 | 0 | { signed char last_val, current ; |
1064 | 0 | int k ; |
1065 | |
|
1066 | 0 | last_val = pxi->last_16 >> 8 ; |
1067 | |
|
1068 | 0 | for (k = 0 ; k < count ; k++) |
1069 | 0 | { current = psf_lrintf (src [k] * normfact) ; |
1070 | 0 | dest [k] = current - last_val ; |
1071 | 0 | last_val = current ; |
1072 | 0 | } ; |
1073 | |
|
1074 | 0 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1075 | 0 | } /* f2dsc_array */ |
1076 | | |
1077 | | static void |
1078 | | d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact) |
1079 | 0 | { signed char last_val, current ; |
1080 | 0 | int k ; |
1081 | |
|
1082 | 0 | last_val = pxi->last_16 >> 8 ; |
1083 | |
|
1084 | 0 | for (k = 0 ; k < count ; k++) |
1085 | 0 | { current = psf_lrint (src [k] * normfact) ; |
1086 | 0 | dest [k] = current - last_val ; |
1087 | 0 | last_val = current ; |
1088 | 0 | } ; |
1089 | |
|
1090 | 0 | pxi->last_16 = arith_shift_left (last_val, 8) ; |
1091 | 0 | } /* d2dsc_array */ |
1092 | | |
1093 | | /*============================================================================== |
1094 | | */ |
1095 | | |
1096 | | static void |
1097 | | dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest) |
1098 | 288 | { short last_val ; |
1099 | 288 | int k ; |
1100 | | |
1101 | 288 | last_val = pxi->last_16 ; |
1102 | | |
1103 | 1.08M | for (k = 0 ; k < count ; k++) |
1104 | 1.08M | { last_val += LE2H_16 (src [k]) ; |
1105 | 1.08M | dest [k] = last_val ; |
1106 | 1.08M | } ; |
1107 | | |
1108 | 288 | pxi->last_16 = last_val ; |
1109 | 288 | } /* dles2s_array */ |
1110 | | |
1111 | | static void |
1112 | | dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest) |
1113 | 460 | { short last_val ; |
1114 | 460 | int k ; |
1115 | | |
1116 | 460 | last_val = pxi->last_16 ; |
1117 | | |
1118 | 1.78M | for (k = 0 ; k < count ; k++) |
1119 | 1.78M | { last_val += LE2H_16 (src [k]) ; |
1120 | 1.78M | dest [k] = arith_shift_left (last_val, 16) ; |
1121 | 1.78M | } ; |
1122 | | |
1123 | 460 | pxi->last_16 = last_val ; |
1124 | 460 | } /* dles2i_array */ |
1125 | | |
1126 | | static void |
1127 | | dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact) |
1128 | 0 | { short last_val ; |
1129 | 0 | int k ; |
1130 | |
|
1131 | 0 | last_val = pxi->last_16 ; |
1132 | |
|
1133 | 0 | for (k = 0 ; k < count ; k++) |
1134 | 0 | { last_val += LE2H_16 (src [k]) ; |
1135 | 0 | dest [k] = last_val * normfact ; |
1136 | 0 | } ; |
1137 | |
|
1138 | 0 | pxi->last_16 = last_val ; |
1139 | 0 | } /* dles2f_array */ |
1140 | | |
1141 | | static void |
1142 | | dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact) |
1143 | 294 | { short last_val ; |
1144 | 294 | int k ; |
1145 | | |
1146 | 294 | last_val = pxi->last_16 ; |
1147 | | |
1148 | 1.09M | for (k = 0 ; k < count ; k++) |
1149 | 1.09M | { last_val += LE2H_16 (src [k]) ; |
1150 | 1.09M | dest [k] = last_val * normfact ; |
1151 | 1.09M | } ; |
1152 | | |
1153 | 294 | pxi->last_16 = last_val ; |
1154 | 294 | } /* dles2d_array */ |
1155 | | |
1156 | | /*------------------------------------------------------------------------------ |
1157 | | */ |
1158 | | |
1159 | | static void |
1160 | | s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count) |
1161 | 0 | { short diff, last_val ; |
1162 | 0 | int k ; |
1163 | |
|
1164 | 0 | last_val = pxi->last_16 ; |
1165 | |
|
1166 | 0 | for (k = 0 ; k < count ; k++) |
1167 | 0 | { diff = src [k] - last_val ; |
1168 | 0 | dest [k] = LE2H_16 (diff) ; |
1169 | 0 | last_val = src [k] ; |
1170 | 0 | } ; |
1171 | |
|
1172 | 0 | pxi->last_16 = last_val ; |
1173 | 0 | } /* s2dles_array */ |
1174 | | |
1175 | | static void |
1176 | | i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count) |
1177 | 0 | { short diff, last_val ; |
1178 | 0 | int k ; |
1179 | |
|
1180 | 0 | last_val = pxi->last_16 ; |
1181 | |
|
1182 | 0 | for (k = 0 ; k < count ; k++) |
1183 | 0 | { diff = (src [k] >> 16) - last_val ; |
1184 | 0 | dest [k] = LE2H_16 (diff) ; |
1185 | 0 | last_val = src [k] >> 16 ; |
1186 | 0 | } ; |
1187 | |
|
1188 | 0 | pxi->last_16 = last_val ; |
1189 | 0 | } /* i2dles_array */ |
1190 | | |
1191 | | static void |
1192 | | f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact) |
1193 | 0 | { short diff, last_val, current ; |
1194 | 0 | int k ; |
1195 | |
|
1196 | 0 | last_val = pxi->last_16 ; |
1197 | |
|
1198 | 0 | for (k = 0 ; k < count ; k++) |
1199 | 0 | { current = psf_lrintf (src [k] * normfact) ; |
1200 | 0 | diff = current - last_val ; |
1201 | 0 | dest [k] = LE2H_16 (diff) ; |
1202 | 0 | last_val = current ; |
1203 | 0 | } ; |
1204 | |
|
1205 | 0 | pxi->last_16 = last_val ; |
1206 | 0 | } /* f2dles_array */ |
1207 | | |
1208 | | static void |
1209 | | d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact) |
1210 | 0 | { short diff, last_val, current ; |
1211 | 0 | int k ; |
1212 | |
|
1213 | 0 | last_val = pxi->last_16 ; |
1214 | |
|
1215 | 0 | for (k = 0 ; k < count ; k++) |
1216 | 0 | { current = psf_lrint (src [k] * normfact) ; |
1217 | 0 | diff = current - last_val ; |
1218 | 0 | dest [k] = LE2H_16 (diff) ; |
1219 | 0 | last_val = current ; |
1220 | 0 | } ; |
1221 | |
|
1222 | 0 | pxi->last_16 = last_val ; |
1223 | 0 | } /* d2dles_array */ |