1 |
/* IO handlers */ |
2 |
/* |
3 |
* -------------------------------- |
4 |
* int mus_create_descriptors (void): initialize (allocate) various global arrays |
5 |
* int mus_read(int fd, int beg, int end, int chans, int **bufs) |
6 |
* int mus_write(int tfd, int beg, int end, int chans, int **bufs) |
7 |
* long mus_seek(int tfd, long offset, int origin) |
8 |
* int mus_open_read(char *arg) |
9 |
* int mus_open_write(char *arg) |
10 |
* int mus_create(char *arg) |
11 |
* int mus_reopen_write(char *arg) |
12 |
* int mus_close(int fd) |
13 |
* int mus_probe_file(char *arg) |
14 |
* int mus_open_file_descriptors (int tfd, int df, int ds, int dl) |
15 |
* int mus_close_file_descriptors(int tfd) |
16 |
* see sndplay.c for a short example |
17 |
* -------------------------------- |
18 |
*/ |
19 |
|
20 |
#if defined(HAVE_CONFIG_H) |
21 |
#include "config.h" |
22 |
#endif |
23 |
|
24 |
#include <math.h> |
25 |
#include <stdio.h> |
26 |
#if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_FCNTL_H)) |
27 |
#include <fcntl.h> |
28 |
#endif |
29 |
#include <signal.h> |
30 |
#if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_LIMITS_H)) |
31 |
#include <limits.h> |
32 |
#endif |
33 |
#include <errno.h> |
34 |
#include <stdlib.h> |
35 |
|
36 |
#if (defined(NEXT) || (defined(HAVE_LIBC_H) && (!defined(HAVE_UNISTD_H)))) |
37 |
#include <libc.h> |
38 |
#else |
39 |
#if (!(defined(_MSC_VER))) && (!(defined(MPW_C))) |
40 |
#include <unistd.h> |
41 |
#endif |
42 |
#endif |
43 |
#if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_STRING_H)) |
44 |
#include <string.h> |
45 |
#endif |
46 |
|
47 |
#if (defined(SIZEOF_INT) && (SIZEOF_INT != 4)) || (defined(INT_MAX) && (INT_MAX != 2147483647)) |
48 |
#error sndlib C code assumes 32-bit ints |
49 |
#endif |
50 |
|
51 |
#if (defined(SIZEOF_LONG) && (SIZEOF_LONG < 4)) || (defined(LONG_MAX) && (LONG_MAX < 2147483647)) |
52 |
#error sndlib C code assumes longs are at least 32 bits |
53 |
#endif |
54 |
|
55 |
#if (defined(SIZEOF_SHORT) && (SIZEOF_SHORT != 2)) || (defined(SHRT_MAX) && (SHRT_MAX != 32767)) |
56 |
#error sndlib C code assumes 16-bit shorts |
57 |
#endif |
58 |
|
59 |
#if (defined(SIZEOF_CHAR) && (SIZEOF_CHAR != 1)) || (defined(CHAR_BIT) && (CHAR_BIT != 8)) |
60 |
#error sndlib C code assumes 8-bit chars |
61 |
#endif |
62 |
|
63 |
#include "sndlib.h" |
64 |
|
65 |
/* data translations for big/little endian machines -- the m_* forms are macros where possible for speed */ |
66 |
|
67 |
void mus_set_big_endian_int(unsigned char *j, int x) |
68 |
{ |
69 |
unsigned char *ox; |
70 |
ox=(unsigned char *)&x; |
71 |
#ifdef SNDLIB_LITTLE_ENDIAN |
72 |
j[0]=ox[3]; j[1]=ox[2]; j[2]=ox[1]; j[3]=ox[0]; |
73 |
#else |
74 |
j[0]=ox[0]; j[1]=ox[1]; j[2]=ox[2]; j[3]=ox[3]; |
75 |
#endif |
76 |
} |
77 |
|
78 |
int mus_big_endian_int (unsigned char *inp) |
79 |
{ |
80 |
int o; |
81 |
unsigned char *outp; |
82 |
outp=(unsigned char *)&o; |
83 |
#ifdef SNDLIB_LITTLE_ENDIAN |
84 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
85 |
#else |
86 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
87 |
#endif |
88 |
return(o); |
89 |
} |
90 |
|
91 |
void mus_set_little_endian_int(unsigned char *j, int x) |
92 |
{ |
93 |
unsigned char *ox; |
94 |
ox=(unsigned char *)&x; |
95 |
#ifndef SNDLIB_LITTLE_ENDIAN |
96 |
j[0]=ox[3]; j[1]=ox[2]; j[2]=ox[1]; j[3]=ox[0]; |
97 |
#else |
98 |
j[0]=ox[0]; j[1]=ox[1]; j[2]=ox[2]; j[3]=ox[3]; |
99 |
#endif |
100 |
} |
101 |
|
102 |
int mus_little_endian_int (unsigned char *inp) |
103 |
{ |
104 |
int o; |
105 |
unsigned char *outp; |
106 |
outp=(unsigned char *)&o; |
107 |
#ifndef SNDLIB_LITTLE_ENDIAN |
108 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
109 |
#else |
110 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
111 |
#endif |
112 |
return(o); |
113 |
} |
114 |
|
115 |
int mus_uninterpreted_int (unsigned char *inp) |
116 |
{ |
117 |
int o; |
118 |
unsigned char *outp; |
119 |
outp=(unsigned char *)&o; |
120 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
121 |
return(o); |
122 |
} |
123 |
|
124 |
unsigned int mus_big_endian_unsigned_int (unsigned char *inp) |
125 |
{ |
126 |
unsigned int o; |
127 |
unsigned char *outp; |
128 |
outp=(unsigned char *)&o; |
129 |
#ifdef SNDLIB_LITTLE_ENDIAN |
130 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
131 |
#else |
132 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
133 |
#endif |
134 |
return(o); |
135 |
} |
136 |
|
137 |
unsigned int mus_little_endian_unsigned_int (unsigned char *inp) |
138 |
{ |
139 |
unsigned int o; |
140 |
unsigned char *outp; |
141 |
outp=(unsigned char *)&o; |
142 |
#ifndef SNDLIB_LITTLE_ENDIAN |
143 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
144 |
#else |
145 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
146 |
#endif |
147 |
return(o); |
148 |
} |
149 |
|
150 |
|
151 |
void mus_set_big_endian_float(unsigned char *j, float x) |
152 |
{ |
153 |
unsigned char *ox; |
154 |
ox=(unsigned char *)&x; |
155 |
#ifdef SNDLIB_LITTLE_ENDIAN |
156 |
j[0]=ox[3]; j[1]=ox[2]; j[2]=ox[1]; j[3]=ox[0]; |
157 |
#else |
158 |
j[0]=ox[0]; j[1]=ox[1]; j[2]=ox[2]; j[3]=ox[3]; |
159 |
#endif |
160 |
} |
161 |
|
162 |
float mus_big_endian_float (unsigned char *inp) |
163 |
{ |
164 |
float o; |
165 |
unsigned char *outp; |
166 |
outp=(unsigned char *)&o; |
167 |
#ifdef SNDLIB_LITTLE_ENDIAN |
168 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
169 |
#else |
170 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
171 |
#endif |
172 |
return(o); |
173 |
} |
174 |
|
175 |
void mus_set_little_endian_float(unsigned char *j, float x) |
176 |
{ |
177 |
unsigned char *ox; |
178 |
ox=(unsigned char *)&x; |
179 |
#ifndef SNDLIB_LITTLE_ENDIAN |
180 |
j[0]=ox[3]; j[1]=ox[2]; j[2]=ox[1]; j[3]=ox[0]; |
181 |
#else |
182 |
j[0]=ox[0]; j[1]=ox[1]; j[2]=ox[2]; j[3]=ox[3]; |
183 |
#endif |
184 |
} |
185 |
|
186 |
float mus_little_endian_float (unsigned char *inp) |
187 |
{ |
188 |
float o; |
189 |
unsigned char *outp; |
190 |
outp=(unsigned char *)&o; |
191 |
#ifndef SNDLIB_LITTLE_ENDIAN |
192 |
outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; |
193 |
#else |
194 |
outp[0]=inp[0]; outp[1]=inp[1]; outp[2]=inp[2]; outp[3]=inp[3]; |
195 |
#endif |
196 |
return(o); |
197 |
} |
198 |
|
199 |
void mus_set_big_endian_short(unsigned char *j, short x) |
200 |
{ |
201 |
unsigned char *ox; |
202 |
ox=(unsigned char *)&x; |
203 |
#ifdef SNDLIB_LITTLE_ENDIAN |
204 |
j[0]=ox[1]; j[1]=ox[0]; |
205 |
#else |
206 |
j[0]=ox[0]; j[1]=ox[1]; |
207 |
#endif |
208 |
} |
209 |
|
210 |
short mus_big_endian_short (unsigned char *inp) |
211 |
{ |
212 |
short o; |
213 |
unsigned char *outp; |
214 |
outp=(unsigned char *)&o; |
215 |
#ifdef SNDLIB_LITTLE_ENDIAN |
216 |
outp[0]=inp[1]; outp[1]=inp[0]; |
217 |
#else |
218 |
outp[0]=inp[0]; outp[1]=inp[1]; |
219 |
#endif |
220 |
return(o); |
221 |
} |
222 |
|
223 |
void mus_set_little_endian_short(unsigned char *j, short x) |
224 |
{ |
225 |
unsigned char *ox; |
226 |
ox=(unsigned char *)&x; |
227 |
#ifndef SNDLIB_LITTLE_ENDIAN |
228 |
j[0]=ox[1]; j[1]=ox[0]; |
229 |
#else |
230 |
j[0]=ox[0]; j[1]=ox[1]; |
231 |
#endif |
232 |
} |
233 |
|
234 |
short mus_little_endian_short (unsigned char *inp) |
235 |
{ |
236 |
short o; |
237 |
unsigned char *outp; |
238 |
outp=(unsigned char *)&o; |
239 |
#ifndef SNDLIB_LITTLE_ENDIAN |
240 |
outp[0]=inp[1]; outp[1]=inp[0]; |
241 |
#else |
242 |
outp[0]=inp[0]; outp[1]=inp[1]; |
243 |
#endif |
244 |
return(o); |
245 |
} |
246 |
|
247 |
void mus_set_big_endian_unsigned_short(unsigned char *j, unsigned short x) |
248 |
{ |
249 |
unsigned char *ox; |
250 |
ox=(unsigned char *)&x; |
251 |
#ifdef SNDLIB_LITTLE_ENDIAN |
252 |
j[0]=ox[1]; j[1]=ox[0]; |
253 |
#else |
254 |
j[0]=ox[0]; j[1]=ox[1]; |
255 |
#endif |
256 |
} |
257 |
|
258 |
unsigned short mus_big_endian_unsigned_short (unsigned char *inp) |
259 |
{ |
260 |
unsigned short o; |
261 |
unsigned char *outp; |
262 |
outp=(unsigned char *)&o; |
263 |
#ifdef SNDLIB_LITTLE_ENDIAN |
264 |
outp[0]=inp[1]; outp[1]=inp[0]; |
265 |
#else |
266 |
outp[0]=inp[0]; outp[1]=inp[1]; |
267 |
#endif |
268 |
return(o); |
269 |
} |
270 |
|
271 |
void mus_set_little_endian_unsigned_short(unsigned char *j, unsigned short x) |
272 |
{ |
273 |
unsigned char *ox; |
274 |
ox=(unsigned char *)&x; |
275 |
#ifndef SNDLIB_LITTLE_ENDIAN |
276 |
j[0]=ox[1]; j[1]=ox[0]; |
277 |
#else |
278 |
j[0]=ox[0]; j[1]=ox[1]; |
279 |
#endif |
280 |
} |
281 |
|
282 |
unsigned short mus_little_endian_unsigned_short (unsigned char *inp) |
283 |
{ |
284 |
unsigned short o; |
285 |
unsigned char *outp; |
286 |
outp=(unsigned char *)&o; |
287 |
#ifndef SNDLIB_LITTLE_ENDIAN |
288 |
outp[0]=inp[1]; outp[1]=inp[0]; |
289 |
#else |
290 |
outp[0]=inp[0]; outp[1]=inp[1]; |
291 |
#endif |
292 |
return(o); |
293 |
} |
294 |
|
295 |
double mus_little_endian_double (unsigned char *inp) |
296 |
{ |
297 |
double o; |
298 |
#ifndef SNDLIB_LITTLE_ENDIAN |
299 |
int i; |
300 |
#endif |
301 |
unsigned char *outp; |
302 |
outp=(unsigned char *)&o; |
303 |
#ifndef SNDLIB_LITTLE_ENDIAN |
304 |
for (i=0;i<8;i++) outp[i]=inp[i]; |
305 |
#else |
306 |
outp[0]=inp[7]; outp[1]=inp[6]; outp[2]=inp[5]; outp[3]=inp[4]; outp[4]=inp[3]; outp[5]=inp[2]; outp[6]=inp[1]; outp[7]=inp[0]; |
307 |
#endif |
308 |
return(o); |
309 |
} |
310 |
|
311 |
double mus_big_endian_double (unsigned char *inp) |
312 |
{ |
313 |
double o; |
314 |
#ifdef SNDLIB_LITTLE_ENDIAN |
315 |
int i; |
316 |
#endif |
317 |
unsigned char *outp; |
318 |
outp=(unsigned char *)&o; |
319 |
#ifndef SNDLIB_LITTLE_ENDIAN |
320 |
outp[0]=inp[7]; outp[1]=inp[6]; outp[2]=inp[5]; outp[3]=inp[4]; outp[4]=inp[3]; outp[5]=inp[2]; outp[6]=inp[1]; outp[7]=inp[0]; |
321 |
#else |
322 |
for (i=0;i<8;i++) outp[i]=inp[i]; |
323 |
#endif |
324 |
return(o); |
325 |
} |
326 |
|
327 |
void mus_set_big_endian_double(unsigned char *j, double x) |
328 |
{ |
329 |
#ifdef SNDLIB_LITTLE_ENDIAN |
330 |
int i; |
331 |
#endif |
332 |
unsigned char *ox; |
333 |
ox=(unsigned char *)&x; |
334 |
#ifndef SNDLIB_LITTLE_ENDIAN |
335 |
j[0]=ox[7]; j[1]=ox[6]; j[2]=ox[5]; j[3]=ox[4]; j[4]=ox[3]; j[5]=ox[2]; j[6]=ox[1]; j[7]=ox[0]; |
336 |
#else |
337 |
for (i=0;i<8;i++) j[i]=ox[i]; |
338 |
#endif |
339 |
} |
340 |
|
341 |
void mus_set_little_endian_double(unsigned char *j, double x) |
342 |
{ |
343 |
#ifndef SNDLIB_LITTLE_ENDIAN |
344 |
int i; |
345 |
#endif |
346 |
unsigned char *ox; |
347 |
ox=(unsigned char *)&x; |
348 |
#ifndef SNDLIB_LITTLE_ENDIAN |
349 |
for (i=0;i<8;i++) j[i]=ox[i]; |
350 |
#else |
351 |
j[0]=ox[7]; j[1]=ox[6]; j[2]=ox[5]; j[3]=ox[4]; j[4]=ox[3]; j[5]=ox[2]; j[6]=ox[1]; j[7]=ox[0]; |
352 |
#endif |
353 |
} |
354 |
|
355 |
/* Vax float translation taken from Mosaic libdtm/vaxcvt.c */ |
356 |
static float from_vax_float(unsigned char *inp) |
357 |
{ |
358 |
unsigned char exp; |
359 |
unsigned char c0, c1, c2, c3; |
360 |
float o; |
361 |
unsigned char *outp; |
362 |
outp=(unsigned char *)&o; |
363 |
c0 = inp[0]; c1 = inp[1]; c2 = inp[2]; c3 = inp[3]; |
364 |
exp = (c1 << 1) | (c0 >> 7); /* extract exponent */ |
365 |
if (!exp && !c1) return(0.0); /* zero value */ |
366 |
else if (exp>2) { /* normal value */ |
367 |
outp[0] = c1 - 1; /* subtracts 2 from exponent */ |
368 |
outp[1] = c0; /* copy mantissa, LSB of exponent */ |
369 |
outp[2] = c3; |
370 |
outp[3] = c2;} |
371 |
else if (exp) { /* denormalized number */ |
372 |
unsigned int shft; |
373 |
outp[0] = c1 & 0x80; /* keep sign, zero exponent */ |
374 |
shft = 3 - exp; |
375 |
/* shift original mant by 1 or 2 to get denormalized mant */ |
376 |
/* prefix mantissa with '1'b or '01'b as appropriate */ |
377 |
outp[1] = ((c0 & 0x7f) >> shft) | (0x10 << exp); |
378 |
outp[2] = (c0 << (8-shft)) | (c3 >> shft); |
379 |
outp[3] = (c3 << (8-shft)) | (c2 >> shft);} |
380 |
else { /* sign=1 -> infinity or NaN */ |
381 |
outp[0] = 0xff; /* set exp to 255 */ |
382 |
outp[1] = c0 | 0x80; /* LSB of exp = 1 */ |
383 |
outp[2] = c3; |
384 |
outp[3] = c2;} |
385 |
return(o); |
386 |
} |
387 |
|
388 |
#if USE_BYTESWAP |
389 |
#include <byteswap.h> |
390 |
/* in fully optimized code, the byteswap macros are about 15% faster than the calls used here */ |
391 |
#endif |
392 |
|
393 |
#ifdef SNDLIB_LITTLE_ENDIAN |
394 |
|
395 |
#if USE_BYTESWAP |
396 |
#define m_big_endian_short(n) ((short)(bswap_16((*((unsigned short *)n))))) |
397 |
#define m_big_endian_int(n) ((int)(bswap_32((*((unsigned int *)n))))) |
398 |
#else |
399 |
#define m_big_endian_short(n) (mus_big_endian_short(n)) |
400 |
#define m_big_endian_int(n) (mus_big_endian_int(n)) |
401 |
#endif |
402 |
#define m_big_endian_float(n) (mus_big_endian_float(n)) |
403 |
#define m_big_endian_double(n) (mus_big_endian_double(n)) |
404 |
#define m_big_endian_unsigned_short(n) (mus_big_endian_unsigned_short(n)) |
405 |
|
406 |
#define m_little_endian_short(n) (*((short *)n)) |
407 |
#define m_little_endian_int(n) (*((int *)n)) |
408 |
#define m_little_endian_float(n) (*((float *)n)) |
409 |
#define m_little_endian_double(n) (*((double *)n)) |
410 |
#define m_little_endian_unsigned_short(n) (*((unsigned short *)n)) |
411 |
|
412 |
#define m_set_big_endian_short(n,x) mus_set_big_endian_short(n,x) |
413 |
#define m_set_big_endian_int(n,x) mus_set_big_endian_int(n,x) |
414 |
#define m_set_big_endian_float(n,x) mus_set_big_endian_float(n,x) |
415 |
#define m_set_big_endian_double(n,x) mus_set_big_endian_double(n,x) |
416 |
#define m_set_big_endian_unsigned_short(n,x) mus_set_big_endian_unsigned_short(n,x) |
417 |
|
418 |
#define m_set_little_endian_short(n,x) (*((short *)n)) = x |
419 |
#define m_set_little_endian_int(n,x) (*((int *)n)) = x |
420 |
#define m_set_little_endian_float(n,x) (*((float *)n)) = x |
421 |
#define m_set_little_endian_double(n,x) (*((double *)n)) = x |
422 |
#define m_set_little_endian_unsigned_short(n,x) (*((unsigned short *)n)) = x |
423 |
|
424 |
#else |
425 |
|
426 |
#ifndef SUN |
427 |
#define m_big_endian_short(n) (*((short *)n)) |
428 |
#define m_big_endian_int(n) (*((int *)n)) |
429 |
#define m_big_endian_float(n) (*((float *)n)) |
430 |
#define m_big_endian_double(n) (*((double *)n)) |
431 |
#define m_big_endian_unsigned_short(n) (*((unsigned short *)n)) |
432 |
|
433 |
#define m_set_big_endian_short(n,x) (*((short *)n)) = x |
434 |
#define m_set_big_endian_int(n,x) (*((int *)n)) = x |
435 |
#define m_set_big_endian_float(n,x) (*((float *)n)) = x |
436 |
#define m_set_big_endian_double(n,x) (*((double *)n)) = x |
437 |
#define m_set_big_endian_unsigned_short(n,x) (*((unsigned short *)n)) = x |
438 |
#else |
439 |
#define m_big_endian_short(n) (mus_big_endian_short(n)) |
440 |
#define m_big_endian_int(n) (mus_big_endian_int(n)) |
441 |
#define m_big_endian_float(n) (mus_big_endian_float(n)) |
442 |
#define m_big_endian_double(n) (mus_big_endian_double(n)) |
443 |
#define m_big_endian_unsigned_short(n) (mus_big_endian_unsigned_short(n)) |
444 |
|
445 |
#define m_set_big_endian_short(n,x) mus_set_big_endian_short(n,x) |
446 |
#define m_set_big_endian_int(n,x) mus_set_big_endian_int(n,x) |
447 |
#define m_set_big_endian_float(n,x) mus_set_big_endian_float(n,x) |
448 |
#define m_set_big_endian_double(n,x) mus_set_big_endian_double(n,x) |
449 |
#define m_set_big_endian_unsigned_short(n,x) mus_set_big_endian_unsigned_short(n,x) |
450 |
#endif |
451 |
|
452 |
#if USE_BYTESWAP |
453 |
#define m_little_endian_short(n) ((short)(bswap_16((*((unsigned short *)n))))) |
454 |
#define m_little_endian_int(n) ((int)(bswap_32((*((unsigned int *)n))))) |
455 |
#else |
456 |
#define m_little_endian_short(n) (mus_little_endian_short(n)) |
457 |
#define m_little_endian_int(n) (mus_little_endian_int(n)) |
458 |
#endif |
459 |
#define m_little_endian_float(n) (mus_little_endian_float(n)) |
460 |
#define m_little_endian_double(n) (mus_little_endian_double(n)) |
461 |
#define m_little_endian_unsigned_short(n) (mus_little_endian_unsigned_short(n)) |
462 |
|
463 |
#define m_set_little_endian_short(n,x) mus_set_little_endian_short(n,x) |
464 |
#define m_set_little_endian_int(n,x) mus_set_little_endian_int(n,x) |
465 |
#define m_set_little_endian_float(n,x) mus_set_little_endian_float(n,x) |
466 |
#define m_set_little_endian_double(n,x) mus_set_little_endian_double(n,x) |
467 |
#define m_set_little_endian_unsigned_short(n,x) mus_set_little_endian_unsigned_short(n,x) |
468 |
|
469 |
#endif |
470 |
|
471 |
|
472 |
/* ---------------- file descriptors ---------------- |
473 |
* |
474 |
* I'm using unbuffered IO here because it is faster on the machines I normally use, |
475 |
* and I'm normally doing very large reads/writes (that is, the stuff is self-buffered). |
476 |
* |
477 |
* machine read/write: fread/fwrite: arithmetic: |
478 |
* 256 512 8192 65536 same sizes tbl bigfft sffts |
479 |
* |
480 |
* NeXT 68040 (32MB): 11575 10514 10256 9943 11951 11923 12358 12259 10478 108122 26622 |
481 |
* NeXT Turbo (16MB): 8329 7760 6933 6833 9216 8742 9416 9238 7825 121591 19495 |
482 |
* HP 90MHz Pentium NextStep: 11970 10069 9840 9920 11930 11209 11399 11540 1930 46389 4019 |
483 |
* Mac 8500 120 MHz PPC MacOS: 21733 15416 5000 2916 9566 9550 9733 9850 <died in memory manager> |
484 |
* Mac G3 266 MHz PPC MacOS: 4866 3216 1850 1366 2400 2400 2366 2450 550 12233 700 |
485 |
* MkLinux G3 266 MHz: 580 462 390 419 640 631 552 500 485 11364 770 |
486 |
* LinuxPPC G3 266 MHz: 456 385 366 397 489 467 467 487 397 11808 763 |
487 |
* Mac clone 120 MHz PPC BeOS: 1567 885 725 3392 1015 1000 1114 1161 1092 37212 1167 |
488 |
* SGI R4600 132 MHz Indy (32MB): 2412 1619 959 1045 1172 1174 1111 1126 1224 30825 3490 |
489 |
* SGI R5000 150 MHz Indy (32MB): 1067 846 684 737 847 817 734 791 885 25878 1591 |
490 |
* SGI R5000 180 MHz O2 (64MB): 1359 788 431 446 1919 1944 1891 1885 828 24658 1390 |
491 |
* Sun Ultra5 270 MHz (128 MB): 981 880 796 827 965 1029 922 903 445 26791 691 |
492 |
* HP 200 MHz Pentium Linux: 576 492 456 482 615 613 599 592 695 14851 882 |
493 |
* Asus 266 MHz Pentium II Linux: 475 426 404 406 466 455 467 465 490 13170 595 |
494 |
* ditto W95: 1320 660 600 550 2470 2470 2470 2470 990 17410 1540 |
495 |
* Dell XPSD300 Pentium II Linux: 393 350 325 332 376 369 397 372 414 8793 576 |
496 |
* 450MHz PC Linux: 263 227 208 217 268 263 274 270 275 6224 506 |
497 |
* |
498 |
* the first 8 numbers are comparing read/write fread/fwrite at various buffer sizes -- CLM uses 65536. |
499 |
* the last 3 numbers are comparing table lookup, a huge fft, and a bunch of small ffts. |
500 |
* In normal CLM usage, small instruments and mixes are IO bound, so these differences can matter. |
501 |
* The reason to use 65536 rather than 8192 is that it allows us to forgo IO completely in |
502 |
* many cases -- the output buffer can collect many notes before flushing, etc. |
503 |
*/ |
504 |
|
505 |
#if defined(SGI) || defined(LINUX) || defined(UW2) || defined(SCO5) |
506 |
#define FILE_DESCRIPTORS 400 |
507 |
#define BASE_FILE_DESCRIPTORS 200 |
508 |
#else |
509 |
#define FILE_DESCRIPTORS 128 |
510 |
#define BASE_FILE_DESCRIPTORS 64 |
511 |
#endif |
512 |
|
513 |
/* this from the glibc FAQ: |
514 |
* You can always get the maximum number of file descriptors a process is |
515 |
* allowed to have open at any time using number = sysconf (_SC_OPEN_MAX) |
516 |
*/ |
517 |
|
518 |
static int io_descriptors_ok = 0; |
519 |
static int *io_data_format,*io_bytes_per_sample,*io_data_location,*io_files,*io_data_clipped,*io_chans,*io_header_type; |
520 |
static int io_files_ready = 0; |
521 |
static int max_descriptor = 0; |
522 |
|
523 |
static int rt_ap_out; /* address of RT audio ports, if any */ |
524 |
|
525 |
#ifdef CLM |
526 |
void set_rt_audio_p (int rt) |
527 |
{ |
528 |
rt_ap_out = rt; |
529 |
} |
530 |
#endif |
531 |
|
532 |
int mus_create_descriptors (void) |
533 |
{ |
534 |
if (!io_descriptors_ok) |
535 |
{ |
536 |
io_descriptors_ok = 1; |
537 |
max_descriptor = 0; |
538 |
io_data_format = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
539 |
io_bytes_per_sample = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
540 |
io_data_clipped = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
541 |
io_header_type = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
542 |
io_chans = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
543 |
io_data_location = (int *)CALLOC(FILE_DESCRIPTORS,sizeof(int)); |
544 |
io_files = (int *)CALLOC(BASE_FILE_DESCRIPTORS,sizeof(int)); |
545 |
if ((io_data_format == NULL) || (io_bytes_per_sample == NULL) || (io_data_location == NULL) || (io_files == NULL) || |
546 |
(io_data_clipped == NULL) || (io_header_type == NULL)) |
547 |
{ |
548 |
mus_error(MUS_MEMORY_ALLOCATION_FAILED,"file descriptor buffer allocation trouble"); |
549 |
return(-1); |
550 |
} |
551 |
} |
552 |
return(0); |
553 |
} |
554 |
|
555 |
static int convert_fd(int n) |
556 |
{ |
557 |
if (n<BASE_FILE_DESCRIPTORS) |
558 |
return(n); |
559 |
else |
560 |
{ |
561 |
int i; |
562 |
for (i=0;i<BASE_FILE_DESCRIPTORS;i++) |
563 |
{ |
564 |
if (io_files[i] == n) return(i+BASE_FILE_DESCRIPTORS); |
565 |
} |
566 |
return(-1); |
567 |
} |
568 |
} |
569 |
|
570 |
static int open_mus_file (int tfd) |
571 |
{ |
572 |
int fd; |
573 |
if (tfd < BASE_FILE_DESCRIPTORS) return(tfd); |
574 |
if (io_files_ready == 0) |
575 |
{ |
576 |
for (fd=0;fd<BASE_FILE_DESCRIPTORS;fd++) io_files[fd]=-1; |
577 |
io_files_ready = 1; |
578 |
} |
579 |
for (fd=0;fd<BASE_FILE_DESCRIPTORS;fd++) |
580 |
{ |
581 |
if (io_files[fd] == -1) |
582 |
{ |
583 |
io_files[fd] = tfd; |
584 |
return(fd+BASE_FILE_DESCRIPTORS); |
585 |
} |
586 |
} |
587 |
return(-1); |
588 |
} |
589 |
|
590 |
int mus_open_file_descriptors (int tfd, int format, int size, int location) |
591 |
{ /* transfers header info from functions in header.c back to us for reads here and in merge.c */ |
592 |
int fd; |
593 |
if (!io_descriptors_ok) return(-1); |
594 |
fd = open_mus_file(tfd); |
595 |
if (fd == -1) return(-1); |
596 |
io_data_format[fd] = format; |
597 |
io_bytes_per_sample[fd] = size; |
598 |
io_data_location[fd] = location; |
599 |
io_data_clipped[fd] = 0; |
600 |
io_header_type[fd] = 0; |
601 |
io_chans[fd] = 1; |
602 |
if (fd > max_descriptor) max_descriptor = fd; |
603 |
return(0); |
604 |
} |
605 |
|
606 |
int mus_set_file_descriptors (int tfd, int format, int size, int location, int chans, int type) |
607 |
{ |
608 |
/* new form to make sound.c handlers cleaner, 4-Sep-99 */ |
609 |
int fd; |
610 |
if (!io_descriptors_ok) return(-1); |
611 |
fd = open_mus_file(tfd); |
612 |
if (fd == -1) return(-1); |
613 |
io_data_format[fd] = format; |
614 |
io_bytes_per_sample[fd] = size; |
615 |
io_data_location[fd] = location; |
616 |
io_header_type[fd] = type; |
617 |
io_data_clipped[fd] = 0; |
618 |
io_chans[fd] = chans; |
619 |
if (fd > max_descriptor) max_descriptor = fd; |
620 |
return(0); |
621 |
} |
622 |
|
623 |
int mus_close_file_descriptors(int tfd) |
624 |
{ |
625 |
int fd; |
626 |
if (!io_descriptors_ok) return(0); /* not necessarily an error -- c-close before with-sound etc */ |
627 |
fd = convert_fd(tfd); |
628 |
if (fd >= 0) |
629 |
{ |
630 |
if (fd >= BASE_FILE_DESCRIPTORS) |
631 |
io_files[fd-BASE_FILE_DESCRIPTORS] = -1; |
632 |
io_data_format[fd]=SNDLIB_NO_SND; |
633 |
io_header_type[fd] = 0; |
634 |
io_data_clipped[fd] = 0; |
635 |
io_chans[fd] = 0; |
636 |
return(0); |
637 |
} |
638 |
return(-1); |
639 |
} |
640 |
|
641 |
int mus_cleanup_file_descriptors(void) |
642 |
{ |
643 |
/* error cleanup -- try to find C-opened files that are invisible to lisp and close them */ |
644 |
int fd,lim; |
645 |
if (!io_descriptors_ok) return(0); |
646 |
lim = BASE_FILE_DESCRIPTORS-1; |
647 |
if (max_descriptor < lim) lim = max_descriptor; |
648 |
for (fd=0;fd<=lim;fd++) |
649 |
if (io_data_format[fd] != SNDLIB_NO_SND) mus_close(fd); |
650 |
if ((io_files_ready) && (max_descriptor > BASE_FILE_DESCRIPTORS)) |
651 |
{ |
652 |
lim = max_descriptor - BASE_FILE_DESCRIPTORS; |
653 |
if (lim >= BASE_FILE_DESCRIPTORS) lim = BASE_FILE_DESCRIPTORS - 1; |
654 |
for (fd=0;fd<=lim;fd++) |
655 |
if (io_files[fd] != -1) |
656 |
mus_close(io_files[fd]); |
657 |
} |
658 |
return(0); |
659 |
} |
660 |
|
661 |
int mus_set_data_clipped (int tfd, int clipped) |
662 |
{ |
663 |
int fd; |
664 |
if (!io_descriptors_ok) return(0); |
665 |
fd = convert_fd(tfd); |
666 |
if (fd < 0) return(-1); |
667 |
io_data_clipped[fd] = clipped; |
668 |
return(0); |
669 |
} |
670 |
|
671 |
int mus_set_header_type (int tfd, int type) |
672 |
{ |
673 |
int fd; |
674 |
if (!io_descriptors_ok) return(0); |
675 |
fd = convert_fd(tfd); |
676 |
if (fd < 0) return(-1); |
677 |
io_header_type[fd] = type; |
678 |
return(0); |
679 |
} |
680 |
|
681 |
int mus_get_header_type(int tfd) |
682 |
{ |
683 |
int fd; |
684 |
if (!io_descriptors_ok) return(0); |
685 |
fd = convert_fd(tfd); |
686 |
if (fd < 0) return(-1); |
687 |
return(io_header_type[fd]); |
688 |
} |
689 |
|
690 |
int mus_set_chans (int tfd, int chans) |
691 |
{ |
692 |
int fd; |
693 |
if (!io_descriptors_ok) return(0); |
694 |
fd = convert_fd(tfd); |
695 |
if (fd < 0) return(-1); |
696 |
io_chans[fd] = chans; |
697 |
return(0); |
698 |
} |
699 |
|
700 |
|
701 |
/* ---------------- open, creat, close ---------------- */ |
702 |
|
703 |
int mus_open_read(char *arg) |
704 |
{ |
705 |
#ifdef MACOS |
706 |
return(open (arg, O_RDONLY)); |
707 |
#else |
708 |
int fd; |
709 |
#ifdef WINDOZE |
710 |
fd = open (arg, O_RDONLY | O_BINARY); |
711 |
#else |
712 |
fd = open (arg, O_RDONLY, 0); |
713 |
#endif |
714 |
return(fd); |
715 |
#endif |
716 |
} |
717 |
|
718 |
int mus_probe_file(char *arg) |
719 |
{ |
720 |
int fd; |
721 |
#ifdef MACOS |
722 |
fd = (open (arg, O_RDONLY)); |
723 |
#else |
724 |
#ifdef WINDOZE |
725 |
fd = open (arg, O_RDONLY | O_BINARY); |
726 |
#else |
727 |
#ifdef O_NONBLOCK |
728 |
fd = open(arg,O_RDONLY,O_NONBLOCK); |
729 |
#else |
730 |
fd = open(arg,O_RDONLY,0); |
731 |
#endif |
732 |
#endif |
733 |
#endif |
734 |
if (fd == -1) return(0); |
735 |
close(fd); |
736 |
return(1); |
737 |
} |
738 |
|
739 |
int mus_open_write(char *arg) |
740 |
{ |
741 |
int fd; |
742 |
#ifdef MACOS |
743 |
if ((fd = open(arg,O_RDWR)) == -1) |
744 |
#ifdef MPW_C |
745 |
fd = creat(arg); |
746 |
#else |
747 |
fd = creat(arg, 0); |
748 |
#endif |
749 |
else |
750 |
lseek(fd,0L,SEEK_END); |
751 |
#else |
752 |
#ifdef WINDOZE |
753 |
if ((fd = open(arg,O_RDWR | O_BINARY)) == -1) |
754 |
#else |
755 |
if ((fd = open(arg,O_RDWR,0)) == -1) |
756 |
#endif |
757 |
{ |
758 |
fd = creat(arg,0666); /* equivalent to the new open(arg,O_RDWR | O_CREAT | O_TRUNC, 0666) */ |
759 |
} |
760 |
else |
761 |
lseek(fd,0L,SEEK_END); |
762 |
#endif |
763 |
return(fd); |
764 |
} |
765 |
|
766 |
int mus_create(char *arg) |
767 |
{ |
768 |
#ifdef MACOS |
769 |
#ifdef MPW_C |
770 |
return(creat(arg)); |
771 |
#else |
772 |
return(creat(arg,0)); |
773 |
#endif |
774 |
#else |
775 |
int fd; |
776 |
fd = creat(arg,0666); |
777 |
return(fd); |
778 |
#endif |
779 |
} |
780 |
|
781 |
int mus_reopen_write(char *arg) |
782 |
{ |
783 |
#ifdef MACOS |
784 |
return(open(arg,O_RDWR)); |
785 |
#else |
786 |
int fd; |
787 |
#ifdef WINDOZE |
788 |
fd = open(arg,O_RDWR | O_BINARY); |
789 |
#else |
790 |
fd = open(arg,O_RDWR,0); |
791 |
#endif |
792 |
return(fd); |
793 |
#endif |
794 |
} |
795 |
|
796 |
int mus_close(int fd) |
797 |
{ |
798 |
mus_close_file_descriptors(fd); |
799 |
return(close(fd)); |
800 |
} |
801 |
|
802 |
|
803 |
|
804 |
/* ---------------- seek ---------------- */ |
805 |
|
806 |
long mus_seek(int tfd, long offset, int origin) |
807 |
{ |
808 |
int fd,siz; /* siz = datum size in bytes */ |
809 |
long loc,true_loc,header_end; |
810 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"mus_seek: file descriptors not initialized!"); return(-1);} |
811 |
if ((tfd == SNDLIB_DAC_CHANNEL) || (tfd == SNDLIB_DAC_REVERB)) return(0); |
812 |
fd = convert_fd(tfd); |
813 |
if (fd < 0) return(-1); |
814 |
if (io_data_format[fd] == SNDLIB_NO_SND) |
815 |
{ |
816 |
mus_error(MUS_NOT_A_SOUND_FILE,"mus_seek: invalid stream: %d (%d, %d, %d)",fd,tfd,(int)offset,origin); |
817 |
return(-1); |
818 |
} |
819 |
siz = io_bytes_per_sample[fd]; |
820 |
if ((siz == 2) || (origin != 0)) |
821 |
return(lseek(tfd,offset,origin)); |
822 |
else |
823 |
{ |
824 |
header_end = io_data_location[fd]; |
825 |
loc = offset - header_end; |
826 |
switch (siz) |
827 |
{ |
828 |
case 1: |
829 |
true_loc = lseek(tfd,header_end+(loc>>1),origin); |
830 |
/* now pretend we're still in 16-bit land and return where we "actually" are in that region */ |
831 |
/* that is, loc (in bytes) = how many (2-byte) samples into the file we want to go, return what we got */ |
832 |
return(header_end + ((true_loc - header_end)<<1)); |
833 |
break; |
834 |
case 3: |
835 |
true_loc = lseek(tfd,header_end+loc+(loc>>1),origin); |
836 |
return(true_loc + ((true_loc - header_end)>>1)); |
837 |
break; |
838 |
case 4: |
839 |
true_loc = lseek(tfd,header_end+(loc<<1),origin); |
840 |
return(header_end + ((true_loc - header_end)>>1)); |
841 |
break; |
842 |
case 8: |
843 |
true_loc = lseek(tfd,header_end+(loc<<2),origin); |
844 |
return(header_end + ((true_loc - header_end)>>2)); |
845 |
break; |
846 |
} |
847 |
} |
848 |
return(-1); |
849 |
} |
850 |
|
851 |
int mus_seek_frame(int tfd, int frame) |
852 |
{ |
853 |
int fd; |
854 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"mus_seek_frame: file descriptors not initialized!"); return(-1);} |
855 |
if ((tfd == SNDLIB_DAC_CHANNEL) || (tfd == SNDLIB_DAC_REVERB)) return(0); |
856 |
fd = convert_fd(tfd); |
857 |
if (fd < 0) return(-1); |
858 |
if (io_data_format[fd] == SNDLIB_NO_SND) |
859 |
{ |
860 |
mus_error(MUS_NOT_A_SOUND_FILE,"mus_seek_frame: invalid stream: %d (%d, %d)",fd,tfd,frame); |
861 |
return(-1); |
862 |
} |
863 |
return(lseek(tfd,io_data_location[fd] + (io_chans[fd] * frame * io_bytes_per_sample[fd]),SEEK_SET)); |
864 |
} |
865 |
|
866 |
|
867 |
|
868 |
/* ---------------- mulaw/alaw conversions ---------------- |
869 |
* |
870 |
* x : input signal with max value 32767 |
871 |
* mu : compression parameter (mu=255 used for telephony) |
872 |
* y = (32767/log(1+mu))*log(1+mu*abs(x)/32767)*sign(x); -- this isn't right -- typo? |
873 |
*/ |
874 |
|
875 |
/* from sox g711.c */ |
876 |
|
877 |
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ |
878 |
#define QUANT_MASK (0xf) /* Quantization field mask. */ |
879 |
#define NSEGS (8) /* Number of A-law segments. */ |
880 |
#define SEG_SHIFT (4) /* Left shift for segment number. */ |
881 |
#define SEG_MASK (0x70) /* Segment field mask. */ |
882 |
|
883 |
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; |
884 |
|
885 |
static int search(int val, short *table, int size) |
886 |
{ |
887 |
int i; |
888 |
for (i = 0; i < size; i++) {if (val <= *table++) return (i);} |
889 |
return (size); |
890 |
} |
891 |
|
892 |
static unsigned char to_alaw(int pcm_val) |
893 |
{ |
894 |
int mask,seg; |
895 |
unsigned char aval; |
896 |
if (pcm_val >= 0) {mask = 0xD5;} else {mask = 0x55; pcm_val = -pcm_val - 8;} |
897 |
seg = search(pcm_val, seg_end, 8); |
898 |
if (seg >= 8) return (0x7F ^ mask); |
899 |
else |
900 |
{ |
901 |
aval = seg << SEG_SHIFT; |
902 |
if (seg < 2) aval |= (pcm_val >> 4) & QUANT_MASK; else aval |= (pcm_val >> (seg + 3)) & QUANT_MASK; |
903 |
return (aval ^ mask); |
904 |
} |
905 |
} |
906 |
|
907 |
static const int alaw[256] = { |
908 |
-5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, |
909 |
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, |
910 |
-22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, |
911 |
-11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, |
912 |
-344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, |
913 |
-88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, |
914 |
-1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, |
915 |
-688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, |
916 |
5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, |
917 |
2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, |
918 |
22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, |
919 |
11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, |
920 |
344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, |
921 |
88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, |
922 |
1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, |
923 |
688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 |
924 |
}; |
925 |
|
926 |
#if 0 |
927 |
static int from_alaw(unsigned char a_val) |
928 |
{ |
929 |
int t,seg; |
930 |
a_val ^= 0x55; |
931 |
t = (a_val & QUANT_MASK) << 4; |
932 |
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; |
933 |
switch (seg) |
934 |
{ |
935 |
case 0: t += 8; break; |
936 |
case 1: t += 0x108; break; |
937 |
default: t += 0x108; t <<= seg - 1; |
938 |
} |
939 |
return((a_val & SIGN_BIT) ? t : -t); |
940 |
} |
941 |
#endif |
942 |
|
943 |
#define BIAS (0x84) /* Bias for linear code. */ |
944 |
|
945 |
static unsigned char to_mulaw(int pcm_val) |
946 |
{ |
947 |
int mask; |
948 |
int seg; |
949 |
unsigned char uval; |
950 |
if (pcm_val < 0) {pcm_val = BIAS - pcm_val; mask = 0x7F;} else {pcm_val += BIAS; mask = 0xFF;} |
951 |
seg = search(pcm_val, seg_end, 8); |
952 |
if (seg >= 8) return (0x7F ^ mask); |
953 |
else |
954 |
{ |
955 |
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); |
956 |
return (uval ^ mask); |
957 |
} |
958 |
} |
959 |
|
960 |
/* generated by SNDiMulaw on a NeXT -- see /usr/include/sound/mulaw.h */ |
961 |
static const int mulaw[256] = { |
962 |
-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, |
963 |
-19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, |
964 |
-11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, |
965 |
-6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, |
966 |
-3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, |
967 |
-1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, |
968 |
-924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, |
969 |
-396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, |
970 |
-132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, |
971 |
30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, |
972 |
15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, |
973 |
8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, |
974 |
4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, |
975 |
2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, |
976 |
988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, |
977 |
356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, |
978 |
88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0}; |
979 |
|
980 |
#if 0 |
981 |
/* in case it's ever needed, here's the mulaw to linear converter from g711.c -- identical to table above */ |
982 |
static int from_mulaw(unsigned char u_val) |
983 |
{ |
984 |
int t; |
985 |
u_val = ~u_val; |
986 |
t = ((u_val & QUANT_MASK) << 3) + BIAS; |
987 |
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; |
988 |
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); |
989 |
} |
990 |
#endif |
991 |
|
992 |
/* ---------------- read/write buffer allocation ---------------- */ |
993 |
|
994 |
#if LONG_INT_P |
995 |
static int **long_int_p_table = NULL; |
996 |
static int long_int_p_table_size = 0; |
997 |
|
998 |
int *delist_ptr(int arr) {return(long_int_p_table[arr]);} |
999 |
|
1000 |
int list_ptr(int *arr) |
1001 |
{ |
1002 |
int i,loc; |
1003 |
loc = -1; |
1004 |
for (i=0;i<long_int_p_table_size;i++) |
1005 |
{ |
1006 |
if (long_int_p_table[i] == NULL) |
1007 |
{ |
1008 |
loc = i; |
1009 |
break; |
1010 |
} |
1011 |
} |
1012 |
if (loc == -1) |
1013 |
{ |
1014 |
loc = long_int_p_table_size; |
1015 |
long_int_p_table_size+=16; |
1016 |
if (long_int_p_table) |
1017 |
{ |
1018 |
long_int_p_table = (int **)REALLOC(long_int_p_table,long_int_p_table_size * sizeof(int *)); |
1019 |
for (i=loc;i<long_int_p_table_size;i++) long_int_p_table[i] = NULL; |
1020 |
} |
1021 |
else |
1022 |
long_int_p_table = (int **)CALLOC(long_int_p_table_size,sizeof(int *)); |
1023 |
} |
1024 |
long_int_p_table[loc] = arr; |
1025 |
return(loc); |
1026 |
} |
1027 |
|
1028 |
void freearray(int ip_1) |
1029 |
{ |
1030 |
int *ip; |
1031 |
ip = delist_ptr(ip_1); |
1032 |
if (ip) FREE(ip); |
1033 |
long_int_p_table[ip_1] = NULL; |
1034 |
} |
1035 |
#else |
1036 |
void freearray(int *ip) {if (ip) FREE(ip);} |
1037 |
#endif |
1038 |
|
1039 |
#define BUFLIM (64*1024) |
1040 |
|
1041 |
static int checked_write(int fd, char *buf, int chars) |
1042 |
{ |
1043 |
#ifdef CLM |
1044 |
#ifndef MACOS |
1045 |
long lisp_call(int index); |
1046 |
#endif |
1047 |
#endif |
1048 |
int bytes,cfd; |
1049 |
if (fd == SNDLIB_DAC_CHANNEL) |
1050 |
{ |
1051 |
write_audio(rt_ap_out,buf,chars); |
1052 |
} |
1053 |
else |
1054 |
{ |
1055 |
bytes=write(fd,buf,chars); |
1056 |
if (bytes != chars) |
1057 |
{ |
1058 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"checked_write: file descriptors not initialized!"); return(-1);} |
1059 |
cfd = convert_fd(fd); |
1060 |
if (cfd < 0) return(-1); |
1061 |
if (io_data_format[cfd] == SNDLIB_NO_SND) mus_error(MUS_FILE_CLOSED,"checked_write called on closed file"); |
1062 |
#if LONG_INT_P |
1063 |
mus_error(MUS_WRITE_ERROR,"IO write error (%s): %d of %d bytes written for %d from %d (%d %d %d)\n", |
1064 |
strerror(errno), |
1065 |
bytes,chars,fd,cfd,io_bytes_per_sample[cfd],io_data_format[cfd],io_data_location[cfd]); |
1066 |
#else |
1067 |
#ifndef MACOS |
1068 |
mus_error(MUS_WRITE_ERROR,"IO write error (%s): %d of %d bytes written for %d from %d (%d %d %d %d)\n", |
1069 |
strerror(errno), |
1070 |
bytes,chars,fd,cfd,(int)buf,io_bytes_per_sample[cfd],io_data_format[cfd],io_data_location[cfd]); |
1071 |
#else |
1072 |
mus_error(MUS_WRITE_ERROR,"IO write error: %d of %d bytes written for %d from %d (%d %d %d %d)\n", |
1073 |
bytes,chars,fd,cfd,(int)buf,io_bytes_per_sample[cfd],io_data_format[cfd],io_data_location[cfd]); |
1074 |
#endif |
1075 |
#endif |
1076 |
return(-1); |
1077 |
} |
1078 |
} |
1079 |
return(0); |
1080 |
} |
1081 |
|
1082 |
|
1083 |
|
1084 |
/* ---------------- read ---------------- */ |
1085 |
|
1086 |
/* normally we assume a 16-bit fractional part, but sometimes user want 24-bits */ |
1087 |
static int shift_24_choice = 0; |
1088 |
#ifdef CLM |
1089 |
int get_shift_24_choice(void) {return(shift_24_choice);} |
1090 |
void set_shift_24_choice(int choice) {shift_24_choice = choice;} |
1091 |
#endif |
1092 |
|
1093 |
int mus_read_any(int tfd, int beg, int chans, int nints, int **bufs, int *cm) |
1094 |
{ |
1095 |
int fd; |
1096 |
int bytes,j,lim,siz,total,leftover,total_read,k,loc,oldloc,siz_chans,buflim; |
1097 |
unsigned char *jchar; |
1098 |
char *charbuf = NULL; |
1099 |
int *buffer; |
1100 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"mus_read: file descriptors not initialized!"); return(-1);} |
1101 |
if (nints <= 0) return(0); |
1102 |
fd = convert_fd(tfd); |
1103 |
if (fd < 0) return(-1); |
1104 |
if (io_data_format[fd] == SNDLIB_NO_SND) {mus_error(MUS_FILE_CLOSED,"read_any called on closed file"); return(-1);} |
1105 |
charbuf = (char *)CALLOC(BUFLIM,sizeof(char)); |
1106 |
if (charbuf == NULL) {mus_error(MUS_MEMORY_ALLOCATION_FAILED,"IO buffer allocation trouble"); return(-1);} |
1107 |
siz = io_bytes_per_sample[fd]; |
1108 |
siz_chans = siz*chans; |
1109 |
leftover = (nints*siz_chans); |
1110 |
k = (BUFLIM) % siz_chans; |
1111 |
if (k != 0) /* for example, 3 channel output of 1-byte (mulaw) samples will need a mod 3 buffer */ |
1112 |
buflim = (BUFLIM) - k; |
1113 |
else buflim = BUFLIM; |
1114 |
total_read = 0; |
1115 |
loc = beg; |
1116 |
while (leftover > 0) |
1117 |
{ |
1118 |
bytes = leftover; |
1119 |
if (bytes > buflim) {leftover = (bytes-buflim); bytes = buflim;} else leftover = 0; |
1120 |
total = read(tfd,charbuf,bytes); |
1121 |
if (total <= 0) |
1122 |
{ |
1123 |
/* zero out trailing section (some callers don't check the returned value) -- this added 9-May-99 */ |
1124 |
lim = beg+nints; |
1125 |
if (loc < lim) |
1126 |
{ |
1127 |
for (k=0;k<chans;k++) |
1128 |
{ |
1129 |
if ((cm == NULL) || (cm[k])) |
1130 |
{ |
1131 |
for (j=loc;j<lim;j++) |
1132 |
bufs[k][j] = 0; |
1133 |
} |
1134 |
} |
1135 |
} |
1136 |
FREE(charbuf); |
1137 |
return(total_read); |
1138 |
} |
1139 |
lim = (int) (total / siz_chans); /* this divide must be exact (hence the buflim calc above) */ |
1140 |
total_read += lim; |
1141 |
oldloc = loc; |
1142 |
|
1143 |
for (k=0;k<chans;k++) |
1144 |
{ |
1145 |
if ((cm == NULL) || (cm[k])) |
1146 |
{ |
1147 |
buffer = (int *)(bufs[k]); |
1148 |
if (buffer) |
1149 |
{ |
1150 |
loc = oldloc; |
1151 |
jchar = (unsigned char *)charbuf; |
1152 |
jchar += (k*siz); |
1153 |
switch (io_data_format[fd]) |
1154 |
{ |
1155 |
case SNDLIB_16_LINEAR: |
1156 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int)m_big_endian_short(jchar); |
1157 |
break; |
1158 |
case SNDLIB_16_LINEAR_LITTLE_ENDIAN: |
1159 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int)m_little_endian_short(jchar); |
1160 |
break; |
1161 |
case SNDLIB_32_LINEAR: |
1162 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = m_big_endian_int(jchar); |
1163 |
break; |
1164 |
case SNDLIB_32_LINEAR_LITTLE_ENDIAN: |
1165 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = m_little_endian_int(jchar); |
1166 |
break; |
1167 |
case SNDLIB_8_MULAW: |
1168 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = mulaw[*jchar]; |
1169 |
break; |
1170 |
case SNDLIB_8_ALAW: |
1171 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = alaw[*jchar]; |
1172 |
break; |
1173 |
case SNDLIB_8_LINEAR: |
1174 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int)(((signed char)(*jchar)) << 8); |
1175 |
break; |
1176 |
case SNDLIB_8_UNSIGNED: |
1177 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int) ((((int)(*jchar))-128) << 8); |
1178 |
break; |
1179 |
case SNDLIB_32_FLOAT: |
1180 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int) (SNDLIB_SNDFIX*(m_big_endian_float(jchar))); |
1181 |
break; |
1182 |
case SNDLIB_64_DOUBLE: |
1183 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int) (SNDLIB_SNDFIX*(m_big_endian_double(jchar))); |
1184 |
break; |
1185 |
case SNDLIB_32_FLOAT_LITTLE_ENDIAN: |
1186 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int) (SNDLIB_SNDFIX*(m_little_endian_float(jchar))); |
1187 |
break; |
1188 |
case SNDLIB_64_DOUBLE_LITTLE_ENDIAN: |
1189 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int) (SNDLIB_SNDFIX*(m_little_endian_double(jchar))); |
1190 |
break; |
1191 |
case SNDLIB_16_UNSIGNED: |
1192 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = ((int)(m_big_endian_unsigned_short(jchar)) - 32768); |
1193 |
break; |
1194 |
case SNDLIB_16_UNSIGNED_LITTLE_ENDIAN: |
1195 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = ((int)(m_little_endian_unsigned_short(jchar)) - 32768); |
1196 |
break; |
1197 |
case SNDLIB_32_VAX_FLOAT: |
1198 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) buffer[loc] = (int)from_vax_float(jchar); |
1199 |
break; |
1200 |
case SNDLIB_24_LINEAR: |
1201 |
if (shift_24_choice == 0) |
1202 |
{ |
1203 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) |
1204 |
buffer[loc] = (int)(((jchar[0]<<24)+(jchar[1]<<16))>>16); |
1205 |
} |
1206 |
else |
1207 |
{ |
1208 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) |
1209 |
buffer[loc] = (int)(((jchar[0]<<24)+(jchar[1]<<16)+(jchar[2]<<8))>>8); |
1210 |
} |
1211 |
break; |
1212 |
case SNDLIB_24_LINEAR_LITTLE_ENDIAN: |
1213 |
if (shift_24_choice == 0) |
1214 |
{ |
1215 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) |
1216 |
buffer[loc] = (int)(((jchar[2]<<24)+(jchar[1]<<16))>>16); |
1217 |
} |
1218 |
else |
1219 |
{ |
1220 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) |
1221 |
buffer[loc] = (int)(((jchar[2]<<24)+(jchar[1]<<16)+(jchar[0]<<8))>>8); |
1222 |
} |
1223 |
break; |
1224 |
} |
1225 |
} |
1226 |
} |
1227 |
} |
1228 |
} |
1229 |
FREE(charbuf); |
1230 |
return(total_read); |
1231 |
} |
1232 |
|
1233 |
int mus_read(int fd, int beg, int end, int chans, int **bufs) |
1234 |
{ |
1235 |
int num,rtn,i,k; |
1236 |
int *buffer; |
1237 |
num=(end-beg+1); |
1238 |
rtn=mus_read_any(fd,beg,chans,num,bufs,NULL); |
1239 |
if (rtn == -1) return(-1); |
1240 |
if (rtn<num) |
1241 |
{ |
1242 |
for (k=0;k<chans;k++) |
1243 |
{ |
1244 |
buffer=(int *)(bufs[k]); |
1245 |
for (i=rtn+beg;i<=end;i++) |
1246 |
{ |
1247 |
buffer[i]=0; |
1248 |
} |
1249 |
} |
1250 |
} |
1251 |
return(num); |
1252 |
} |
1253 |
|
1254 |
int mus_read_chans(int fd, int beg, int end, int chans, int **bufs, int *cm) |
1255 |
{ |
1256 |
/* an optimization of mus_read -- just reads the desired channels */ |
1257 |
int num,rtn,i,k; |
1258 |
int *buffer; |
1259 |
num=(end-beg+1); |
1260 |
rtn=mus_read_any(fd,beg,chans,num,bufs,cm); |
1261 |
if (rtn == -1) return(-1); |
1262 |
if (rtn<num) |
1263 |
{ |
1264 |
for (k=0;k<chans;k++) |
1265 |
{ |
1266 |
if ((cm == NULL) || (cm[k])) |
1267 |
{ |
1268 |
buffer=(int *)(bufs[k]); |
1269 |
for (i=rtn+beg;i<=end;i++) |
1270 |
{ |
1271 |
buffer[i]=0; |
1272 |
} |
1273 |
} |
1274 |
} |
1275 |
} |
1276 |
return(num); |
1277 |
} |
1278 |
|
1279 |
|
1280 |
/* ---------------- write ---------------- */ |
1281 |
|
1282 |
#ifdef WINDOZE |
1283 |
#undef min |
1284 |
#endif |
1285 |
|
1286 |
#define min(x,y) ((x) < (y) ? (x) : (y)) |
1287 |
|
1288 |
int mus_write_zeros(int tfd, int num) |
1289 |
{ |
1290 |
int i,lim,curnum,fd,err; |
1291 |
char *charbuf = NULL; |
1292 |
if (tfd == -1) return(-1); |
1293 |
if (tfd == SNDLIB_DAC_REVERB) return(0); |
1294 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"mus_write: file descriptors not initialized!"); return(-1);} |
1295 |
fd = convert_fd(tfd); |
1296 |
if (fd < 0) return(-1); |
1297 |
if (io_data_format[fd] == SNDLIB_NO_SND) {mus_error(MUS_FILE_CLOSED,"write_zeros called on closed file"); return(-1);} |
1298 |
charbuf = (char *)CALLOC(BUFLIM,sizeof(char)); |
1299 |
if (charbuf == NULL) {mus_error(MUS_MEMORY_ALLOCATION_FAILED,"IO buffer allocation trouble"); return(-1);} |
1300 |
lim = num*(io_bytes_per_sample[fd]); |
1301 |
curnum=min(lim,BUFLIM); |
1302 |
for (i=0;i<curnum;i++) charbuf[i]=0; |
1303 |
while (curnum>0) |
1304 |
{ |
1305 |
err = checked_write(tfd,charbuf,curnum); |
1306 |
if (err == -1) return(-1); |
1307 |
lim -= (BUFLIM); |
1308 |
curnum=min(lim,BUFLIM); |
1309 |
} |
1310 |
FREE(charbuf); |
1311 |
return(num); |
1312 |
} |
1313 |
|
1314 |
|
1315 |
#ifdef CLM |
1316 |
void mus_write_float(int fd, float val) {write(fd,(char *)(&val),4);} |
1317 |
|
1318 |
#if defined(ACL4) && defined(ALPHA) |
1319 |
/* in this case, the array passed from lisp is a list of table indices */ |
1320 |
void mus_write_1(int tfd, int beg, int end, int chans, int *buflist) |
1321 |
{ |
1322 |
int i; |
1323 |
int **bufs; |
1324 |
bufs = (int **)CALLOC(chans,sizeof(int *)); |
1325 |
for (i=0;i<chans;i++) bufs[i] = delist_ptr(buflist[i]); |
1326 |
mus_write(tfd,beg,end,chans,bufs); |
1327 |
FREE(bufs); |
1328 |
} |
1329 |
void mus_read_1(int fd, int beg, int end, int chans, int *buflist) |
1330 |
{ |
1331 |
int i; |
1332 |
int **bufs; |
1333 |
bufs = (int **)CALLOC(chans,sizeof(int *)); |
1334 |
for (i=0;i<chans;i++) bufs[i] = delist_ptr(buflist[i]); |
1335 |
mus_read(fd,beg,end,chans,bufs); |
1336 |
FREE(bufs); |
1337 |
} |
1338 |
#endif |
1339 |
#endif |
1340 |
|
1341 |
int mus_write(int tfd, int beg, int end, int chans, int **bufs) |
1342 |
{ |
1343 |
int fd,err; |
1344 |
int bytes,j,k,lim,siz,leftover,loc,bk,oldloc,buflim,siz_chans,cliploc; |
1345 |
unsigned char *jchar; |
1346 |
char *charbuf = NULL; |
1347 |
int *buffer; |
1348 |
if (tfd == -1) return(-1); |
1349 |
if (tfd == SNDLIB_DAC_REVERB) return(0); |
1350 |
if (!io_descriptors_ok) {mus_error(MUS_FILE_DESCRIPTORS_NOT_INITIALIZED,"mus_write: file descriptors not initialized!"); return(-1);} |
1351 |
fd = convert_fd(tfd); |
1352 |
if (fd < 0) return(-1); |
1353 |
if (io_data_format[fd] == SNDLIB_NO_SND) {mus_error(MUS_FILE_CLOSED,"write called on closed file"); return(-1);} |
1354 |
charbuf = (char *)CALLOC(BUFLIM,sizeof(char)); |
1355 |
if (charbuf == NULL) {mus_error(MUS_MEMORY_ALLOCATION_FAILED,"IO buffer allocation trouble"); return(-1);} |
1356 |
siz = io_bytes_per_sample[fd]; |
1357 |
lim=(end-beg+1); |
1358 |
siz_chans = siz*chans; |
1359 |
leftover = lim*siz_chans; |
1360 |
k = (BUFLIM) % siz_chans; |
1361 |
if (k != 0) |
1362 |
buflim = (BUFLIM) - k; |
1363 |
else buflim = BUFLIM; |
1364 |
loc = beg; |
1365 |
while (leftover > 0) |
1366 |
{ |
1367 |
bytes = leftover; |
1368 |
if (bytes > buflim) {leftover = (bytes-buflim); bytes = buflim;} else leftover = 0; |
1369 |
lim = (int)(bytes/siz_chans); /* see note above */ |
1370 |
oldloc = loc; |
1371 |
|
1372 |
for (k=0;k<chans;k++) |
1373 |
{ |
1374 |
loc = oldloc; |
1375 |
buffer = (int *)(bufs[k]); |
1376 |
if (io_data_clipped[fd]) |
1377 |
{ |
1378 |
cliploc = oldloc; |
1379 |
for (j=0;j<lim;j++,cliploc++) |
1380 |
{ |
1381 |
if (buffer[cliploc] > 32767) |
1382 |
buffer[cliploc] = 32767; |
1383 |
else |
1384 |
if (buffer[cliploc] < -32768) |
1385 |
buffer[cliploc] = -32768; |
1386 |
} |
1387 |
} |
1388 |
jchar = (unsigned char *)charbuf; |
1389 |
jchar += (k*siz); |
1390 |
switch (io_data_format[fd]) |
1391 |
{ |
1392 |
case SNDLIB_16_LINEAR: |
1393 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_big_endian_short(jchar,(short)(buffer[loc])); |
1394 |
break; |
1395 |
case SNDLIB_16_LINEAR_LITTLE_ENDIAN: |
1396 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_little_endian_short(jchar,(short)(buffer[loc])); |
1397 |
break; |
1398 |
case SNDLIB_32_LINEAR: |
1399 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_big_endian_int(jchar,buffer[loc]); |
1400 |
break; |
1401 |
case SNDLIB_32_LINEAR_LITTLE_ENDIAN: |
1402 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_little_endian_int(jchar,buffer[loc]); |
1403 |
break; |
1404 |
case SNDLIB_8_MULAW: |
1405 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) (*jchar) = to_mulaw(buffer[loc]); |
1406 |
break; |
1407 |
case SNDLIB_8_ALAW: |
1408 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) (*jchar) = to_alaw(buffer[loc]); |
1409 |
break; |
1410 |
case SNDLIB_8_LINEAR: |
1411 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) (*((signed char *)jchar)) = ((buffer[loc])>>8); |
1412 |
break; |
1413 |
case SNDLIB_8_UNSIGNED: |
1414 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) (*jchar) = ((buffer[loc])>>8)+128; |
1415 |
break; |
1416 |
case SNDLIB_32_FLOAT: |
1417 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_big_endian_float(jchar,(SNDLIB_SNDFLT * (buffer[loc]))); |
1418 |
break; |
1419 |
case SNDLIB_32_FLOAT_LITTLE_ENDIAN: |
1420 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_little_endian_float(jchar,(SNDLIB_SNDFLT * (buffer[loc]))); |
1421 |
break; |
1422 |
case SNDLIB_64_DOUBLE: |
1423 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_big_endian_double(jchar,(SNDLIB_SNDFLT * (buffer[loc]))); |
1424 |
break; |
1425 |
case SNDLIB_64_DOUBLE_LITTLE_ENDIAN: |
1426 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_little_endian_double(jchar,(SNDLIB_SNDFLT * (buffer[loc]))); |
1427 |
break; |
1428 |
case SNDLIB_16_UNSIGNED: |
1429 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_big_endian_unsigned_short(jchar,(short)(buffer[loc] + 32768)); |
1430 |
break; |
1431 |
case SNDLIB_16_UNSIGNED_LITTLE_ENDIAN: |
1432 |
for (j=0;j<lim;j++,loc++,jchar+=siz_chans) m_set_little_endian_unsigned_short(jchar,(short)(buffer[loc] + 32768)); |
1433 |
break; |
1434 |
case SNDLIB_24_LINEAR: |
1435 |
bk=(k*3); |
1436 |
if (shift_24_choice == 0) |
1437 |
{ |
1438 |
for (j=0;j<lim;j++,loc++,bk+=(chans*3)) |
1439 |
{ |
1440 |
charbuf[bk]=((buffer[loc])>>8); |
1441 |
charbuf[bk+1]=((buffer[loc])&0xFF); |
1442 |
charbuf[bk+2]=0; |
1443 |
} |
1444 |
} |
1445 |
else |
1446 |
{ |
1447 |
for (j=0;j<lim;j++,loc++,bk+=(chans*3)) |
1448 |
{ |
1449 |
charbuf[bk]=((buffer[loc])>>16); |
1450 |
charbuf[bk+1]=((buffer[loc])>>8); |
1451 |
charbuf[bk+2]=((buffer[loc])&0xFF); |
1452 |
} |
1453 |
} |
1454 |
break; |
1455 |
case SNDLIB_24_LINEAR_LITTLE_ENDIAN: |
1456 |
bk=(k*3); |
1457 |
if (shift_24_choice == 0) |
1458 |
{ |
1459 |
for (j=0;j<lim;j++,loc++,bk+=(chans*3)) |
1460 |
{ |
1461 |
charbuf[bk+2]=((buffer[loc])>>8); |
1462 |
charbuf[bk+1]=((buffer[loc])&0xFF); |
1463 |
charbuf[bk]=0; |
1464 |
} |
1465 |
} |
1466 |
else |
1467 |
{ |
1468 |
for (j=0;j<lim;j++,loc++,bk+=(chans*3)) |
1469 |
{ |
1470 |
charbuf[bk+2]=((buffer[loc])>>16); |
1471 |
charbuf[bk+1]=((buffer[loc])>>8); |
1472 |
charbuf[bk]=((buffer[loc])&0xFF); |
1473 |
} |
1474 |
} |
1475 |
break; |
1476 |
} |
1477 |
} |
1478 |
err = checked_write(tfd,charbuf,bytes); |
1479 |
if (err == -1) {FREE(charbuf); return(-1);} |
1480 |
} |
1481 |
FREE(charbuf); |
1482 |
return(0); |
1483 |
} |
1484 |
|
1485 |
int mus_float_sound(char *charbuf, int samps, int charbuf_format, float *buffer) |
1486 |
{ |
1487 |
/* translate whatever is in charbuf to 32-bit floats still interleaved */ |
1488 |
int j,siz; |
1489 |
unsigned char *jchar; |
1490 |
siz = mus_format2bytes(charbuf_format); |
1491 |
jchar = (unsigned char *)charbuf; |
1492 |
switch (charbuf_format) |
1493 |
{ |
1494 |
case SNDLIB_16_LINEAR: |
1495 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_big_endian_short(jchar)); |
1496 |
break; |
1497 |
case SNDLIB_16_LINEAR_LITTLE_ENDIAN: |
1498 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_little_endian_short(jchar)); |
1499 |
break; |
1500 |
case SNDLIB_32_LINEAR: |
1501 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_big_endian_int(jchar)); |
1502 |
break; |
1503 |
case SNDLIB_32_LINEAR_LITTLE_ENDIAN: |
1504 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_little_endian_int(jchar)); |
1505 |
break; |
1506 |
case SNDLIB_8_MULAW: |
1507 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(mulaw[*jchar]); |
1508 |
break; |
1509 |
case SNDLIB_8_ALAW: |
1510 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(alaw[*jchar]); |
1511 |
break; |
1512 |
case SNDLIB_8_LINEAR: |
1513 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int)((*((signed char *)jchar)) << 8)); |
1514 |
break; |
1515 |
case SNDLIB_8_UNSIGNED: |
1516 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int) ((((int)(*jchar))-128) << 8)); |
1517 |
break; |
1518 |
case SNDLIB_24_LINEAR: |
1519 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int)(((jchar[0]<<24)+(jchar[1]<<16))>>16)); |
1520 |
break; |
1521 |
case SNDLIB_24_LINEAR_LITTLE_ENDIAN: |
1522 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int)(((jchar[2]<<24)+(jchar[1]<<16))>>16)); |
1523 |
break; |
1524 |
case SNDLIB_32_FLOAT: |
1525 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = m_big_endian_float(jchar); |
1526 |
break; |
1527 |
case SNDLIB_64_DOUBLE: |
1528 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_big_endian_double(jchar)); |
1529 |
break; |
1530 |
case SNDLIB_32_FLOAT_LITTLE_ENDIAN: |
1531 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = m_little_endian_float(jchar); |
1532 |
break; |
1533 |
case SNDLIB_64_DOUBLE_LITTLE_ENDIAN: |
1534 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(m_little_endian_double(jchar)); |
1535 |
break; |
1536 |
case SNDLIB_16_UNSIGNED: |
1537 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)(((int)(m_big_endian_unsigned_short(jchar)) - 32768)); |
1538 |
break; |
1539 |
case SNDLIB_32_VAX_FLOAT: |
1540 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int)from_vax_float(jchar)); |
1541 |
break; |
1542 |
case SNDLIB_16_UNSIGNED_LITTLE_ENDIAN: |
1543 |
for (j=0;j<samps;j++,jchar+=siz) buffer[j] = (float)((int)(m_little_endian_unsigned_short(jchar)) - 32768); |
1544 |
break; |
1545 |
default: return(-1); break; |
1546 |
} |
1547 |
return(0); |
1548 |
} |
1549 |
|
1550 |
#ifdef CLM |
1551 |
|
1552 |
/* originally part of clmnet.c, but requires endian handlers and is easier to deal with on the Mac if it's in this file */ |
1553 |
int net_mix(int fd, int loc, char *buf1, char *buf2, int bytes) |
1554 |
{ |
1555 |
#if defined(SNDLIB_LITTLE_ENDIAN) || defined(SUN) |
1556 |
unsigned char*b1,*b2; |
1557 |
#else |
1558 |
short *dat1,*dat2; |
1559 |
#endif |
1560 |
int i,lim,rtn; |
1561 |
lim = bytes>>1; |
1562 |
lseek(fd,loc,SEEK_SET); |
1563 |
rtn = read(fd,buf1,bytes); |
1564 |
if (rtn < bytes) |
1565 |
{ |
1566 |
for (i=rtn;i<bytes;i++) buf1[i]=buf2[i]; |
1567 |
lim = rtn>>1; |
1568 |
} |
1569 |
lseek(fd,loc,SEEK_SET); |
1570 |
#if defined(SNDLIB_LITTLE_ENDIAN) || defined(SUN) |
1571 |
/* all intermediate results are written as big-endian shorts (NeXT output) */ |
1572 |
b1 = (unsigned char *)buf1; |
1573 |
b2 = (unsigned char *)buf2; |
1574 |
for (i=0;i<lim;i++,b1+=2,b2+=2) mus_set_big_endian_short(b1,(short)(mus_big_endian_short(b1) + mus_big_endian_short(b2))); |
1575 |
#else |
1576 |
dat1 = (short *)buf1; |
1577 |
dat2 = (short *)buf2; |
1578 |
for (i=0;i<lim;i++) dat1[i] += dat2[i]; |
1579 |
#endif |
1580 |
write(fd,buf1,bytes); |
1581 |
return(0); |
1582 |
} |
1583 |
#endif |
1584 |
|
1585 |
int mus_unshort_sound(short *in_buf, int samps, int new_format, char *out_buf) |
1586 |
{ |
1587 |
int j,siz; |
1588 |
unsigned char *jchar; |
1589 |
siz = mus_format2bytes(new_format); |
1590 |
jchar = (unsigned char *)out_buf; |
1591 |
switch (new_format) |
1592 |
{ |
1593 |
case SNDLIB_16_LINEAR: |
1594 |
for (j=0;j<samps;j++,jchar+=siz) m_set_big_endian_short(jchar,in_buf[j]); |
1595 |
break; |
1596 |
case SNDLIB_16_LINEAR_LITTLE_ENDIAN: |
1597 |
for (j=0;j<samps;j++,jchar+=siz) m_set_little_endian_short(jchar,in_buf[j]); |
1598 |
break; |
1599 |
case SNDLIB_32_LINEAR: |
1600 |
for (j=0;j<samps;j++,jchar+=siz) m_set_big_endian_int(jchar,(int)in_buf[j]); |
1601 |
break; |
1602 |
case SNDLIB_32_LINEAR_LITTLE_ENDIAN: |
1603 |
for (j=0;j<samps;j++,jchar+=siz) m_set_little_endian_int(jchar,(int)in_buf[j]); |
1604 |
break; |
1605 |
case SNDLIB_8_MULAW: |
1606 |
for (j=0;j<samps;j++,jchar+=siz) (*jchar) = to_mulaw(in_buf[j]); |
1607 |
break; |
1608 |
case SNDLIB_8_ALAW: |
1609 |
for (j=0;j<samps;j++,jchar+=siz) (*jchar) = to_alaw(in_buf[j]); |
1610 |
break; |
1611 |
case SNDLIB_8_LINEAR: |
1612 |
for (j=0;j<samps;j++,jchar+=siz) (*((signed char *)jchar)) = ((in_buf[j])>>8); |
1613 |
break; |
1614 |
case SNDLIB_8_UNSIGNED: |
1615 |
for (j=0;j<samps;j++,jchar+=siz) (*jchar) = ((in_buf[j])>>8)+128; |
1616 |
break; |
1617 |
case SNDLIB_32_FLOAT: |
1618 |
for (j=0;j<samps;j++,jchar+=siz) m_set_big_endian_float(jchar,(SNDLIB_SNDFLT * (in_buf[j]))); |
1619 |
break; |
1620 |
case SNDLIB_32_FLOAT_LITTLE_ENDIAN: |
1621 |
for (j=0;j<samps;j++,jchar+=siz) m_set_little_endian_float(jchar,(SNDLIB_SNDFLT * (in_buf[j]))); |
1622 |
break; |
1623 |
default: return(0); break; |
1624 |
} |
1625 |
return(samps*siz); |
1626 |
} |
1627 |
|
1628 |
#ifdef CLM |
1629 |
void reset_io_c(void) |
1630 |
{ |
1631 |
io_descriptors_ok = 0; |
1632 |
io_files_ready = 0; |
1633 |
#if LONG_INT_P |
1634 |
long_int_p_table = NULL; |
1635 |
long_int_p_table_size = 0; |
1636 |
#endif |
1637 |
} |
1638 |
#endif |
1639 |
|
1640 |
char *mus_complete_filename(char *tok) |
1641 |
{ |
1642 |
/* fill out under-specified library pathnames and check for the damned '//' business (SGI file selection box uses this) */ |
1643 |
/* what about "../" and "./" ? these work, but perhaps we should handle them explicitly) */ |
1644 |
char *file_name_buf; |
1645 |
int i,j,len; |
1646 |
file_name_buf = (char *)CALLOC(SNDLIB_MAX_FILE_NAME,sizeof(char)); |
1647 |
if ((tok) && (*tok)) len = strlen(tok); else len = 0; |
1648 |
j = 0; |
1649 |
for (i=0;i<len-1;i++) |
1650 |
{ |
1651 |
if ((tok[i] == '/') && (tok[i+1] == '/')) j=i+1; |
1652 |
} |
1653 |
if (j > 0) |
1654 |
{ |
1655 |
for (i=0;j<len;i++,j++) tok[i] = tok[j]; |
1656 |
tok[i]='\0'; |
1657 |
} |
1658 |
#ifdef MACOS |
1659 |
strcpy(file_name_buf,tok); |
1660 |
#else |
1661 |
if (tok[0] != '/') |
1662 |
{ |
1663 |
file_name_buf[0] = '\0'; |
1664 |
if (tok[0] == '~') |
1665 |
{ |
1666 |
strcpy(file_name_buf,getenv("HOME")); |
1667 |
strcat(file_name_buf,++tok); |
1668 |
} |
1669 |
else |
1670 |
{ |
1671 |
#if (!defined(NEXT)) || defined(HAVE_GETCWD) |
1672 |
getcwd(file_name_buf,SNDLIB_MAX_FILE_NAME); |
1673 |
#else |
1674 |
getwd(file_name_buf); |
1675 |
#endif |
1676 |
strcat(file_name_buf,"/"); |
1677 |
strcat(file_name_buf,tok); |
1678 |
} |
1679 |
} |
1680 |
else strcpy(file_name_buf,tok); |
1681 |
#endif |
1682 |
return(file_name_buf); |
1683 |
} |