(Metux) autogen.sh: not running ./configure anymore (breaks certain distro builders)
[mirror-ossqm-audiofile.git] / libaudiofile / modules.c
blobd98a059cbb8c2c4a42f61222cc2634f0ae719d33
1 /*
2 Audio File Library
3 Copyright (C) 2000, Silicon Graphics, Inc.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307 USA.
22 modules.c
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
34 #include <assert.h>
36 #include <audiofile.h>
37 #include "afinternal.h"
38 #include "modules.h"
39 #include "pcm.h"
40 #include "util.h"
41 #include "units.h"
42 #include "compression.h"
43 #include "byteorder.h"
44 #include "print.h"
45 #include "debug.h"
47 #include "modules/rebuffer.h"
49 #ifdef DEBUG
50 #define CHNK(X) X
51 #define DEBG(X) X
52 #else
53 #define CHNK(X)
54 #define DEBG(X)
55 #endif
57 #define NULLMODULEPARAM
59 extern const _PCMInfo _af_default_signed_integer_pcm_mappings[];
60 extern const _PCMInfo _af_default_unsigned_integer_pcm_mappings[];
61 extern const _PCMInfo _af_default_float_pcm_mapping;
62 extern const _PCMInfo _af_default_double_pcm_mapping;
64 extern _CompressionUnit _af_compression[];
66 /* Define rebuffering modules. */
67 extern const _AFmodule int2rebufferv2f, int2rebufferf2v;
70 module utility routines
74 _AFnewmodinst creates a module instance from a module.
75 It returns a structure, not a pointer to a structure.
77 _AFmoduleinst _AFnewmodinst (const _AFmodule *mod)
79 _AFmoduleinst ret;
81 ret.inc = ret.outc = NULL;
82 ret.modspec = NULL;
83 ret.u.pull.source = NULL;
84 ret.mod = mod;
85 ret.free_on_close = false;
86 ret.valid = false;
88 return(ret);
92 _AFfreemodspec: useful routine for mod.free function pointer
94 void _AFfreemodspec (_AFmoduleinst *i)
96 if (i->modspec)
97 free(i->modspec);
98 i->modspec = NULL;
102 _AFpull: used a lot -- see comments in README.modules
104 AFframecount _AFpull (_AFmoduleinst *i, AFframecount nframes2pull)
106 _AFmoduleinst *src = i->u.pull.source;
108 i->inc->nframes = nframes2pull;
109 CHNK(printf("%s pulling %" AF_FRAMECOUNT_PRINT_FMT " frames from %s\n",
110 i->mod->name, i->inc->nframes, src->mod->name));
111 (*src->mod->run_pull)(src);
112 CHNK(_af_print_chunk(i->inc));
114 CHNK(printf("%s received %" AF_FRAMECOUNT_PRINT_FMT " frames from %s\n",
115 i->mod->name, i->inc->nframes, src->mod->name));
116 return i->inc->nframes;
120 _AFsimplemodrun
122 void _AFsimplemodrun_pull (_AFmoduleinst *i)
124 _AFpull(i, i->outc->nframes);
125 (*i->mod->run)(i->inc, i->outc, i->modspec);
129 _AFpush
131 void _AFpush (_AFmoduleinst *i, AFframecount nframes2push)
133 _AFmoduleinst *snk = i->u.push.sink;
134 i->outc->nframes = nframes2push;
135 CHNK(printf("%s pushing %" AF_FRAMECOUNT_PRINT_FMT " frames into %s\n",
136 i->mod->name, i->outc->nframes, snk->mod->name));
137 CHNK(_af_print_chunk(i->outc));
138 (*(snk->mod->run_push))(snk);
142 _AFpushat
144 void _AFpushat (_AFmoduleinst *i, AFframecount startframe, bool stretchint,
145 AFframecount nframes2push)
147 _AFmoduleinst *snk = i->u.push.sink;
149 void *saved_buf = i->outc->buf;
150 i->outc->buf = ((char *)i->outc->buf) +
151 (_af_format_frame_size_uncompressed(&i->outc->f,stretchint) * startframe);
153 i->outc->nframes = nframes2push;
154 CHNK(printf("%s pushing %" AF_FRAMECOUNT_PRINT_FMT " frames into %s "
155 "with OFFSET %" AF_FILEOFFSET_PRINT_FMT " frames\n",
156 i->mod->name, i->outc->nframes, snk->mod->name, startframe));
157 CHNK(_af_print_chunk(i->outc));
158 (*(snk->mod->run_push))(snk);
160 i->outc->buf = saved_buf;
164 _AFsimplemodrun
166 void _AFsimplemodrun_push (_AFmoduleinst *i)
168 i->outc->nframes = i->inc->nframes;
169 (*(i->mod->run))(i->inc, i->outc, i->modspec);
170 _AFpush(i, i->outc->nframes);
174 These macros each declare a module.
176 The module uses _AFsimplemodrun_pull and _AFsimplemodrun_push
177 (see comments in README.modules). Thus we only have to define
178 one routine that does the actual processing.
180 The arguments to the macros are as follows:
182 name - name of module
183 desc - code for module's "describe" function (see README.modules)
184 intype - type of elements of input buffer
185 outtype - type of elements of output buffer
186 action - action to take in inner loop -- indexes "ip" and "op" with "i"
188 modspectype - (MODULEM) this will initialize a pointer "m"
189 to this instance's modspec data, which is of type modspectype
191 Don't use _MODULE directly.
193 The code in "desc" is executed once, after the module is
194 initialized. It can reference "i->modspec" and should modify
195 "i->outc->f". A pointer "f" initialized to "&i->outc->f" is
196 emitted prior to "desc"; use this to to keep the code cleaner.
198 Note that the generated "run" routine shouldn't set outc->nframes since
200 * outc->nframes is set to inc->nframes by _AFsimplemodrun_push
201 * inc->nframes is set to outc->nframes by _AFsimplemodrun_pull
203 The whole point of the simplified "run" routine is that you don't
204 have to worry about push or pull.
206 See README.modules for more info on how modules work.
209 #define _MODULE( name, desc, \
210 intype, outtype, chans, preamble, action, postamble )\
211 static void name##run(_AFchunk *inc, _AFchunk *outc, void *modspec)\
213 intype *ip = inc->buf;\
214 outtype *op = outc->buf;\
215 int count = inc->nframes * (chans);\
216 int i;\
218 preamble;\
219 for(i=0; i < count; ++i) \
220 action;\
221 postamble;\
224 static void name##describe(struct _AFmoduleinst *i)\
226 _AudioFormat *f = &i->outc->f; \
227 desc;\
230 static const _AFmodule name =\
232 #name,\
233 name##describe, \
234 AF_NULL, AF_NULL, \
235 _AFsimplemodrun_pull, AF_NULL, AF_NULL, \
236 _AFsimplemodrun_push, AF_NULL, AF_NULL, \
237 name##run, \
238 _AFfreemodspec \
241 #define MODULE(name, desc, intype, outtype, action)\
242 _MODULE(name, desc, intype, outtype, inc->f.channelCount, \
243 NULLMODULEPARAM, action, NULLMODULEPARAM)
245 #define MODULEM(name, desc, intype, outtype, modspectype, action)\
246 _MODULE(name, desc, intype, outtype, inc->f.channelCount, \
247 modspectype *m = (modspectype *) modspec, action, NULLMODULEPARAM)
250 Byte-order-swapping modules.
253 #define MODULESWAP(name, type, action) \
254 MODULE(name, \
255 f->byteOrder = (f->byteOrder==AF_BYTEORDER_LITTLEENDIAN) ?\
256 AF_BYTEORDER_BIGENDIAN : AF_BYTEORDER_LITTLEENDIAN,\
257 type, type,\
258 action)
260 MODULESWAP(swap2, uchar2,
261 { char3u u; uchar1 c; u.uchar2.s0 = ip[i];
262 c = u.uchar1.c1; u.uchar1.c1 = u.uchar1.c0; u.uchar1.c0 = c;
263 op[i] = u.uchar2.s0; })
265 MODULESWAP(swap3, real_char3,
266 { char3u u; uchar1 c; u.real_char3_low.c3 = ip[i];
267 c = u.uchar1.c3; u.uchar1.c3 = u.uchar1.c1; u.uchar1.c1 = c;
268 op[i] = u.real_char3_low.c3; })
270 MODULESWAP(swap4, uchar4,
271 { char3u u; uchar1 c; u.uchar4.i = ip[i];
272 c = u.uchar1.c3; u.uchar1.c3 = u.uchar1.c0; u.uchar1.c0 = c;
273 c = u.uchar1.c1; u.uchar1.c1 = u.uchar1.c2; u.uchar1.c2 = c;
274 op[i] = u.uchar4.i; })
276 MODULESWAP(swap8, real_char8,
277 { real_char8 *i8 = &ip[i]; real_char8 *o8 = &op[i];
278 o8->c0 = i8->c7;
279 o8->c1 = i8->c6;
280 o8->c2 = i8->c5;
281 o8->c3 = i8->c4;
282 o8->c4 = i8->c3;
283 o8->c5 = i8->c2;
284 o8->c6 = i8->c1;
285 o8->c7 = i8->c0; })
288 modules for dealing with 3-byte integers
291 /* convert 0xaabbcc to 0xssaabbcc */
292 #ifdef WORDS_BIGENDIAN
293 MODULE(real_char3_to_schar3, f /* NOTUSED */, real_char3, schar3,
295 char3u u;
296 u.real_char3_high.c3 = ip[i];
297 u.real_char3_high.pad = 0;
298 op[i] = u.schar3.i >> 8;
300 #else
301 MODULE(real_char3_to_schar3, f /* NOTUSED */, real_char3, schar3,
303 char3u u;
304 u.real_char3_low.c3 = ip[i];
305 u.real_char3_low.pad = 0;
306 op[i] = u.schar3.i >> 8;
308 #endif
310 /* convert 0xaabbcc to 0x00aabbcc */
311 #ifdef WORDS_BIGENDIAN
312 MODULE(real_char3_to_uchar3, f /* NOTUSED */, real_char3, uchar3,
314 char3u u;
315 u.real_char3_high.c3 = ip[i];
316 u.real_char3_high.pad = 0;
317 op[i] = u.uchar3.i >> 8;
319 #else
320 MODULE(real_char3_to_uchar3, f /* NOTUSED */, real_char3, uchar3,
322 char3u u;
323 u.real_char3_low.c3 = ip[i];
324 u.real_char3_low.pad = 0;
325 op[i] = u.uchar3.i >> 8;
327 #endif
329 /* convert 0x??aabbcc to 0xaabbcc */
330 #ifdef WORDS_BIGENDIAN
331 MODULE(char3_to_real_char3, f /* NOTUSED */, uchar3, real_char3,
333 char3u u;
334 u.uchar3.i = ip[i];
335 op[i] = u.real_char3_low.c3;
337 #else
338 MODULE(char3_to_real_char3, f /* NOTUSED */, uchar3, real_char3,
340 char3u u;
341 u.uchar3.i = ip[i];
342 op[i] = u.real_char3_high.c3;
344 #endif
347 float <--> double ; CASTS
350 MODULE(float2double, f->sampleFormat = AF_SAMPFMT_DOUBLE,
351 float, double, op[i] = ip[i] )
352 MODULE(double2float, f->sampleFormat = AF_SAMPFMT_FLOAT,
353 double, float, op[i] = ip[i] )
356 int2floatN - expects 8N-bit 2's comp ints, outputs floats ; CASTS
359 MODULE(int2float1, f->sampleFormat = AF_SAMPFMT_FLOAT,
360 schar1, float, op[i] = ip[i])
361 MODULE(int2float2, f->sampleFormat = AF_SAMPFMT_FLOAT,
362 schar2, float, op[i] = ip[i])
363 MODULE(int2float3, f->sampleFormat = AF_SAMPFMT_FLOAT,
364 schar3, float, op[i] = ip[i])
365 MODULE(int2float4, f->sampleFormat = AF_SAMPFMT_FLOAT,
366 schar4, float, op[i] = ip[i])
369 int2doubleN - expects 8N-bit 2's comp ints, outputs doubles ; CASTS
372 MODULE(int2double1, f->sampleFormat = AF_SAMPFMT_DOUBLE,
373 schar1, double, op[i] = ip[i])
374 MODULE(int2double2, f->sampleFormat = AF_SAMPFMT_DOUBLE,
375 schar2, double, op[i] = ip[i])
376 MODULE(int2double3, f->sampleFormat = AF_SAMPFMT_DOUBLE,
377 schar3, double, op[i] = ip[i])
378 MODULE(int2double4, f->sampleFormat = AF_SAMPFMT_DOUBLE,
379 schar4, double, op[i] = ip[i])
382 The following modules perform the transformation between one
383 pcm mapping and another.
385 The modules all use MODULETRANS; some of them also perform
386 clipping.
388 Use initpcmmod() to create an instance of any of these modules.
389 initpcmmod() takes an _PCMInfo describing the desired output
390 pcm mapping.
393 typedef struct pcmmodspec
395 /* These are the computed parameters of the transformation. */
396 double m, b;
397 double maxv, minv;
399 /* This is what goes in i->outc->f. */
400 _PCMInfo output_mapping;
401 } pcmmodspec;
404 initpcmmod
406 static _AFmoduleinst initpcmmod (const _AFmodule *mod,
407 _PCMInfo *input_mapping, _PCMInfo *output_mapping)
409 _AFmoduleinst ret = _AFnewmodinst(mod);
410 pcmmodspec *m = _af_malloc(sizeof (pcmmodspec));
411 ret.modspec = m;
413 /* Remember output mapping for use in the describe function. */
414 m->output_mapping = *output_mapping;
417 Compute values needed to perform transformation if the module
418 being initialized does a transformation..
420 if (input_mapping)
422 m->m = output_mapping->slope / input_mapping->slope;
423 m->b = output_mapping->intercept - m->m * input_mapping->intercept;
426 /* Remember clip values. */
427 m->minv = output_mapping->minClip;
428 m->maxv = output_mapping->maxClip;
429 return ret;
432 #define MODULETRANS( name, xtradesc, intype, outtype, action ) \
433 MODULEM(name, \
435 f->pcm = ((pcmmodspec *) i->modspec)->output_mapping; \
436 xtradesc; \
437 }, \
438 intype, outtype, pcmmodspec, \
439 action)
442 MODULETRANS(floattransform, NULLMODULEPARAM, float, float, \
443 op[i]=(m->b + m->m * ip[i]))
444 MODULETRANS(doubletransform, NULLMODULEPARAM, double, double, \
445 op[i]=(m->b + m->m * ip[i]))
448 float2intN_clip - expects floats,
449 outputs CLIPped, 8N-bit, transformed 2's comp ints
450 double2intN_clip - same deal with doubles
453 #define TRANS_CLIP(type) \
455 double d=(m->b + m->m * ip[i]); \
456 op[i] = \
457 (((type)((d>(m->maxv)) ? (m->maxv) : ((d<(m->minv))?(m->minv):d)))); \
460 MODULETRANS(float2int1_clip,
461 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 8; },
462 float, schar1, TRANS_CLIP(schar1))
463 MODULETRANS(float2int2_clip,
464 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 16; },
465 float, schar2, TRANS_CLIP(schar2))
466 MODULETRANS(float2int3_clip,
467 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 24; },
468 float, schar3, TRANS_CLIP(schar3))
469 MODULETRANS(float2int4_clip,
470 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 32; },
471 float, schar4, TRANS_CLIP(schar4))
473 MODULETRANS(double2int1_clip,
474 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 8; },
475 double, schar1, TRANS_CLIP(schar1))
476 MODULETRANS(double2int2_clip,
477 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 16; },
478 double, schar2, TRANS_CLIP(schar2))
479 MODULETRANS(double2int3_clip,
480 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 24; },
481 double, schar3, TRANS_CLIP(schar3))
482 MODULETRANS(double2int4_clip,
483 { f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 32; },
484 double, schar4, TRANS_CLIP(schar4))
487 clipping modules - use initpcmmod() to make one of these
489 clips to range given as argument to init function.
492 #define MODULECLIP(name, type)\
493 MODULEM(name, \
494 { f->pcm = ((pcmmodspec *)i->modspec)->output_mapping; }, \
495 type, type, pcmmodspec, \
497 type d=ip[i]; \
498 type min=(type)(m->minv); \
499 type max=(type)(m->maxv); \
500 op[i] = ((d>max) ? max : ((d<min) ? min : d)); \
503 MODULECLIP(clipfloat, float)
504 MODULECLIP(clipdouble, double)
505 MODULECLIP(clip1, schar1)
506 MODULECLIP(clip2, schar2)
507 MODULECLIP(clip3, schar3)
508 MODULECLIP(clip4, schar4)
511 unsigned2signedN - expects 8N-bit unsigned ints, outputs 2's comp
514 MODULE(unsigned2signed1,
516 double shift = (double) MIN_INT8;
517 f->sampleFormat = AF_SAMPFMT_TWOSCOMP;
518 f->pcm.intercept += shift;
519 f->pcm.minClip += shift;
520 f->pcm.maxClip += shift;
522 uchar1, schar1,
523 op[i] = ip[i] + MIN_INT8)
524 MODULE(unsigned2signed2,
526 double shift = (double) MIN_INT16;
527 f->sampleFormat = AF_SAMPFMT_TWOSCOMP;
528 f->pcm.intercept += shift;
529 f->pcm.minClip += shift;
530 f->pcm.maxClip += shift;
532 uchar2, schar2,
533 op[i] = ip[i] + MIN_INT16)
534 MODULE(unsigned2signed3,
536 double shift = (double) MIN_INT24;
537 f->sampleFormat = AF_SAMPFMT_TWOSCOMP;
538 f->pcm.intercept += shift;
539 f->pcm.minClip += shift;
540 f->pcm.maxClip += shift;
542 uchar3, schar3,
543 op[i] = ip[i] + MIN_INT24)
544 MODULE(unsigned2signed4,
546 double shift = (double) MIN_INT32;
547 f->sampleFormat = AF_SAMPFMT_TWOSCOMP;
548 f->pcm.intercept += shift;
549 f->pcm.minClip += shift;
550 f->pcm.maxClip += shift;
552 uchar4, schar4,
553 op[i] = ip[i] + MIN_INT32)
555 /* !! unsigned2signed4 shouldn't work, but it does !! */
559 signed2unsignedN - expects 8N-bit 2's comp ints, outputs unsigned
562 MODULE(signed2unsigned1,
564 double shift = -(double) MIN_INT8;
565 f->sampleFormat = AF_SAMPFMT_UNSIGNED;
566 f->pcm.intercept += shift;
567 f->pcm.minClip += shift;
568 f->pcm.maxClip += shift;
570 schar1, uchar1,
571 op[i] = ip[i] - MIN_INT8)
572 MODULE(signed2unsigned2,
574 double shift = -(double) MIN_INT16;
575 f->sampleFormat = AF_SAMPFMT_UNSIGNED;
576 f->pcm.intercept += shift;
577 f->pcm.minClip += shift;
578 f->pcm.maxClip += shift;
580 schar2, uchar2,
581 op[i] = ip[i] - MIN_INT16)
582 MODULE(signed2unsigned3,
584 double shift = -(double) MIN_INT24;
585 f->sampleFormat = AF_SAMPFMT_UNSIGNED;
586 f->pcm.intercept += shift;
587 f->pcm.minClip += shift;
588 f->pcm.maxClip += shift;
590 schar3, uchar3,
591 op[i] = ip[i] - MIN_INT24)
592 MODULE(signed2unsigned4,
594 double shift = -(double) MIN_INT32;
595 f->sampleFormat = AF_SAMPFMT_UNSIGNED;
596 f->pcm.intercept += shift;
597 f->pcm.minClip += shift;
598 f->pcm.maxClip += shift;
600 schar4, uchar4,
601 op[i] = ip[i] - MIN_INT32)
603 /* !! signed2unsigned4 shouldn't work, but it does !! */
607 These convert between different 2's complement integer formats
608 with no roundoff/asymmetric errors. They should also work faster
609 than converting integers to floats and back to other integers.
611 They are only meant to be used when the input and output integers
612 have the default PCM mapping; otherwise, arrangemodules will
613 make the conversion go through floating point and these modules
614 will not be used.
617 #define intmap _af_default_signed_integer_pcm_mappings /* shorthand */
619 MODULE(int1_2, { f->sampleWidth = 16; f->pcm=intmap[2]; },
620 schar1, schar2, op[i] = ip[i] << 8)
621 MODULE(int1_3, { f->sampleWidth = 24; f->pcm=intmap[3]; },
622 schar1, schar3, op[i] = ip[i] << 16)
623 MODULE(int1_4, { f->sampleWidth = 32; f->pcm=intmap[4]; },
624 schar1, schar4, op[i] = ip[i] << 24)
626 MODULE(int2_1, { f->sampleWidth = 8; f->pcm=intmap[1]; },
627 schar2, schar1, op[i] = ip[i] >> 8)
628 MODULE(int2_3, { f->sampleWidth = 24; f->pcm=intmap[3]; },
629 schar2, schar3, op[i] = ip[i] << 8)
630 MODULE(int2_4, { f->sampleWidth = 32; f->pcm=intmap[4]; },
631 schar2, schar4, op[i] = ip[i] << 16)
633 MODULE(int3_1, { f->sampleWidth = 8; f->pcm=intmap[1]; },
634 schar3, schar1, op[i] = ip[i] >> 16)
635 MODULE(int3_2, { f->sampleWidth = 16; f->pcm=intmap[2]; },
636 schar3, schar2, op[i] = ip[i] >> 8)
637 MODULE(int3_4, { f->sampleWidth = 32; f->pcm=intmap[4]; },
638 schar3, schar4, op[i] = ip[i] << 8)
640 MODULE(int4_1, { f->sampleWidth = 8; f->pcm=intmap[1]; },
641 schar4, schar1, op[i] = ip[i] >> 24)
642 MODULE(int4_2, { f->sampleWidth = 16; f->pcm=intmap[2]; },
643 schar4, schar2, op[i] = ip[i] >> 16)
644 MODULE(int4_3, { f->sampleWidth = 24; f->pcm=intmap[3]; },
645 schar4, schar3, op[i] = ip[i] >> 8)
647 #undef intmap
650 channel changer modules - convert channels using channel matrix
652 The channel matrix is a two-dimensional array of doubles, the rows
653 of which correspond to the virtual format, and the columns
654 of which correspond to the file format.
656 If the channel matrix is null (unspecified), then the default
657 behavior occurs (see initchannelchange).
659 Internally, the module holds a copy of the matrix in which the
660 rows correspond to the output format, and the columns correspond
661 to the input format (therefore, if reading==false, the matrix
662 is transposed as it is copied).
665 typedef struct channelchangedata
667 int outchannels;
668 double minClip;
669 double maxClip;
670 double *matrix;
671 } channelchangedata;
674 channelchangefree
676 static void channelchangefree (struct _AFmoduleinst *i)
678 channelchangedata *d = i->modspec;
680 assert(d);
681 assert(d->matrix);
683 free(d->matrix);
684 free(d);
686 i->modspec = AF_NULL;
690 channelchangedescribe
692 static void channelchangedescribe (struct _AFmoduleinst *i)
694 channelchangedata *m = (channelchangedata *) i->modspec;
695 i->outc->f.channelCount = m->outchannels;
696 i->outc->f.pcm.minClip = m->minClip;
697 i->outc->f.pcm.maxClip = m->maxClip;
700 #define CHANNELMOD( name, type, zero_op, action, afteraction ) \
701 static void name##run(_AFchunk *inc, _AFchunk *outc, void *modspec) \
703 type *ip = inc->buf; \
704 type *op = outc->buf; \
705 double *matrix = ((channelchangedata *)modspec)->matrix; \
706 double *m; \
707 int frame, inch, outch; \
709 for (frame=0; frame < outc->nframes; frame++) \
711 type *ipsave; \
713 m = matrix; \
714 ipsave = ip; \
716 for (outch = 0; outch < outc->f.channelCount; outch++) \
718 zero_op; \
719 ip = ipsave; \
721 for (inch = 0; inch < inc->f.channelCount; inch++) \
722 action;\
724 afteraction; \
725 op++;\
730 static const _AFmodule name =\
732 #name, \
733 channelchangedescribe, \
734 AF_NULL, AF_NULL, \
735 _AFsimplemodrun_pull, AF_NULL, AF_NULL, \
736 _AFsimplemodrun_push, AF_NULL, AF_NULL, \
737 name##run, \
738 channelchangefree \
741 CHANNELMOD(channelchangefloat, float, *op = 0.0, *op += *ip++ * *m++, \
742 NULLMODULEPARAM)
743 CHANNELMOD(channelchangedouble, double, *op = 0.0, *op += *ip++ * *m++, \
744 NULLMODULEPARAM)
746 #define CHANNELINTMOD(name, type) \
747 CHANNELMOD(name, type, \
748 double d=0.0, \
749 d += *ip++ * *m++, \
751 double minv=outc->f.pcm.minClip; \
752 double maxv=outc->f.pcm.maxClip; \
753 *op = (type) ((d>maxv) ? maxv : ((d<minv) ? minv : d)); \
756 CHANNELINTMOD(channelchange1, schar1)
757 CHANNELINTMOD(channelchange2, schar2)
758 CHANNELINTMOD(channelchange3, schar3)
759 CHANNELINTMOD(channelchange4, schar4)
762 initchannelchange
764 static _AFmoduleinst initchannelchange (const _AFmodule *mod,
765 double *matrix, _PCMInfo *outpcm,
766 int inchannels, int outchannels,
767 bool reading)
769 _AFmoduleinst ret;
770 channelchangedata *d;
771 int i, j;
773 ret = _AFnewmodinst(mod);
775 d = _af_malloc(sizeof (channelchangedata));
776 ret.modspec = d;
777 d->outchannels = outchannels;
778 d->minClip = outpcm->minClip;
779 d->maxClip = outpcm->maxClip;
780 d->matrix = _af_malloc(sizeof (double) * inchannels * outchannels);
783 Set d->matrix to a default matrix if a matrix was not specified.
785 if (!matrix)
787 bool special=false;
789 /* Handle many common special cases. */
791 if (inchannels==1 && outchannels==2)
793 static double m[]={1,1};
794 matrix=m;
795 special=true;
797 else if (inchannels==1 && outchannels==4)
799 static double m[]={1,1,0,0};
800 matrix=m;
801 special=true;
803 else if (inchannels==2 && outchannels==1)
805 static double m[]={.5,.5};
806 matrix=m;
807 special=true;
809 else if (inchannels==2 && outchannels==4)
811 static double m[]={1,0,0,1,0,0,0,0};
812 matrix=m;
813 special=true;
815 else if (inchannels==4 && outchannels==1)
817 static double m[]={.5,.5,.5,.5};
818 matrix=m;
819 special=true;
821 else if (inchannels==4 && outchannels==2)
823 static double m[]={1,0,1,0,0,1,0,1};
824 matrix=m;
825 special=true;
827 else
830 Each input channel from 1 to N
831 maps to output channel 1 to N where
832 N=min(inchannels, outchannels).
835 for(i=0; i < inchannels; i++)
836 for(j=0; j < outchannels; j++)
837 d->matrix[j*inchannels + i] =
838 (i==j) ? 1.0 : 0.0;
841 if (special)
842 memcpy(d->matrix, matrix,
843 sizeof (double) * inchannels * outchannels);
845 /* Otherwise transfer matrix into d->matrix. */
846 else
848 /* reading: copy matrix */
849 if (reading)
851 memcpy(d->matrix, matrix, sizeof (double) * inchannels * outchannels);
853 /* writing: transpose matrix */
854 else
856 for (i=0; i < inchannels; i++)
857 for (j=0; j < outchannels; j++)
858 d->matrix[j*inchannels + i] =
859 matrix[i*outchannels + j];
863 DEBG(printf("channelchange d->matrix="));
864 DEBG(_af_print_channel_matrix(d->matrix, inchannels, outchannels));
865 DEBG(printf("\n"));
867 return(ret);
870 /* just used here */
871 typedef struct current_state
873 _AFmoduleinst *modinst; /* current mod instance we're creating */
874 _AFchunk *inchunk; /* current input chunk */
875 _AFchunk *outchunk; /* current output chunk */
876 } current_state;
879 addmod is called once per added module instance. It does the
880 work of putting the module instance in the list and assigning
881 it an input and output chunk.
883 static void addmod (current_state *current, _AFmoduleinst modinst)
885 *(current->modinst) = modinst;
886 current->modinst->valid = true; /* at this point mod must be valid */
888 /* Assign the new module instance an input and an output chunk. */
890 current->modinst->inc = current->inchunk;
891 current->modinst->outc = current->outchunk;
894 The output chunk has the same format and number of frames
895 as input chunk, except in whatever way the 'describe'
896 method tells us (see README.modules).
899 *(current->outchunk) = *(current->inchunk);
901 if (current->modinst->mod->describe)
902 (*current->modinst->mod->describe)(current->modinst);
905 Advance to next module and next chunks. Note that next
906 moduleinst will have this module's out chunk as input.
909 current->modinst++;
910 current->inchunk = current->outchunk;
911 current->outchunk++;
915 initfilemods:
917 Functions that deal with extended-lifetime file read / file write
918 modules and their extended-lifetime rebuffer modules.
919 called once in the lifetime of an AFfilehandle.
921 If h->access == _AF_READ_ACCESS:
923 Create the module which will be the first module in the chain,
924 the one which reads the file. This module does the decompression
925 if necessary, or it could just be a PCM file reader.
927 If h->access == _AF_WRITE_ACCESS:
929 Create the module which will be the last module in the chain,
930 the one which writes the file. This module does the compression
931 if necessary, or it could just be a PCM file writer.
933 Also creates a rebuffer module for these modules if necessary.
935 static status initfilemods (_Track *track, AFfilehandle h)
937 int compressionIndex;
938 _CompressionUnit *compunit;
939 AFframecount chunkframes;
941 compressionIndex = _af_compression_index_from_id(track->f.compressionType);
942 compunit = &_af_compression[compressionIndex];
944 /* Invalidate everything. */
946 track->ms.filemodinst.valid = false;
947 track->ms.filemod_rebufferinst.valid = false;
950 Seek to beginning of sound data in the track.
952 This is needed ONLY for those modules which have to
953 read/write some kind of pre-data header or table in the
954 sound data chunk of the file (such as aware). This is NOT
955 the seek that sets the file at the beginning of the data.
957 /* XXXmpruett -- we currently don't set seekok.
958 if (h->seekok && af_fseek(h->fh, track->fpos_first_frame, SEEK_SET) < 0)
960 if (af_fseek(h->fh, track->fpos_first_frame, SEEK_SET) < 0)
962 _af_error(AF_BAD_LSEEK, "unable to position file handle at beginning of sound data");
963 return AF_FAIL;
966 /* Create file read/write module. */
968 track->filemodhappy = true;
970 if (h->access == _AF_READ_ACCESS)
971 track->ms.filemodinst =
972 (*compunit->initdecompress)(track, h->fh, h->seekok,
973 (h->fileFormat==AF_FILE_RAWDATA), &chunkframes);
974 else
975 track->ms.filemodinst =
976 (*compunit->initcompress)(track, h->fh, h->seekok,
977 (h->fileFormat==AF_FILE_RAWDATA), &chunkframes);
979 if (!track->filemodhappy)
980 return AF_FAIL;
982 track->ms.filemodinst.valid = true;
985 WHEN DOES THE FILE GET LSEEKED ?
987 Somebody sometime has got to lseek the file to the
988 beginning of the audio data. Similarly, somebody
989 has to lseek the file at the time of reset or sync.
990 Furthermore, we have to make sure that we operate
991 correctly if more than one track is being read or written.
992 This is handled differently based on whether we are
993 reading or writing, and whether the ONE_TRACK_ONLY lseek
994 optimization is engaged.
996 READING:
998 If we are reading, the file needs to be positioned once
999 before we start reading and then once per seek.
1001 If ONE_TRACK_ONLY is not defined, then there can
1002 be multiple tracks in the file. Thus any call to
1003 afReadFrames could cause the file pointer to be
1004 put anywhere: we can not rely on the file pointer
1005 tracking only one track in the file, thus we must seek
1006 to the current position in track N whenever we begin
1007 an AFreadframes on track N. Thus the lseek is done in
1008 afReadFrames. When a reset occurs (including the initial
1009 one), we merely set trk->fpos_next_frame, and the next
1010 afReadFrames will seek the file there before proceeding.
1012 If ONE_TRACK_ONLY is defined, meaning there can only
1013 be 1 track in the file, we do not need to ever seek
1014 during normal sequential operation, because the file
1015 read module is the only module which ever accesses the
1016 file after _afOpenFile returns. In this case, we do
1017 not need to do the expensive lseek at the beginning of
1018 every AFreadframes call. We need only seek once when the
1019 file is first opened and once when the file is seeked.
1020 At both of these times, we reset the modules. So we
1021 can do the lseek in resetmodules() right after it has
1022 called all of the modules' reset2 methods.
1024 WRITING:
1026 If we are writing, the file needs to be positioned once
1027 before we start writing and it needs to be positioned
1028 after every complete sync operation on the file.
1030 If ONE_TRACK_ONLY is not defined, then there can be
1031 multiple tracks in the file. This assumes space for
1032 the tracks has been preallocated. Thus any call to
1033 AFwriteframes could cause the file pointer to be
1034 put anywhere: we can not rely on the file pointer
1035 tracking only one track in the file, thus we must seek
1036 to the current position in track n whenever we begin
1037 an AFwriteframes on track n. Thus the lseek is done
1038 in AFwriteframes. When we first start, and when a sync
1039 occurs, we merely set trk->fpos_next_frame, and the next
1040 AFwriteframes will seek the file there before proceeding.
1042 If ONE_TRACK_ONLY is defined, meaning there can only
1043 be 1 track in the file, we do not need to ever seek
1044 during normal sequential operation, because the file
1045 write module is the only module which ever accesses
1046 the file after _AFopenfile returns. In this case, we
1047 do not need to do the expensive lseek at the beginning
1048 of every AFwriteframes call. We can do the lseek for
1049 the initial case right here (that's what you see below),
1050 and we can do the lseek for syncs in _AFsyncmodules right
1051 after it has called all of the modules' sync2 methods.
1053 One annoying exceptional case is _AFeditrate, which
1054 can get called at any time. But it saves and restores
1055 the file position at its beginning and end, so it's
1056 no problem.
1058 WHY THE F(*#&@ DON'T YOU JUST HAVE MULTIPLE FILE DESCRIPTORS?
1060 The obviously and blatantly better way to do this would be
1061 to simply open one fd per track and then all the problems
1062 go away! Too bad we offer afOpenFD() in the API, which
1063 makes it impossible for the AF to get more than 1 fd
1064 for the file. afOpenFD() is unfortunately used far
1065 more often than afOpenFile(), so the benefit of doing
1066 the optimization the "right" way in the cases where
1067 afOpenFile() are used are not currently too great.
1068 But one day we will have to phase out afOpenFD().
1069 Too bad, it seemed like such a great idea when we put
1070 it in.
1073 #ifdef ONE_TRACK_ONLY
1074 if (h->access == _AF_WRITE_ACCESS)
1076 if (h->seekok && af_fseek(h->fh, track->fpos_next_frame, SEEK_SET) < 0)
1078 _af_error(AF_BAD_LSEEK,
1079 "unable to position write ptr at first data frame");
1080 return AF_FAIL;
1083 #endif
1085 /* Create its rebuffer module. */
1087 if (compunit->needsRebuffer)
1089 /* We assume the following for now. */
1090 assert(compunit->nativeSampleFormat == AF_SAMPFMT_TWOSCOMP);
1091 assert(compunit->nativeSampleWidth == 16);
1093 if (h->access == _AF_WRITE_ACCESS)
1094 track->ms.filemod_rebufferinst =
1095 _af_initint2rebufferv2f(chunkframes*track->f.channelCount,
1096 compunit->multiple_of);
1097 else
1098 track->ms.filemod_rebufferinst =
1099 _af_initint2rebufferf2v(chunkframes*track->f.channelCount,
1100 compunit->multiple_of);
1102 track->ms.filemod_rebufferinst.valid = true;
1104 else
1105 track->ms.filemod_rebufferinst.valid = false;
1108 These modules should not get freed until the file handle
1109 is destroyed (i.e. the file is closed).
1112 track->ms.filemodinst.free_on_close = true;
1113 track->ms.filemod_rebufferinst.free_on_close = true;
1115 return AF_SUCCEED;
1119 addfilereadmods: called once per setup of the modules
1120 for a given AFfilehandle
1122 static status addfilereadmods (current_state *current, _Track *track,
1123 AFfilehandle h)
1125 assert(track->ms.filemodinst.valid);
1127 /* Fail in case code is broken and NDEBUG is defined. */
1128 if (!track->ms.filemodinst.valid)
1129 return AF_FAIL;
1131 addmod(current, track->ms.filemodinst);
1132 if (track->ms.filemod_rebufferinst.valid)
1133 addmod(current, track->ms.filemod_rebufferinst);
1135 return AF_SUCCEED;
1139 addfilewritemods is called once per setup of the modules
1140 for a given AFfilehandle.
1142 static status addfilewritemods (current_state *current, _Track *track,
1143 AFfilehandle h)
1145 assert(track->ms.filemodinst.valid);
1147 /* Fail in case code is broken and NDEBUG is defined. */
1148 if (!track->ms.filemodinst.valid)
1149 return(AF_FAIL);
1151 if (track->ms.filemod_rebufferinst.valid)
1152 addmod(current, track->ms.filemod_rebufferinst);
1154 addmod(current, track->ms.filemodinst);
1156 return(AF_SUCCEED);
1160 disposefilemods: called once in the lifetime of an AFfilehandle
1162 static status disposefilemods (_Track *track)
1164 if (track->ms.filemodinst.valid &&
1165 track->ms.filemodinst.mod->free)
1166 (*track->ms.filemodinst.mod->free)(&track->ms.filemodinst);
1168 track->ms.filemodinst.valid = false;
1170 if (track->ms.filemod_rebufferinst.valid &&
1171 track->ms.filemod_rebufferinst.mod->free)
1172 (*track->ms.filemod_rebufferinst.mod->free)(&track->ms.filemod_rebufferinst);
1174 track->ms.filemod_rebufferinst.valid = false;
1176 return AF_SUCCEED;
1180 useAP: rate conversion AP decision maker and warner and kludger
1182 static bool useAP (double inrate, double outrate,
1183 double *inratep, double *outratep)
1185 bool instandard =
1186 (inrate==8000 || inrate==11025 || inrate==16000 ||
1187 inrate==22050 || inrate==32000 || inrate==44100 ||
1188 inrate==48000);
1189 bool outstandard =
1190 (outrate==8000 || outrate==11025 || outrate==16000 ||
1191 outrate==22050 || outrate==32000 || outrate==44100 ||
1192 outrate==48000);
1193 bool incodec;
1194 bool outcodec;
1196 incodec = (inrate==_AF_SRATE_CODEC || inrate==(long)_AF_SRATE_CODEC);
1197 outcodec = (outrate==_AF_SRATE_CODEC || outrate==(long)_AF_SRATE_CODEC);
1199 *inratep = inrate;
1200 *outratep = outrate;
1202 if (instandard && outstandard) return true;
1203 if (incodec && outstandard && outrate != 8000.00)
1205 _af_error(AF_WARNING_CODEC_RATE,
1206 "WARNING using input rate 8 kHz instead of %.30g Hz "
1207 "to allow high-quality rate conversion",
1208 inrate);
1209 *inratep = 8000.00;
1210 return true;
1212 if (instandard && inrate != 8000.00 && outcodec)
1214 _af_error(AF_WARNING_CODEC_RATE,
1215 "WARNING using output rate 8 kHz instead of %.30g Hz "
1216 "to allow high-quality rate conversion",
1217 outrate);
1218 *outratep = 8000.00;
1219 return true;
1222 if (!instandard && !outstandard)
1223 _af_error(AF_WARNING_RATECVT,
1224 "WARNING using lower quality rate conversion due to "
1225 "rates %.30g and %.30g -- "
1226 "output file may contain audible artifacts",
1227 inrate, outrate);
1228 else if (!instandard)
1229 _af_error(AF_WARNING_RATECVT,
1230 "WARNING using lower quality rate conversion due to "
1231 "input rate %.30g -- "
1232 "output file may contain audible artifacts",
1233 inrate);
1234 else /* !outstandard */
1235 _af_error(AF_WARNING_RATECVT,
1236 "WARNING using lower quality rate conversion due to "
1237 "output rate %.30g -- "
1238 "output file may contain audible artifacts",
1239 outrate);
1241 return false;
1245 initrateconvertmods handles the extended-life rate conversion
1246 module and its extended-life rebuffer module called once in the
1247 lifetime of an AFfilehandle.
1249 static void initrateconvertmods (bool reading, _Track *track)
1251 /* no rate conversion initially */
1252 track->ms.rateconvertinst.valid = false;
1253 track->ms.rateconvert_rebufferinst.valid = false;
1256 static void disposerateconvertmods (_Track *);
1258 /* XXXmpruett rate conversion is disabled for now */
1259 #if 0
1261 addrateconvertmods: called once per setup of the modules
1262 for a given AFfilehandle
1264 static void addrateconvertmods (current_state *current, int nchannels,
1265 double inrate, double outrate,
1266 bool reading, _Track *track)
1268 AFframecount inframes, outframes;
1270 /* Check if we are no longer rate converting. */
1271 if (inrate == outrate)
1273 disposerateconvertmods(track);
1274 track->ratecvt_filter_params_set = false; /* XXX HACK */
1276 else
1279 We need new rateconverter if we didn't have one
1280 or if rate has changed or rate conversion params
1281 have changed.
1283 if (!track->ms.rateconvertinst.valid ||
1284 inrate != track->ms.rateconvert_inrate ||
1285 outrate != track->ms.rateconvert_outrate ||
1286 track->ratecvt_filter_params_set /* HACK */)
1288 bool usingAP = useAP(inrate, outrate, &inrate, &outrate);
1290 disposerateconvertmods(track);
1291 track->ratecvt_filter_params_set = false; /* HACK */
1293 if (usingAP)
1295 track->ms.rateconvertinst = InitAFRateConvert(inrate, outrate,
1296 nchannels,
1297 track->taper, track->dynamic_range,
1298 &inframes, &outframes,
1299 track, reading);
1301 if (!reading)
1302 track->ms.rateconvert_rebufferinst =
1303 initfloatrebufferv2f(inframes*nchannels, false);
1304 else
1305 track->ms.rateconvert_rebufferinst =
1306 initfloatrebufferf2v(outframes*nchannels, false);
1308 track->ms.rateconvertinst.valid = true;
1309 track->ms.rateconvert_rebufferinst.valid = true;
1311 else
1313 track->ms.rateconvertinst = initpolyratecvt(track,
1314 inrate, outrate,
1315 nchannels, reading);
1317 track->ms.rateconvertinst.valid = true;
1318 track->ms.rateconvert_rebufferinst.valid = false;
1321 track->ms.rateconvert_inrate = inrate;
1322 track->ms.rateconvert_outrate = outrate;
1324 track->ms.rateconvertinst.free_on_close = true;
1325 track->ms.rateconvert_rebufferinst.free_on_close = true;
1328 /* Add the rate conversion modules. */
1330 if (!reading && track->ms.rateconvert_rebufferinst.valid)
1331 addmod(current, track->ms.rateconvert_rebufferinst);
1333 addmod(current, track->ms.rateconvertinst);
1335 if (reading && track->ms.rateconvert_rebufferinst.valid)
1336 addmod(current, track->ms.rateconvert_rebufferinst);
1341 disposerateconvertmods is called once in the lifetime of an
1342 AFfilehandle.
1344 static void disposerateconvertmods (_Track *track)
1347 Neither module is necessarily valid--there could have been
1348 an error, or the modules could possibly never have been set up.
1350 if (track->ms.rateconvertinst.valid &&
1351 track->ms.rateconvertinst.mod->free)
1353 (*track->ms.rateconvertinst.mod->free)
1354 (&track->ms.rateconvertinst);
1357 track->ms.rateconvertinst.valid = false;
1359 if (track->ms.rateconvert_rebufferinst.valid &&
1360 track->ms.rateconvert_rebufferinst.mod->free)
1362 (*track->ms.rateconvert_rebufferinst.mod->free)
1363 (&track->ms.rateconvert_rebufferinst);
1366 track->ms.rateconvert_rebufferinst.valid = false;
1368 #endif /* XXXmpruett rate conversion is disabled for now */
1370 /* -------------------------------------------------------------- */
1372 /* The stuff in this section is used by arrangemodules(). */
1374 static const _AFmodule * const unsigned2signed[5] =
1376 NULL,
1377 &unsigned2signed1, &unsigned2signed2,
1378 &unsigned2signed3, &unsigned2signed4
1381 static const _AFmodule * const signed2unsigned[5] =
1383 NULL,
1384 &signed2unsigned1, &signed2unsigned2,
1385 &signed2unsigned3, &signed2unsigned4
1388 static const _AFmodule * const swapbytes[9] =
1390 NULL, NULL, &swap2, &swap3, &swap4,
1391 NULL, NULL, NULL, &swap8
1394 /* don't forget int24_fmt is really 24 bits right-justified in 32 bits */
1396 typedef enum format_code
1398 int8_fmt,
1399 int16_fmt,
1400 int24_fmt,
1401 int32_fmt,
1402 float_fmt,
1403 double_fmt
1404 } format_code;
1406 #define isinteger(fc) ((fc) <= int32_fmt)
1407 #define isfloating(fc) ((fc) >= float_fmt)
1410 get_format_code
1412 static format_code get_format_code (_AudioFormat *fmt)
1414 if (fmt->sampleFormat == AF_SAMPFMT_FLOAT)
1415 return float_fmt;
1416 if (fmt->sampleFormat == AF_SAMPFMT_DOUBLE)
1417 return double_fmt;
1419 if (fmt->sampleFormat == AF_SAMPFMT_TWOSCOMP ||
1420 fmt->sampleFormat == AF_SAMPFMT_UNSIGNED)
1422 switch (_af_format_sample_size_uncompressed(fmt, false))
1424 case 1: return int8_fmt;
1425 case 2: return int16_fmt;
1426 case 3: return int24_fmt;
1427 case 4: return int32_fmt;
1431 /* NOTREACHED */
1432 assert(0);
1433 return -1;
1436 static const _AFmodule * const to_flt[6] =
1438 &int2float1, &int2float2, &int2float3, &int2float4,
1439 NULL, &double2float
1442 static const _AFmodule * const to_dbl[6] =
1444 &int2double1, &int2double2, &int2double3, &int2double4,
1445 &float2double, NULL
1448 static const _AFmodule * const clip[6] =
1450 &clip1, &clip2, &clip3, &clip4,
1451 &clipfloat, &clipdouble
1454 static const _AFmodule * const channelchanges[6] =
1456 &channelchange1, &channelchange2, &channelchange3, &channelchange4,
1457 &channelchangefloat, &channelchangedouble
1460 /* indices are of type format_code: matrix[infmtcode][outfmtcode] */
1461 static const _AFmodule * const convertmatrix[6][6] =
1463 /* TO:
1465 int8_fmt, int16_fmt,
1466 int24_fmt, int32_fmt,
1467 float_fmt, double_fmt
1471 /* FROM int8_fmt */
1473 NULL, &int1_2,
1474 &int1_3, &int1_4,
1475 &int2float1, &int2double1
1478 /* FROM int16_fmt */
1480 &int2_1, NULL,
1481 &int2_3, &int2_4,
1482 &int2float2, &int2double2
1485 /* FROM int24_fmt */
1487 &int3_1, &int3_2,
1488 NULL, &int3_4,
1489 &int2float3, &int2double3
1492 /* FROM int32_fmt */
1494 &int4_1, &int4_2,
1495 &int4_3, NULL,
1496 &int2float4, &int2double4
1499 /* FROM float_fmt */
1501 &float2int1_clip, &float2int2_clip,
1502 &float2int3_clip, &float2int4_clip,
1503 NULL, &float2double
1506 /* FROM double_fmt */
1508 &double2int1_clip, &double2int2_clip,
1509 &double2int3_clip, &double2int4_clip,
1510 &double2float, NULL
1514 static const _PCMInfo *intmappings[6] =
1516 &_af_default_signed_integer_pcm_mappings[1],
1517 &_af_default_signed_integer_pcm_mappings[2],
1518 &_af_default_signed_integer_pcm_mappings[3],
1519 &_af_default_signed_integer_pcm_mappings[4],
1520 AF_NULL, AF_NULL
1524 trivial_int_clip
1526 static bool trivial_int_clip (_AudioFormat *f, format_code code)
1528 return (intmappings[code] != NULL &&
1529 f->pcm.minClip == intmappings[code]->minClip &&
1530 f->pcm.maxClip == intmappings[code]->maxClip);
1534 trivial_int_mapping
1536 static bool trivial_int_mapping (_AudioFormat *f, format_code code)
1538 return (intmappings[code] != NULL &&
1539 f->pcm.slope == intmappings[code]->slope &&
1540 f->pcm.intercept == intmappings[code]->intercept);
1544 arrangemodules decides which modules to use and creates instances
1545 of them.
1547 static status arrangemodules (_AFfilehandle *h, _Track *track)
1549 bool reading = (h->access == _AF_READ_ACCESS);
1551 current_state current;
1553 bool rateconverting, transforming;
1554 bool already_clipped_output, already_transformed_output;
1556 int insampbytes, outsampbytes;
1557 int chans;
1559 format_code infc, outfc;
1562 in and out are the formats at the start and end of the
1563 chain of modules, respectively.
1566 _AudioFormat in, out;
1568 /* in==FILE, out==virtual (user) */
1569 if (reading)
1571 in = track->f;
1572 out = track->v;
1574 /* in==virtual (user), out==FILE */
1575 else
1577 in = track->v;
1578 out = track->f;
1581 infc = get_format_code(&in);
1582 outfc = get_format_code(&out);
1584 /* flags */
1586 rateconverting = (in.sampleRate != out.sampleRate);
1589 throughout routine:
1591 current.modinst points to current module
1592 current.inchunk points to current in chunk, always outchunk-1
1593 current.outchunk points to current out chunk
1595 The addmod() function does most of the work. It calls the
1596 "describe" module function, during which a module looks
1597 at inc->f and writes the format it will output in outc->f.
1600 current.modinst = track->ms.module;
1602 current.inchunk = track->ms.chunk;
1603 current.outchunk = track->ms.chunk + 1;
1605 current.inchunk->f = in;
1608 max # of modules that could be needed together
1609 may need to change this if you change this function
1611 #define MAX_MODULES 17
1613 /* Actually arrange the modules. Call addmod() to add one. */
1615 /* Add file reader and possibly a decompressor. */
1617 if (reading)
1618 if (AF_FAIL == addfilereadmods(&current, track, h))
1619 return AF_FAIL;
1621 /* Make data native-endian. */
1623 if (in.byteOrder != _AF_BYTEORDER_NATIVE)
1625 int bytes_per_samp = _af_format_sample_size_uncompressed(&in, !reading);
1627 if (bytes_per_samp > 1 &&
1628 in.compressionType == AF_COMPRESSION_NONE)
1630 assert(swapbytes[bytes_per_samp]);
1631 addmod(&current, _AFnewmodinst(swapbytes[bytes_per_samp]));
1633 else
1634 in.byteOrder = _AF_BYTEORDER_NATIVE;
1637 /* Handle nasty 3-byte input cases. */
1639 insampbytes = _af_format_sample_size_uncompressed(&in, false);
1641 if (isinteger(infc) && insampbytes == 3)
1643 if (reading || in.compressionType != AF_COMPRESSION_NONE)
1646 We're reading 3-byte ints from a file.
1647 At this point stretch them to 4-byte ints
1648 by sign-extending or adding a zero-valued
1649 most significant byte. We could also
1650 be reading/writing 3-byte samples output
1651 from a decompressor.
1653 if (in.sampleFormat == AF_SAMPFMT_UNSIGNED)
1654 addmod(&current, _AFnewmodinst(&real_char3_to_uchar3));
1655 else
1656 addmod(&current, _AFnewmodinst(&real_char3_to_schar3));
1658 else /* writing, non-compressed */
1661 We're processing 3-byte ints from the
1662 user, which come in as sign-extended
1663 4-byte quantities. How convenient:
1664 this is what we want.
1669 /* Make data signed. */
1671 if (in.sampleFormat == AF_SAMPFMT_UNSIGNED)
1673 addmod(&current, _AFnewmodinst(unsigned2signed[insampbytes]));
1676 /* Standardize pcm mapping of "in" and "out". */
1679 Since they are used to compute transformations in the
1680 inner section of this routine (inside of sign conversion),
1681 we need in.pcm and out.pcm in terms of AF_SAMPFMT_TWOSCOMP
1682 numbers.
1684 in.pcm = current.inchunk->f.pcm; /* "in" is easy */
1686 if (out.sampleFormat == AF_SAMPFMT_UNSIGNED) /* "out": undo the unsigned shift */
1688 double shift = intmappings[outfc]->minClip;
1689 out.pcm.intercept += shift;
1690 out.pcm.minClip += shift;
1691 out.pcm.maxClip += shift;
1694 /* ------ CLIP user's input samples if necessary */
1696 if (in.pcm.minClip < in.pcm.maxClip && !trivial_int_clip(&in, infc))
1697 addmod(&current, initpcmmod(clip[infc], AF_NULL, &in.pcm));
1700 At this point, we assume we can have doubles, floats,
1701 and 1-, 2-, and 4-byte signed integers on the input and
1702 on the output (or 4-byte integers with 24 significant
1703 (low) bits, int24_fmt).
1705 Now we handle rate conversion and pcm transformation.
1708 /* If rate conversion will happen, we must have floats. */
1710 This may result in loss of precision. This bug must be
1711 fixed eventually.
1713 if (rateconverting && infc != float_fmt)
1715 addmod(&current, _AFnewmodinst(to_flt[infc]));
1716 infc = float_fmt;
1720 We must make sure the output samples will get clipped
1721 to SOMETHING reasonable if we are rateconverting.
1722 The user cannot possibly expect to need to clip values
1723 just because rate conversion is on.
1726 if (out.pcm.minClip >= out.pcm.maxClip && rateconverting)
1728 out.pcm.minClip = out.pcm.intercept - out.pcm.slope;
1729 out.pcm.maxClip = out.pcm.intercept + out.pcm.slope;
1732 already_clipped_output = false;
1733 already_transformed_output = false;
1736 We need to perform a transformation (in floating point)
1737 if the input and output PCM mappings are different.
1739 The only exceptions are the trivial integer conversions
1740 (i.e., full-range integers of one # of bytes to full-range
1741 integers to another # of bytes).
1744 transforming = (in.pcm.slope != out.pcm.slope ||
1745 in.pcm.intercept != out.pcm.intercept) &&
1746 !(trivial_int_mapping(&in, infc) &&
1747 trivial_int_mapping(&out,outfc));
1750 If we have ints on input and the user is performing a
1751 change of mapping other than a trivial one, we must go
1752 to floats or doubles.
1755 if (isinteger(infc) && transforming)
1758 Use doubles if either the in or out format has
1759 that kind of precision.
1761 if (infc == int32_fmt ||
1762 outfc == double_fmt || outfc == int32_fmt)
1764 addmod(&current, _AFnewmodinst(to_dbl[infc]));
1765 infc = double_fmt;
1767 else
1769 addmod(&current, _AFnewmodinst(to_flt[infc]));
1770 infc = float_fmt;
1774 DEBG(printf("arrangemodules in="); _af_print_audioformat(&in););
1775 DEBG(printf("arrangemodules out="); _af_print_audioformat(&out););
1776 DEBG(printf("arrangemodules transforming=%d\n", transforming));
1777 DEBG(printf("arrangemodules infc=%d outfc=%d\n", infc, outfc));
1780 invariant:
1782 At this point, if infc is an integer format, then we are
1783 not rate converting, nor are we perfoming any change of
1784 mapping other than possibly a trivial int->int conversion.
1787 /* ----- convert format infc to format outfc */
1789 /* change channels if appropriate now */
1791 if (in.channelCount != out.channelCount &&
1792 (infc > outfc || (infc==outfc && out.channelCount < in.channelCount)))
1794 addmod(&current,
1795 initchannelchange(channelchanges[infc],
1796 track->channelMatrix, &in.pcm,
1797 in.channelCount, out.channelCount,
1798 reading));
1799 chans = out.channelCount;
1801 else
1802 chans = in.channelCount;
1804 /* Transform floats if appropriate now. */
1806 if (transforming &&
1807 infc==double_fmt && isfloating(outfc))
1809 addmod(&current, initpcmmod(&doubletransform, &in.pcm, &out.pcm));
1812 #if 0 /* XXXmpruett */
1814 Handle rate conversion (will do the right thing if
1815 not rate converting).
1818 addrateconvertmods(&current, chans, in.sampleRate, out.sampleRate, reading, track);
1819 #endif
1821 /* Add format conversion, if needed */
1823 if (convertmatrix[infc][outfc])
1826 for float/double -> int conversions, the module
1827 we use here also does the transformation and
1828 clipping.
1830 We use initpcmmod() in any case because it is harmless
1831 for the other modules in convertmatrix[][].
1833 if (isfloating(infc) && isinteger(outfc)) /* "float"->"int" */
1835 already_clipped_output = true;
1836 already_transformed_output = true;
1838 addmod(&current, initpcmmod(convertmatrix[infc][outfc],
1839 &in.pcm, &out.pcm));
1842 /* Transform floats if appropriate now. */
1844 if (transforming && !already_transformed_output && infc != double_fmt)
1846 if (outfc==double_fmt)
1847 addmod(&current, initpcmmod(&doubletransform,
1848 &in.pcm, &out.pcm));
1849 else if (outfc==float_fmt)
1850 addmod(&current, initpcmmod(&floattransform,
1851 &in.pcm, &out.pcm));
1854 /* Change channels if appropriate now. */
1856 if (in.channelCount != out.channelCount &&
1857 (outfc > infc || (infc==outfc && in.channelCount < out.channelCount)))
1859 addmod(&current,
1860 initchannelchange(channelchanges[outfc],
1861 track->channelMatrix, &out.pcm,
1862 in.channelCount, out.channelCount,
1863 reading));
1866 /* ------ CLIP user's output samples if needed */
1868 if (!already_clipped_output)
1870 if (out.pcm.minClip < out.pcm.maxClip &&
1871 !trivial_int_clip(&out, outfc))
1873 addmod(&current, initpcmmod(clip[outfc], NULL, &out.pcm));
1877 /* Make data unsigned if neccessary. */
1879 outsampbytes = _af_format_sample_size_uncompressed(&out, false);
1881 if (out.sampleFormat == AF_SAMPFMT_UNSIGNED)
1882 addmod(&current, _AFnewmodinst(signed2unsigned[outsampbytes]));
1884 /* Handle nasty 3-byte output cases. */
1886 if (isinteger(outfc) && outsampbytes == 3)
1888 if (!reading || out.compressionType != AF_COMPRESSION_NONE)
1891 We're writing 3-byte ints into a file.
1892 We have 4-byte ints. Squish them to
1893 3 by truncating the high byte off.
1894 we could also be reading/writing ints
1895 into a compressor. note this works for
1896 signed and unsigned, and has to.
1898 addmod(&current, _AFnewmodinst(&char3_to_real_char3));
1900 else /* reading, not compressed */
1903 We're reading 3-byte ints into the
1904 user's buffer.
1906 The user expects
1907 1. 4-byte sign-extended ints (3 bytes
1908 sign extended in 4 bytes) or
1909 2. 4-byte unsigned ints (3 bytes in 4 bytes).
1911 How convenient: this is just what we have.
1916 if (out.byteOrder != _AF_BYTEORDER_NATIVE)
1918 int bytes_per_samp = _af_format_sample_size_uncompressed(&out, reading);
1920 if (bytes_per_samp > 1 && out.compressionType == AF_COMPRESSION_NONE)
1922 assert(swapbytes[bytes_per_samp]);
1923 addmod(&current, _AFnewmodinst(swapbytes[bytes_per_samp]));
1927 /* Add file writer, possibly a compressor. */
1929 if (!reading)
1930 if (AF_FAIL == addfilewritemods(&current, track, h))
1931 return(AF_FAIL);
1933 /* Now all modules are arranged! */
1935 track->ms.nmodules = current.modinst - track->ms.module;
1937 #ifdef UNLIMITED_CHUNK_NVFRAMES
1939 OPTIMIZATION: normally, when we set up the modules, AFreadframes
1940 and AFwriteframes must pull and push chunks of size at most
1941 _AF_ATOMIC_NVFRAMES.
1943 For the simplest configurations of modules (1 module, no
1944 compression), no buffering at all needs to be done by the
1945 module system. In these cases, afReadFrames/afWriteFrames
1946 can pull/push as many virtual frames as they want
1947 in one call. This flag tells tells afReadFrames and
1948 afWriteFrames whether they can do so.
1950 Note that if this flag is set, file modules cannot rely
1951 on the intermediate working buffer which _AFsetupmodules
1952 usually allocates for them in their input or output chunk
1953 (for reading or writing, respectively). This is why if
1954 we are reading/writing compressed data, this optimization
1955 is turned off.
1957 There are warnings to this effect in the pcm
1958 (uncompressed) file read/write module. If you want to
1959 apply this optimization to other types, be sure to put
1960 similar warnings in the code.
1962 if (track->ms.nmodules == 1 &&
1963 track->v.compressionType == AF_COMPRESSION_NONE &&
1964 track->f.compressionType == AF_COMPRESSION_NONE)
1965 track->ms.mustuseatomicnvframes = false;
1966 else
1967 track->ms.mustuseatomicnvframes = true;
1968 #else
1969 track->ms.mustuseatomicnvframes = true;
1970 #endif
1972 return AF_SUCCEED;
1976 disposemodules will free old buffers and free old modules, except
1977 those marked with free_on_close.
1979 The modules existing before we dispose them could be:
1981 1. none (we may have only called _AFinitmodules and not _AFsetupmodules)
1982 2. some invalid PARTIALLY ALLOCATED ones (e.g. the last _AFsetupmodules
1983 had an error) or
1984 3. a perfectly valid set of modules.
1986 disposemodules will deal with all three cases.
1988 static void disposemodules (_Track *track)
1990 if (track->ms.module)
1992 int i;
1994 for (i=0; i < MAX_MODULES; i++)
1996 _AFmoduleinst *mod = &track->ms.module[i];
1998 #ifdef AF_DEBUG
1999 if (!mod->valid && i < track->ms.nmodules)
2000 printf("disposemodules: WARNING in-range invalid module found '%s'\n", mod->mod->name);
2001 #endif
2003 if (mod->valid && !mod->free_on_close && mod->mod->free)
2005 (*mod->mod->free)(mod);
2006 mod->valid = false;
2010 free(track->ms.module);
2011 track->ms.module = AF_NULL;
2013 track->ms.nmodules = 0;
2015 if (track->ms.chunk)
2017 free(track->ms.chunk);
2018 track->ms.chunk = AF_NULL;
2021 if (track->ms.buffer)
2023 int i;
2024 for (i=0; i < (MAX_MODULES+1); i++)
2026 if (track->ms.buffer[i] != AF_NULL)
2028 free(track->ms.buffer[i]);
2029 track->ms.buffer[i] = AF_NULL;
2032 free(track->ms.buffer);
2033 track->ms.buffer = AF_NULL;
2038 resetmodules: see advanced section in README.modules for more info
2040 static status resetmodules (_AFfilehandle *h, _Track *track)
2042 int i;
2045 We should already have called _AFsetupmodules.
2046 (Actually this is called from the end of _AFsetupmodules
2047 but whatever).
2050 assert(!track->ms.modulesdirty);
2052 /* Assume all is well with track. */
2053 track->filemodhappy = true;
2055 CHNK(printf("resetmodules running reset1 routines\n"));
2057 /* Reset all modules. */
2058 for (i=track->ms.nmodules-1; i >= 0; i--)
2060 /* reset1 */
2061 if (track->ms.module[i].mod->reset1 != AF_NULL)
2062 (*track->ms.module[i].mod->reset1)(&track->ms.module[i]);
2065 /* Clear out frames2ignore here; the modules will increment it. */
2066 track->frames2ignore = 0;
2068 if (!track->filemodhappy)
2069 return AF_FAIL;
2071 CHNK(printf("resetmodules running reset2 routines\n"));
2073 for (i=0; i < track->ms.nmodules; i++)
2075 /* reset2 */
2076 if (track->ms.module[i].mod->reset2 != AF_NULL)
2077 (*track->ms.module[i].mod->reset2)(&track->ms.module[i]);
2080 CHNK(printf("resetmodules completed\n"));
2082 if (!track->filemodhappy)
2083 return AF_FAIL;
2085 #ifdef ONE_TRACK_ONLY
2087 For an explanation of this, see the comment in
2088 initfilemods which explains how and when the file is
2089 lseek'ed.
2091 if (h->seekok)
2092 if (lseek(h->fd, track->fpos_next_frame, SEEK_SET) < 0)
2094 _af_error(AF_BAD_LSEEK,
2095 "unable to position read pointer at next data frame");
2096 return AF_FAIL;
2098 #endif
2100 return AF_SUCCEED;
2104 _AFsyncmodules
2106 status _AFsyncmodules (AFfilehandle h, _Track *track)
2108 int i;
2110 /* We should already have called _AFsetupmodules. */
2111 assert(!track->ms.modulesdirty);
2113 /* Assume all is well with track. */
2114 track->filemodhappy = true;
2116 CHNK(printf("_AFsyncmodules running sync1 routines\n"));
2118 /* Sync all modules. */
2119 for(i=track->ms.nmodules-1; i >= 0; i-- )
2121 /* sync1 */
2122 if (AF_NULL != track->ms.module[i].mod->sync1)
2123 (*track->ms.module[i].mod->sync1)(&track->ms.module[i]);
2126 if (!track->filemodhappy)
2127 return AF_FAIL;
2129 CHNK(printf("_AFsyncmodules running sync2 routines\n"));
2131 for (i=0; i < track->ms.nmodules; i++)
2133 /* sync2 */
2134 if (AF_NULL != track->ms.module[i].mod->sync2)
2135 (*track->ms.module[i].mod->sync2)(&track->ms.module[i]);
2138 CHNK(printf("_AFsyncmodules completed\n"));
2140 if (!track->filemodhappy)
2141 return AF_FAIL;
2143 #ifdef ONE_TRACK_ONLY
2145 For an explanation of this, see the comment in
2146 initfilemods which explains how and when the file is
2147 lseek'ed.
2149 if (h->seekok)
2150 if (lseek( h->fd, track->fpos_next_frame, SEEK_SET) < 0 )
2152 _af_error(AF_BAD_LSEEK,
2153 "unable to position write ptr at next data frame");
2154 return(AF_FAIL);
2156 #endif
2158 return AF_SUCCEED;
2162 _AFsetupmodules:
2163 - frees any old modules, chunks, and buffers
2164 - looks at the input and output format and sets up a whole new
2165 set of input and output modules (using arrangemodules())
2166 - assigns those modules chunks
2167 - allocates buffers and assigns the buffers to the chunks
2168 - initializes various track fields pertaining to the module system
2170 It returns AF_FAIL on any kind of error.
2172 It sets modulesdirty to false if it was able to clean the
2173 modules (although an error still could have occurred after
2174 cleaning them).
2176 status _AFsetupmodules (AFfilehandle h, _Track *track)
2178 _AFmoduleinst *modules;
2179 _AFchunk *chunks;
2180 void **buffers;
2181 int maxbufsize, bufsize, i;
2182 double rateratiof2v, fframepos;
2185 The purpose of this function is to "clean" the modules:
2187 * All of the fields in trk->ms are completely set
2188 and valid.
2190 * track->totalvframes and track->next[fv]frame are set
2191 and valid and trk->modulesdirty will be set to false
2192 if this function succeeds.
2194 This function also resets the modules on files open for read.
2195 it will return AF_FAIL if either cleaning the modules fails,
2196 or this reset fails.
2198 The comments will tell you which part does what.
2202 NOTE: we cannot trust any value in track->ms until we
2203 have called disposemodules(), at which time things are
2204 cleared to reasonable "zero" values.
2206 It is possible for track->ms to be in an illegal state
2207 at this point, if the last _AFsetupmodules failed with
2208 an error.
2210 We can trust track->totalvframes and track->next[fv]frame
2211 because they are only modified after successfully building
2212 the modules.
2216 Disallow compression in virtual format for now.
2218 if (track->v.compressionType != AF_COMPRESSION_NONE)
2220 _af_error(AF_BAD_NOT_IMPLEMENTED,
2221 "library does not support compression in virtual format yet");
2222 return AF_FAIL;
2226 Check that virtual compression parameters are ok.
2229 int idx = _af_compression_index_from_id(track->v.compressionType);
2230 if (!(*_af_compression[idx].fmtok)(&track->v))
2232 return AF_FAIL;
2237 track->nextvframe and track->nextfframe:
2239 At this point, only track->nextvframe contains useful
2240 information, since track->nextfframe may be swayed by
2241 currently buffered frames.
2243 Also track->nextvframe is currently in the scale of the
2244 old sampling rate, not the new one we are setting up.
2246 So at this point we remember where we are in the file
2247 (in floating point) in terms of the file sampling rate.
2249 We will use this later in this function to set both
2250 track->nextfframe (for reading) and track->nextvframe
2251 (for reading and writing).
2253 We must be careful to use the old rates, not the ones
2254 in track->{f,v}.
2257 /* If modules have been set up at all */
2258 if (track->ms.old_v_rate > 0)
2260 assert(track->ms.old_f_rate > 0);
2261 rateratiof2v = track->ms.old_f_rate / track->ms.old_v_rate;
2262 fframepos = track->nextvframe * rateratiof2v;
2264 else
2265 /* We start at frame zero. */
2266 fframepos = 0;
2269 Dispose the existing modules (except extended-life ones).
2271 See the function for info on what the module state could
2272 be at this time.
2275 disposemodules(track);
2278 Here we allocate the highest number of module instances
2279 (and chunks) chained together we could possibly need.
2281 This is how the chunks are used:
2283 module[n]'s input chunk is chunk[n]
2284 module[n]'s output chunk is chunk[n+1]
2286 chunk[n]'s buffer, if it is not the user's buffer, is buffer[n].
2288 For reading chunk[0] is not usually used.
2289 For writing chunk[nmodules] is not usually used.
2291 We allocate a buffer for chunk[0] on reading and
2292 chunk[nmodules] when writing because the file reading
2293 or file writing module, if it does compression or
2294 decompression, may need extra space in which to place
2295 the result of its processing before reading or writing it.
2297 Also note that chunk[0].f and chunk[nmodules].f are used in
2298 arrangemodules().
2300 modules = _af_malloc(sizeof (_AFmoduleinst) * MAX_MODULES);
2301 if (modules == AF_NULL)
2302 return AF_FAIL;
2303 for (i=0; i < MAX_MODULES; i++)
2304 modules[i].valid = false;
2306 chunks = _af_malloc(sizeof (_AFchunk) * (MAX_MODULES+1));
2307 if (chunks == AF_NULL)
2308 return AF_FAIL;
2310 buffers = _af_malloc(sizeof (void *) * (MAX_MODULES+1));
2311 if (buffers == AF_NULL)
2312 return AF_FAIL;
2314 It is very important to initialize each buffers[i] to NULL;
2315 dispose frees them all if !NULL.
2318 for (i=0; i < (MAX_MODULES+1); i++)
2319 buffers[i] = AF_NULL;
2321 track->ms.module = modules;
2323 nmodules is a bogus value here, set just for sanity
2324 (in case of broken code).
2327 track->ms.nmodules = 0;
2328 track->ms.chunk = chunks;
2329 track->ms.buffer = buffers;
2332 Figure out the best modules to use to convert the
2333 data and initialize instances of those modules.
2334 Fills "track->ms.module" and most of "track->ms.chunk"
2335 arrays (all but the buffers) as it goes. Sets
2336 "track->ms.nmodules" As a side benefit, this function
2337 also leaves information about the data format at each
2338 stage in the "f" field of each chunk.
2340 if (arrangemodules(h, track) == AF_FAIL)
2343 At this point the modules are in an incompletely
2344 initialized and probably illegal state. nmodules
2345 could be meaningful or not. Things are nasty.
2347 But as long as any API call that uses the
2348 modules calls _AFsetupmodules() first (which
2349 then calls disposemodules(), which can handle
2350 this nastiness), we can restore the modules to
2351 a sane initial state and things will be ok.
2354 return AF_FAIL;
2358 At this point modules and nmodules are almost completely
2359 filled in (modules aren't actually connected to one
2360 another), but buffer[n] and chunk[n].buf are still in
2361 a null state.
2363 track->totalvframes and track->next[fv]frame have not yet been
2364 set to a valid state.
2368 Now go through the modules:
2370 1. Connect up the source/sink fields properly.
2371 2. Use the information left in the _AudioFormat field
2372 of each chunk by setupmodules() along with the
2373 "max_pull"/"max_push" module function to figure
2374 out the biggest buffer size that could be needed.
2377 /* filemod reports error here */
2378 track->filemodhappy = true;
2379 maxbufsize = 0;
2381 if (h->access == _AF_READ_ACCESS)
2383 track->ms.chunk[track->ms.nmodules].nframes = _AF_ATOMIC_NVFRAMES;
2385 for (i=track->ms.nmodules-1; i >= 0; i--)
2387 _AFchunk *inc = &track->ms.chunk[i];
2388 _AFchunk *outc = &track->ms.chunk[i+1];
2390 /* check bufsize needed for current output chunk */
2392 bufsize = outc->nframes * _af_format_frame_size(&outc->f, true);
2393 if (bufsize > maxbufsize)
2394 maxbufsize = bufsize;
2396 if (i != 0)
2398 /* Connect source pointer for this module. */
2400 track->ms.module[i].u.pull.source = &track->ms.module[i-1];
2404 Determine inc->nframes from outc->nframes.
2405 If the max_pull function is present, we use it,
2406 otherwise we assume module does no weird
2407 buffering or rate conversion.
2409 if (track->ms.module[i].mod->max_pull)
2410 (*track->ms.module[i].mod->max_pull)(&track->ms.module[i]);
2411 else
2412 inc->nframes = outc->nframes;
2415 if (!track->filemodhappy)
2416 return AF_FAIL;
2419 Check bufsize needed for filemod's input chunk
2420 (intermediate buffer) based on an uncompressed
2421 (output chunk) framesize.
2425 _AFmoduleinst *filemod = &track->ms.module[0];
2426 bufsize = filemod->inc->nframes *
2427 _af_format_frame_size(&filemod->outc->f, true);
2428 if (bufsize > maxbufsize)
2429 maxbufsize = bufsize;
2432 else
2434 track->ms.chunk[0].nframes = _AF_ATOMIC_NVFRAMES;
2436 for (i=0; i < track->ms.nmodules; i++)
2438 _AFchunk *inc = &track->ms.chunk[i];
2439 _AFchunk *outc = &track->ms.chunk[i+1];
2441 /* Check bufsize needed for current input chunk. */
2443 bufsize = inc->nframes * _af_format_frame_size(&inc->f, true);
2444 if (bufsize > maxbufsize)
2445 maxbufsize = bufsize;
2447 if (i != track->ms.nmodules-1)
2449 /* Connect sink pointer. */
2451 track->ms.module[i].u.push.sink = &track->ms.module[i+1];
2455 Determine outc->nframes from inc->nframes.
2456 If the max_push function is present, we use it,
2457 otherwise we assume module does no weird
2458 buffering or rate conversion.
2460 if (track->ms.module[i].mod->max_push)
2461 (*track->ms.module[i].mod->max_push)(&track->ms.module[i]);
2462 else
2463 outc->nframes = inc->nframes;
2466 if (!track->filemodhappy)
2467 return AF_FAIL;
2470 Check bufsize needed for filemod's output chunk
2471 (intermediate buffer) based on an uncompressed (input
2472 chunk) framesize.
2476 _AFmoduleinst *filemod = &track->ms.module[track->ms.nmodules-1];
2477 bufsize = filemod->outc->nframes *
2478 _af_format_frame_size(&filemod->inc->f, true);
2479 if (bufsize > maxbufsize)
2480 maxbufsize = bufsize;
2485 At this point everything is totally set up with the
2486 modules except that the chunk buffers have not been
2487 allocated, and thus buffer[n] and chunk[n].buf have
2488 not been set. But now we know how big they should be
2489 (maxbufsize).
2491 track->totalvframes and track->next[fv]frame have not
2492 yet been set to a valid state.
2494 DEBG(printf("_AFsetupmodules: maxbufsize=%d\n", maxbufsize));
2497 One of these will get overwritten to point to user's
2498 buffer. The other one will be allocated below (for file
2499 read/write module).
2502 track->ms.chunk[track->ms.nmodules].buf = AF_NULL;
2503 track->ms.chunk[0].buf = AF_NULL;
2506 One of these will be allocated for the file read/write
2507 module The other will be completely unused.
2509 track->ms.buffer[track->ms.nmodules] = AF_NULL;
2510 track->ms.buffer[0] = AF_NULL;
2513 Now that we know how big buffers have to be, allocate
2514 buffers and assign them to the module instances.
2516 Note that track->ms.chunk[nmodules].buf (reading) or
2517 track->ms.chunk[0].buf (writing) will get overwritten
2518 in _AFreadframes or _AFwriteframes to point to the
2519 user's buffer.
2521 We allocate a buffer for track->ms.chunk[0].buf (reading)
2522 or track->ms.chunk[nmodules].buf (writing) not because
2523 it is needed for the modules to work, but as a working
2524 buffer for the file reading / file writing modules.
2526 Also note that some modules may change their inc->buf or
2527 outc->buf to point to something internal to the module
2528 before calling their source or sink.
2530 So module code must be careful not to assume that a buffer
2531 address will not change. Only for chunk[nmodules]
2532 (reading) or chunk[0] (writing) is such trickery
2533 disallowed.
2536 if (h->access == _AF_READ_ACCESS)
2537 for (i=track->ms.nmodules-1; i >= 0; i--)
2539 if ((track->ms.buffer[i] = _af_malloc(maxbufsize)) == AF_NULL)
2540 return AF_FAIL;
2541 track->ms.chunk[i].buf = track->ms.buffer[i];
2543 else
2544 for (i=1; i <= track->ms.nmodules; i++)
2546 if ((track->ms.buffer[i] = _af_malloc(maxbufsize)) == AF_NULL)
2547 return AF_FAIL;
2548 track->ms.chunk[i].buf = track->ms.buffer[i];
2552 Hooray! The modules are now in a completely valid state.
2553 But we can't set track->ms.modulesdirty to false yet...
2555 track->totalvframes and track->next[fv]frame have not yet been
2556 set to a valid state.
2558 if (h->access == _AF_READ_ACCESS)
2561 Set total number of virtual frames based on new rate.
2563 if (track->totalfframes == -1)
2564 track->totalvframes = -1;
2565 else
2566 track->totalvframes = track->totalfframes *
2567 (track->v.sampleRate / track->f.sampleRate);
2570 track->nextvframe and track->nextfframe:
2572 Currently our only indication of where we were
2573 in the file is the variable fframepos, which
2574 contains (in floating point) our offset in file
2575 frames based on the old track->nextvframe.
2577 Now we get as close as we can to that original
2578 position, given the new sampling rate.
2581 track->nextfframe = (AFframecount) fframepos;
2582 track->nextvframe = (AFframecount) (fframepos * (track->v.sampleRate / track->f.sampleRate));
2585 Now we can say the module system is in a
2586 clean state. Any errors we get from here on
2587 are reported but not critical.
2590 track->ms.modulesdirty = false;
2592 /* Set up for next time. */
2593 track->ms.old_f_rate = track->f.sampleRate;
2594 track->ms.old_v_rate = track->v.sampleRate;
2597 Now we reset all the modules.
2599 If we are here because the user did afSeekFrame,
2600 the actual seek will be performed here.
2601 Otherwise this reset will set things up so that
2602 we are at the same file offset we were at before
2603 (or as close as possible given a change in
2604 rate conversion).
2607 /* Report error, but we're still clean. */
2608 if (AF_SUCCEED != resetmodules(h, track))
2609 return AF_FAIL;
2611 /* Handle the case of _AF_WRITE_ACCESS. */
2612 else
2615 Don't mess with track->nextfframe or
2616 track->totalfframes. Scale virtual frame position
2617 relative to old virtual position.
2620 track->nextvframe = track->totalvframes =
2621 (AFframecount) (fframepos * (track->v.sampleRate / track->f.sampleRate));
2624 Now we can say the module system is in a
2625 clean state. Any errors we get from here on
2626 are reported but not critical.
2629 track->ms.modulesdirty = false;
2631 /* Set up for next time. */
2632 track->ms.old_f_rate = track->f.sampleRate;
2633 track->ms.old_v_rate = track->v.sampleRate;
2636 DEBG(_af_print_filehandle(h));
2638 #ifdef DEBUG
2639 for (i=track->ms.nmodules-1; i >= 0; i--)
2641 _AFmoduleinst *inst = &track->ms.module[i];
2645 /* Print format summary. */
2647 printf("%s ->\n", (h->access == _AF_READ_ACCESS) ? "file" : "user");
2648 for (i=0; i < track->ms.nmodules; i++)
2650 _AFmoduleinst *inst = &track->ms.module[i];
2651 _af_print_audioformat(&inst->inc->f);
2652 printf(" -> %s(%d) ->\n", inst->mod->name, i);
2654 _af_print_audioformat(&track->ms.chunk[track->ms.nmodules].f);
2655 printf(" -> %s\n", (h->access != _AF_READ_ACCESS) ? "file" : "user");
2657 #endif
2660 If we get here, then not only are the modules clean, but
2661 whatever we did after the modules became clean succeeded.
2662 So we gloat about our success.
2664 return AF_SUCCEED;
2668 _AFinitmodules: this routine sets the initial value of the module-
2669 related fields of the track when the track is first created.
2671 It also initializes the file read or file write modules.
2672 See README.modules for info on this.
2674 Set "modulesdirty" flag on each track, so that the first
2675 read/write/seek will set up the modules.
2677 status _AFinitmodules (AFfilehandle h, _Track *track)
2679 track->channelMatrix = NULL;
2681 /* HACK: see private.h for a description of this hack */
2682 track->taper = 10;
2683 track->dynamic_range = 100;
2684 track->ratecvt_filter_params_set = true;
2686 track->ms.nmodules = 0;
2687 track->ms.module = NULL;
2688 track->ms.chunk = NULL;
2689 track->ms.buffer = NULL;
2691 track->ms.modulesdirty = true;
2693 track->ms.filemodinst.valid = false;
2694 track->ms.filemod_rebufferinst.valid = false;
2696 track->ms.rateconvertinst.valid = false;
2697 track->ms.rateconvert_rebufferinst.valid = false;
2699 /* bogus value in case of bad code */
2700 track->ms.mustuseatomicnvframes = true;
2702 /* old_f_rate and old_v_rate MUST be set to <= 0 here. */
2703 track->ms.old_f_rate = -1;
2704 track->ms.old_v_rate = -1;
2707 Initialize extended-life file read or file write modules.
2709 if (AF_FAIL == initfilemods(track, h))
2710 return AF_FAIL;
2713 Initialize extended-life rate convert modules (to NULL).
2715 initrateconvertmods(h->access == _AF_READ_ACCESS, track);
2718 NOTE: Only now that we have initialized filemods is
2719 track->totalfframes guaranteed to be ready. (The unit
2720 cannot always tell how many frames are in the file.)
2723 /* totalfframes could be -1. */
2724 track->totalvframes = track->totalfframes;
2725 track->nextvframe = 0;
2726 track->frames2ignore = 0;
2728 return AF_SUCCEED;
2732 _AFfreemodules:
2733 called once when filehandle is being freed
2734 opposite of initmodules
2735 free all modules, even the active ones
2737 void _AFfreemodules (_Track *track)
2739 disposemodules(track);
2740 disposefilemods(track);
2741 #if 0 /* XXXmpruett rate conversion is deactivated for now */
2742 disposerateconvertmods(track);
2743 #endif