Refactor global variables for signal processing

These are:
	device, sample rate, buffer, latency
Called now:
	dsp_device, dsp_samplerate, dsp_buffer, dsp_latency
Call audio device:
	call_device, call_samplerate, call_buffer
This commit is contained in:
Andreas Eversberg 2021-09-18 11:43:01 +02:00
parent eb462f6158
commit f7d4eb961e
14 changed files with 124 additions and 113 deletions

View File

@ -71,7 +71,7 @@ typedef struct console {
char audiodev[64]; /* headphone interface, if used */
int samplerate; /* sample rate of headphone interface */
void *sound; /* headphone interface */
int latspl; /* sample latency at headphone interface */
int buffer_size; /* sample buffer size at headphone interface */
samplerate_t srstate; /* patterns/announcement upsampling */
jitter_t dejitter; /* headphone audio dejittering */
int test_audio_pos; /* position for test tone toward mobile */
@ -358,7 +358,7 @@ static void _print_console_text(void)
printf("\033[0;39m");
}
int console_init(const char *station_id, const char *audiodev, int samplerate, int latency, int num_digits, int loopback, int echo_test, const char *digits)
int console_init(const char *station_id, const char *audiodev, int samplerate, int buffer, int num_digits, int loopback, int echo_test, const char *digits)
{
int rc = 0;
@ -372,7 +372,7 @@ int console_init(const char *station_id, const char *audiodev, int samplerate, i
strncpy(console.station_id, station_id, sizeof(console.station_id) - 1);
strncpy(console.audiodev, audiodev, sizeof(console.audiodev) - 1);
console.samplerate = samplerate;
console.latspl = latency * samplerate / 1000;
console.buffer_size = buffer * samplerate / 1000;
console.num_digits = num_digits;
console.loopback = loopback;
console.echo_test = echo_test;
@ -400,7 +400,7 @@ error:
return rc;
}
int console_open_audio(int __attribute__((unused)) latspl)
int console_open_audio(int __attribute__((unused)) buffer_size, double __attribute__((unused)) interval)
{
if (!console.audiodev[0])
return 0;
@ -408,7 +408,7 @@ int console_open_audio(int __attribute__((unused)) latspl)
#ifdef HAVE_ALSA
/* open sound device for call control */
/* use factor 1.4 of speech level for complete range of sound card */
console.sound = sound_open(console.audiodev, NULL, NULL, NULL, 1, 0.0, console.samplerate, latspl, 1.4, 4000.0, 2.0);
console.sound = sound_open(console.audiodev, NULL, NULL, NULL, 1, 0.0, console.samplerate, buffer_size, interval, 1.4, 4000.0, 2.0);
if (!console.sound) {
PDEBUG(DSENDER, DEBUG_ERROR, "No sound device!\n");
return -EIO;
@ -547,12 +547,12 @@ void process_console(int c)
#ifdef HAVE_ALSA
/* handle audio, if sound device is used */
sample_t samples[console.latspl + 10], *samples_list[1];
sample_t samples[console.buffer_size + 10], *samples_list[1];
uint8_t *power_list[1];
int count;
int rc;
count = sound_get_tosend(console.sound, console.latspl);
count = sound_get_tosend(console.sound, console.buffer_size);
if (count < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to get samples in buffer (rc = %d)!\n", count);
if (count == -EPIPE)
@ -572,7 +572,7 @@ void process_console(int c)
}
}
samples_list[0] = samples;
count = sound_read(console.sound, samples_list, console.latspl, 1, NULL);
count = sound_read(console.sound, samples_list, console.buffer_size, 1, NULL);
if (count < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count);
if (count == -EPIPE)

View File

@ -1,8 +1,8 @@
void console_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg);
int console_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int echo_test, const char *digits);
int console_init(const char *station_id, const char *audiodev, int samplerate, int buffer, int dial_digits, int loopback, int echo_test, const char *digits);
void console_cleanup(void);
int console_open_audio(int latspl);
int console_open_audio(int buffer_size, double interval);
int console_start_audio(void);
void console_process(int c);
void process_console(int c);

View File

