@@ -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
98235FreeDV 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