3 This file is part of a program that implements a Software-Defined Radio.
5 The code in this file is derived from routines originally written by
6 Pierre-Philippe Coupard for his CWirc X-chat program. That program
7 is issued under the GPL and is
8 Copyright (C) Pierre-Philippe Coupard - 18/06/2003
10 This derived version is
11 Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 The authors can be reached by email at
35 The DTTS Microwave Society
40 // see below for places where serial port is read
41 // and needs replacement for parallel port hookup
45 //========================================================================
46 // nothing affected by physical port connection here
54 BOOLEAN midelementmodeB,
57 BOOLEAN autocharspacing,
58 BOOLEAN autowordspacing,
62 double ditlen = 1200 / wpm;
63 int set_element_timeouts = NO_TIMEOUTS_SCHED;
65 /* Do we need to initialize the keyer? */
67 kl->flag.prev.dit = dit;
68 kl->flag.prev.dah = dah;
69 kl->element.last = kl->element.curr = NO_ELEMENT;
70 kl->element.iamb = NO_PADDLE_SQUEEZE;
71 kl->element.psqam = 0;
72 kl->element.invtd = 0;
73 kl->timeout.midl = kl->timeout.beep = kl->timeout.elem = 0;
75 kl->dlay_type = NO_DELAY;
79 /* Decrement the timeouts */
80 kl->timeout.dlay -= kl->timeout.dlay > 0 ? ticklen : 0;
81 if (kl->timeout.dlay <= 0) {
82 /* If nothing is scheduled to play, and we just did a character
83 spacing delay, and we do auto word spacing, wait for a word
84 spacing delay, otherwise resume the normal element timeout
86 if (kl->timeout.elem <= 0 &&
87 kl->dlay_type == CHAR_SPACING_DELAY &&
89 kl->timeout.dlay = ditlen * 4;
90 kl->dlay_type = WORD_SPACING_DELAY;
92 kl->dlay_type = NO_DELAY;
93 kl->timeout.midl -= kl->timeout.midl > 0 ? ticklen : 0;
94 kl->timeout.beep -= kl->timeout.beep > 0 ? ticklen : 0;
95 kl->timeout.elem -= kl->timeout.elem > 0 ? ticklen : 0;
99 /* Are both paddles squeezed? */
101 kl->element.iamb = PADDLES_SQUEEZED;
103 /* Are the paddles squeezed past the middle of the element? */
104 if (kl->timeout.midl <= 0)
105 kl->element.psqam = 1;
107 /* Are both paddles released and we had gotten a squeeze in this element? */
108 if (!dit && !dah && kl->element.iamb == PADDLES_SQUEEZED)
109 kl->element.iamb = PADDLES_RELEASED;
111 /* Is the current element finished? */
112 if (kl->timeout.elem <= 0 && kl->element.curr != NO_ELEMENT) {
113 kl->element.last = kl->element.curr;
115 /* Should we insert an inverted element? */
117 (kl->element.invtd &&
118 kl->element.iamb != PADDLES_RELEASED) ||
119 (kl->element.iamb == PADDLES_RELEASED &&
120 iambicmode == MODE_B &&
121 (!midelementmodeB || kl->element.psqam)))) {
122 if (kl->element.last == DAH)
123 set_element_timeouts = kl->element.curr = DIT;
125 set_element_timeouts = kl->element.curr = DAH;
127 /* No more element */
128 kl->element.curr = NO_ELEMENT;
130 /* Do we do automatic character spacing? */
131 if (autocharspacing && !dit && !dah) {
132 kl->timeout.dlay = ditlen * 2;
133 kl->dlay_type = CHAR_SPACING_DELAY;
137 kl->element.invtd = 0;
138 kl->element.iamb = NO_PADDLE_SQUEEZE;
139 kl->element.psqam = 0;
142 /* Is an element currently being played? */
143 if (kl->element.curr == NO_ELEMENT) {
144 if (dah) /* Dah paddle down ? */
145 set_element_timeouts = kl->element.curr = DAH;
146 else if (dit) /* Dit paddle down ? */
147 set_element_timeouts = kl->element.curr = DIT;
150 /* Do the dah memory */
151 if (kl->element.curr == DIT &&
152 !kl->flag.prev.dah &&
155 kl->element.invtd = 1;
157 /* Do the dit memory */
158 if (kl->element.curr == DAH &&
159 !kl->flag.prev.dit &&
162 kl->element.invtd = 1;
164 /* If we had a dit (or dah) scheduled to be played after a delay,
165 and the operator lifted both paddles before the end of the delay,
166 and we have no dit (or dah) memory, forget it */
168 if (kl->timeout.dlay > 0 &&
171 ((kl->element.curr == DIT &&
173 (kl->element.curr == DAH
175 set_element_timeouts = kl->element.curr = NO_ELEMENT;
177 /* Do we need to set the playing timeouts of an element? */
178 switch (set_element_timeouts) {
179 case NO_ELEMENT: /* Cancel any dit or dah */
180 kl->timeout.beep = 0;
181 kl->timeout.midl = 0;
182 kl->timeout.elem = 0;
185 case DIT: /* Schedule a dit? */
186 kl->timeout.beep = (ditlen * (double) weight) / 50;
187 kl->timeout.midl = kl->timeout.beep / 2;
188 kl->timeout.elem = ditlen * 2;
191 case DAH: /* Schedule a dah? */
192 kl->timeout.beep = (ditlen * (double) weight) / 50 + ditlen * 2;
193 kl->timeout.midl = kl->timeout.beep / 2;
194 kl->timeout.elem = ditlen * 4;
198 kl->flag.prev.dit = dit;
199 kl->flag.prev.dah = dah;
201 return kl->timeout.beep > 0 && kl->timeout.dlay <= 0;
206 newKeyerState(void) {
207 return (KeyerState) safealloc(1, sizeof(KeyerStateInfo), "newKeyerState");
211 delKeyerState(KeyerState ks) {
212 safefree((char *) ks);
216 newKeyerLogic(void) {
217 return (KeyerLogic) safealloc(1, sizeof(KeyerLogicInfo), "newKeyerLogic");
221 delKeyerLogic(KeyerLogic kl) {
222 safefree((char *) kl);
225 //========================================================================