@ -50,15 +50,16 @@ static int got_init = 0;
/* common mobile settings */
int num_kanal = 0;
const char *kanal[MAX_SENDER];
int num_audiodev = 0;
const char *audiodev[MAX_SENDER] = { "hw:0,0" };
int num_device = 0;
const char *dsp_device[MAX_SENDER] = { "hw:0,0" };
int allow_sdr = 1;
int use_sdr = 0;
static const char *call_audiodev = "";
int samplerate = 48000;
int dsp_samplerate = 48000;
double dsp_interval = 1.0;
int dsp_buffer = 50;
static const char *call_device = "";
static int call_samplerate = 48000;
int interval = 1;
int latency = 50;
static int call_buffer = 50;
int uses_emphasis = 1;
int do_pre_emphasis = 0;
int do_de_emphasis = 0;
@ -106,16 +107,17 @@ void main_mobile_print_help(const char *arg0, const char *ext_usage)
printf(" -k --channel <channel>\n");
printf(" Channel (German = Kanal) number of \"Sender\" (German = Transceiver)\n");
printf(" -a --audio-device hw:<card>,<device>\n");
printf(" Sound card and device number (default = '%s')\n", audiodev[0]);
printf(" Sound card and device number (default = '%s')\n", dsp_device[0]);
printf(" Don't set it for SDR!\n");
printf(" -s --samplerate <rate>\n");
printf(" Sample rate of sound device (default = '%d')\n", samplerate);
printf(" -i --interval 1..25\n");
printf(" Interval of processing loop in ms (default = '%d' ms)\n", interval);
printf(" Use 25 to drastically reduce CPU usage. In case of buffer underrun,\n");
printf(" increase latency accordingly.\n");
printf(" Sample rate of sound device (default = '%d')\n", dsp_samplerate);
printf(" -i --interval 0.1..25\n");
printf(" Interval of processing loop in ms (default = '%.1f' ms)\n", dsp_interval);
printf(" Use 10 to drastically reduce CPU usage. In case of buffer underrun,\n");
printf(" increase buffer accordingly.\n");
printf(" -b --buffer <ms>\n");
printf(" How many milliseconds are processed in advance (default = '%d')\n", latency);
printf(" How many milliseconds are processed in advance (default = '%d')\n", dsp_buffer);
printf(" A buffer below 10 ms requires low interval like 0.1 ms.\n");
if (uses_emphasis) {
printf(" -p --pre-emphasis\n");
printf(" Enable pre-emphasis, if you directly connect to the oscillator of the\n");
@ -134,9 +136,11 @@ void main_mobile_print_help(const char *arg0, const char *ext_usage)
printf(" Use echo test, to send back audio from mobile phone's microphone to\n");
printf(" the speaker. (German: 'Blasprobe').\n");
printf(" -c --call-device hw:<card>,<device>\n");
printf(" Sound card and device number for headset (default = '%s')\n", call_audiodev);
printf(" Sound card and device number for headset (default = '%s')\n", call_device);
printf(" --call-samplerate <rate>\n");
printf(" Sample rate of sound device for headset (default = '%d')\n", call_samplerate);
printf(" --call-buffer <ms>\n");
printf(" How many milliseconds are processed in advance (default = '%d')\n", call_buffer);
printf(" -x --osmocc-cross\n");
printf(" Enable built-in call forwarding between mobiles. Be sure to have\n");
printf(" at least one control channel and two voice channels. Alternatively\n");
@ -198,7 +202,8 @@ void main_mobile_print_hotkeys(void)
#define OPT_READ_RX_WAVE 1006
#define OPT_READ_TX_WAVE 1007
#define OPT_CALL_SAMPLERATE 1008
#define OPT_FAST_MATH 1009
#define OPT_CALL_BUFFER 1009
#define OPT_FAST_MATH 1010
#define OPT_LIMESDR 1100
#define OPT_LIMESDR_MINI 1101
@ -222,6 +227,7 @@ void main_mobile_add_options(void)
option_add(OPT_OSMO_CC, "cc", 1);
option_add('c', "call-device", 1);
option_add(OPT_CALL_SAMPLERATE, "call-samplerate", 1);
option_add(OPT_CALL_BUFFER, "call-buffer", 1);
option_add('t', "tones", 1);
option_add('l', "loopback", 1);
option_add('r', "realtime", 1);
@ -264,20 +270,20 @@ int main_mobile_handle_options(int short_option, int argi, char **argv)
OPT_ARRAY(num_kanal, kanal, argv[argi])
break;
case 'a':
OPT_ARRAY(num_audiodev, audiodev, options_strdup(argv[argi]))
OPT_ARRAY(num_device, dsp_device, options_strdup(argv[argi]))
break;
case 's':
samplerate = atoi(argv[argi]);
dsp_samplerate = atoi(argv[argi]);
break;
case 'i':
interval = atoi(argv[argi]);
if (interval < 1)
interval = 1;
if (interval > 25)
interval = 25;
dsp_interval = atof(argv[argi]);
if (dsp_interval < 0.1)
dsp_interval = 0.1;
if (dsp_interval > 10)
dsp_interval = 10;
break;
case 'b':
latency = atoi(argv[argi]);
dsp_buffer = atoi(argv[argi]);
break;
case 'p':
if (!uses_emphasis) {
@ -321,11 +327,14 @@ int main_mobile_handle_options(int short_option, int argi, char **argv)
cc_argv[cc_argc++] = options_strdup(argv[argi]);
break;
case 'c':
call_audiodev = options_strdup(argv[argi]);
call_device = options_strdup(argv[argi]);
break;
case OPT_CALL_SAMPLERATE:
call_samplerate = atoi(argv[argi]);
break;
case OPT_CALL_BUFFER:
call_buffer = atoi(argv[argi]);
break;
case 't':
send_patterns = atoi(argv[argi]);
break;
@ -431,9 +440,9 @@ static int get_char()
}
/* Loop through all transceiver instances of one network. */
void main_mobile(const char *name, int *quit, int latency, int interval, void (*myhandler)(void), const char *station_id, int station_id_digits)
void main_mobile(const char *name, int *quit, void (*myhandler)(void), const char *station_id, int station_id_digits)
{
int latspl;
int buffer_size;
sender_t *sender;
double last_time_call = 0, begin_time, now, sleep;
struct termios term, term_orig;
@ -445,8 +454,8 @@ void main_mobile(const char *name, int *quit, int latency, int interval, void (*
abort();
}
/* latency of send buffer in samples */
latspl = samplerate * latency / 1000;
/* size of dsp buffer in samples */
buffer_size = dsp_samplerate * dsp_buffer / 1000;
/* check OSMO-CC support */
if (use_osmocc_cross && num_kanal == 1) {
@ -457,15 +466,15 @@ void main_mobile(const char *name, int *quit, int latency, int interval, void (*
fprintf(stderr, "You selected OSMO-CC socket interface and built-in call forwarding, but only one can be selected.\n");
return;
}
if (echo_test && call_audiodev[0]) {
if (echo_test && call_device[0]) {
fprintf(stderr, "You selected call device (headset) and echo test, but only one can be selected.\n");
return;
}
if (use_osmocc_sock && call_audiodev[0]) {
if (use_osmocc_sock && call_device[0]) {
fprintf(stderr, "You selected OSMO-CC socket interface, but it cannot be used with call device (headset).\n");
return;
}
if (use_osmocc_cross && call_audiodev[0]) {
if (use_osmocc_cross && call_device[0]) {
fprintf(stderr, "You selected built-in call forwarding, but it cannot be used with call device (headset).\n");
return;
}
@ -488,7 +497,7 @@ void main_mobile(const char *name, int *quit, int latency, int interval, void (*
/* init OSMO-CC */
if (!use_osmocc_sock)
console_init(station_id, call_audiodev, call_samplerate, latency, station_id_digits, loopback, echo_test, console_digits);
console_init(station_id, call_device, call_samplerate, call_buffer, station_id_digits, loopback, echo_test, console_digits);
/* init call control instance */
rc = call_init(name, (use_osmocc_sock) ? send_patterns : 0, release_on_disconnect, use_osmocc_sock, cc_argc, cc_argv);
@ -498,15 +507,15 @@ void main_mobile(const char *name, int *quit, int latency, int interval, void (*
}
#ifdef HAVE_SDR
rc = sdr_configure(samplerate);
rc = sdr_configure(dsp_samplerate);
if (rc < 0)
return;
#endif
/* open audio */
if (sender_open_audio(latspl))
if (sender_open_audio(buffer_size, dsp_interval))
return;
if (console_open_audio(latspl))
if (console_open_audio(buffer_size, dsp_interval))
return;
if (!loopback)
@ -552,7 +561,7 @@ void main_mobile(const char *name, int *quit, int latency, int interval, void (*
/* do not process audio for an audio slave, since it is done by audio master */
if (sender->master) /* if master is set, we are an audio slave */
continue;
process_sender_audio(sender, quit, latspl);
process_sender_audio(sender, quit, buffer_size);
}
/* process timers */
@ -646,12 +655,12 @@ next_char:
if (myhandler)
myhandler();
display_measurements((double)interval / 1000.0);
display_measurements(dsp_interval / 1000.0);
now = get_time();
/* sleep interval */
sleep = ((double)interval / 1000.0) - (now - begin_time);
sleep = (dsp_interval / 1000.0) - (now - begin_time);
if (sleep > 0)
usleep(sleep * 1000000.0);

View File

@ -2,13 +2,13 @@
extern int num_kanal;
extern const char *kanal[];
extern int swap_links;
extern int num_audiodev;
extern const char *audiodev[];
extern int num_device;
extern int allow_sdr;
extern int use_sdr;
extern int samplerate;
extern int interval;
extern int latency;
extern const char *dsp_device[];
extern int dsp_samplerate;
extern double dsp_interval;
extern int dsp_buffer;
extern int uses_emphasis;
extern int do_pre_emphasis;
extern int do_de_emphasis;
@ -42,7 +42,7 @@ int main_mobile_handle_options(int short_option, int argi, char **argv);
extern int quit;
void sighandler(int sigset);
void main_mobile(const char *name, int *quit, int latency, int interval, void (*myhandler)(void), const char *station_id, int station_id_digits);
void main_mobile(const char *name, int *quit, void (*myhandler)(void), const char *station_id, int station_id_digits);
void dump_info(void);

View File

@ -38,7 +38,7 @@ int cant_recover = 0;
int check_channel = 1;
/* Init transceiver instance and link to list of transceivers. */
int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, double empfangsfrequenz, const char *audiodev, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, enum paging_signal paging_signal)
int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, double empfangsfrequenz, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, enum paging_signal paging_signal)
{
sender_t *master, *slave;
int rc = 0;
@ -46,7 +46,7 @@ int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, dou
sender->kanal = kanal;
sender->sendefrequenz = sendefrequenz;
sender->empfangsfrequenz = (loopback) ? sendefrequenz : empfangsfrequenz;
strncpy(sender->audiodev, audiodev, sizeof(sender->audiodev) - 1);
strncpy(sender->device, device, sizeof(sender->device) - 1);
sender->samplerate = samplerate;
sender->rx_gain = rx_gain;
sender->tx_gain = tx_gain;
@ -90,7 +90,7 @@ int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, dou
PDEBUG(DSENDER, DEBUG_NOTICE, "Please use at least one channel distance to avoid that.\n");
PDEBUG(DSENDER, DEBUG_NOTICE, "------------------------------------------------------------------------\n");
}
if (!strcmp(master->audiodev, audiodev))
if (!strcmp(master->device, device))
break;
}
if (master) {
@ -169,7 +169,7 @@ error:
return rc;
}
int sender_open_audio(int latspl)
int sender_open_audio(int buffer_size, double interval)
{
sender_t *master, *inst;
int channels;
@ -226,7 +226,7 @@ int sender_open_audio(int latspl)
}
/* open device */
master->audio = master->audio_open(master->audiodev, tx_f, rx_f, am, channels, paging_frequency, master->samplerate, latspl, (master->max_deviation) ?: 1.0, master->max_modulation, master->modulation_index);
master->audio = master->audio_open(master->device, tx_f, rx_f, am, channels, paging_frequency, master->samplerate, buffer_size, interval, (master->max_deviation) ?: 1.0, master->max_modulation, master->modulation_index);
if (!master->audio) {
PDEBUG(DSENDER, DEBUG_ERROR, "No device for transceiver!\n");
return -EIO;
@ -321,7 +321,7 @@ static void gain_samples(sample_t *samples, int length, double gain)
}
/* Handle audio streaming of one transceiver. */
void process_sender_audio(sender_t *sender, int *quit, int latspl)
void process_sender_audio(sender_t *sender, int *quit, int buffer_size)
{
sender_t *inst;
int rc, count;
@ -332,8 +332,8 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl)
/* count instances for audio channel */
for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave);
sample_t buff[num_chan][latspl], *samples[num_chan];
uint8_t pbuff[num_chan][latspl], *power[num_chan];
sample_t buff[num_chan][buffer_size], *samples[num_chan];
uint8_t pbuff[num_chan][buffer_size], *power[num_chan];
enum paging_signal paging_signal[num_chan];
int on[num_chan];
double rf_level_db[num_chan];
@ -345,7 +345,7 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl)
#ifdef DEBUG_TIME_CONSUMPTION
t1 = get_time();
#endif
count = sender->audio_get_tosend(sender->audio, latspl);
count = sender->audio_get_tosend(sender->audio, buffer_size);
if (count < 0) {
PDEBUG_CHAN(DSENDER, DEBUG_ERROR, "Failed to get number of samples in buffer (rc = %d)!\n", count);
if (count == -EPIPE) {
@ -364,8 +364,8 @@ cant_recover:
#endif
if (count > 0) {
/* limit to our buffer */
if (count > latspl)
count = latspl;
if (count > buffer_size)
count = buffer_size;
/* loop through all channels */
for (i = 0, inst = sender; inst; i++, inst = inst->slave) {
/* load TX data from audio loop or from sender instance */
@ -414,7 +414,7 @@ cant_recover:
t3 = get_time();
#endif
count = sender->audio_read(sender->audio, samples, latspl, num_chan, rf_level_db);
count = sender->audio_read(sender->audio, samples, buffer_size, num_chan, rf_level_db);
if (count < 0) {
/* special case when audio_read wants us to quit */
if (count == -EPERM) {

View File

@ -43,8 +43,8 @@ typedef struct sender {
/* audio */
void *audio;
char audiodev[64]; /* audio device name (alsa or sdr) */
void *(*audio_open)(const char *, double *, double *, int *, int, double, int, int, double, double, double);
char device[64]; /* audio device name (alsa or sdr) */
void *(*audio_open)(const char *, double *, double *, int *, int, double, int, int, double, double, double, double);
int (*audio_start)(void *);
void (*audio_close)(void *);
int (*audio_write)(void *, sample_t **, uint8_t **, int, enum paging_signal *, int *, int);
@ -93,13 +93,13 @@ extern sender_t *sender_head;
extern int cant_recover;
extern int check_channel;
int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, double empfangsfrequenz, const char *audiodev, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, enum paging_signal paging_signal);
int sender_create(sender_t *sender, const char *kanal, double sendefrequenz, double empfangsfrequenz, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, enum paging_signal paging_signal);
void sender_destroy(sender_t *sender);
void sender_set_fm(sender_t *sender, double max_deviation, double max_modulation, double speech_deviation, double max_display);
void sender_set_am(sender_t *sender, double max_modulation, double speech_deviation, double max_display, double modulation_index);
int sender_open_audio(int latspl);
int sender_open_audio(int buffer_size, double interval);
int sender_start_audio(void);
void process_sender_audio(sender_t *sender, int *quit, int latspl);
void process_sender_audio(sender_t *sender, int *quit, int buffer_size);
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int count);
void sender_receive(sender_t *sender, sample_t *samples, int count, double rf_level_db);
void sender_paging(sender_t *sender, int on);

View File

@ -93,7 +93,8 @@ typedef struct sdr {
int channels; /* number of frequencies */
double amplitude; /* amplitude of each carrier */
int samplerate; /* sample rate of audio data */
int latspl; /* latency in audio samples */
int buffer_size; /* buffer in audio samples */
double interval; /* how often to process the loop */
wave_rec_t wave_rx_rec;
wave_rec_t wave_tx_rec;
wave_play_t wave_rx_play;
@ -136,7 +137,7 @@ static void show_spectrum(const char *direction, double halfbandwidth, double ce
PDEBUG(DSDR, DEBUG_INFO, "Frequency P = %.4f MHz (Paging Frequency)\n", paging_frequency / 1e6);
}
void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int latspl, double max_deviation, double max_modulation, double modulation_index)
void *sdr_open(const char __attribute__((__unused__)) *device, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int buffer_size, double interval, double max_deviation, double max_modulation, double modulation_index)
{
sdr_t *sdr;
int threads = 1, oversample = 1; /* always use threads */
@ -179,13 +180,14 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
sdr->channels = channels;
sdr->amplitude = 1.0 / (double)channels;
sdr->samplerate = samplerate;
sdr->latspl = latspl;
sdr->buffer_size = buffer_size;
sdr->interval = interval;
sdr->threads = threads; /* always required, because write may block */
sdr->oversample = oversample;
if (threads) {
memset(&sdr->thread_read, 0, sizeof(sdr->thread_read));
sdr->thread_read.buffer_size = sdr->latspl * 2 * sdr->oversample + 2;
sdr->thread_read.buffer_size = sdr->buffer_size * 2 * sdr->oversample + 2;
sdr->thread_read.buffer = calloc(sdr->thread_read.buffer_size, sizeof(*sdr->thread_read.buffer));
if (!sdr->thread_read.buffer) {
PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
@ -202,7 +204,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
iir_lowpass_init(&sdr->thread_read.lp[1], samplerate / 2.0, sdr_config->samplerate, 2);
}
memset(&sdr->thread_write, 0, sizeof(sdr->thread_write));
sdr->thread_write.buffer_size = sdr->latspl * 2 + 2;
sdr->thread_write.buffer_size = sdr->buffer_size * 2 + 2;
sdr->thread_write.buffer = calloc(sdr->thread_write.buffer_size, sizeof(*sdr->thread_write.buffer));
if (!sdr->thread_write.buffer) {
PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
@ -221,32 +223,32 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
}
/* alloc fm modulation buffers */
sdr->modbuff = calloc(sdr->latspl * 2, sizeof(*sdr->modbuff));
sdr->modbuff = calloc(sdr->buffer_size * 2, sizeof(*sdr->modbuff));
if (!sdr->modbuff) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
}
sdr->modbuff_I = calloc(sdr->latspl, sizeof(*sdr->modbuff_I));
sdr->modbuff_I = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_I));
if (!sdr->modbuff_I) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
}
sdr->modbuff_Q = calloc(sdr->latspl, sizeof(*sdr->modbuff_Q));
sdr->modbuff_Q = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_Q));
if (!sdr->modbuff_Q) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
}
sdr->modbuff_carrier = calloc(sdr->latspl, sizeof(*sdr->modbuff_carrier));
sdr->modbuff_carrier = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_carrier));
if (!sdr->modbuff_carrier) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
}
sdr->wavespl0 = calloc(sdr->latspl, sizeof(*sdr->wavespl0));
sdr->wavespl0 = calloc(sdr->buffer_size, sizeof(*sdr->wavespl0));
if (!sdr->wavespl0) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
}
sdr->wavespl1 = calloc(sdr->latspl, sizeof(*sdr->wavespl1));
sdr->wavespl1 = calloc(sdr->buffer_size, sizeof(*sdr->wavespl1));
if (!sdr->wavespl1) {
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error;
@ -567,7 +569,7 @@ static void *sdr_write_child(void *arg)
}
/* delay some time */
usleep(1000);
usleep(sdr->interval * 1000.0);
}
PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n");
@ -619,7 +621,7 @@ static void *sdr_read_child(void *arg)
}
/* delay some time */
usleep(1000);
usleep(sdr->interval * 1000.0);
}
PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n");
@ -757,8 +759,8 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag
int c, s, ss;
int sent = 0;
if (num > sdr->latspl) {
fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n");
if (num > sdr->buffer_size) {
fprintf(stderr, "exceeding maximum size given by sdr->buffer_size, please fix!\n");
abort();
}
if (channels != sdr->channels && channels != 0) {
@ -858,8 +860,8 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
int count = 0;
int c, s, ss;
if (num > sdr->latspl) {
fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n");
if (num > sdr->buffer_size) {
fprintf(stderr, "exceeding maximum size given by sdr->buffer_size, please fix!\n");
abort();
}
@ -981,19 +983,19 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
return count;
}
/* how much do we need to send (in audio sample duration) to get the target delay (latspl) */
int sdr_get_tosend(void *inst, int latspl)
/* how much do we need to send (in audio sample duration) to get the target delay (buffer size) */
int sdr_get_tosend(void *inst, int buffer_size)
{
sdr_t *sdr = (sdr_t *)inst;
int count = 0;
#ifdef HAVE_UHD
if (sdr_config->uhd)
count = uhd_get_tosend(latspl * sdr->oversample);
count = uhd_get_tosend(buffer_size * sdr->oversample);
#endif
#ifdef HAVE_SOAPY
if (sdr_config->soapy)
count = soapy_get_tosend(latspl * sdr->oversample);
count = soapy_get_tosend(buffer_size * sdr->oversample);
#endif
if (count < 0)
return count;

View File

@ -2,10 +2,10 @@
enum paging_signal;
int sdr_start(void *inst);
void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int latspl, double max_deviation, double max_modulation, double modulation_index);
void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int buffer_size, double interval, double max_deviation, double max_modulation, double modulation_index);
void sdr_close(void *inst);
int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels);
int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_level_db);
int sdr_get_tosend(void *inst, int latspl);
int sdr_get_tosend(void *inst, int buffer_size);
void calibrate_bias(void);

