Skip to content

Commit e54b50d

Browse files
committed
Add some basic FreeDV API usage to documentation.
1 parent eb4c43a commit e54b50d

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

README_freedv.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,143 @@ See also [freedv_api.h](src/freedv_api.h) and [freedv_api.c](src/freedv_api.c),
9393
$ ./freedv_tx 1600 ../../raw/hts1.raw - | ./freedv_rx 1600 - - | aplay -f S16_LE
9494
$ cat freedv_rx_log.txt
9595
```
96+
97+
### Using the API
98+
99+
Generally, the FreeDV API is used as follows:
100+
101+
#### Creating FreeDV objects
102+
103+
Call freedv\_open() or freedv\_advanced\_open() depending on the mode being used:
104+
105+
```
106+
\#include "freedv\_api.h"
107+
108+
struct freedv* dv;
109+
if ((mode == FREEDV\_MODE\_700D) || (mode == FREEDV\_MODE\_700E) || (mode == FREEDV\_MODE\_2020)) {
110+
struct freedv_advanced adv;
111+
dv = freedv\_open\_advanced(mode, &adv);
112+
} else {
113+
dv = fredv\_open(mode);
114+
}
115+
116+
if (dv == NULL) {
117+
// handle error condition
118+
}
119+
```
120+
121+
Available modes:
122+
123+
* FREEDV\_MODE\_1600
124+
* FREEDV\_MODE\_2400A
125+
* FREEDV\_MODE\_2400B
126+
* FREEDV\_MODE\_800XA
127+
* FREEDV\_MODE\_700C
128+
* FREEDV\_MODE\_700D
129+
* FREEDV\_MODE\_2020
130+
* FREEDV\_MODE\_700E
131+
132+
#### Enabling reliable receiving/sending of callsigns in the voice stream (e.g. for PSK Reporter)
133+
134+
```
135+
\#include "reliable\_text.h"
136+
137+
reliable\_text\_t rt = reliable\_text\_create();
138+
if (rt == NULL) { /* handle error */ }
139+
140+
void* stateObject = NULL; /* can be a pointer to anything */
141+
reliable\_text\_use\_with\_freedv(rt, dv, &OnReliableTextRx, stateObject);
142+
143+
char* callsign = "KA6ABC";
144+
reliable\_text\_set\_string(rt, callsign, strlen(callsign));
145+
146+
...
147+
148+
void OnReliableTextRx(reliable\_text\_t rt, const char* txt\_ptr, int length, void* state)
149+
{
150+
fprintf(stderr, "OnReliableTextRx: received %s\n", txt\_ptr);
151+
...
152+
reliable\_text\_reset(rt);
153+
}
154+
```
155+
156+
#### Enabling normal text (e.g. not callsigns)
157+
158+
*Note: this is mutually exclusive with reliable\_text above.*
159+
160+
```
161+
freedv\_set\_callback\_txt(dv, &TextRxFn, &TextTxFn, stateObject);
162+
163+
...
164+
165+
static char* text = "This is a test";
166+
static int currentIndex = 0;
167+
168+
char TextTxFn(void *callback_state)
169+
{
170+
currentIndex = (currentIndex + 1) % strlen(text);
171+
return text[currentIndex];
172+
}
173+
174+
void TextRxFn(void *callback\_state, char c)
175+
{
176+
fprintf(stderr, "Received character %c from stream\n", c);
177+
}
178+
```
179+
180+
#### Decoding audio
181+
182+
```
183+
int freedvRxModulatedSampleRate = freedv\_get\_modem\_sample\_rate(dv);
184+
int freedvRxSpeechSampleRate = freedv\_get\_speech\_sample\_rate(dv);
185+
186+
/* Note that FreeDV expects int16 samples, not float. Input audio should be
187+
resampled to the rate expected by the current mode (e.g. inside freedvRxModulatedSampleRate
188+
above). */
189+
short* resampledRxInput = malloc(/* size of resampled input buffer */);
190+
short* rxOutput = malloc(/* size of output buffer */);
191+
resample(rxInput, resampledRxInput, radioRate, freedvRxModulatedSampleRate);
192+
193+
/* Loop through available samples until we run out. Each time, call freedv\_nin() to get
194+
the current number of samples the mode needs followed by freedv\_rx() to actually feed
195+
them in. 0 is perfectly okay for freedv\_nin() depending on the current internal state. */
196+
int nsamples = freedv\_nin(dv);
197+
short* currentBuf = resampledRxInput;
198+
while (currentBuf < sizeofBuffer)
199+
{
200+
freedv\_rx(dv, rxOutput, currentBuf);
201+
resample(rxOutput, radioOutput, freedvRxSpeechSampleRate, radioRate);
202+
currentBuf += nsamples;
203+
nsamples = freedv\_nin(dv);
204+
}
205+
```
206+
207+
#### Transmitting audio
208+
209+
```
210+
int freedvTxModulatedSampleRate = freedv\_get\_modem\_sample\_rate(dv);
211+
int freedvTxSpeechSampleRate = freedv\_get\_speech\_sample\_rate(dv);
212+
int requiredTxSpeechSamples = freedv\_get\_n\_speech\_samples(dv);
213+
214+
short* txInput = malloc(/* size of resampled output buffer */);
215+
short* txOutput = malloc(/* size of output buffer */);
216+
217+
while(speech samples available)
218+
{
219+
memcpy(txInput, radioSamples, requiredTxSpeechSamples);
220+
freedv\_tx(dv, txOutput, txInput);
221+
}
222+
223+
#### Cleanup
224+
225+
```
226+
/* if reliable\_text is enabled */
227+
reliable\_text\_unlink\_from\_freedv(rt);
228+
229+
/* always required to free memory */
230+
freedv\_close(dv);
231+
```
232+
96233
## FreeDV 2400A and 2400B modes
97234
98235
FreeDV 2400A and FreeDV 2400B are modes designed for VHF radio. FreeDV 2400A is designed for SDR radios (it has a 5 kHz RF bandwidth), however FreeDV 2400B is designed to pass through commodity FM radios.

0 commit comments

Comments
 (0)