3 This file is part of a program that implements a Software-Defined Radio.
5 Copyright (C) 2005 by Frank Brickle, AB2KT and Bob McGwier, N4HY
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 The authors can be reached by email at
29 The DTTS Microwave Society
36 //------------------------------------------------------------------------
37 // An ASR envelope on a complex phasor,
38 // with asynchronous trigger for R stage.
39 // A/R use sine shaping.
40 //------------------------------------------------------------------------
43 CWTone(CWToneGen cwt) {
46 ComplexOSC(cwt->osc.gen);
48 for (i = 0; i < n; i++) {
50 // in an envelope stage?
52 if (cwt->stage == CWTone_RISE) {
55 if (cwt->rise.have++ < cwt->rise.want) {
56 cwt->curr += cwt->rise.incr;
57 cwt->mul = cwt->scl * sin(cwt->curr * M_PI / 2.0);
59 // no, assert steady-state, force level
62 cwt->stage = CWTone_STDY;
63 // won't come back into envelopes
64 // until FALL asserted from outside
67 } else if (cwt->stage == CWTone_FALL) {
70 if (cwt->fall.have++ < cwt->fall.want) {
71 cwt->curr -= cwt->fall.incr;
72 cwt->mul = cwt->scl * sin(cwt->curr * M_PI / 2.0);
74 // no, assert trailing, force level
77 cwt->stage = CWTone_HOLD;
78 // won't come back into envelopes hereafter
83 // (same base as osc.gen internal buf)
84 CXBdata(cwt->buf, i) = Cscl(CXBdata(cwt->buf, i), cwt->mul);
87 // indicate whether it's turned itself off
88 // sometime during this pass
90 return cwt->stage != CWTone_HOLD;
93 //------------------------------------------------------------------------
94 // turn tone on with current settings
97 CWToneOn(CWToneGen cwt) {
101 cwt->scl = pow(10.0, cwt->gain / 20.0);
102 cwt->curr = cwt->mul = 0.0;
104 // A/R times are in msec
106 cwt->rise.want = (int) (0.5 + cwt->sr * (cwt->rise.dur / 1e3));
108 if (cwt->rise.want <= 1)
109 cwt->rise.incr = 1.0;
111 cwt->rise.incr = 1.0 / (cwt->rise.want - 1);
113 cwt->fall.want = (int) (0.5 + cwt->sr * (cwt->fall.dur / 1e3));
115 if (cwt->fall.want <= 1)
116 cwt->fall.incr = 1.0;
118 cwt->fall.incr = 1.0 / (cwt->fall.want - 1);
122 OSCfreq(cwt->osc.gen) = 2.0 * M_PI * cwt->osc.freq / cwt->sr;
123 OSCphase(cwt->osc.gen) = 0.0;
125 cwt->stage = CWTone_RISE;
128 //------------------------------------------------------------------------
132 CWToneOff(CWToneGen cwt) { cwt->stage = CWTone_FALL; }
134 //------------------------------------------------------------------------
137 setCWToneGenVals(CWToneGen cwt,
143 cwt->osc.freq = freq;
144 cwt->rise.dur = rise;
145 cwt->fall.dur = fall;
149 newCWToneGen(REAL gain, // dB
156 CWToneGen cwt = (CWToneGen) safealloc(1, sizeof(CWToneGenDesc),
159 setCWToneGenVals(cwt, gain, freq, rise, fall);
161 cwt->sr = samplerate;
163 cwt->osc.gen = newOSC(cwt->size,
170 // overload oscillator buf
171 cwt->buf = newCXB(cwt->size, OSCCbase(cwt->osc.gen), "CWToneGen buf");
177 delCWToneGen(CWToneGen cwt) {
180 delOSC(cwt->osc.gen);
181 safefree((char *) cwt);