~ubuntu-branches/ubuntu/trusty/fldigi/trusty

« back to all changes in this revision

Viewing changes to src/rsid/rsid.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Joop Stakenborg
  • Date: 2008-11-17 19:40:43 UTC
  • mfrom: (1.1.6 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20081117194043-sfe108e41ppsyhxr
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <config.h>
 
2
 
 
3
#include <math.h>
 
4
 
 
5
#include "rsid.h"
 
6
#include "filters.h"
 
7
#include "main.h"
 
8
#include "trx.h"
 
9
#include "configuration.h"
 
10
#include "confdialog.h"
 
11
#include "qrunner.h"
 
12
 
 
13
#include "rsid_fft.cxx"
 
14
 
 
15
enum {
 
16
        RSID_NONE = 0,
 
17
 
 
18
        RSID_BPSK31 = 1, RSID_QPSK31 = 110, RSID_BPSK63 = 2, RSID_QPSK63 = 3,
 
19
        RSID_BPSK125 = 4, RSID_QPSK125 = 5, RSID_BPSK250 = 126, RSID_QPSK250 = 127,
 
20
 
 
21
        RSID_UNKNOWN_1 = 7, RSID_UNKNOWN_2 = 8,
 
22
 
 
23
        RSID_MT63_500_LG = 9, RSID_MT63_500_ST = 10, RSID_MT63_500_VST = 11,
 
24
        RSID_MT63_1000_LG = 12, RSID_MT63_1000_ST = 13, RSID_MT63_1000_VST = 14,
 
25
        RSID_MT63_2000_LG = 15, RSID_MT63_2000_ST = 17, RSID_MT63_2000_VST = 18,
 
26
 
 
27
        RSID_PSKAM10 = 19, RSID_PSKAM31 = 20, RSID_PSKAM50 = 21, RSID_PSK63F = 22,
 
28
        RSID_PSK220F = 23, RSID_CHIP64 = 24, RSID_CHIP128 = 25,
 
29
 
 
30
        RSID_CW = 26,
 
31
 
 
32
        RSID_CCW_OOK_12 = 27, RSID_CCW_OOK_24 = 28, RSID_CCW_OOK_48 = 29,
 
33
        RSID_CCW_FSK_12 = 30, RSID_CCW_FSK_24 = 31, RSID_CCW_FSK_48 = 33,
 
34
 
 
35
        RSID_PACTOR1_FEC = 34, RSID_PACKET_300 = 35, RSID_PACKET_1200 = 36,
 
36
 
 
37
        RSID_RTTY_ASCII_7 = 37, RSID_RTTY_ASCII_8 = 38, RSID_RTTY_45 = 39,
 
38
        RSID_RTTY_50 = 40, RSID_RTTY_75 = 41,
 
39
 
 
40
        RSID_AMTOR_FEC = 42,
 
41
 
 
42
        RSID_THROB_1 = 43, RSID_THROB_2 = 44, RSID_THROB_4 = 45,
 
43
        RSID_THROBX_1 = 46, RSID_THROBX_2 = 47, RSID_THROBX_4 = 146,
 
44
 
 
45
        RSID_CONTESTIA_8_250 = 49, RSID_CONTESTIA_16_500 = 50, RSID_CONTESTIA_32_1000 = 51,
 
46
        RSID_CONTESTIA_8_500 = 52, RSID_CONTESTIA_16_1000 = 53, RSID_CONTESTIA_4_500 = 54,
 
47
        RSID_CONTESTIA_4_250 = 55,
 
48
 
 
49
        RSID_VOICE = 56,
 
50
 
 
51
        RSID_MFSK8 = 60, RSID_MFSK16 = 57, RSID_MFSK32 = 147,
 
52
        RSID_MFSK11 = 148, RSID_MFSK22 = 152,
 
53
 
 
54
        RSID_RTTYM_8_250 = 61, RSID_RTTYM_16_500 = 62, RSID_RTTYM_32_1000 = 63,
 
55
        RSID_RTTYM_8_500 = 65, RSID_RTTYM_16_1000 = 66, RSID_RTTYM_4_500 = 67,
 
56
        RSID_RTTYM_4_250 = 68,
 
57
 
 
58
        RSID_OLIVIA_8_250 = 69, RSID_OLIVIA_16_500 = 70, RSID_OLIVIA_32_1000 = 71,
 
59
        RSID_OLIVIA_8_500 = 72, RSID_OLIVIA_16_1000 = 73, RSID_OLIVIA_4_500 = 74,
 
60
        RSID_OLIVIA_4_250 = 75,
 
61
 
 
62
        RSID_PAX = 76, RSID_PAX2 = 77, RSID_DOMINOF = 78, RSID_FAX = 79, RSID_SSTV = 81,
 
63
 
 
64
        RSID_DOMINOEX_4 = 84, RSID_DOMINOEX_5 = 85, RSID_DOMINOEX_8 = 86,
 
65
        RSID_DOMINOEX_11 = 87, RSID_DOMINOEX_16 = 88, RSID_DOMINOEX_22 = 90,
 
66
        RSID_DOMINOEX_4_FEC = 92, RSID_DOMINOEX_5_FEC = 93, RSID_DOMINOEX_8_FEC = 97,
 
67
        RSID_DOMINOEX_11_FEC = 98, RSID_DOMINOEX_16_FEC = 99, RSID_DOMINOEX_22_FEC = 101,
 
68
 
 
69
        RSID_FELD_HELL = 104, RSID_PSK_HELL = 105, RSID_HELL_80 = 106,
 
70
        RSID_FM_HELL_105 = 107, RSID_FM_HELL_245 = 108,
 
71
 
 
72
        RSID_THOR_4 = 136, RSID_THOR_5 = 139, RSID_THOR_8 = 137,
 
73
        RSID_THOR_11 = 143, RSID_THOR_16 = 138, RSID_THOR_22 = 145,
 
74
};
 
75
 
 
76
RSIDs cRsId::rsid_ids[] = {
 
77
        { RSID_BPSK31, MODE_BPSK31 },
 
78
        { RSID_QPSK31, MODE_QPSK31 },
 
79
        { RSID_BPSK63, MODE_PSK63 },
 
80
        { RSID_QPSK63, MODE_QPSK63 },
 
81
        { RSID_BPSK125, MODE_PSK125 },
 
82
        { RSID_QPSK125, MODE_QPSK125 },
 
83
        { RSID_BPSK250, MODE_PSK250 },
 
84
        { RSID_QPSK250, MODE_QPSK250 },
 
85
 
 
86
        { RSID_UNKNOWN_1, NUM_MODES },
 
87
        { RSID_UNKNOWN_2, NUM_MODES },
 
88
 
 
89
        { RSID_MT63_500_LG, MODE_MT63_500 },
 
90
        { RSID_MT63_500_ST, MODE_MT63_500 },
 
91
        { RSID_MT63_500_VST, MODE_MT63_500 },
 
92
        { RSID_MT63_1000_LG, MODE_MT63_1000 },
 
93
        { RSID_MT63_1000_ST, MODE_MT63_1000 },
 
94
        { RSID_MT63_1000_VST, MODE_MT63_1000 },
 
95
        { RSID_MT63_2000_LG, MODE_MT63_2000 },
 
96
        { RSID_MT63_2000_ST, MODE_MT63_2000 },
 
97
        { RSID_MT63_2000_VST, MODE_MT63_2000 },
 
98
 
 
99
        { RSID_PSKAM10,  NUM_MODES },
 
100
        { RSID_PSKAM31, NUM_MODES },
 
101
        { RSID_PSKAM50, NUM_MODES },
 
102
        { RSID_PSK63F, NUM_MODES },
 
103
        { RSID_PSK220F, NUM_MODES },
 
104
        { RSID_CHIP64, NUM_MODES },
 
105
        { RSID_CHIP128, NUM_MODES },
 
106
 
 
107
        { RSID_CW, MODE_CW },
 
108
 
 
109
        { RSID_CCW_OOK_12, NUM_MODES },
 
110
        { RSID_CCW_OOK_24, NUM_MODES },
 
111
        { RSID_CCW_OOK_48, NUM_MODES },
 
112
        { RSID_CCW_FSK_12, NUM_MODES },
 
113
        { RSID_CCW_FSK_24, NUM_MODES },
 
114
        { RSID_CCW_FSK_48, NUM_MODES },
 
115
 
 
116
        { RSID_PACTOR1_FEC, NUM_MODES },
 
117
        { RSID_PACKET_300, NUM_MODES },
 
118
        { RSID_PACKET_1200, NUM_MODES },
 
119
 
 
120
        { RSID_RTTY_ASCII_7, MODE_RTTY },
 
121
        { RSID_RTTY_ASCII_8, MODE_RTTY },
 
122
        { RSID_RTTY_45, MODE_RTTY },
 
123
        { RSID_RTTY_50 , MODE_RTTY },
 
124
        { RSID_RTTY_75 , MODE_RTTY },
 
125
 
 
126
        { RSID_AMTOR_FEC, NUM_MODES },
 
127
 
 
128
        { RSID_THROB_1, MODE_THROB1 },
 
129
        { RSID_THROB_2, MODE_THROB2 },
 
130
        { RSID_THROB_4, MODE_THROB4 },
 
131
        { RSID_THROBX_1, MODE_THROBX1 },
 
132
        { RSID_THROBX_2, MODE_THROBX2 },
 
133
        { RSID_THROBX_4, MODE_THROBX4 },
 
134
 
 
135
        { RSID_CONTESTIA_8_250, NUM_MODES },
 
136
        { RSID_CONTESTIA_16_500, NUM_MODES },
 
137
        { RSID_CONTESTIA_32_1000, NUM_MODES },
 
138
        { RSID_CONTESTIA_8_500, NUM_MODES },
 
139
        { RSID_CONTESTIA_16_1000, NUM_MODES },
 
140
        { RSID_CONTESTIA_4_500, NUM_MODES },
 
141
        { RSID_CONTESTIA_4_250, NUM_MODES },
 
142
 
 
143
        { RSID_VOICE, NUM_MODES },
 
144
 
 
145
        { RSID_MFSK8, MODE_MFSK8 },
 
146
        { RSID_MFSK16, MODE_MFSK16 },
 
147
        { RSID_MFSK32, MODE_MFSK32 },
 
148
#ifdef EXPERIMENTAL
 
149
        { RSID_MFSK11, MODE_MFSK11 },
 
150
        { RSID_MFSK22, MODE_MFSK22 },
 
151
#else
 
152
        { RSID_MFSK11, NUM_MODES },
 
153
        { RSID_MFSK22, NUM_MODES },
 
154
#endif
 
155
 
 
156
        { RSID_RTTYM_8_250, NUM_MODES },
 
157
        { RSID_RTTYM_16_500, NUM_MODES },
 
158
        { RSID_RTTYM_32_1000, NUM_MODES },
 
159
        { RSID_RTTYM_8_500, NUM_MODES },
 
160
        { RSID_RTTYM_16_1000, NUM_MODES },
 
161
        { RSID_RTTYM_4_500, NUM_MODES },
 
162
        { RSID_RTTYM_4_250, NUM_MODES },
 
163
 
 
164
        { RSID_OLIVIA_8_250, MODE_OLIVIA },
 
165
        { RSID_OLIVIA_16_500, MODE_OLIVIA },
 
166
        { RSID_OLIVIA_32_1000, MODE_OLIVIA },
 
167
        { RSID_OLIVIA_8_500, MODE_OLIVIA },
 
168
        { RSID_OLIVIA_16_1000, MODE_OLIVIA },
 
169
        { RSID_OLIVIA_4_500, MODE_OLIVIA },
 
170
        { RSID_OLIVIA_4_250, MODE_OLIVIA },
 
171
 
 
172
        { RSID_PAX, NUM_MODES },
 
173
        { RSID_PAX2, NUM_MODES },
 
174
        { RSID_DOMINOF, NUM_MODES },
 
175
        { RSID_FAX, NUM_MODES },
 
176
        { RSID_SSTV, NUM_MODES },
 
177
 
 
178
        { RSID_DOMINOEX_4, MODE_DOMINOEX4 },
 
179
        { RSID_DOMINOEX_5, MODE_DOMINOEX5 },
 
180
        { RSID_DOMINOEX_8, MODE_DOMINOEX8 },
 
181
        { RSID_DOMINOEX_11, MODE_DOMINOEX11 },
 
182
        { RSID_DOMINOEX_16, MODE_DOMINOEX16 },
 
183
        { RSID_DOMINOEX_22, MODE_DOMINOEX22 },
 
184
        { RSID_DOMINOEX_4_FEC, MODE_DOMINOEX4 },
 
185
        { RSID_DOMINOEX_5_FEC, MODE_DOMINOEX5 },
 
186
        { RSID_DOMINOEX_8_FEC, MODE_DOMINOEX8 },
 
187
        { RSID_DOMINOEX_11_FEC, MODE_DOMINOEX11 },
 
188
        { RSID_DOMINOEX_16_FEC, MODE_DOMINOEX16 },
 
189
        { RSID_DOMINOEX_22_FEC, MODE_DOMINOEX22 },
 
190
 
 
191
        { RSID_FELD_HELL, MODE_FELDHELL },
 
192
        { RSID_PSK_HELL, NUM_MODES },
 
193
        { RSID_HELL_80 , MODE_HELL80 },
 
194
        { RSID_FM_HELL_105, MODE_FSKH105 },
 
195
        { RSID_FM_HELL_245, NUM_MODES },
 
196
 
 
197
        { RSID_THOR_4, MODE_THOR4 },
 
198
        { RSID_THOR_8, MODE_THOR8 },
 
199
        { RSID_THOR_16, MODE_THOR16 },
 
200
        { RSID_THOR_5, MODE_THOR5 },
 
201
        { RSID_THOR_11, MODE_THOR11 },
 
202
        { RSID_THOR_22, MODE_THOR22 },
 
203
 
 
204
        { RSID_NONE, NUM_MODES }
 
205
};
 
206
 
 
207
const int cRsId::Squares[256] = {
 
208
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
209
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
 
210
        0, 2, 4, 6, 8,10,12,14, 9,11,13,15, 1, 3, 5, 7,
 
211
        0, 3, 6, 5,12,15,10, 9, 1, 2, 7, 4,13,14,11, 8,
 
212
        0, 4, 8,12, 9,13, 1, 5,11,15, 3, 7, 2, 6,10,14,
 
213
        0, 5,10,15,13, 8, 7, 2, 3, 6, 9,12,14,11, 4, 1,
 
214
        0, 6,12,10, 1, 7,13,11, 2, 4,14, 8, 3, 5,15, 9,
 
215
        0, 7,14, 9, 5, 2,11,12,10,13, 4, 3,15, 8, 1, 6,
 
216
        0, 8, 9, 1,11, 3, 2,10,15, 7, 6,14, 4,12,13, 5,
 
217
        0, 9,11, 2,15, 6, 4,13, 7,14,12, 5, 8, 1, 3,10,
 
218
        0,10,13, 7, 3, 9,14, 4, 6,12,11, 1, 5,15, 8, 2,
 
219
        0,11,15, 4, 7,12, 8, 3,14, 5, 1,10, 9, 2, 6,13,
 
220
        0,12, 1,13, 2,14, 3,15, 4, 8, 5, 9, 6,10, 7,11,
 
221
        0,13, 3,14, 6,11, 5, 8,12, 1,15, 2,10, 7, 9, 4,
 
222
        0,14, 5,11,10, 4,15, 1,13, 3, 8, 6, 7, 9, 2,12,
 
223
        0,15, 7, 8,14, 1, 9, 6, 5,10, 2,13,11, 4,12, 3
 
224
};
 
225
 
 
226
const int cRsId::indices[] = { 
 
227
        2, 4, 8, 9, 11, 15, 7, 14, 5, 10, 13, 3 
 
228
};
 
229
 
 
230
cRsId :: cRsId()
 
231
{
 
232
        memset (aInputSamples, 0, RSID_ARRAY_SIZE * sizeof(double));    
 
233
        memset (aFFTReal, 0, RSID_ARRAY_SIZE * sizeof(double)); 
 
234
        memset (aFFTAmpl, 0, RSID_FFT_SIZE * sizeof(double));
 
235
        memset (fftwindow, 0, RSID_ARRAY_SIZE * sizeof(double));
 
236
        
 
237
        memset (aHashTable1, 255, 256);
 
238
        memset (aHashTable2, 255, 256);
 
239
        
 
240
// compute current size of rsid_ids
 
241
        rsid_ids_size = 0;
 
242
        while (rsid_ids[rsid_ids_size].rs) rsid_ids_size++;
 
243
 
 
244
        pCodes = new uchar[rsid_ids_size * RSID_NSYMBOLS];
 
245
        memset (pCodes, 0, rsid_ids_size * RSID_NSYMBOLS);
 
246
 
 
247
// Initialization  of assigned mode/submode IDs.
 
248
// HashTable is used for finding a code with lowest Hamming distance.
 
249
        
 
250
        for (int i = 0; i < rsid_ids_size; i++) {
 
251
                uchar *c = pCodes + i * RSID_NSYMBOLS;
 
252
                int    hash1;
 
253
                int    hash2;
 
254
                Encode(rsid_ids[i].rs, c);
 
255
                hash1 = c[11] | (c[12] << 4);
 
256
                hash2 = c[13] | (c[14] << 4);
 
257
 
 
258
                aHashTable1[hash1] = i;
 
259
                aHashTable2[hash2] = i;
 
260
        }
 
261
 
 
262
        for (int i = 0; i < RSID_NTIMES; i++)
 
263
                for (int j = 0; j < RSID_FFT_SIZE; j++)
 
264
                        aBuckets[i][j] = 0;
 
265
 
 
266
        iPrevDistance = 99;
 
267
 
 
268
        BlackmanWindow(fftwindow, RSID_FFT_SIZE);
 
269
 
 
270
        nBinLow = RSID_RESOL + 1;
 
271
        nBinHigh = RSID_FFT_SIZE - 32;
 
272
        iTime = 0;
 
273
        bPrevTimeSliceValid = false;
 
274
        
 
275
        _samplerate = 11025;
 
276
}
 
277
 
 
278
cRsId::~cRsId()
 
279
{
 
280
        delete [] pCodes;
 
281
}
 
282
 
 
283
void cRsId::reset()
 
284
{
 
285
        iPrevDistance = 99;
 
286
        bPrevTimeSliceValid = false;
 
287
        iTime = 0;
 
288
        memset (aInputSamples, 0, RSID_ARRAY_SIZE * sizeof(double));    
 
289
        memset (aFFTReal, 0, RSID_ARRAY_SIZE * sizeof(double)); 
 
290
        memset (aFFTAmpl, 0, RSID_FFT_SIZE * sizeof(double));
 
291
        for (int i = 0; i < RSID_NTIMES; i++)
 
292
                for (int j = 0; j < RSID_FFT_SIZE; j++)
 
293
                        aBuckets[i][j] = 0;
 
294
}
 
295
 
 
296
void cRsId::Encode(int code, uchar *rsid)
 
297
{
 
298
        rsid[0] = code >> 8;
 
299
        rsid[1] = (code >> 4) & 0x0f;
 
300
        rsid[2] = code & 0x0f;
 
301
        for (int i = 3; i < RSID_NSYMBOLS; i++)
 
302
                rsid[i] = 0;
 
303
        for (int i = 0; i < 12; i++) {
 
304
                for (int j = RSID_NSYMBOLS - 1; j > 0; j--)
 
305
                        rsid[j] = rsid[j - 1] ^ Squares[(rsid[j] << 4) + indices[i]];
 
306
                rsid[0] = Squares[(rsid[0] << 4) + indices[i]];
 
307
        }
 
308
}
 
309
 
 
310
 
 
311
void cRsId::CalculateBuckets(const double *pSpectrum, int iBegin, int iEnd)
 
312
{
 
313
        double   Amp = 0.0, AmpMax = 0.0;
 
314
        int   iBucketMax = iBegin - RSID_RESOL;
 
315
        int   i, j;
 
316
        bool  firstpass = true;
 
317
 
 
318
        for (i = iBegin; i < iEnd; i += RSID_RESOL) {
 
319
                if (firstpass) {
 
320
                        AmpMax          = pSpectrum[i];
 
321
                        iBucketMax      = i;
 
322
                        for (j = i + RSID_RESOL; j < i + RSID_NTIMES + RSID_RESOL; j += RSID_RESOL) {
 
323
                                Amp = pSpectrum[j];
 
324
                                if (Amp > AmpMax) {
 
325
                                        AmpMax    = Amp;
 
326
                                        iBucketMax = j;
 
327
                                }
 
328
                        }
 
329
                        firstpass = false;
 
330
                } else {
 
331
                        j    = i + RSID_NTIMES;
 
332
                        Amp = pSpectrum[j];
 
333
                        if (Amp > AmpMax) {
 
334
                                AmpMax    = Amp;
 
335
                                iBucketMax = j;
 
336
                        }
 
337
                }
 
338
                aBuckets[iTime][i] = (iBucketMax - i) >> 1;
 
339
        }
 
340
}
 
341
 
 
342
 
 
343
void cRsId::search( const double *pSamples, int nSamples )
 
344
{
 
345
        int i, ns;
 
346
        bool bReverse = false;
 
347
        double Real, Imag;
 
348
        double centerfreq = active_modem->get_freq();
 
349
 
 
350
        if (progdefaults.rsidWideSearch) {
 
351
                nBinLow = RSID_RESOL + 1;
 
352
                nBinHigh = RSID_FFT_SIZE - 32;
 
353
        } else {
 
354
                nBinLow = (int)((centerfreq  - 100.0 * RSID_RESOL) * 2048.0 / 11025.0);
 
355
                nBinHigh = (int)((centerfreq  + 100.0 * RSID_RESOL) * 2048.0 / 11025.0);
 
356
        }
 
357
        
 
358
        if (wf->Reverse() == true && wf->USB() == true) bReverse = true;
 
359
        if (wf->Reverse() == false && wf->USB() == false) bReverse = true;
 
360
        
 
361
        ns = nSamples;
 
362
        if (ns > RSID_ARRAY_SIZE / 4) {
 
363
                ns = RSID_ARRAY_SIZE / 4;
 
364
        }
 
365
        
 
366
        if (bReverse) {
 
367
                nBinLow  = RSID_FFT_SIZE - nBinHigh;
 
368
                nBinHigh = RSID_FFT_SIZE - nBinLow;
 
369
        }
 
370
 
 
371
        memmove (aInputSamples, aInputSamples + ns, ns * sizeof(double));
 
372
        memcpy  (aInputSamples + ns, pSamples, ns * sizeof(double));
 
373
        
 
374
        memset  (aFFTReal, 0, RSID_ARRAY_SIZE * sizeof(double));
 
375
        memcpy  (aFFTReal, aInputSamples, RSID_FFT_SIZE * sizeof(double));
 
376
// or 
 
377
//      for (int i = 0; i < RSID_FFT_SIZE; i++)
 
378
//              aFFTReal[i] = aInputSamples[i] * fftwindow[i];
 
379
 
 
380
        rsrfft( aFFTReal, 11);
 
381
 
 
382
        memset(aFFTAmpl, 0, RSID_FFT_SIZE * sizeof(double));
 
383
        for (i = 1; i < RSID_FFT_SIZE; i++) {
 
384
                if (bReverse) {
 
385
                        Real = aFFTReal[RSID_FFT_SIZE - i];
 
386
                        Imag = aFFTReal[RSID_FFT_SIZE + i];
 
387
                } else {
 
388
                        Real = aFFTReal[i];
 
389
                        Imag = aFFTReal[2 * RSID_FFT_SIZE - i];
 
390
                }
 
391
                aFFTAmpl[i] = Real * Real + Imag * Imag;
 
392
        }
 
393
 
 
394
        int SymbolOut = -1, 
 
395
            BinOut = -1;
 
396
        
 
397
        if (search_amp ( SymbolOut, BinOut ) ){
 
398
                if (bReverse)
 
399
                        BinOut = 1024 - BinOut - 31;
 
400
                apply(SymbolOut, BinOut);
 
401
        }
 
402
}
 
403
 
 
404
void cRsId::apply(int iSymbol, int iBin)
 
405
{
 
406
 
 
407
        double freq = (iBin + (RSID_NSYMBOLS - 1) * RSID_RESOL / 2) * 11025.0 / 2048.0;
 
408
 
 
409
        int mbin = 0;
 
410
        for (int n = 0; n < rsid_ids_size; n++)
 
411
                if (rsid_ids[n].rs == iSymbol) {
 
412
                        mbin = rsid_ids[n].mode;
 
413
                        break;
 
414
                }
 
415
                
 
416
        REQ(toggleRSID);
 
417
 
 
418
        if (mbin == NUM_MODES) return;
 
419
 
 
420
        switch (iSymbol) {
 
421
        // rtty parameters
 
422
        case RSID_RTTY_ASCII_7:
 
423
                progdefaults.rtty_baud = 5;
 
424
                progdefaults.rtty_bits = 1;
 
425
                progdefaults.rtty_shift = 9;
 
426
                REQ(&set_rtty_tab_widgets);
 
427
                break;
 
428
        case RSID_RTTY_ASCII_8:
 
429
                progdefaults.rtty_baud = 5;
 
430
                progdefaults.rtty_bits = 2;
 
431
                progdefaults.rtty_shift = 9;
 
432
                REQ(&set_rtty_tab_widgets);
 
433
                break;
 
434
        case RSID_RTTY_45:
 
435
                progdefaults.rtty_baud = 1;
 
436
                progdefaults.rtty_bits = 0;
 
437
                progdefaults.rtty_shift = 3;
 
438
                REQ(&set_rtty_tab_widgets);
 
439
                break;
 
440
        case RSID_RTTY_50:
 
441
                progdefaults.rtty_baud = 2;
 
442
                progdefaults.rtty_bits = 0;
 
443
                progdefaults.rtty_shift = 3;
 
444
                REQ(&set_rtty_tab_widgets);
 
445
                break;
 
446
        case RSID_RTTY_75:
 
447
                progdefaults.rtty_baud = 4;
 
448
                progdefaults.rtty_bits = 0;
 
449
                progdefaults.rtty_shift = 9;
 
450
                REQ(&set_rtty_tab_widgets);
 
451
                break;
 
452
        // special MultiPsk FEC modes
 
453
        case RSID_DOMINOEX_4_FEC: case RSID_DOMINOEX_5_FEC: case RSID_DOMINOEX_8_FEC:
 
454
        case RSID_DOMINOEX_11_FEC: case RSID_DOMINOEX_16_FEC: case RSID_DOMINOEX_22_FEC:
 
455
                progdefaults.DOMINOEX_FEC = true;
 
456
                break;
 
457
        // olivia parameters
 
458
        case RSID_OLIVIA_8_250:
 
459
                progdefaults.oliviatones = 2;
 
460
                progdefaults.oliviabw = 1;
 
461
                REQ(&set_olivia_tab_widgets);
 
462
                break;
 
463
        case RSID_OLIVIA_16_500:
 
464
                progdefaults.oliviatones = 3;
 
465
                progdefaults.oliviabw = 2;
 
466
                REQ(&set_olivia_tab_widgets);
 
467
                break;
 
468
        case RSID_OLIVIA_32_1000:
 
469
                progdefaults.oliviatones = 4;
 
470
                progdefaults.oliviabw = 3;
 
471
                REQ(&set_olivia_tab_widgets);
 
472
                break;
 
473
        case RSID_OLIVIA_8_500:
 
474
                progdefaults.oliviatones = 2;
 
475
                progdefaults.oliviabw = 2;
 
476
                REQ(&set_olivia_tab_widgets);
 
477
                break;
 
478
        case RSID_OLIVIA_16_1000:
 
479
                progdefaults.oliviatones = 3;
 
480
                progdefaults.oliviabw = 3;
 
481
                REQ(&set_olivia_tab_widgets);
 
482
                break;
 
483
        case RSID_OLIVIA_4_500:
 
484
                progdefaults.oliviatones = 1;
 
485
                progdefaults.oliviabw = 2;
 
486
                REQ(&set_olivia_tab_widgets);
 
487
                break;
 
488
        case RSID_OLIVIA_4_250:
 
489
                progdefaults.oliviatones = 1;
 
490
                progdefaults.oliviabw = 1;
 
491
                REQ(&set_olivia_tab_widgets);
 
492
                break;
 
493
        // mt63
 
494
        case RSID_MT63_500_LG: case RSID_MT63_1000_LG: case RSID_MT63_2000_LG:
 
495
                progdefaults.mt63_interleave = 64;
 
496
                break;
 
497
        case RSID_MT63_500_ST: case RSID_MT63_1000_ST: case RSID_MT63_2000_ST:
 
498
        case RSID_MT63_500_VST: case RSID_MT63_1000_VST: case RSID_MT63_2000_VST:
 
499
                progdefaults.mt63_interleave = 32;
 
500
                break;
 
501
 
 
502
        default:
 
503
                break;
 
504
        }
 
505
 
 
506
        REQ(&configuration::loadDefaults, &progdefaults);
 
507
 
 
508
        active_modem->set_freq(freq);
 
509
        REQ(init_modem, mbin);
 
510
        
 
511
}
 
512
 
 
513
//=============================================================================
 
514
// search_amp routine #1
 
515
//=============================================================================
 
516
 
 
517
int cRsId::HammingDistance(int iBucket, uchar *p2)
 
518
{
 
519
        int dist = 0;
 
520
        int j = iTime - RSID_NTIMES + 1; // first value
 
521
        if (j < 0)
 
522
                j += RSID_NTIMES;
 
523
        for (int i = 0; i < RSID_NSYMBOLS; i++) {
 
524
                if (aBuckets[j][iBucket] != p2[i])//*p2++)
 
525
                        if (++dist == 2)
 
526
                                return dist;
 
527
                j += RSID_RESOL;//2;
 
528
                if (j >= RSID_NTIMES)
 
529
                        j -= RSID_NTIMES;
 
530
        }
 
531
        return dist;
 
532
}
 
533
 
 
534
bool cRsId::search_amp( int &SymbolOut, int &BinOut)
 
535
{
 
536
        int i, j;
 
537
        int iDistanceMin = 99;  // infinity
 
538
        int iDistance;
 
539
        int iBin                 = -1;
 
540
        int iSymbol              = -1;
 
541
        int iEnd                 = nBinHigh - RSID_NTIMES;//30;
 
542
        int i1, i2, i3;
 
543
 
 
544
        if (++iTime == RSID_NTIMES)
 
545
                iTime = 0;
 
546
 
 
547
        i1 = iTime - 3 * RSID_RESOL;//6;
 
548
        i2 = i1 + RSID_RESOL;//2;
 
549
        i3 = i2 + RSID_RESOL;//2;
 
550
 
 
551
        if (i1 < 0) {
 
552
                i1 += RSID_NTIMES;
 
553
                if (i2 < 0) {
 
554
                        i2 += RSID_NTIMES;
 
555
                        if (i3 < 0)
 
556
                                i3 += RSID_NTIMES;
 
557
                }
 
558
        }
 
559
 
 
560
        CalculateBuckets ( aFFTAmpl, nBinLow,     iEnd);//nBinHigh - 30);
 
561
        CalculateBuckets ( aFFTAmpl, nBinLow + 1, iEnd);//nBinHigh - 30);
 
562
 
 
563
        for (i = nBinLow; i < iEnd; ++ i) {
 
564
                j = aHashTable1[aBuckets[i1][i] | (aBuckets[i2][i] << 4)];
 
565
                if (j < rsid_ids_size)  { //!= 255) {
 
566
                        iDistance = HammingDistance(i, pCodes + j * RSID_NSYMBOLS);
 
567
                        if (iDistance < 2 && iDistance < iDistanceMin) {
 
568
                                iDistanceMin = iDistance;
 
569
                                iSymbol          = rsid_ids[j].rs;
 
570
                                iBin             = i;
 
571
                        }
 
572
                }
 
573
                j = aHashTable2[aBuckets[i3][i] | (aBuckets[iTime][i] << 4)];
 
574
                if (j < rsid_ids_size)  { //!= 255) {
 
575
                        iDistance = HammingDistance (i, pCodes + j * RSID_NSYMBOLS);
 
576
                        if (iDistance < 2 && iDistance < iDistanceMin) {
 
577
                                iDistanceMin = iDistance;
 
578
                                iSymbol          = rsid_ids[j].rs;
 
579
                                iBin             = i;
 
580
                        }
 
581
                }
 
582
        }
 
583
 
 
584
        if (iSymbol == -1) {
 
585
                // No RSID found in this time slice.
 
586
                // If there is a code stored from the previous time slice, return it.
 
587
                if (bPrevTimeSliceValid) {
 
588
                        SymbolOut                       = iPrevSymbol;
 
589
                        BinOut                          = iPrevBin;
 
590
                        DistanceOut             = iPrevDistance;
 
591
                        MetricsOut                      = 0;
 
592
                        bPrevTimeSliceValid = false;
 
593
                        return true;
 
594
                }
 
595
                return false;
 
596
        }
 
597
 
 
598
        if (! bPrevTimeSliceValid || 
 
599
                iDistanceMin <= iPrevDistance) {
 
600
                iPrevSymbol             = iSymbol;
 
601
                iPrevBin                = iBin;
 
602
                iPrevDistance   = iDistanceMin;
 
603
        }
 
604
        bPrevTimeSliceValid = true;
 
605
        return false;
 
606
}
 
607
 
 
608
//=============================================================================
 
609
// transmit rsid code for current mode
 
610
//=============================================================================
 
611
 
 
612
void cRsId::send()
 
613
{
 
614
        int iTone;
 
615
        uchar rsid[RSID_NSYMBOLS];
 
616
        double phaseincr;
 
617
        double freq, fr;
 
618
        double sr;
 
619
        int symlen;
 
620
        
 
621
        sr = active_modem->get_samplerate();
 
622
        symlen = (int)floor(RSID_SYMLEN * sr);
 
623
        fr = 1.0 * active_modem->get_txfreq() - (11025.0 * 7 / 1024);
 
624
        
 
625
        trx_mode mode = active_modem->get_mode();
 
626
        uchar rmode = RSID_NONE;
 
627
 
 
628
        switch (mode) {
 
629
        case MODE_RTTY :
 
630
                if (progdefaults.rtty_baud == 5 && progdefaults.rtty_bits == 1 && progdefaults.rtty_shift == 9)
 
631
                        rmode = RSID_RTTY_ASCII_7;
 
632
                else if (progdefaults.rtty_baud == 5 && progdefaults.rtty_bits == 1 && progdefaults.rtty_shift == 9)
 
633
                        rmode = RSID_RTTY_ASCII_8;
 
634
                else if (progdefaults.rtty_baud == 1 && progdefaults.rtty_bits == 0 && progdefaults.rtty_shift == 3)
 
635
                        rmode = RSID_RTTY_45;
 
636
                else if (progdefaults.rtty_baud == 2 && progdefaults.rtty_bits == 0 && progdefaults.rtty_shift == 3)
 
637
                        rmode = RSID_RTTY_50;
 
638
                else if (progdefaults.rtty_baud == 4 && progdefaults.rtty_bits == 0 && progdefaults.rtty_shift == 9)
 
639
                        rmode = RSID_RTTY_75;
 
640
                else
 
641
                        rmode = RSID_RTTY_45;; // 45 baud Baudot, shift 170
 
642
                break;
 
643
 
 
644
        case MODE_OLIVIA:
 
645
                if (progdefaults.oliviatones == 2 && progdefaults.oliviabw == 1)
 
646
                        rmode = RSID_OLIVIA_8_250;
 
647
                else if (progdefaults.oliviatones == 3 && progdefaults.oliviabw == 2)
 
648
                        rmode = RSID_OLIVIA_16_500;
 
649
                else if (progdefaults.oliviatones == 4 && progdefaults.oliviabw == 3)
 
650
                        rmode = RSID_OLIVIA_32_1000;
 
651
                else if (progdefaults.oliviatones == 2 && progdefaults.oliviabw == 2)
 
652
                        rmode = RSID_OLIVIA_8_500;
 
653
                else if (progdefaults.oliviatones == 3 && progdefaults.oliviabw == 3)
 
654
                        rmode = RSID_OLIVIA_16_1000;
 
655
                else if (progdefaults.oliviatones == 1 && progdefaults.oliviabw == 2)
 
656
                        rmode = RSID_OLIVIA_4_500;
 
657
                else if (progdefaults.oliviatones == 1 && progdefaults.oliviabw == 1)
 
658
                        rmode = RSID_OLIVIA_4_250;
 
659
                else
 
660
                        rmode = RSID_OLIVIA_16_500;
 
661
                break;
 
662
 
 
663
        case MODE_DOMINOEX4:
 
664
                if (progdefaults.DOMINOEX_FEC)
 
665
                        rmode = RSID_DOMINOEX_4_FEC;
 
666
                break;
 
667
        case MODE_DOMINOEX5:
 
668
                if (progdefaults.DOMINOEX_FEC)
 
669
                        rmode = RSID_DOMINOEX_5_FEC;
 
670
                break;
 
671
        case MODE_DOMINOEX8:
 
672
                if (progdefaults.DOMINOEX_FEC)
 
673
                        rmode = RSID_DOMINOEX_8_FEC;
 
674
                break;
 
675
        case MODE_DOMINOEX11:
 
676
                if (progdefaults.DOMINOEX_FEC)
 
677
                        rmode = RSID_DOMINOEX_11_FEC;
 
678
                break;
 
679
        case MODE_DOMINOEX16:
 
680
                if (progdefaults.DOMINOEX_FEC)
 
681
                        rmode = RSID_DOMINOEX_16_FEC;
 
682
                break;
 
683
        case MODE_DOMINOEX22:
 
684
                if (progdefaults.DOMINOEX_FEC)
 
685
                        rmode = RSID_DOMINOEX_22_FEC;
 
686
                break;
 
687
 
 
688
        case MODE_MT63_500:
 
689
                if (progdefaults.mt63_interleave == 32)
 
690
                        rmode = RSID_MT63_500_ST;
 
691
                break;
 
692
        case MODE_MT63_1000:
 
693
                if (progdefaults.mt63_interleave == 32)
 
694
                        rmode = RSID_MT63_1000_ST;
 
695
                break;
 
696
        case MODE_MT63_2000:
 
697
                if (progdefaults.mt63_interleave == 32)
 
698
                        rmode = RSID_MT63_2000_ST;
 
699
                break;
 
700
        }
 
701
 
 
702
        // if rmode is still unset, look it up
 
703
        if (rmode == RSID_NONE) {
 
704
                for (size_t i = 0; i < sizeof(rsid_ids)/sizeof(*rsid_ids); i++) {
 
705
                        if (mode == rsid_ids[i].mode) {
 
706
                                rmode = rsid_ids[i].rs;
 
707
                                break;
 
708
                        }
 
709
                }
 
710
        }
 
711
        if (rmode == RSID_NONE)
 
712
                return;
 
713
        Encode(rmode, rsid);
 
714
 
 
715
 
 
716
        outbuf = new double[symlen];
 
717
                
 
718
// transmit sequence of 15 symbols (tones)
 
719
        phase = 0.0;
 
720
        for (int i = 0; i < 15; i++) {
 
721
                iTone = rsid[i];
 
722
                if (active_modem->get_reverse())
 
723
                        iTone = 15 - iTone;
 
724
                freq = fr + iTone * 11025.0 / 1024;
 
725
                phaseincr = 2.0 * M_PI * freq / sr;
 
726
 
 
727
                for (int j = 0; j < symlen; j++) {
 
728
                        phase += phaseincr;
 
729
                        if (phase > 2.0 * M_PI) phase -= 2.0 * M_PI;
 
730
                        outbuf[j] = sin(phase);
 
731
                }
 
732
                active_modem->ModulateXmtr(outbuf, symlen);
 
733
 
 
734
        }
 
735
// transmit 3 symbol periods of silence
 
736
        for (int j = 0; j < symlen; j++) outbuf[j] = 0.0;
 
737
        active_modem->ModulateXmtr(outbuf, symlen);
 
738
        active_modem->ModulateXmtr(outbuf, symlen);
 
739
        active_modem->ModulateXmtr(outbuf, symlen);
 
740
// clean up
 
741
 
 
742
        delete [] outbuf;
 
743
}
 
744