From 1146537d849c30aa20a4cb742cdd18654f041a8d Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Fri, 25 Mar 2016 13:58:16 +0100 Subject: [PATCH] common code: Add feature to record received audio and replay it -W writes a wave file of received audio -R reads a wave file to feed into decoder This way you can record a phone and later debug without a phone and radio equipment. --- src/anetz/anetz.c | 4 +- src/anetz/anetz.h | 2 +- src/anetz/main.c | 2 +- src/bnetz/bnetz.c | 4 +- src/bnetz/bnetz.h | 2 +- src/bnetz/main.c | 2 +- src/common/Makefile.am | 1 + src/common/main.h | 2 + src/common/main_common.c | 18 ++- src/common/sender.c | 32 ++++- src/common/sender.h | 7 +- src/common/wave.c | 300 +++++++++++++++++++++++++++++++++++++++ src/common/wave.h | 19 +++ src/nmt/main.c | 2 +- src/nmt/nmt.c | 4 +- src/nmt/nmt.h | 2 +- 16 files changed, 386 insertions(+), 17 deletions(-) create mode 100644 src/common/wave.c create mode 100644 src/common/wave.h diff --git a/src/anetz/anetz.c b/src/anetz/anetz.c index 5b4d0b3..8d965fe 100644 --- a/src/anetz/anetz.c +++ b/src/anetz/anetz.c @@ -137,7 +137,7 @@ static void anetz_timeout(struct timer *timer); static void anetz_go_idle(anetz_t *anetz); /* Create transceiver instance and link to a list. */ -int anetz_create(const char *sounddev, int samplerate, int kanal, int loopback, double loss_volume) +int anetz_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int loopback, double loss_volume) { anetz_t *anetz; int rc; @@ -156,7 +156,7 @@ int anetz_create(const char *sounddev, int samplerate, int kanal, int loopback, PDEBUG(DANETZ, DEBUG_DEBUG, "Creating 'A-Netz' instance for 'Kanal' = %d (sample rate %d).\n", kanal, samplerate); /* init general part of transceiver */ - rc = sender_create(&anetz->sender, sounddev, samplerate, kanal, loopback, loss_volume, -1); + rc = sender_create(&anetz->sender, sounddev, samplerate, write_wave, read_wave, kanal, loopback, loss_volume, -1); if (rc < 0) { PDEBUG(DANETZ, DEBUG_ERROR, "Failed to init 'Sender' processing!\n"); goto error; diff --git a/src/anetz/anetz.h b/src/anetz/anetz.h index 5400016..a8a4382 100644 --- a/src/anetz/anetz.h +++ b/src/anetz/anetz.h @@ -41,7 +41,7 @@ typedef struct anetz { double anetz_kanal2freq(int kanal, int unterband); int anetz_init(void); -int anetz_create(const char *sounddev, int samplerate, int kanal, int loopback, double loss_volume); +int anetz_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int loopback, double loss_volume); void anetz_destroy(sender_t *sender); void anetz_loss_indication(anetz_t *anetz); void anetz_receive_tone(anetz_t *anetz, int bit); diff --git a/src/anetz/main.c b/src/anetz/main.c index 59a3f23..fce3df5 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -142,7 +142,7 @@ int main(int argc, char *argv[]) } /* create transceiver instance */ - rc = anetz_create(sounddev, samplerate, kanal, loopback, lossdetect / 100.0); + rc = anetz_create(sounddev, samplerate, write_wave, read_wave, kanal, loopback, lossdetect / 100.0); if (rc < 0) { fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n"); goto fail; diff --git a/src/bnetz/bnetz.c b/src/bnetz/bnetz.c index 9819211..7829590 100644 --- a/src/bnetz/bnetz.c +++ b/src/bnetz/bnetz.c @@ -242,7 +242,7 @@ static void bnetz_timeout(struct timer *timer); static void bnetz_go_idle(bnetz_t *bnetz); /* Create transceiver instance and link to a list. */ -int bnetz_create(const char *sounddev, int samplerate, int kanal, int gfs, int loopback, double loss_factor, const char *pilot) +int bnetz_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int gfs, int loopback, double loss_factor, const char *pilot) { bnetz_t *bnetz; int use_pilot_tone = -1; @@ -300,7 +300,7 @@ error_pilot: PDEBUG(DBNETZ, DEBUG_DEBUG, "Creating 'B-Netz' instance for 'Kanal' = %d 'Gruppenfreisignal' = %d (sample rate %d).\n", kanal, gfs, samplerate); /* init general part of transceiver */ - rc = sender_create(&bnetz->sender, sounddev, samplerate, kanal, loopback, loss_factor, use_pilot_tone); + rc = sender_create(&bnetz->sender, sounddev, samplerate, write_wave, read_wave, kanal, loopback, loss_factor, use_pilot_tone); if (rc < 0) { PDEBUG(DBNETZ, DEBUG_ERROR, "Failed to init transceiver process!\n"); goto error; diff --git a/src/bnetz/bnetz.h b/src/bnetz/bnetz.h index 3eed7c8..1d9ddd3 100644 --- a/src/bnetz/bnetz.h +++ b/src/bnetz/bnetz.h @@ -90,7 +90,7 @@ typedef struct bnetz { double bnetz_kanal2freq(int kanal, int unterband); int bnetz_init(void); -int bnetz_create(const char *sounddev, int samplerate, int kanal, int gfs, int loopback, double loss_volume, const char *pilot); +int bnetz_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int gfs, int loopback, double loss_volume, const char *pilot); void bnetz_destroy(sender_t *sender); void bnetz_loss_indication(bnetz_t *bnetz); void bnetz_receive_tone(bnetz_t *bnetz, int bit); diff --git a/src/bnetz/main.c b/src/bnetz/main.c index a788529..fe0c5b5 100644 --- a/src/bnetz/main.c +++ b/src/bnetz/main.c @@ -154,7 +154,7 @@ int main(int argc, char *argv[]) } /* create transceiver instance */ - rc = bnetz_create(sounddev, samplerate, kanal, gfs, loopback, (double)lossdetect / 100.0, pilot); + rc = bnetz_create(sounddev, samplerate, write_wave, read_wave, kanal, gfs, loopback, (double)lossdetect / 100.0, pilot); if (rc < 0) { fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n"); goto fail; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index c6a90e9..0d3baa3 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -6,6 +6,7 @@ libcommon_a_SOURCES = \ ../common/debug.c \ ../common/timer.c \ ../common/sound_alsa.c \ + ../common/wave.c \ ../common/goertzel.c \ ../common/jitter.c \ ../common/loss.c \ diff --git a/src/common/main.h b/src/common/main.h index 54c4fe3..fc4f01f 100644 --- a/src/common/main.h +++ b/src/common/main.h @@ -8,6 +8,8 @@ extern int use_mncc_sock; extern int send_patterns; extern int loopback; extern int rt_prio; +extern const char *read_wave; +extern const char *write_wave; void print_help(const char *arg0); void print_help_common(const char *arg0, const char *ext_usage); diff --git a/src/common/main_common.c b/src/common/main_common.c index 47a3ca3..c634f7e 100644 --- a/src/common/main_common.c +++ b/src/common/main_common.c @@ -36,6 +36,8 @@ int use_mncc_sock = 0; int send_patterns = 1; int loopback = 0; int rt_prio = 0; +const char *read_wave = NULL; +const char *write_wave = NULL; void print_help_common(const char *arg0, const char *ext_usage) { @@ -64,6 +66,10 @@ void print_help_common(const char *arg0, const char *ext_usage) printf(" Loopback test: 1 = internal | 2 = external | 3 = echo\n"); printf(" -r --realtime \n"); printf(" Set prio: 0 to diable, 99 for maximum (default = %d)\n", rt_prio); + printf(" -W --write-wave \n"); + printf(" Write received audio to given wav audio file.\n"); + printf(" -R --read-wave \n"); + printf(" Replace received audio by given wav audio file.\n"); } static struct option long_options_common[] = { @@ -78,10 +84,12 @@ static struct option long_options_common[] = { {"send-patterns", 0, 0, 'p'}, {"loopback", 1, 0, 'L'}, {"realtime", 1, 0, 'r'}, + {"write-wave", 1, 0, 'W'}, + {"read-wave", 1, 0, 'R'}, {0, 0, 0, 0} }; -const char *optstring_common = "hD:k:d:s:c:l:mp:L:r:"; +const char *optstring_common = "hD:k:d:s:c:l:mp:L:r:W:R:"; struct option *long_options; char *optstring; @@ -151,6 +159,14 @@ void opt_switch_common(int c, char *arg0, int *skip_args) rt_prio = atoi(optarg); *skip_args += 2; break; + case 'W': + write_wave = strdup(optarg); + *skip_args += 2; + break; + case 'R': + read_wave = strdup(optarg); + *skip_args += 2; + break; default: exit (0); } diff --git a/src/common/sender.c b/src/common/sender.c index 97abcdc..5f14a25 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -32,7 +32,7 @@ sender_t *sender_head = NULL; static sender_t **sender_tailp = &sender_head; /* Init transceiver instance and link to list of transceivers. */ -int sender_create(sender_t *sender, const char *sounddev, int samplerate, int kanal, int loopback, double loss_volume, int use_pilot_signal) +int sender_create(sender_t *sender, const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int loopback, double loss_volume, int use_pilot_signal) { int rc = 0; @@ -65,6 +65,21 @@ int sender_create(sender_t *sender, const char *sounddev, int samplerate, int ka goto error; } + if (write_wave) { + rc = wave_create_record(&sender->wave_rec, write_wave, samplerate); + if (rc < 0) { + PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); + goto error; + } + } + if (read_wave) { + rc = wave_create_playback(&sender->wave_play, read_wave, samplerate); + if (rc < 0) { + PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); + goto error; + } + } + *sender_tailp = sender; sender_tailp = &sender->next; @@ -90,6 +105,9 @@ void sender_destroy(sender_t *sender) if (sender->sound) sound_close(sender->sound); + wave_destroy_record(&sender->wave_rec); + wave_destroy_playback(&sender->wave_play); + jitter_destroy(&sender->audio); } @@ -167,8 +185,11 @@ void process_sender(sender_t *sender, int latspl) PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover!\n"); return; } - if (sender->loopback == 1) + if (sender->loopback == 1) { + if (sender->wave_rec.fp) + wave_write(&sender->wave_rec, samples, count); sender_receive(sender, samples, count); + } } count = sound_read(sender->sound, samples, latspl); @@ -180,8 +201,13 @@ void process_sender(sender_t *sender, int latspl) return; } if (count) { - if (sender->loopback != 1) + if (sender->wave_play.fp) + wave_read(&sender->wave_play, samples, count); + if (sender->loopback != 1) { + if (sender->wave_rec.fp) + wave_write(&sender->wave_rec, samples, count); sender_receive(sender, samples, count); + } if (sender->loopback == 3) { jitter_save(&sender->audio, samples, count); } diff --git a/src/common/sender.h b/src/common/sender.h index e01f97d..795a055 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -1,4 +1,5 @@ #include "sound.h" +#include "wave.h" #include "samplerate.h" #include "jitter.h" #include "loss.h" @@ -21,6 +22,10 @@ typedef struct sender { /* loopback test */ int loopback; /* 0 = off, 1 = internal, 2 = external */ + /* record and playback */ + wave_rec_t wave_rec; /* wave recording */ + wave_play_t wave_play; /* wave playback */ + /* audio buffer for audio to send to transmitter (also used as loopback buffer) */ jitter_t audio; @@ -42,7 +47,7 @@ typedef struct sender { /* list of all senders */ extern sender_t *sender_head; -int sender_create(sender_t *sender, const char *sounddev, int samplerate, int kanal, int loopback, double loss_volume, int use_pilot_signal); +int sender_create(sender_t *sender, const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int kanal, int loopback, double loss_volume, int use_pilot_signal); void sender_destroy(sender_t *sender); void sender_send(sender_t *sender, int16_t *samples, int count); void sender_receive(sender_t *sender, int16_t *samples, int count); diff --git a/src/common/wave.c b/src/common/wave.c new file mode 100644 index 0000000..572f989 --- /dev/null +++ b/src/common/wave.c @@ -0,0 +1,300 @@ +/* wave recording and playback functions + * + * (C) 2016 by Andreas Eversberg + * All Rights Reserved + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include "wave.h" + +struct fmt { + uint16_t format; /* 1 = pcm, 2 = adpcm */ + uint16_t channels; /* number of channels */ + uint32_t sample_rate; /* sample rate */ + uint32_t data_rate; /* data rate */ + uint16_t bytes_sample; /* bytes per sample (all channels) */ + uint16_t bits_sample; /* bits per sample (one channel) */ +}; + +int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate) +{ + /* RIFFxxxxWAVEfmt xxxx(fmt size)dataxxxx... */ + char dummyheader[4 + 4 + 4 + 4 + 4 + sizeof(struct fmt) + 4 + 4]; + int __attribute__((__unused__)) len; + + memset(rec, 0, sizeof(*rec)); + rec->samplerate = samplerate; + + rec->fp = fopen(filename, "w"); + if (!rec->fp) { + fprintf(stderr, "Failed to open recording file '%s'! (errno %d)\n", filename, errno); + return -errno; + } + + memset(&dummyheader, 0, sizeof(dummyheader)); + len = fwrite(dummyheader, 1, sizeof(dummyheader), rec->fp); + + printf("*** Writing received audio to %s.\n", filename); + + return 0; +} + +int wave_create_playback(wave_play_t *play, const char *filename, int samplerate) +{ + uint8_t buffer[256]; + struct fmt fmt; + uint32_t size, chunk, len; + int gotfmt = 0, gotdata = 0; + int rc = -EINVAL; + + memset(play, 0, sizeof(*play)); + + play->fp = fopen(filename, "r"); + if (!play->fp) { + fprintf(stderr, "Failed to open playback file '%s'! (errno %d)\n", filename, errno); + return -errno; + } + + len = fread(buffer, 1, 12, play->fp); + if (len != 12) { + fprintf(stderr, "Failed to read RIFF header!\n"); + rc = -EIO; + goto error; + } + if (!!strncmp((char *)buffer, "RIFF", 4)) { + fprintf(stderr, "Missing RIFF header, seems that this is no WAVE file!\n"); + rc = -EINVAL; + goto error; + } + size = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 24); + if (!!strncmp((char *)buffer + 8, "WAVE", 4)) { + fprintf(stderr, "Missing WAVE header, seems that this is no WAVE file!\n"); + rc = -EINVAL; + goto error; + } + size -= 4; + while (size) { + if (size < 8) { + fprintf(stderr, "Short read of WAVE file!\n"); + rc = -EINVAL; + goto error; + } + len = fread(buffer, 1, 8, play->fp); + if (len != 8) { + fprintf(stderr, "Failed to read chunk of WAVE file!\n"); + rc = -EIO; + goto error; + } + chunk = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 24); + size -= 8 + chunk; + if (size < 0) { + fprintf(stderr, "WAVE error: Chunk '%c%c%c%c' overflows file size!\n", buffer[4], buffer[5], buffer[6], buffer[7]); + rc = -EIO; + goto error; + } + if (!strncmp((char *)buffer, "fmt ", 4)) { + if (chunk < 16 || chunk > sizeof(buffer)) { + fprintf(stderr, "WAVE error: Short or corrupt 'fmt' chunk!\n"); + rc = -EINVAL; + goto error; + } + len = fread(buffer, 1, chunk, play->fp); + fmt.format = buffer[0] + (buffer[1] << 8); + fmt.channels = buffer[2] + (buffer[3] << 8); + fmt.sample_rate = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 24); + fmt.data_rate = buffer[8] + (buffer[9] << 8) + (buffer[10] << 16) + (buffer[11] << 24); + fmt.bytes_sample = buffer[12] + (buffer[13] << 8); + fmt.bits_sample = buffer[14] + (buffer[15] << 8); + gotfmt = 1; + } else + if (!strncmp((char *)buffer, "data", 4)) { + if (!gotfmt) { + fprintf(stderr, "WAVE error: 'data' without 'fmt' chunk!\n"); + rc = -EINVAL; + goto error; + } + gotdata = 1; + break; + } else { + while(chunk > sizeof(buffer)) { + len = fread(buffer, 1, sizeof(buffer), play->fp); + chunk -= sizeof(buffer); + } + if (chunk) + len = fread(buffer, 1, chunk, play->fp); + } + } + + if (!gotfmt || !gotdata) { + fprintf(stderr, "WAVE error: Missing 'data' or 'fmt' chunk!\n"); + rc = -EINVAL; + goto error; + } + + if (fmt.format != 1) { + fprintf(stderr, "WAVE error: We support only PCM files!\n"); + rc = -EINVAL; + goto error; + } + if (fmt.channels != 1) { + fprintf(stderr, "WAVE error: We support only mono files!\n"); + rc = -EINVAL; + goto error; + } + if (fmt.sample_rate != samplerate) { + fprintf(stderr, "WAVE error: The WAVE file's sample rate (%d) does not match our sample rate (%d)!\n", fmt.sample_rate, samplerate); + rc = -EINVAL; + goto error; + } + if (fmt.bits_sample != 16) { + fprintf(stderr, "WAVE error: We support only 16 bit files!\n"); + rc = -EINVAL; + goto error; + } + + play->left = chunk >> 1; + + printf("*** Replacing received audio by %s.\n", filename); + + return 0; + +error: + fclose(play->fp); + play->fp = NULL; + return rc; +} + +int wave_read(wave_play_t *play, int16_t *samples, int length) +{ + uint8_t *buffer = (uint8_t *)samples; + int __attribute__((__unused__)) len; + int i; + + if (length > play->left) { + memset(samples, 0, length << 1); + length = play->left; + } + if (!length) + return length; + + play->left -= length; + if (!play->left) + printf("*** Finished reading WAVE file.\n"); + + /* read and correct endiness */ + len = fread(samples, 1, length << 1, play->fp); + for (i = 0; i < length; i++) { + *samples++ = buffer[0] + (buffer[1] << 8); + buffer += 2; + } + + return length; +} + +int wave_write(wave_rec_t *rec, int16_t *samples, int length) +{ + uint8_t buffer[length << 1]; + int __attribute__((__unused__)) len; + int i, j; + + /* write and correct endiness */ + for (i = 0, j = 0; i < length; i++) { + buffer[j++] = *samples; + buffer[j++] = (*samples) >> 8; + samples++; + } + len = fwrite(buffer, 1, length << 1, rec->fp); + rec->written += length; + + return length; +} + +void wave_destroy_record(wave_rec_t *rec) +{ + uint8_t buffer[256]; + uint32_t size, wsize; + struct fmt fmt; + int __attribute__((__unused__)) len; + + if (!rec->fp) + return; + + /* cue */ + fprintf(rec->fp, "cue %c%c%c%c%c%c%c%c", 4, 0, 0, 0, 0,0,0,0); + + /* LIST */ + fprintf(rec->fp, "LIST%c%c%c%cadtl", 4, 0, 0, 0); + + /* go to header */ + fseek(rec->fp, 0, SEEK_SET); + + size = rec->written << 1; + wsize = 4 + 8 + sizeof(fmt) + 8 + size + 8 + 4 + 8 + 4; + + /* RIFF */ + fprintf(rec->fp, "RIFF%c%c%c%c", wsize & 0xff, (wsize >> 8) & 0xff, (wsize >> 16) & 0xff, wsize >> 24); + + /* WAVE */ + fprintf(rec->fp, "WAVE"); + + /* fmt */ + fprintf(rec->fp, "fmt %c%c%c%c", (uint8_t)sizeof(fmt), 0, 0, 0); + fmt.format = 1; + fmt.channels = 1; + fmt.sample_rate = rec->samplerate; /* samples/sec */ + fmt.data_rate = rec->samplerate * 2; /* full data rate */ + fmt.bytes_sample = 2; /* all channels */ + fmt.bits_sample = 16; /* one channel */ + buffer[0] = fmt.format; + buffer[1] = fmt.format >> 8; + buffer[2] = fmt.channels; + buffer[3] = fmt.channels >> 8; + buffer[4] = fmt.sample_rate; + buffer[5] = fmt.sample_rate >> 8; + buffer[6] = fmt.sample_rate >> 16; + buffer[7] = fmt.sample_rate >> 24; + buffer[8] = fmt.data_rate; + buffer[9] = fmt.data_rate >> 8; + buffer[10] = fmt.data_rate >> 16; + buffer[11] = fmt.data_rate >> 24; + buffer[12] = fmt.bytes_sample; + buffer[13] = fmt.bytes_sample >> 8; + buffer[14] = fmt.bits_sample; + buffer[15] = fmt.bits_sample >> 8; + len = fwrite(buffer, 1, sizeof(fmt), rec->fp); + + /* data */ + fprintf(rec->fp, "data%c%c%c%c", size & 0xff, (size >> 8) & 0xff, (size >> 16) & 0xff, size >> 24); + + fclose(rec->fp); + rec->fp = NULL; + + printf("*** Received audio is written to WAVE file.\n"); +} + +void wave_destroy_playback(wave_play_t *play) +{ + if (!play->fp) + return; + + fclose(play->fp); + play->fp = NULL; +} + diff --git a/src/common/wave.h b/src/common/wave.h new file mode 100644 index 0000000..b9575d6 --- /dev/null +++ b/src/common/wave.h @@ -0,0 +1,19 @@ + +typedef struct wave_rec { + FILE *fp; + int samplerate; + uint32_t written; /* how much samples written */ +} wave_rec_t; + +typedef struct wave_play { + FILE *fp; + uint32_t left; /* how much samples left */ +} wave_play_t; + +int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate); +int wave_create_playback(wave_play_t *play, const char *filename, int samplerate); +int wave_read(wave_play_t *play, int16_t *samples, int length); +int wave_write(wave_rec_t *rec, int16_t *samples, int length); +void wave_destroy_record(wave_rec_t *rec); +void wave_destroy_playback(wave_play_t *play); + diff --git a/src/nmt/main.c b/src/nmt/main.c index cea0169..0d6a7d4 100644 --- a/src/nmt/main.c +++ b/src/nmt/main.c @@ -235,7 +235,7 @@ int main(int argc, char *argv[]) } /* create transceiver instance */ - rc = nmt_create(sounddev, samplerate, kanal, (loopback) ? CHAN_TYPE_TEST : chan_type, ms_power, nmt_digits2value(traffic_area, 2), area_no, compander, supervisory, loopback); + rc = nmt_create(sounddev, samplerate, write_wave, read_wave, kanal, (loopback) ? CHAN_TYPE_TEST : chan_type, ms_power, nmt_digits2value(traffic_area, 2), area_no, compander, supervisory, loopback); if (rc < 0) { fprintf(stderr, "Failed to create transceiver instance. Quitting!\n"); goto fail; diff --git a/src/nmt/nmt.c b/src/nmt/nmt.c index 1e8166e..22c9295 100644 --- a/src/nmt/nmt.c +++ b/src/nmt/nmt.c @@ -283,7 +283,7 @@ static void nmt_timeout(struct timer *timer); static void nmt_go_idle(nmt_t *nmt); /* Create transceiver instance and link to a list. */ -int nmt_create(const char *sounddev, int samplerate, int channel, enum nmt_chan_type chan_type, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compander, int supervisory, int loopback) +int nmt_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int channel, enum nmt_chan_type chan_type, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compander, int supervisory, int loopback) { nmt_t *nmt; int rc; @@ -324,7 +324,7 @@ int nmt_create(const char *sounddev, int samplerate, int channel, enum nmt_chan_ PDEBUG(DNMT, DEBUG_DEBUG, "Creating 'NMT' instance for channel = %d (sample rate %d).\n", channel, samplerate); /* init general part of transceiver */ - rc = sender_create(&nmt->sender, sounddev, samplerate, channel, loopback, 0, -1); + rc = sender_create(&nmt->sender, sounddev, samplerate, write_wave, read_wave, channel, loopback, 0, -1); if (rc < 0) { PDEBUG(DNMT, DEBUG_ERROR, "Failed to init transceiver process!\n"); goto error; diff --git a/src/nmt/nmt.h b/src/nmt/nmt.h index 385f4fb..edb1497 100644 --- a/src/nmt/nmt.h +++ b/src/nmt/nmt.h @@ -134,7 +134,7 @@ const char *chan_type_long_name(enum nmt_chan_type chan_type); double nmt_channel2freq(int channel, int uplink); void nmt_country_list(void); uint8_t nmt_country_by_short_name(const char *short_name); -int nmt_create(const char *sounddev, int samplerate, int channel, enum nmt_chan_type chan_type, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compander, int supervisory, int loopback); +int nmt_create(const char *sounddev, int samplerate, const char *write_wave, const char *read_wave, int channel, enum nmt_chan_type chan_type, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compander, int supervisory, int loopback); void nmt_destroy(sender_t *sender); void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double level, double frames_elapsed); const char *nmt_get_frame(nmt_t *nmt);