# Set default build type
if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE "Release")
+ set(CMAKE_BUILD_TYPE "Debug")
endif()
# Set default C++ flags.
struct COHPSK;
+extern const int test_bits_coh[];
+
struct COHPSK *cohpsk_create(void);
void cohpsk_destroy(struct COHPSK *coh);
void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[]);
void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame);
void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats);
void cohpsk_set_verbose(struct COHPSK *coh, int verbose);
+void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
+void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
+ int *bit_errors, float rx_bits_sd[]);
#endif
#include "kiss_fft.h"
#include "linreg.h"
#include "rn_coh.h"
+#include "test_bits_coh.h"
static COMP qpsk_mod[] = {
{ 1.0, 0.0},
coh->rx_timing_log = NULL;
coh->rx_timing_log_index = 0;
+ /* test frames */
+
+ coh->ptest_bits_coh_tx = coh->ptest_bits_coh_rx = (int*)test_bits_coh;
+ coh->ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
+
return coh;
}
}
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: cohpsk_get_test_bits()
+ AUTHOR......: David Rowe
+ DATE CREATED: June 2015
+
+ Returns a frame of known test bits.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[])
+{
+ memcpy(rx_bits, coh->ptest_bits_coh_tx, sizeof(int)*COHPSK_BITS_PER_FRAME);
+ coh->ptest_bits_coh_tx += COHPSK_BITS_PER_FRAME;
+ if (coh->ptest_bits_coh_tx >=coh->ptest_bits_coh_end) {
+ coh->ptest_bits_coh_tx = (int*)test_bits_coh;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: cohpsk_put_test_bits()
+ AUTHOR......: David Rowe
+ DATE CREATED: June 2015
+
+ Accepts bits from demod and attempts to sync with the known
+ test_bits sequence. When synced measures bit errors.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
+ int *bit_errors, float rx_bits_sd[])
+{
+ int i, next_state, anerror;
+ int rx_bits[COHPSK_BITS_PER_FRAME];
+
+ for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+ rx_bits[i] = rx_bits_sd[i] < 0.0;
+ }
+
+ *bit_errors = 0;
+ for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+ anerror = (rx_bits[i] & 0x1) ^ coh->ptest_bits_coh_rx[i];
+ *bit_errors += anerror;
+ error_pattern[i] = anerror;
+ }
+
+ /* state logic */
+
+ next_state = *state;
+
+ if (*state == 0) {
+ if (*bit_errors < 4) {
+ next_state = 1;
+ coh->ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+ }
+ }
+
+ if (*state == 1) {
+ coh->ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+ if (coh->ptest_bits_coh_rx >= coh->ptest_bits_coh_end) {
+ coh->ptest_bits_coh_rx = (int*)test_bits_coh;
+ }
+ }
+
+ *state = next_state;
+}
+
+
{
FILE *fout;
int tx_bits[COHPSK_BITS_PER_FRAME];
+ float sd_tx_bits[COHPSK_BITS_PER_FRAME];
int numBits, nFrames, n;
- int *ptest_bits_coh, *ptest_bits_coh_end;
+ int *ptest_bits_coh, *ptest_bits_coh_end, i;
if (argc < 2) {
- printf("usage: %s OutputOneBitPerIntFile numBits\n", argv[0]);
+ printf("usage: %s OutputOneFloatPerBitFile numBits\n", argv[0]);
exit(1);
}
ptest_bits_coh = (int*)test_bits_coh;
}
- fwrite(tx_bits, sizeof(int), COHPSK_BITS_PER_FRAME, fout);
+ for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+ sd_tx_bits[i] = 1.0 - 2.0*tx_bits[i];
+
+ fwrite(sd_tx_bits, sizeof(float), COHPSK_BITS_PER_FRAME, fout);
/* if this is in a pipeline, we probably don't want the usual
buffering to occur */
int verbose;
+ int *ptest_bits_coh_tx;
+ int *ptest_bits_coh_rx;
+ int *ptest_bits_coh_end;
+
/* optional log variables used for testing Octave to C port */
COMP *rx_baseband_log;
int i;
if (argc < 3) {
- printf("usage: %s InputOneBitPerIntFile OutputModemRawFile\n", argv[0]);
+ printf("usage: %s InputOneFloatPerBitFile OutputModemRawFile\n", argv[0]);
exit(1);
}
#include <errno.h>
#include "codec2_cohpsk.h"
-#include "test_bits_coh.h"
#include "octave.h"
#define LOG_FRAMES 100
{
FILE *fin, *foct;
float rx_bits_sd[COHPSK_BITS_PER_FRAME];
- int rx_bits[COHPSK_BITS_PER_FRAME];
- int *ptest_bits_coh, *ptest_bits_coh_end;
- int state, next_state, i, nbits, errors, nerrors;
+ int state, i, nbits, bit_errors, nerrors;
+ short error_pattern[COHPSK_BITS_PER_FRAME];
int error_positions_hist[COHPSK_BITS_PER_FRAME], logframes;
int nerr_log[LOG_FRAMES];
+ struct COHPSK *coh;
for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
error_positions_hist[i] = 0;
if (argc < 2) {
- fprintf(stderr, "usage: %s InputOneBitPerIntFile [OctaveLogFile]\n", argv[0]);
+ fprintf(stderr, "usage: %s InputOneFloatPerBitFile [OctaveLogFile]\n", argv[0]);
exit(1);
}
exit(1);
}
+ coh = cohpsk_create();
+
foct = NULL;
logframes = 0;
if (argc == 3) {
for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
error_positions_hist[i] = 0;
- ptest_bits_coh = (int*)test_bits_coh;
- ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
-
state = 0; nbits = 0; nerrors = 0;
while (fread(rx_bits_sd, sizeof(float), COHPSK_BITS_PER_FRAME, fin) == COHPSK_BITS_PER_FRAME) {
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
- rx_bits[i] = rx_bits_sd[i] < 0.0;
- //fprintf(stderr,"%f %d\n", rx_bits_sd[i], rx_bits[i]);
- }
-
- errors = 0;
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
- errors += (rx_bits[i] & 0x1) ^ ptest_bits_coh[i];
- if (state == 1) {
- if ((state == 1 ) && (rx_bits[i] & 0x1) ^ ptest_bits_coh[i])
- error_positions_hist[i]++;
- }
- }
- //printf("state: %d errors: %d nerrors: %d\n", state, errors, nerrors);
-
- /* state logic */
-
- next_state = state;
-
- if (state == 0) {
- if (errors < 4) {
- next_state = 1;
- ptest_bits_coh += COHPSK_BITS_PER_FRAME;
- nerrors = errors;
- nbits = COHPSK_BITS_PER_FRAME;
- if (logframes < LOG_FRAMES)
- nerr_log[logframes++] = errors;
- }
- }
+ cohpsk_put_test_bits(coh, &state, error_pattern, &bit_errors, rx_bits_sd);
if (state == 1) {
- nerrors += errors;
+ for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+ error_positions_hist[i] += error_pattern[i];
+ if (logframes < LOG_FRAMES)
+ nerr_log[logframes++] = bit_errors;
+ nerrors += bit_errors;
nbits += COHPSK_BITS_PER_FRAME;
- ptest_bits_coh += COHPSK_BITS_PER_FRAME;
- if (ptest_bits_coh >= ptest_bits_coh_end) {
- ptest_bits_coh = (int*)test_bits_coh;
- }
- if (logframes < LOG_FRAMES)
- nerr_log[logframes++] = errors;
}
- state = next_state;
-
if (fin == stdin) fflush(stdin);
}
struct freedv *freedv_open(int mode) {
struct freedv *f;
- int Nc, codec2_mode, nbit, nbyte, i;
+ int Nc, codec2_mode, nbit, nbyte;
if ((mode != FREEDV_MODE_1600) && (mode != FREEDV_MODE_700))
return NULL;
return NULL;
f->mode = mode;
+ f->test_frames = 0;
if (mode == FREEDV_MODE_1600) {
Nc = 16;
return NULL;
}
+ f->test_frame_sync_state = 0;
+ f->total_bits = 0;
+ f->total_bit_errors = 0;
+
f->codec2 = codec2_create(codec2_mode);
if (f->codec2 == NULL)
return NULL;
}
f->tx_bits[i] = 0; /* spare bit */
+ /* optionally overwrite with test frames */
+
+ if (f->test_frames) {
+ fdmdv_get_test_bits(f->fdmdv, f->tx_bits);
+ fdmdv_get_test_bits(f->fdmdv, &f->tx_bits[bits_per_modem_frame]);
+ //fprintf(stderr, "test frames on tx\n");
+ }
+
/* modulate even and odd frames */
fdmdv_mod(f->fdmdv, tx_fdm, f->tx_bits, &f->tx_sync_bit);
}
+ /* optionally ovwerwrite the codec bits with test frames */
+
+ if (f->test_frames) {
+ cohpsk_get_test_bits(f->cohpsk, f->codec_bits);
+ }
+
/* cohpsk modulator */
cohpsk_mod(f->cohpsk, tx_fdm, f->codec_bits);
int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
assert(f != NULL);
int bits_per_codec_frame, bytes_per_codec_frame, bits_per_fdmdv_frame;
- int sync, i, j, bit, byte, nin_prev, nout, k;
+ int i, j, bit, byte, nin_prev, nout, k;
int recd_codeword, codeword1, data_flag_index, n_ascii;
short abit[1];
char ascii_out;
else {
memcpy(&f->rx_bits[bits_per_fdmdv_frame], f->fdmdv_bits, bits_per_fdmdv_frame*sizeof(int));
- if (f->mode == FREEDV_MODE_1600) {
+ if (f->test_frames == 0) {
recd_codeword = 0;
for(i=0; i<8; i++) {
recd_codeword <<= 1;
for(i=8,j=11; i<12; i++,j++) {
f->codec_bits[j] = (codeword1 >> (22-i)) & 0x1;
}
- }
+
+ // extract txt msg data bit ------------------------------------------------------------
- // extract txt msg data bit ------------------------------------------------------------
+ data_flag_index = codec2_get_spare_bit_index(f->codec2);
+ abit[0] = f->codec_bits[data_flag_index];
- data_flag_index = codec2_get_spare_bit_index(f->codec2);
- abit[0] = f->codec_bits[data_flag_index];
+ n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+ if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+ (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+ }
- n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
- if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
- (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+ // reconstruct missing bit we steal for data bit and decode speech
+
+ codec2_rebuild_spare_bit(f->codec2, f->codec_bits);
+
+ // pack bits, MSB received first
+
+ bit = 7;
+ byte = 0;
+ memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
+ for(i=0; i<bits_per_codec_frame; i++) {
+ f->packed_codec_bits[byte] |= (f->codec_bits[i] << bit);
+ bit--;
+ if(bit < 0) {
+ bit = 7;
+ byte++;
+ }
+ }
+
+ codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
}
+ else {
+ int test_frame_sync, bit_errors, ntest_bits, k;
+ short error_pattern[fdmdv_error_pattern_size(f->fdmdv)];
- // reconstruct missing bit we steal for data bit and decode speech
+ for(k=0; k<2; k++) {
+ /* test frames, so lets sync up to the test frames and count any errors */
+ fdmdv_put_test_bits(f->fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, &f->rx_bits[k*bits_per_fdmdv_frame]);
- codec2_rebuild_spare_bit(f->codec2, f->codec_bits);
+ if (test_frame_sync == 1) {
+ f->test_frame_sync_state = 1;
+ f->test_frame_count = 0;
+ }
- // pack bits, MSB received first
+ if (f->test_frame_sync_state) {
+ if (f->test_frame_count == 0) {
+ f->total_bit_errors += bit_errors;
+ f->total_bits += ntest_bits;
+ }
+ f->test_frame_count++;
+ if (f->test_frame_count == 4)
+ f->test_frame_count = 0;
+ }
- bit = 7;
- byte = 0;
- memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
- for(i=0; i<bits_per_codec_frame; i++) {
- f->packed_codec_bits[byte] |= (f->codec_bits[i] << bit);
- bit--;
- if(bit < 0) {
- bit = 7;
- byte++;
+ //fprintf(stderr, "test_frame_sync: %d test_frame_sync_state: %d bit_errors: %d ntest_bits: %d\n",
+ // test_frame_sync, f->test_frame_sync_state, bit_errors, ntest_bits);
}
}
- codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
- /* squelch if beneath SNR threshold */
+ /* squelch if beneath SNR threshold or test frames enabled */
- if (f->stats.snr_est < f->snr_thresh) {
+ if ((f->stats.snr_est < f->snr_thresh) || f->test_frames) {
for(i=0; i<f->n_speech_samples; i++)
speech_out[i] = 0;
}
if (sync) {
- data_flag_index = codec2_get_spare_bit_index(f->codec2);
+ if (f->test_frames == 0) {
+ data_flag_index = codec2_get_spare_bit_index(f->codec2);
- for (j=0; j<COHPSK_BITS_PER_FRAME; j+=bits_per_codec_frame) {
+ for (j=0; j<COHPSK_BITS_PER_FRAME; j+=bits_per_codec_frame) {
- /* extract txt msg data bits */
+ /* extract txt msg data bits */
- for(k=0; k<2; k++) {
- abit[0] = rx_bits[data_flag_index+j+k] < 0.0;
+ for(k=0; k<2; k++) {
+ abit[0] = rx_bits[data_flag_index+j+k] < 0.0;
- n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
- if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
- (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+ n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+ if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+ (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+ }
}
- }
- /* pack bits, MSB received first */
+ /* pack bits, MSB received first */
- bit = 7; byte = 0;
- memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
- for(i=0; i<bits_per_codec_frame; i++) {
- f->packed_codec_bits[byte] |= ((rx_bits[j+i] < 0.0) << bit);
- bit--;
- if (bit < 0) {
- bit = 7;
- byte++;
+ bit = 7; byte = 0;
+ memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
+ for(i=0; i<bits_per_codec_frame; i++) {
+ f->packed_codec_bits[byte] |= ((rx_bits[j+i] < 0.0) << bit);
+ bit--;
+ if (bit < 0) {
+ bit = 7;
+ byte++;
+ }
}
+
+ codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
+ speech_out += codec2_samples_per_frame(f->codec2);
}
+ nout = f->n_speech_samples;
+ }
+ else {
+ short error_pattern[COHPSK_BITS_PER_FRAME];
+ int bit_errors;
+
+ /* test data, lets see if we can sync to the test data sequence */
- codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
- speech_out += codec2_samples_per_frame(f->codec2);
+ cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits);
+ if (f->test_frame_sync_state == 1) {
+ //for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+ // error_positions_hist[i] += error_pattern[i];
+ f->total_bit_errors += bit_errors;
+ f->total_bits += COHPSK_BITS_PER_FRAME;
+ }
}
- nout = f->n_speech_samples;
+
}
- else {
+
+ if ((sync == 0) || f->test_frames) {
float t,a,b,s;
int t1,t2;
nout = f->n_speech_samples;
//fprintf(stderr, "%d %d %d\n", f->n_speech_samples, speech_out[0], speech_out[nin_prev-1]);
}
- }
-
+ }
+
return nout;
}
-
-#ifdef TODO
- if (g_testFrames) {
- int bit_errors, ntest_bits, test_frame_sync;
-
- // test frame processing, g_test_frame_sync will be asserted when we detect a
- // valid test frame.
-
- fdmdv_put_test_bits(g_pFDMDV, &test_frame_sync, g_error_pattern, &bit_errors, &ntest_bits, codec_bits);
-
- if (test_frame_sync == 1) {
- g_test_frame_sync_state = 1;
- g_test_frame_count = 0;
- }
-
- if (g_test_frame_sync_state) {
- if (g_test_frame_count == 0) {
- //printf("bit_errors: %d ntest_bits: %d\n", bit_errors, ntest_bits);
- g_total_bit_errors += bit_errors;
- g_total_bits += ntest_bits;
- fifo_write(g_errorFifo, g_error_pattern, g_sz_error_pattern);
- }
- g_test_frame_count++;
- if (g_test_frame_count == 4)
- g_test_frame_count = 0;
- }
-
- fdmdv_put_test_bits(g_pFDMDV, &test_frame_sync, g_error_pattern, &bit_errors, &ntest_bits, &codec_bits[bits_per_fdmdv_frame]);
-
- if (test_frame_sync == 1) {
- g_test_frame_sync_state = 1;
- g_test_frame_count = 0;
- }
-
- if (g_test_frame_sync_state) {
- if (g_test_frame_count == 0) {
- //printf("bit_errors: %d ntest_bits: %d\n", bit_errors, ntest_bits);
- g_total_bit_errors += bit_errors;
- g_total_bits += ntest_bits;
- fifo_write(g_errorFifo, g_error_pattern, g_sz_error_pattern);
- }
- g_test_frame_count++;
- if (g_test_frame_count == 4)
- g_test_frame_count = 0;
- }
-
- // silent audio
-
- for(i=0; i<2*N8; i++)
- output_buf[i] = 0;
-#endif
int *fdmdv_bits;
int *rx_bits;
int tx_sync_bit;
+
+ int *ptest_bits_coh;
+ int *ptest_bits_coh_end;
+
+ int test_frames; // set this baby for 1 to tx/rx test frames to look at bit error stats
+ int test_frame_sync_state;
+ int test_frame_count;
+ int total_bits;
int total_bit_errors;
int sync;
void my_put_next_rx_char(void *callback_state, char c) {
struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
if (pstate->ftxt != NULL) {
- fprintf(stderr, "%c", c);
+ fprintf(pstate->ftxt, "%c", c);
}
}
short *speech_out;
short *demod_in;
struct freedv *freedv;
- int nin, nout, frame;
+ int nin, nout, frame = 0;
struct my_callback_state my_cb_state;
int mode;
if (argc < 4) {
- printf("usage: %s 1600|700 InputModemSpeechFile OutputSpeechawFile txtLogFile\n", argv[0]);
+ printf("usage: %s 1600|700 InputModemSpeechFile OutputSpeechRawFile [--test_frames]\n", argv[0]);
printf("e.g %s 1600 hts1a_fdmdv.raw hts1a_out.raw txtLogFile\n", argv[0]);
exit(1);
}
exit(1);
}
- ftxt = NULL;
- if ( (argc > 4) && (strcmp(argv[4],"|") != 0) ) {
- if ((ftxt = fopen(argv[4],"wt")) == NULL ) {
- fprintf(stderr, "Error opening txt Log File: %s: %s.\n",
- argv[4], strerror(errno));
- exit(1);
- }
- }
-
freedv = freedv_open(mode);
- cohpsk_set_verbose(freedv->cohpsk, 1);
+ if (mode == FREEDV_MODE_700)
+ cohpsk_set_verbose(freedv->cohpsk, 1);
assert(freedv != NULL);
+ if ( (argc > 4) && (strcmp(argv[4], "--testframes") == 0) ) {
+ freedv->test_frames = 1;
+ }
+
speech_out = (short*)malloc(sizeof(short)*freedv->n_speech_samples);
assert(speech_out != NULL);
demod_in = (short*)malloc(sizeof(short)*freedv->n_max_modem_samples);
assert(demod_in != NULL);
+ ftxt = stderr;
my_cb_state.ftxt = ftxt;
freedv->callback_state = (void*)&my_cb_state;
freedv->freedv_put_next_rx_char = &my_put_next_rx_char;
fwrite(speech_out, sizeof(short), nout, fout);
nin = freedv_nin(freedv);
+ if (freedv->mode == FREEDV_MODE_1600)
+ fdmdv_get_demod_stats(freedv->fdmdv, &freedv->stats);
+ if (freedv->mode == FREEDV_MODE_700)
+ cohpsk_get_demod_stats(freedv->cohpsk, &freedv->stats);
+
/* log some side info to the txt file */
frame++;
+ /*
if (ftxt != NULL) {
fprintf(ftxt, "frame: %d demod sync: %d demod snr: %3.2f dB bit errors: %d\n", frame,
freedv->stats.sync, freedv->stats.snr_est, freedv->total_bit_errors);
}
+ */
/* if this is in a pipeline, we probably don't want the usual
buffering to occur */
if (fin == stdin) fflush(stdin);
}
+ if (freedv->test_frames) {
+ fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", freedv->total_bits, freedv->total_bit_errors, (float)freedv->total_bit_errors/freedv->total_bits);
+ }
+
free(speech_out);
free(demod_in);
freedv_close(freedv);
int mode;
if (argc < 4) {
- printf("usage: %s 1600|700 InputRawSpeechFile OutputModemRawFile\n", argv[0]);
+ printf("usage: %s 1600|700 InputRawSpeechFile OutputModemRawFile [--testframes]\n", argv[0]);
printf("e.g %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]);
exit(1);
}
freedv = freedv_open(mode);
assert(freedv != NULL);
+ if ((argc > 4) && (strcmp(argv[4], "--testframes") == 0)) {
+ freedv->test_frames = 1;
+ }
+
speech_in = (short*)malloc(sizeof(short)*freedv->n_speech_samples);
assert(speech_in != NULL);
mod_out = (short*)malloc(sizeof(short)*freedv->n_nom_modem_samples);