View File

@ -27,9 +27,9 @@
*
* If a RX time stamp is valid and first chunk is to be transmitted (tosend()
* is called), TX time stamp becomes valid and is set to RX time stamp, but
* advanced by the duration of the latency (latspl). tosend() always returns
* advanced by the duration of the buffer size. tosend() always returns
* the number of samples that are needed, to make TX time stamp advance RX time
* stamp by given latency.
* stamp by given buffer size.
*
* If chunk is transmitted to SDR, the TX time stamp is advanced by the
* duration of the transmitted chunk.
@ -557,7 +557,7 @@ int soapy_receive(float *buff, int max)
}
/* estimate number of samples that can be sent */
int soapy_get_tosend(int latspl)
int soapy_get_tosend(int buffer_size)
{
int tosend;
@ -567,23 +567,23 @@ int soapy_get_tosend(int latspl)
/* RX time stamp is valid the first time, set the TX time stamp in advance */
if (!tx_valid) {
tx_timeNs = rx_timeNs + latspl * Ns_per_sample;
tx_timeNs = rx_timeNs + buffer_size * Ns_per_sample;
tx_valid = 1;
return 0;
}
/* we check how advance our transmitted time stamp is */
pthread_mutex_lock(&timestamp_mutex);
tosend = latspl - (tx_timeNs - rx_timeNs) / Ns_per_sample;
tosend = buffer_size - (tx_timeNs - rx_timeNs) / Ns_per_sample;
pthread_mutex_unlock(&timestamp_mutex);
/* in case of underrun */
if (tosend > latspl) {
if (tosend > buffer_size) {
PDEBUG(DSOAPY, DEBUG_ERROR, "SDR TX underrun, seems we are too slow. Use lower SDR sample rate.\n");
tosend = latspl;
tosend = buffer_size;
}
/* race condition and routing errors may cause TX time stamps to be in advance of slightly more than latspl */
/* race condition and routing errors may cause TX time stamps to be in advance of slightly more than buffer_size */
if (tosend < 0)
tosend = 0;

View File

@ -4,5 +4,5 @@ int soapy_start(void);
void soapy_close(void);
int soapy_send(float *buff, int num);
int soapy_receive(float *buff, int max);
int soapy_get_tosend(int latspl);
int soapy_get_tosend(int buffer_size);

View File

@ -631,7 +631,7 @@ int uhd_receive(float *buff, int max)
}
/* estimate number of samples that can be sent */
int uhd_get_tosend(int latspl)
int uhd_get_tosend(int buffer_size)
{
double advance;
int tosend;
@ -645,7 +645,7 @@ int uhd_get_tosend(int latspl)
tx_time_secs = rx_time_secs;
tx_time_fract_sec = rx_time_fract_sec;
if (tx_timestamps) {
tx_time_fract_sec += (double)latspl / samplerate;
tx_time_fract_sec += (double)buffer_size / samplerate;
if (tx_time_fract_sec >= 1.0) {
tx_time_fract_sec -= 1.0;
tx_time_secs++;
@ -660,7 +660,7 @@ int uhd_get_tosend(int latspl)
PDEBUG(DSOAPY, DEBUG_ERROR, "SDR TX underrun, seems we are too slow. Use lower SDR sample rate.\n");
advance = 0;
}
tosend = latspl - (int)(advance * samplerate);
tosend = buffer_size - (int)(advance * samplerate);
if (tosend < 0)
tosend = 0;

View File

@ -4,5 +4,5 @@ int uhd_start(void);
void uhd_close(void);
int uhd_send(float *buff, int num);
int uhd_receive(float *buff, int max);
int uhd_get_tosend(int latspl);
int uhd_get_tosend(int buffer_size);

View File

@ -1,10 +1,10 @@
enum paging_signal;
void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int latspl, double max_deviation, double max_modulation, double modulation_index);
void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int buffer_size, double interval, double max_deviation, double max_modulation, double modulation_index);
int sound_start(void *inst);
void sound_close(void *inst);
int sound_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels);
int sound_read(void *inst, sample_t **samples, int num, int channels, double *rf_level_db);
int sound_get_tosend(void *inst, int latspl);
int sound_get_tosend(void *inst, int buffer_size);

