TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
OFDM.h
Go to the documentation of this file.
1#pragma once
2
3#include <ctype.h>
4#include <math.h>
5#include <stdint.h>
6#include <stdlib.h>
7
8#include "AudioTools.h"
9
10namespace tinymodem {
11
23struct OFDMConfig : public audio_tools::AudioInfo {
25 sample_rate = 48000;
26 channels = 1;
27 bits_per_sample = 16;
28 }
29
31 int carriers = 32;
33 float carrier_spacing = 62.5f;
35 float first_freq = 1000.0f;
37 float guard = 0.25f;
39 float volume = 1.0f;
41 int max_frame = 512;
43 float sync_threshold = 0.5f;
45 bool rx_one = false;
47 uint8_t channel = 0;
49 float rx_noise = 0.0f;
50
52 bool setMode(const char* mode) {
53 int n = modeCarriers(mode);
54 if (n == 0) return false;
55 carriers = n;
56 carrier_spacing = 2000.0f / n;
57 first_freq = 1000.0f;
58 return true;
59 }
60
62 static bool isMode(const char* mode) { return modeCarriers(mode) > 0; }
63
65 int fftSize() const {
66 int n = lroundf(sample_rate / carrier_spacing);
67 return n + (n & 1); // even, for the sync symbol
68 }
69
71 int prefixSize() const { return lroundf(fftSize() * guard); }
72
74 int firstBin() const {
75 int bin = lroundf(first_freq * fftSize() / sample_rate);
76 return bin + (bin & 1);
77 }
78
80 float carrierFrequency(int idx) const {
81 return (float)(firstBin() + idx) * sample_rate / fftSize();
82 }
83
85 float symbolRate() const {
86 return (float)sample_rate / (fftSize() + prefixSize());
87 }
88
90 float bitRate() const { return symbolRate() * carriers * 2; }
91
93 bool isValid() const {
95 LOGE("OFDM: carriers must be between 4 and 128, not %d", carriers);
96 return false;
97 }
98 if (carrier_spacing <= 0 || first_freq <= 0 || guard < 0 || guard > 0.5f) {
99 LOGE("OFDM: invalid carrier_spacing, first_freq or guard");
100 return false;
101 }
102 if (2 * (firstBin() + carriers) >= fftSize()) {
103 LOGE("OFDM: the highest carrier %.1f Hz must be below %.1f Hz",
104 (double)carrierFrequency(carriers - 1),
105 (double)(sample_rate / 2.0f));
106 return false;
107 }
109 LOGE("OFDM: invalid max_frame: %d", max_frame);
110 return false;
111 }
112 return true;
113 }
114
116 static int headerSymbols(int carriers) { return (32 + carriers - 1) / carriers; }
117
120 static int knownPhase(int symbol, int carrier) {
121 uint32_t x = (uint32_t)(carrier + 1) * 2654435761u + symbol * 40503u;
122 x ^= x >> 13;
123 x *= 0x5bd1e995u;
124 x ^= x >> 15;
125 return x & 3;
126 }
127
128 protected:
129 static int modeCarriers(const char* mode) {
130 if (mode == nullptr) return 0;
131 const char* prefix = "ofdm";
132 for (int j = 0; j < 4; j++)
133 if (tolower(mode[j]) != prefix[j]) return 0;
134 int n = atoi(mode + 4);
135 return (n == 16 || n == 32 || n == 64) ? n : 0;
136 }
137};
138
141 public:
142 void begin(int size) {
143 this->size = size;
144 cos_table.resize(size);
145 sin_table.resize(size);
146 for (int i = 0; i < size; i++) {
147 double angle = 2.0 * M_PI * i / size;
148 cos_table[i] = cos(angle);
149 sin_table[i] = sin(angle);
150 }
151 }
152 float cosine(int i) const { return cos_table[i]; }
153 float sine(int i) const { return sin_table[i]; }
154
155 protected:
156 int size = 0;
157 audio_tools::Vector<float> cos_table;
158 audio_tools::Vector<float> sin_table;
159};
160
161} // namespace tinymodem
Sine and cosine of 2 * PI * i / size.
Definition OFDM.h:140
int size
Definition OFDM.h:156
audio_tools::Vector< float > cos_table
Definition OFDM.h:157
void begin(int size)
Definition OFDM.h:142
float cosine(int i) const
Definition OFDM.h:152
audio_tools::Vector< float > sin_table
Definition OFDM.h:158
float sine(int i) const
Definition OFDM.h:153
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
float symbolRate() const
OFDM symbols per second.
Definition OFDM.h:85
float first_freq
frequency of the first carrier in Hz
Definition OFDM.h:35
float carrier_spacing
distance of the carriers in Hz
Definition OFDM.h:33
float rx_noise
receiver: (testing only) amplitude of added uniform noise
Definition OFDM.h:49
static bool isMode(const char *mode)
true if the mode is an OFDM mode
Definition OFDM.h:62
int firstBin() const
DFT bin of the first carrier: even, for the sync symbol.
Definition OFDM.h:74
static int knownPhase(int symbol, int carrier)
Definition OFDM.h:120
float volume
transmit amplitude (0.0 - 1.0)
Definition OFDM.h:39
OFDMConfig()
Definition OFDM.h:24
uint8_t channel
receiver: input channel which is used for the decoding
Definition OFDM.h:47
int prefixSize() const
length of the cyclic prefix in samples
Definition OFDM.h:71
int carriers
number of carriers (4 - 128)
Definition OFDM.h:31
bool isValid() const
Checks the configuration: returns false (and logs the reason) if invalid.
Definition OFDM.h:93
float bitRate() const
data bits per second
Definition OFDM.h:90
int fftSize() const
length of the useful part of a symbol (DFT size) in samples
Definition OFDM.h:65
static int headerSymbols(int carriers)
Number of symbols of the header (32 bits, one bit per carrier).
Definition OFDM.h:116
bool rx_one
receiver: stop after the first frame
Definition OFDM.h:45
float guard
length of the cyclic prefix relative to the symbol (0.0 - 0.5)
Definition OFDM.h:37
float sync_threshold
receiver: minimum normalized correlation of the sync symbol
Definition OFDM.h:43
bool setMode(const char *mode)
Selects "ofdm16", "ofdm32" or "ofdm64": returns false if invalid.
Definition OFDM.h:52
float carrierFrequency(int idx) const
frequency of the carrier with the indicated index
Definition OFDM.h:80
int max_frame
transmitter: max number of bytes per frame
Definition OFDM.h:41
static int modeCarriers(const char *mode)
Definition OFDM.h:129