wav: simplify extended fmt chunk handling [bug #198]
[sox.git] / src / earwax.c
blob0f7241830a7649ba3985869ab1a888bde660629a
1 /* libSoX earwax - makes listening to headphones easier November 9, 2000
3 * Copyright (c) 2000 Edward Beingessner And Sundry Contributors.
4 * This source code is freely redistributable and may be used for any purpose.
5 * This copyright notice must be maintained. Edward Beingessner And Sundry
6 * Contributors are not responsible for the consequences of using this
7 * software.
9 * This effect takes a 44.1kHz stereo (CD format) signal that is meant to be
10 * listened to on headphones, and adds audio cues to move the soundstage from
11 * inside your head (standard for headphones) to outside and in front of the
12 * listener (standard for speakers). This makes the sound much easier to listen
13 * to on headphones.
16 #include "sox_i.h"
17 #include <string.h>
19 static const sox_sample_t filt[32 * 2] = {
20 /* 30° 330° */
21 4, -6, /* 32 tap stereo FIR filter. */
22 4, -11, /* One side filters as if the */
23 -1, -5, /* signal was from 30 degrees */
24 3, 3, /* from the ear, the other as */
25 -2, 5, /* if 330 degrees. */
26 -5, 0,
27 9, 1,
28 6, 3, /* Input */
29 -4, -1, /* Left Right */
30 -5, -3, /* __________ __________ */
31 -2, -5, /* | | | | */
32 -7, 1, /* .---| Hh,0(f) | | Hh,0(f) |---. */
33 6, -7, /* / |__________| |__________| \ */
34 30, -29, /* / \ / \ */
35 12, -3, /* / X \ */
36 -11, 4, /* / / \ \ */
37 -3, 7, /* ____V_____ __________V V__________ _____V____ */
38 -20, 23, /* | | | | | | | | */
39 2, 0, /* | Hh,30(f) | | Hh,330(f)| | Hh,330(f)| | Hh,30(f) | */
40 1, -6, /* |__________| |__________| |__________| |__________| */
41 -14, -5, /* \ ___ / \ ___ / */
42 15, -18, /* \ / \ / _____ \ / \ / */
43 6, 7, /* `->| + |<--' / \ `-->| + |<-' */
44 15, -10, /* \___/ _/ \_ \___/ */
45 -14, 22, /* \ / \ / \ / */
46 -7, -2, /* `--->| | | |<---' */
47 -4, 9, /* \_/ \_/ */
48 6, -12, /* */
49 6, -6, /* Headphones */
50 0, -11,
51 0, -5,
52 4, 0};
54 #define NUMTAPS array_length(filt)
55 typedef struct {sox_sample_t tap[NUMTAPS];} priv_t; /* FIR filter z^-1 delays */
57 static int start(sox_effect_t * effp)
59 priv_t * p = (priv_t *)effp->priv;
60 if (effp->in_signal.rate != 44100 || effp->in_signal.channels != 2) {
61 lsx_fail("works only with stereo audio sampled at 44100Hz (i.e. CDDA)");
62 return SOX_EOF;
64 memset(p->tap, 0, NUMTAPS * sizeof(*p->tap)); /* zero tap memory */
65 if (effp->in_signal.mult)
66 *effp->in_signal.mult *= dB_to_linear(-4.4);
67 return SOX_SUCCESS;
70 static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
71 sox_sample_t * obuf, size_t * isamp, size_t * osamp)
73 priv_t * p = (priv_t *)effp->priv;
74 size_t i, len = *isamp = *osamp = min(*isamp, *osamp);
76 while (len--) { /* update taps and calculate output */
77 double output = 0;
79 for (i = NUMTAPS - 1; i; --i) {
80 p->tap[i] = p->tap[i - 1];
81 output += p->tap[i] * filt[i];
83 p->tap[0] = *ibuf++ / 64; /* scale output */
84 output += p->tap[0] * filt[0];
85 *obuf++ = SOX_ROUND_CLIP_COUNT(output, effp->clips);
87 return SOX_SUCCESS;
90 /* No drain: preserve audio file length; it's only 32 samples anyway. */
92 sox_effect_handler_t const *lsx_earwax_effect_fn(void)
94 static sox_effect_handler_t handler = {"earwax", NULL, SOX_EFF_MCHAN,
95 NULL, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
96 return &handler;