mirror of
https://github.com/aicodix/modem.git
synced 2026-04-27 14:30:34 +00:00
added some more modes
This commit is contained in:
parent
f0f0aace39
commit
b10e171e9a
3 changed files with 151 additions and 46 deletions
31
README.md
vendored
31
README.md
vendored
|
|
@ -12,7 +12,7 @@ dd if=/dev/urandom of=uncoded.dat bs=1 count=256
|
|||
Encode file ```uncoded.dat``` to ```encoded.wav``` [WAV](https://en.wikipedia.org/wiki/WAV) audio file with 8000 Hz sample rate, 16 bits and only 1 (real) channel:
|
||||
|
||||
```
|
||||
./encode encoded.wav 8000 16 1 1500 23 CALLSIGN uncoded.dat
|
||||
./encode encoded.wav 8000 16 1 1500 5 uncoded.dat
|
||||
```
|
||||
|
||||
Start recording to ```recorded.wav``` audio file and stop after 5 seconds:
|
||||
|
|
@ -41,18 +41,23 @@ diff -s uncoded.dat decoded.dat
|
|||
|
||||
### Supported Modes
|
||||
|
||||
Ping:
|
||||
* Mode 0: DBPSK, 2/7-rate code, 1600 Hz bandwidth, 0.36 seconds and no payload
|
||||
All modes need a bandwidth of 2000 Hz and use a 1/2-rate forward error correction code
|
||||
|
||||
Next:
|
||||
* Mode 23: DQPSK, 1/2-rate code, 1600 Hz bandwidth, 1.80 seconds and 256 bytes
|
||||
* Mode 24: DQPSK, 1/2-rate code, 1600 Hz bandwidth, 3.24 seconds and 512 bytes
|
||||
* Mode 25: DQPSK, 1/2-rate code, 1600 Hz bandwidth, 6.12 seconds and 1024 bytes
|
||||
* Mode 26: QAM16, 1/2-rate code, 1700 Hz bandwidth, 1.08 seconds and 256 bytes
|
||||
* Mode 27: QAM16, 1/2-rate code, 1700 Hz bandwidth, 1.80 seconds and 512 bytes
|
||||
* Mode 28: QAM16, 1/2-rate code, 1700 Hz bandwidth, 3.24 seconds and 1024 bytes
|
||||
* Mode 29: QAM64, 1/2-rate code, 1900 Hz bandwidth, 1.26 seconds and 512 bytes
|
||||
* Mode 30: QAM64, 1/2-rate code, 1900 Hz bandwidth, 2.16 seconds and 1024 bytes
|
||||
* Mode 1: QPSK, 1.02 seconds and 128 bytes
|
||||
* Mode 2: QPSK, 1.70 seconds and 256 bytes
|
||||
* Mode 3: QPSK, 3.06 seconds and 512 bytes
|
||||
* Mode 4: QPSK, 5.78 seconds and 1024 bytes
|
||||
* Mode 5: QAM16, 1.02 seconds and 256 bytes
|
||||
* Mode 6: QAM16, 1.70 seconds and 512 bytes
|
||||
* Mode 7: QAM16, 3.06 seconds and 1024 bytes
|
||||
* Mode 8: QAM16, 5.78 seconds and 2048 bytes
|
||||
* Mode 9: QAM64, 2.21 seconds and 1024 bytes
|
||||
* Mode 10: QAM64, 4.08 seconds and 2048 bytes
|
||||
* Mode 11: QAM64, 7.82 seconds and 4096 bytes
|
||||
* Mode 12: QAM256, 1.02 seconds and 512 bytes
|
||||
* Mode 13: QAM256, 1.70 seconds and 1024 bytes
|
||||
* Mode 14: QAM256, 3.06 seconds and 2048 bytes
|
||||
* Mode 15: QAM256, 5.78 seconds and 4096 bytes
|
||||
|
||||
### Simulating
|
||||
|
||||
|
|
@ -61,7 +66,7 @@ Prerequisite: [disorders](https://github.com/aicodix/disorders)
|
|||
Encode ```uncoded.dat``` to [analytic](https://en.wikipedia.org/wiki/Analytic_signal) audio signal, add [multipath](https://en.wikipedia.org/wiki/Multipath_propagation), [CFO, SFO](https://en.wikipedia.org/wiki/Carrier_frequency_offset), [AWGN](https://en.wikipedia.org/wiki/Additive_white_Gaussian_noise), decode and compare:
|
||||
|
||||
```
|
||||
./encode - 8000 16 2 1500 23 CALLSIGN uncoded.dat | ../disorders/multipath - - ../disorders/multipath.txt 10 | ../disorders/cfo - - 234.567 | ../disorders/sfo - - 147 | ../disorders/awgn - - -30 | ./decode - - | diff -q -s uncoded.dat -
|
||||
./encode - 8000 16 2 1500 5 uncoded.dat | ../disorders/multipath - - ../disorders/multipath.txt 10 | ../disorders/cfo - - 234.567 | ../disorders/sfo - - 147 | ../disorders/awgn - - -30 | ./decode - - | diff -q -s uncoded.dat -
|
||||
```
|
||||
|
||||
### Reading
|
||||
|
|
|
|||
87
decode.cc
87
decode.cc
|
|
@ -45,11 +45,11 @@ struct Decoder
|
|||
static const int symbol_len = guard_len * 16;
|
||||
static const int filter_len = (((21 * rate) / 8000) & ~3) | 1;
|
||||
static const int extended_len = symbol_len + guard_len;
|
||||
static const int mod_max = 6;
|
||||
static const int mod_max = 8;
|
||||
static const int code_max = 16;
|
||||
static const int bits_max = 1 << code_max;
|
||||
static const int data_max = 1024;
|
||||
static const int symbols_max = 32;
|
||||
static const int data_max = 4096;
|
||||
static const int symbols_max = 44;
|
||||
static const int mls0_poly = 0b1100110001;
|
||||
static const int mls0_seed = 214;
|
||||
static const int mls1_poly = 0b100101011;
|
||||
|
|
@ -127,6 +127,8 @@ struct Decoder
|
|||
return QuadratureAmplitudeModulation<16, cmplx, code_type>::soft(b, c, precision);
|
||||
case 6:
|
||||
return QuadratureAmplitudeModulation<64, cmplx, code_type>::soft(b, c, precision);
|
||||
case 8:
|
||||
return QuadratureAmplitudeModulation<256, cmplx, code_type>::soft(b, c, precision);
|
||||
}
|
||||
}
|
||||
void shuffle(code_type *dest, const code_type *src)
|
||||
|
|
@ -174,61 +176,110 @@ struct Decoder
|
|||
void setup(int oper_mode) {
|
||||
switch (oper_mode) {
|
||||
case 1:
|
||||
mod_bits = 2;
|
||||
symbol_count = 4;
|
||||
code_order = 11;
|
||||
data_bits = 1024;
|
||||
frozen_bits = frozen_2048_1056;
|
||||
break;
|
||||
case 2:
|
||||
mod_bits = 2;
|
||||
symbol_count = 8;
|
||||
code_order = 12;
|
||||
data_bits = 2048;
|
||||
frozen_bits = frozen_4096_2080;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
mod_bits = 2;
|
||||
symbol_count = 16;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
mod_bits = 2;
|
||||
symbol_count = 32;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
mod_bits = 4;
|
||||
symbol_count = 4;
|
||||
code_order = 12;
|
||||
data_bits = 2048;
|
||||
frozen_bits = frozen_4096_2080;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
mod_bits = 4;
|
||||
symbol_count = 8;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
mod_bits = 4;
|
||||
symbol_count = 16;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 7:
|
||||
mod_bits = 6;
|
||||
symbol_count = 6;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 8:
|
||||
mod_bits = 4;
|
||||
symbol_count = 32;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 9:
|
||||
mod_bits = 6;
|
||||
symbol_count = 11;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 10:
|
||||
mod_bits = 6;
|
||||
symbol_count = 22;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 11:
|
||||
mod_bits = 6;
|
||||
symbol_count = 44;
|
||||
code_order = 16;
|
||||
data_bits = 32768;
|
||||
frozen_bits = frozen_65536_32800;
|
||||
break;
|
||||
case 12:
|
||||
mod_bits = 8;
|
||||
symbol_count = 4;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 13:
|
||||
mod_bits = 8;
|
||||
symbol_count = 8;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 14:
|
||||
mod_bits = 8;
|
||||
symbol_count = 16;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 15:
|
||||
mod_bits = 8;
|
||||
symbol_count = 32;
|
||||
code_order = 16;
|
||||
data_bits = 32768;
|
||||
frozen_bits = frozen_65536_32800;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -276,7 +327,7 @@ struct Decoder
|
|||
for (int i = 0; i < pilot_tones; ++i)
|
||||
mode[i] = clamp(std::nearbyint(127 * demod_or_erase(tone[i*block_length+pilot_offset], chan[i*block_length+pilot_offset]).real() * nrz(seq1())));
|
||||
int oper_mode = hadamarddec(mode);
|
||||
if (oper_mode < 0 || oper_mode > 8) {
|
||||
if (oper_mode < 0 || oper_mode > 15) {
|
||||
std::cerr << "operation mode " << oper_mode << " unsupported." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -347,9 +398,7 @@ struct Decoder
|
|||
if (i % block_length == roff)
|
||||
continue;
|
||||
int bits = mod_bits;
|
||||
if (oper_mode == 7 && k % 32 == 30)
|
||||
bits = 2;
|
||||
else if (oper_mode == 8 && k % 64 == 60)
|
||||
if (oper_mode >= 9 && oper_mode <= 11 && k % 64 == 60)
|
||||
bits = 4;
|
||||
demap_bits(perm+k, demod[tone_count*j+i], precision, bits);
|
||||
k += bits;
|
||||
|
|
|
|||
85
encode.cc
85
encode.cc
|
|
@ -30,7 +30,7 @@ struct Encoder
|
|||
static const int guard_len = rate / 100;
|
||||
static const int symbol_len = guard_len * 16;
|
||||
static const int bits_max = 65536;
|
||||
static const int data_max = 1024;
|
||||
static const int data_max = 4096;
|
||||
static const int mls0_poly = 0b1100110001;
|
||||
static const int mls0_seed = 214;
|
||||
static const int mls1_poly = 0b100101011;
|
||||
|
|
@ -172,6 +172,8 @@ struct Encoder
|
|||
return QuadratureAmplitudeModulation<16, cmplx, code_type>::map(b);
|
||||
case 6:
|
||||
return QuadratureAmplitudeModulation<64, cmplx, code_type>::map(b);
|
||||
case 8:
|
||||
return QuadratureAmplitudeModulation<256, cmplx, code_type>::map(b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -184,6 +186,8 @@ struct Encoder
|
|||
return QuadratureAmplitudeModulation<16, cmplx, code_type>::DIST;
|
||||
case 6:
|
||||
return QuadratureAmplitudeModulation<64, cmplx, code_type>::DIST;
|
||||
case 8:
|
||||
return QuadratureAmplitudeModulation<256, cmplx, code_type>::DIST;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
|
@ -228,61 +232,110 @@ struct Encoder
|
|||
symbol_count = 1;
|
||||
break;
|
||||
case 1:
|
||||
mod_bits = 2;
|
||||
symbol_count = 4;
|
||||
code_order = 11;
|
||||
data_bits = 1024;
|
||||
frozen_bits = frozen_2048_1056;
|
||||
break;
|
||||
case 2:
|
||||
mod_bits = 2;
|
||||
symbol_count = 8;
|
||||
code_order = 12;
|
||||
data_bits = 2048;
|
||||
frozen_bits = frozen_4096_2080;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
mod_bits = 2;
|
||||
symbol_count = 16;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
mod_bits = 2;
|
||||
symbol_count = 32;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
mod_bits = 4;
|
||||
symbol_count = 4;
|
||||
code_order = 12;
|
||||
data_bits = 2048;
|
||||
frozen_bits = frozen_4096_2080;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
mod_bits = 4;
|
||||
symbol_count = 8;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
mod_bits = 4;
|
||||
symbol_count = 16;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 7:
|
||||
mod_bits = 6;
|
||||
symbol_count = 6;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 8:
|
||||
mod_bits = 4;
|
||||
symbol_count = 32;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 9:
|
||||
mod_bits = 6;
|
||||
symbol_count = 11;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 10:
|
||||
mod_bits = 6;
|
||||
symbol_count = 22;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 11:
|
||||
mod_bits = 6;
|
||||
symbol_count = 44;
|
||||
code_order = 16;
|
||||
data_bits = 32768;
|
||||
frozen_bits = frozen_65536_32800;
|
||||
break;
|
||||
case 12:
|
||||
mod_bits = 8;
|
||||
symbol_count = 4;
|
||||
code_order = 13;
|
||||
data_bits = 4096;
|
||||
frozen_bits = frozen_8192_4128;
|
||||
break;
|
||||
case 13:
|
||||
mod_bits = 8;
|
||||
symbol_count = 8;
|
||||
code_order = 14;
|
||||
data_bits = 8192;
|
||||
frozen_bits = frozen_16384_8224;
|
||||
break;
|
||||
case 14:
|
||||
mod_bits = 8;
|
||||
symbol_count = 16;
|
||||
code_order = 15;
|
||||
data_bits = 16384;
|
||||
frozen_bits = frozen_32768_16416;
|
||||
break;
|
||||
case 15:
|
||||
mod_bits = 8;
|
||||
symbol_count = 32;
|
||||
code_order = 16;
|
||||
data_bits = 32768;
|
||||
frozen_bits = frozen_65536_32800;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -365,9 +418,7 @@ struct Encoder
|
|||
tone[i] = 0;
|
||||
} else {
|
||||
int bits = mod_bits;
|
||||
if (oper_mode == 7 && k % 32 == 30)
|
||||
bits = 2;
|
||||
else if (oper_mode == 8 && k % 64 == 60)
|
||||
if (oper_mode >= 9 && oper_mode <= 11 && k % 64 == 60)
|
||||
bits = 4;
|
||||
tone[i] = map_bits(perm+k, bits);
|
||||
k += bits;
|
||||
|
|
@ -409,7 +460,7 @@ int main(int argc, char **argv)
|
|||
std::cerr << "Using operation mode " << oper_mode << " but " << input_count << " input file" << (input_count == 1 ? "" : "s") << " provided." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (oper_mode < 0 || oper_mode > 8) {
|
||||
if (oper_mode < 0 || oper_mode > 15) {
|
||||
std::cerr << "Unsupported operation mode." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue