]> git.rkrishnan.org Git - dttsp.git/blob - jDttSP/wscompand.c
Major update
[dttsp.git] / jDttSP / wscompand.c
1 // wscompand.c
2 // waveshaping compander, mostly for speech
3 /*
4 This file is part of a program that implements a Software-Defined Radio.
5
6 Copyright (C) 2004-2005 by Frank Brickle, AB2KT and Bob McGwier, N4HY
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
22 The authors can be reached by email at
23
24 ab2kt@arrl.net
25 or
26 rwmcgwier@comcast.net
27
28 or by paper mail at
29
30 The DTTS Microwave Society
31 6 Kathleen Place
32 Bridgewater, NJ 08807
33 */
34
35 #include <wscompand.h>
36
37 PRIVATE INLINE REAL
38 WSCLookup(WSCompander wsc, REAL x) {
39   if (x > 0.0) {
40     REAL d = x - (int) x, y, *tbl = wsc->tbl;
41     int i = (int) (x * wsc->npts), end = wsc->nend;
42     if (i < end)
43       y = tbl[i] + d * (tbl[i + 1] - tbl[i]);
44     else
45       y = tbl[end];
46     return y / x;
47   } else
48     return 0.0;
49 }
50
51 void
52 WSCompand(WSCompander wsc) {
53   int i, n = CXBsize(wsc->buff);
54   for (i = 0; i < n; i++) {
55     COMPLEX val = CXBdata(wsc->buff, i);
56     REAL mag = Cmag(val),
57          scl = WSCLookup(wsc, mag);
58     CXBdata(wsc->buff, i) = Cscl(val, scl);
59   }
60 }
61
62 void
63 WSCReset(WSCompander wsc, REAL fac) {
64   int i;
65   REAL *tbl = wsc->tbl;
66
67   if (fac == 0.0)       // just linear
68     for (i = 0; i < wsc->npts; i++)
69       tbl[i] = i / (REAL) wsc->npts;
70
71   else {                // exponential
72     REAL del = fac / wsc->nend,
73          scl = 1.0 - exp(fac);
74     for (i = 0; i < wsc->npts; i++)
75       tbl[i] = (1.0 - exp(i * del)) / scl;
76   }
77
78   wsc->fac = fac;
79 }
80
81 // fac < 0: compression
82 // fac > 0: expansion
83
84 WSCompander
85 newWSCompander(int npts,
86                REAL fac,
87                CXB buff) {
88   WSCompander wsc;
89
90   wsc = (WSCompander) safealloc(1,
91                                 sizeof(WSCompanderInfo),
92                                 "WSCompander struct");
93   wsc->npts = npts;
94   wsc->nend = npts - 1;
95   wsc->tbl = newvec_REAL(npts, "WSCompander table");
96   wsc->buff = newCXB(npts, CXBbase(buff), "WSCompander buff");
97   WSCReset(wsc, fac);
98   return wsc;
99 }
100
101 void
102 delWSCompander(WSCompander wsc) {
103   if (wsc) {
104     delvec_REAL(wsc->tbl);
105     delCXB(wsc->buff);
106     safefree((char *) wsc);
107   }
108 }