SoDaRadio-5.0.3-master:8901fb5
CWTX.cxx
Go to the documentation of this file.
1 /*
2  Copyright (c) 2012, Matthew H. Reilly (kb1vc)
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "CWTX.hxx"
30 #include "CWGenerator.hxx"
31 
32 SoDa::CWTX::CWTX(Params * params, CmdMBox * _cwtxt_stream, DatMBox * _cw_env_stream, CmdMBox * _cmd_stream) : SoDa::SoDaThread("CWTX")
33 {
34  cwtxt_stream = _cwtxt_stream;
36 
37  cw_env_stream = _cw_env_stream;
38 
39  cmd_stream = _cmd_stream;
41 
42 
43  // get the controlling audio parameters
44  // like the audio sample rate and buffer size
45  rf_sample_rate = params->getTXRate();
46  rf_buffer_size = params->getRFBufferSize();
47 
48  // build the beacon buffer.
49  beacon_envelope = new float[rf_buffer_size];
50  for(unsigned int i = 0; i < rf_buffer_size; i++) {
51  beacon_envelope[i] = 0.0;
52  }
53 
54  // setup the CW generator unit
55  cwgen = new SoDa::CWGenerator(_cw_env_stream, rf_sample_rate, rf_buffer_size);
56 
57  sent_char_count = 0;
58 }
59 
61 {
62  bool exitflag = false;
63  Command * cmd, *txtcmd;
64 
65  while(!exitflag) {
66  bool workdone = false;
67  while((cmd = cmd_stream->get(cmd_subs)) != NULL) {
68  // process the command.
69  execCommand(cmd);
70  exitflag |= (cmd->target == Command::STOP);
71  cmd_stream->free(cmd);
72  workdone = true;
73  }
74 
75  while((txtcmd = cwtxt_stream->get(cwtxt_subs)) != NULL) {
76  // pend the text to the text queue
77  execCommand(txtcmd);
78  exitflag |= (txtcmd->target == Command::STOP);
79  cwtxt_stream->free(txtcmd);
80  workdone = true;
81  }
82 
83  bool dochar = cwgen->readyForMore();
84 
85  // if we've got text in the queue and we're ready
86  // for more outbound envelope, send the character
87  if(dochar) {
88  workdone |= sendAvailChar();
89  }
90 
91  if(!workdone) {
92  usleep(1000);
93  }
94  }
95 }
96 
98 {
99  // if we are in CW mode
100  if(!txmode_is_cw) return false;
101  if(!tx_on) return false;
102 
103  char outchar;
104  bool sent_char = false;
105  // if there are any characters to send
106  // and the generator is not stuffed
107  int itercount = 0;
108  char tbuf[2];
109  tbuf[1] = '\000';
110  while (cwgen->readyForMore()) {
111  itercount++;
112  if(1) {
113  boost::mutex::scoped_lock mt_lock(text_lock);
114  if(text_queue.empty()) return false;
115 
116  outchar = text_queue.front(); text_queue.pop();
117  }
118  if(outchar != '\003') {
119  cwgen->sendChar(outchar);
120  sent_char = true;
121  tbuf[0] = outchar;
124  tbuf, sent_char_count++));
125  }
126  else {
129  0));
130  }
131  }
132 
133  return sent_char;
134 }
135 
137 {
138  switch(cmd->target) {
140  break;
142  break;
144  break;
146  break;
148  break;
150  break;
151  default:
152  break;
153  }
154 }
155 
157 {
159 
160  switch(cmd->target) {
162  if(cmd->iparms[0] == 3) tx_on = true;
163  else tx_on = false;
164  break;
166  if(cmd->iparms[0] == 1) {
168  txmode_is_cw = false;
169  }
170  else {
172  }
173  break;
175  txmode = SoDa::Command::ModulationType(cmd->iparms[0]);
176  if((txmode == SoDa::Command::CW_L) || (txmode == SoDa::Command::CW_U)) {
177  txmode_is_cw = true;
178  old_txmode_is_cw = true;
179  }
180  else {
181  txmode_is_cw = false;
182  old_txmode_is_cw = false;
183  }
184  break;
186  cwgen->setCWSpeed(cmd->iparms[0]);
187  break;
189  enqueueText(cmd->sparm);
190  break;
192  // set the ETX marker.
193  enqueueText("\003");
194  // pend the iparm to the break notification queue
195  if(1) {
196  boost::mutex::scoped_lock lock(break_id_lock);
197  break_notification_id_queue.push(cmd->iparms[0]);
198  }
199  break;
201  clearTextQueue();
202  break;
203  default:
204  break;
205  }
206 }
207 
208 void SoDa::CWTX::enqueueText(const char * buf)
209 {
210  boost::mutex::scoped_lock lock(text_lock);
211 
212  const char * cp = buf;
213  int i;
214  for(i = 0; i < SoDa::Command::getMaxStringLen(); i++) {
215  if(*cp == '\000') break;
216  // enqueue a character.
217  text_queue.push(*cp);
218  cp++;
219  }
220 }
221 
223 {
224  // empty the text_queue
225  if(1) {
226  boost::mutex::scoped_lock lock(text_lock);
227 
228  int deleted_count = text_queue.size();
229 
230  text_queue = std::queue<char>();
231  sent_char_count += deleted_count;
232  }
236  cmd_stream->put(ncmd);
237 
238 }
239 
241 {
242  switch(cmd->target) {
244  // The CW generator has run out of things to send.
245  {
246  boost::mutex::scoped_lock mt_lock(break_id_lock);
247  // we got an ETX marker -- get the next completion code from
248  // the break queue and send it back in a REPORT
249  if(!break_notification_id_queue.empty()) {
253  bkid);
254  cmd_stream->put(ncmd);
255  }
256  }
257  break;
258  default:
259  break;
260  }
261 }
The Thread baseclass for all SoDa thread objects.
Definition: SoDaBase.hxx:284
unsigned int cmd_subs
subscription for command stream
Definition: CWTX.hxx:103
float * beacon_envelope
the currently generated envelope
Definition: CWTX.hxx:112
turn transmitter on and off.
Definition: Command.hxx:197
T * get(unsigned int subscriber_id)
Definition: MultiMBox.hxx:110
CmdMBox * cmd_stream
stream of commands to modify radio state
Definition: CWTX.hxx:100
int iparms[4]
integer parameters
Definition: Command.hxx:668
void execSetCommand(Command *cmd)
handle SET commands from the command channel
Definition: CWTX.cxx:156
Set the modulation mode for the transmit chain.
Definition: Command.hxx:259
Report when CW TX envelope buffer was empty (cmd enables report)
Definition: Command.hxx:242
This class handles command line parameters and built-ins.
Definition: Params.hxx:42
void run()
CWTX run loop: translate text to CW envelopes, handle incoming commands.
Definition: CWTX.cxx:60
CmdTarget target
the thing we&#39;re touching
Definition: Command.hxx:673
TX Carrier Control – send a dead carrier.
Definition: Command.hxx:208
void execGetCommand(Command *cmd)
execute GET commands from the command channel
Definition: CWTX.cxx:136
std::queue< int > break_notification_id_queue
tags inserted into text stream – send tag when the CW envelope generator gets to this character...
Definition: CWTX.hxx:117
static int getMaxStringLen()
how long can a string parameter to a command be?
Definition: Command.hxx:664
bool sendAvailChar()
if a character is available, encode it into an envelope
Definition: CWTX.cxx:97
CWTX(Params *params, CmdMBox *cwtxt_stream, DatMBox *cw_env_stream, CmdMBox *cmd_stream)
Constructor.
Definition: CWTX.cxx:32
Flush outstanding CW text strings from pending buffer.
Definition: Command.hxx:228
std::queue< char > text_queue
characters waiting to be sent
Definition: CWTX.hxx:114
unsigned int getRFBufferSize() const
Definition: Params.hxx:105
On receipt of a STOP command, all threads should exit their run loop.
Definition: Command.hxx:371
This is a list of all the commands that can "do something" to one or more components in the SoDa radi...
Definition: Command.hxx:47
double rf_sample_rate
samples/sec for generating the envelope
Definition: CWTX.hxx:109
void setCWSpeed(unsigned int wpm)
set the speed of the cw stream in words per minute
char sparm[64]
a buffer holding the string
Definition: Command.hxx:670
void clearTextQueue()
forget all enqueued text
Definition: CWTX.cxx:222
ModulationType
modulation selector targets take one of these values
Definition: Command.hxx:478
void execRepCommand(Command *cmd)
handle Report commands from the command channel
Definition: CWTX.cxx:240
CmdMBox * cwtxt_stream
stream of characters to be encoded (from UI or elsewhere)
Definition: CWTX.hxx:99
unsigned int cwtxt_subs
subscription for text stream
Definition: CWTX.hxx:102
boost::mutex text_lock
lock for text_queue
Definition: CWTX.hxx:115
boost::mutex break_id_lock
lock for break_notification queue
Definition: CWTX.hxx:118
bool sendChar(char c)
encode a character into the envelope buffer
double getTXRate() const
TX rate will always be 625K.
Definition: Params.hxx:102
TX CW text control – a buffer of up to 8 characters.
Definition: Command.hxx:215
void free(T *m)
Definition: MultiMBox.hxx:118
unsigned int rf_buffer_size
the size of the envelope buffer
Definition: CWTX.hxx:110
send character count from start-of-time each time we send a character.
Definition: Command.hxx:466
Set speed of CW generator.
Definition: Command.hxx:221
bool txmode_is_cw
if true, we&#39;re transmitting a CW stream
Definition: CWTX.hxx:105
CWGenerator * cwgen
Pointer to a text-to-morse translator.
Definition: CWTX.hxx:97
int sent_char_count
Definition: CWTX.hxx:95
bool tx_on
if true, we&#39;re transmitting a CW stream or a beacon
Definition: CWTX.hxx:107
void enqueueText(const char *buf)
add text to the outbound text queue
Definition: CWTX.cxx:208
bool readyForMore()
check envelope stream to see if we have less than 1 second&#39;s worth of stuff enqueued ...
Definition: CWGenerator.cxx:92
DatMBox * cw_env_stream
stream carrying cw envelope buffers to USRPTX
Definition: CWTX.hxx:101
void put(T *m)
Definition: MultiMBox.hxx:97
A text to morse envelope converter.
Definition: CWGenerator.hxx:44
void execCommand(Command *cmd)
Execute (dispatch) a message removed from the command stream to one of the basic Command handler func...
Definition: SoDaBase.hxx:335
Put a marker in the CW text stream, report its "passing".
Definition: Command.hxx:235
bool old_txmode_is_cw
remember the mode we were in
Definition: CWTX.hxx:106