~ubuntu-branches/ubuntu/breezy/sox/breezy

« back to all changes in this revision

Viewing changes to highp.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-03-21 13:08:29 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050321130829-ycexf5si46wn9p25
Tags: 12.17.7-2
Moved ststdint.h to -dev package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Sound Tools High-Pass effect file.
3
 
 *
4
 
 * (C) 2000 Chris Bagwell <cbagwell@sprynet.com>
5
 
 * See License file for further copyright information.
6
 
 *
7
 
 * Algorithm:  Recursive single pole high-pass filter
8
 
 *
9
 
 * Reference: The Scientist and Engineer's Guide to Digital Processing
10
 
 *
11
 
 *      output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
12
 
 *
13
 
 *      X  = exp(-2.0 * pi * Fc)
14
 
 *      A0 = (1 + X) / 2
15
 
 *      A1 = -(1 + X) / 2
16
 
 *      B1 = X
17
 
 *      Fc = cutoff freq / sample rate
18
 
 *
19
 
 * Mimics an RC high-pass filter:
20
 
 *
21
 
 *        || C
22
 
 *    ----||--------->
23
 
 *        ||    |
24
 
 *              <
25
 
 *              > R
26
 
 *              <
27
 
 *              |
28
 
 *              V
29
 
 *
30
 
 */
31
 
 
32
 
#include <math.h>
33
 
#include "st_i.h"
34
 
 
35
 
/* Private data for Highpass effect */
36
 
typedef struct highpstuff {
37
 
        float   cutoff;
38
 
        double  A0, A1, B1;
39
 
        double  inm1, outm1;
40
 
} *highp_t;
41
 
 
42
 
/*
43
 
 * Process options
44
 
 */
45
 
int st_highp_getopts(eff_t effp, int n, char **argv) 
46
 
{
47
 
        highp_t highp = (highp_t) effp->priv;
48
 
 
49
 
        if ((n < 1) || !sscanf(argv[0], "%f", &highp->cutoff))
50
 
        {
51
 
                st_fail("Usage: highp cutoff");
52
 
                return (ST_EOF);
53
 
        }
54
 
        return (ST_SUCCESS);
55
 
}
56
 
 
57
 
/*
58
 
 * Prepare processing.
59
 
 */
60
 
int st_highp_start(eff_t effp)
61
 
{
62
 
        highp_t highp = (highp_t) effp->priv;
63
 
        if (highp->cutoff > effp->ininfo.rate/2)
64
 
        {
65
 
                st_fail("Highpass: cutoff must be < sample rate / 2 (Nyquest rate)\n");
66
 
                return (ST_EOF);
67
 
        }
68
 
 
69
 
        highp->B1 = exp((-2.0 * M_PI * (highp->cutoff / effp->ininfo.rate)));
70
 
        highp->A0 = (1 + highp->B1) / 2;
71
 
        highp->A1 = (-1 * (1 + highp->B1)) / 2;
72
 
        highp->inm1 = 0.0;
73
 
        highp->outm1 = 0.0;
74
 
        return (ST_SUCCESS);
75
 
}
76
 
 
77
 
/*
78
 
 * Processed signed long samples from ibuf to obuf.
79
 
 * Return number of samples processed.
80
 
 */
81
 
int st_highp_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
82
 
                  st_size_t *isamp, st_size_t *osamp)
83
 
{
84
 
        highp_t highp = (highp_t) effp->priv;
85
 
        int len, done;
86
 
        double d;
87
 
        st_sample_t l;
88
 
 
89
 
        len = ((*isamp > *osamp) ? *osamp : *isamp);
90
 
 
91
 
        for(done = 0; done < len; done++) {
92
 
                l = *ibuf++;
93
 
                d = highp->A0 * l + 
94
 
                    highp->A1 * highp->inm1 + 
95
 
                    highp->B1 * highp->outm1;
96
 
                if (d < -2147483647L)
97
 
                    d = -2147483647L;
98
 
                else if (d > 2147483647L)
99
 
                    d = 2147483647L;
100
 
                highp->inm1 = l;
101
 
                highp->outm1 = d;
102
 
                *obuf++ = d;
103
 
        }
104
 
        *isamp = len;
105
 
        *osamp = len;
106
 
        return (ST_SUCCESS);
107
 
}
108
 
 
109
 
/*
110
 
 * Do anything required when you stop reading samples.  
111
 
 * Don't close input file! 
112
 
 */
113
 
int st_highp_stop(eff_t effp)
114
 
{
115
 
        /* nothing to do */
116
 
    return (ST_SUCCESS);
117
 
}
118