forked from g0orx/pihpsdr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
freedv.c
125 lines (106 loc) · 3.13 KB
/
freedv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <codec2/freedv_api.h>
#include "radio.h"
static struct freedv* modem;
int n_speech_samples;
int n_max_modem_samples;
int n_nom_modem_samples;
short *speech_out;
short *demod_in;
short *speech_in;
short *mod_out;
int rx_samples_in;
int tx_samples_in;
int samples_out;
int nin;
int freedv_sync;
float freedv_snr;
int freedv_tx_text_index=0;
char freedv_rx_text_data[64];
int freedv_rx_text_data_index=0;
static void my_put_next_rx_char(void *callback_state, char c) {
fprintf(stderr, "freedv: my_put_next_rx_char: %c sync=%d\n", c, freedv_sync);
if(freedv_sync) {
if(c==0x0D) {
freedv_rx_text_data_index=0;
} else {
freedv_rx_text_data[freedv_rx_text_data_index++]=c;
freedv_rx_text_data[freedv_rx_text_data_index]=0;
if(freedv_rx_text_data_index>=62) {
freedv_rx_text_data_index=0;
}
}
}
}
static char my_get_next_tx_char(void *callback_state){
char c=freedv_tx_text_data[freedv_tx_text_index++];
if(c==0) {
c=0x0D;
freedv_tx_text_index=0;
}
fprintf(stderr,"freedv: my_get_next_tx_char=%c\n",c);
return c;
}
void init_freedv() {
fprintf(stderr,"init_freedv\n");
modem=freedv_open(FREEDV_MODE_1600);
if(modem==NULL) {
fprintf(stderr,"freedv_open: modem is null\n");
return;
}
freedv_set_snr_squelch_thresh(modem, -100.0);
freedv_set_squelch_en(modem, 1);
n_speech_samples = freedv_get_n_speech_samples(modem);
n_max_modem_samples = freedv_get_n_max_modem_samples(modem);
n_nom_modem_samples = freedv_get_n_nom_modem_samples(modem);
fprintf(stderr,"n_speech_samples=%d n_max_modem_samples=%d\n",n_speech_samples, n_max_modem_samples);
speech_out = (short*)malloc(sizeof(short)*n_speech_samples);
demod_in = (short*)malloc(sizeof(short)*n_max_modem_samples);
speech_in = (short*)malloc(sizeof(short)*n_speech_samples);
mod_out = (short*)malloc(sizeof(short)*n_nom_modem_samples);
nin = freedv_nin(modem);
rx_samples_in=0;
tx_samples_in=0;
freedv_set_callback_txt(modem, &my_put_next_rx_char, &my_get_next_tx_char, NULL);
//freedv_set_callback_protocol(modem, &my_put_next_rx_proto, NULL, NULL);
//freedv_set_callback_data(modem, my_datarx, my_datatx, NULL);
int rate=freedv_get_modem_sample_rate(modem);
fprintf(stderr,"freedv modem sample rate=%d\n",rate);
strcpy(freedv_rx_text_data,"");
}
void close_freedv() {
fprintf(stderr,"freedv_close\n");
if(modem!=NULL) {
freedv_close(modem);
} else {
fprintf(stderr,"freedv_close: modem is null\n");
}
}
int demod_sample_freedv(short sample) {
int nout=0;
demod_in[rx_samples_in]=sample;
rx_samples_in++;
if(rx_samples_in==nin) {
nout=freedv_rx(modem,speech_out,demod_in);
nin=freedv_nin(modem);
rx_samples_in=0;
freedv_get_modem_stats(modem, &freedv_sync, &freedv_snr);
}
return nout;
}
int mod_sample_freedv(short sample) {
int nout=0;
speech_in[tx_samples_in]=sample;
tx_samples_in++;
if(tx_samples_in==n_speech_samples) {
freedv_tx(modem,mod_out,speech_in);
tx_samples_in=0;
nout=n_nom_modem_samples;
}
return nout;
}
void freedv_reset_tx_text_index() {
freedv_tx_text_index=0;
}