View File

@ -187,7 +187,7 @@ static void dev_close(sound_t *sound)
snd_pcm_close(sound->chandle);
}
void *sound_open(const char *audiodev, double __attribute__((unused)) *tx_frequency, double __attribute__((unused)) *rx_frequency, int __attribute__((unused)) *am, int channels, double __attribute__((unused)) paging_frequency, int samplerate, int __attribute((unused)) latspl, double max_deviation, double __attribute__((unused)) max_modulation, double __attribute__((unused)) modulation_index)
void *sound_open(const char *audiodev, double __attribute__((unused)) *tx_frequency, double __attribute__((unused)) *rx_frequency, int __attribute__((unused)) *am, int channels, double __attribute__((unused)) paging_frequency, int samplerate, int __attribute((unused)) buffer_size, double __attribute__((unused)) interval, double max_deviation, double __attribute__((unused)) max_modulation, double __attribute__((unused)) modulation_index)
{
sound_t *sound;
int rc;
@ -487,7 +487,7 @@ int sound_read(void *inst, sample_t **samples, int num, int channels, double __a
* get playback buffer space
*
* return number of samples to be sent */
int sound_get_tosend(void *inst, int latspl)
int sound_get_tosend(void *inst, int buffer_size)
{
sound_t *sound = (sound_t *)inst;
int rc;
@ -497,7 +497,7 @@ int sound_get_tosend(void *inst, int latspl)
rc = snd_pcm_delay(sound->phandle, &delay);
if (rc < 0) {
if (rc == -32)
PDEBUG(DSOUND, DEBUG_ERROR, "Buffer underrun: Please use higher latency and enable real time scheduling\n");
PDEBUG(DSOUND, DEBUG_ERROR, "Buffer underrun: Please use higher buffer and enable real time scheduling\n");
else
PDEBUG(DSOUND, DEBUG_ERROR, "failed to get delay from interface (%s)\n", snd_strerror(rc));
if (rc == -EPIPE) {
@ -511,7 +511,7 @@ int sound_get_tosend(void *inst, int latspl)
return rc;
}
tosend = latspl - delay;
tosend = buffer_size - delay;
return tosend;
}