mirror of https://github.com/wb2osz/direwolf.git
Allow data rates greater than 9600 baud.
modified: audio.h modified: demod.c modified: direwolf.c modified: gen_packets.c modified: gen_tone.c
This commit is contained in:
parent
8b9c6fcf4a
commit
ccae7529bf
16
audio.h
16
audio.h
|
@ -278,8 +278,12 @@ struct audio_s {
|
||||||
/* 44100 works a little better than 22050. */
|
/* 44100 works a little better than 22050. */
|
||||||
/* If you have a reasonable machine, use the highest rate. */
|
/* If you have a reasonable machine, use the highest rate. */
|
||||||
#define MIN_SAMPLES_PER_SEC 8000
|
#define MIN_SAMPLES_PER_SEC 8000
|
||||||
#define MAX_SAMPLES_PER_SEC 48000 /* Formerly 44100. */
|
//#define MAX_SAMPLES_PER_SEC 48000 /* Originally 44100. Later increased because */
|
||||||
/* Software defined radio often uses 48000. */
|
/* Software Defined Radio often uses 48000. */
|
||||||
|
|
||||||
|
#define MAX_SAMPLES_PER_SEC 192000 /* The cheap USB-audio adapters (e.g. CM108) can handle 44100 and 48000. */
|
||||||
|
/* The "soundcard" in my desktop PC can do 96kHz or even 192kHz. */
|
||||||
|
/* We will probably need to increase the sample rate to go much above 9600 baud. */
|
||||||
|
|
||||||
#define DEFAULT_BITS_PER_SAMPLE 16
|
#define DEFAULT_BITS_PER_SAMPLE 16
|
||||||
|
|
||||||
|
@ -301,12 +305,12 @@ struct audio_s {
|
||||||
#define DEFAULT_BAUD 1200
|
#define DEFAULT_BAUD 1200
|
||||||
|
|
||||||
/* Used for sanity checking in config file and command line options. */
|
/* Used for sanity checking in config file and command line options. */
|
||||||
/* 9600 is known to work. */
|
/* 9600 baud is known to work. */
|
||||||
/* TODO: Is 19200 possible with a soundcard at 44100 samples/sec? */
|
/* TODO: Is 19200 possible with a soundcard at 44100 samples/sec or do we need a higher sample rate? */
|
||||||
|
|
||||||
#define MIN_BAUD 100
|
#define MIN_BAUD 100
|
||||||
#define MAX_BAUD 10000
|
//#define MAX_BAUD 10000
|
||||||
|
#define MAX_BAUD 40000 // Anyone want to try 38.4 k baud?
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Typical transmit timings for VHF.
|
* Typical transmit timings for VHF.
|
||||||
|
|
29
demod.c
29
demod.c
|
@ -562,6 +562,35 @@ int demod_init (struct audio_s *pa)
|
||||||
save_audio_config_p->achan[chan].num_slicers = MAX_SLICERS;
|
save_audio_config_p->achan[chan].num_slicers = MAX_SLICERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* We need a minimum number of audio samples per bit time for good performance. */
|
||||||
|
/* Easier to check here because demod_9600_init might have an adjusted sample rate. */
|
||||||
|
|
||||||
|
float ratio = (float)(save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec)
|
||||||
|
/ (float)(save_audio_config_p->achan[chan].baud);
|
||||||
|
|
||||||
|
text_color_set(DW_COLOR_INFO);
|
||||||
|
dw_printf ("The ratio of audio samples per sec (%d) to data rate in baud (%d) is %.1f\n",
|
||||||
|
save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec,
|
||||||
|
save_audio_config_p->achan[chan].baud,
|
||||||
|
ratio);
|
||||||
|
if (ratio < 3) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("There is little hope of success with such a low ratio. Use a higher sample rate.\n");
|
||||||
|
}
|
||||||
|
else if (ratio < 5) {
|
||||||
|
dw_printf ("This is on the low side for best performance. Can you use a higher sample rate?\n");
|
||||||
|
}
|
||||||
|
else if (ratio < 6) {
|
||||||
|
dw_printf ("Increasing the sample rate should improve decoder performance.\n");
|
||||||
|
}
|
||||||
|
else if (ratio > 15) {
|
||||||
|
dw_printf ("Sample rate is more than adequate. You might lower it if CPU load is a concern.\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dw_printf ("This is a suitable ratio for good performance.\n");
|
||||||
|
}
|
||||||
|
|
||||||
demod_9600_init (UPSAMPLE * save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, save_audio_config_p->achan[chan].baud, D);
|
demod_9600_init (UPSAMPLE * save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, save_audio_config_p->achan[chan].baud, D);
|
||||||
|
|
||||||
if (strchr(save_audio_config_p->achan[chan].profiles, '+') != NULL) {
|
if (strchr(save_audio_config_p->achan[chan].profiles, '+') != NULL) {
|
||||||
|
|
|
@ -369,9 +369,9 @@ int main (int argc, char *argv[])
|
||||||
case 'B': /* -B baud rate and modem properties. */
|
case 'B': /* -B baud rate and modem properties. */
|
||||||
|
|
||||||
B_opt = atoi(optarg);
|
B_opt = atoi(optarg);
|
||||||
if (B_opt < 100 || B_opt > 10000) {
|
if (B_opt < MIN_BAUD || B_opt > MAX_BAUD) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Use a more reasonable data baud rate in range of 100 - 10000.\n");
|
dw_printf ("Use a more reasonable data baud rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -196,9 +196,9 @@ int main(int argc, char **argv)
|
||||||
modem.achan[0].baud = atoi(optarg);
|
modem.achan[0].baud = atoi(optarg);
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud);
|
dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud);
|
||||||
if (modem.achan[0].baud < 100 || modem.achan[0].baud > 10000) {
|
if (modem.achan[0].baud < MIN_BAUD || modem.achan[0].baud > MAX_BAUD) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Use a more reasonable bit rate in range of 100 - 10000.\n");
|
dw_printf ("Use a more reasonable bit rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -208,29 +208,30 @@ int main(int argc, char **argv)
|
||||||
/* 1200 implies 1200/2200 AFSK. */
|
/* 1200 implies 1200/2200 AFSK. */
|
||||||
/* 9600 implies scrambled. */
|
/* 9600 implies scrambled. */
|
||||||
|
|
||||||
|
/* If you want something else, specify -B first */
|
||||||
|
/* then anything to override these defaults. */
|
||||||
|
|
||||||
modem.achan[0].baud = atoi(optarg);
|
modem.achan[0].baud = atoi(optarg);
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud);
|
dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud);
|
||||||
if (modem.achan[0].baud < 100 || modem.achan[0].baud > 10000) {
|
if (modem.achan[0].baud < MIN_BAUD || modem.achan[0].baud > MAX_BAUD) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Use a more reasonable bit rate in range of 100 - 10000.\n");
|
dw_printf ("Use a more reasonable bit rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (modem.achan[0].baud) {
|
if (modem.achan[0].baud < 600) {
|
||||||
case 300:
|
|
||||||
modem.achan[0].mark_freq = 1600;
|
modem.achan[0].mark_freq = 1600;
|
||||||
modem.achan[0].space_freq = 1800;
|
modem.achan[0].space_freq = 1800;
|
||||||
break;
|
}
|
||||||
case 1200:
|
else if (modem.achan[0].baud <= 2400) {
|
||||||
modem.achan[0].mark_freq = 1200;
|
modem.achan[0].mark_freq = 1200;
|
||||||
modem.achan[0].space_freq = 2200;
|
modem.achan[0].space_freq = 2200;
|
||||||
break;
|
}
|
||||||
case 9600:
|
else {
|
||||||
modem.achan[0].modem_type = MODEM_SCRAMBLE;
|
modem.achan[0].modem_type = MODEM_SCRAMBLE;
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf ("Using scrambled baseband signal rather than AFSK.\n");
|
dw_printf ("Using scrambled baseband signal rather than AFSK.\n");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
32
gen_tone.c
32
gen_tone.c
|
@ -210,10 +210,18 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
||||||
a = ((double)(j) / 256.0) * (2 * M_PI);
|
a = ((double)(j) / 256.0) * (2 * M_PI);
|
||||||
s = (int) (sin(a) * 32767 * amp / 100.0);
|
s = (int) (sin(a) * 32767 * amp / 100.0);
|
||||||
|
|
||||||
/* 16 bit sound sample is in range of -32768 .. +32767. */
|
/* 16 bit sound sample must fit in range of -32768 .. +32767. */
|
||||||
|
|
||||||
assert (s >= -32768 && s <= 32767);
|
|
||||||
|
|
||||||
|
if (s < -32768) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("gen_tone_init: Excessive amplitude is being clipped.\n");
|
||||||
|
s = -32768;
|
||||||
|
}
|
||||||
|
else if (s > 32767) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("gen_tone_init: Excessive amplitude is being clipped.\n");
|
||||||
|
s = 32767;
|
||||||
|
}
|
||||||
sine_table[j] = s;
|
sine_table[j] = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +243,8 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
||||||
/* These numbers were by trial and error. Need more investigation here. */
|
/* These numbers were by trial and error. Need more investigation here. */
|
||||||
|
|
||||||
float filter_len_bits = 88 * 9600.0 / (44100.0 * 2.0);
|
float filter_len_bits = 88 * 9600.0 / (44100.0 * 2.0);
|
||||||
/* Filter length in number of data bits. */
|
/* Filter length in number of data bits. */
|
||||||
|
/* Currently 9.58 */
|
||||||
|
|
||||||
float lpf_baud = 0.8; /* Lowpass cutoff freq as fraction of baud rate */
|
float lpf_baud = 0.8; /* Lowpass cutoff freq as fraction of baud rate */
|
||||||
|
|
||||||
|
@ -250,10 +259,15 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp)
|
||||||
|
|
||||||
lp_filter_size[chan] = (int) (( filter_len_bits * (float)samples_per_sec / baud) + 0.5);
|
lp_filter_size[chan] = (int) (( filter_len_bits * (float)samples_per_sec / baud) + 0.5);
|
||||||
|
|
||||||
if (lp_filter_size[chan] < 10 || lp_filter_size[chan] > MAX_FILTER_SIZE) {
|
if (lp_filter_size[chan] < 10) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
dw_printf ("gen_tone_init: INTERNAL ERROR, chan %d, lp_filter_size %d\n", chan, lp_filter_size[chan]);
|
dw_printf ("gen_tone_init: unexpected, chan %d, lp_filter_size %d < 10\n", chan, lp_filter_size[chan]);
|
||||||
lp_filter_size[chan] = MAX_FILTER_SIZE / 2;
|
lp_filter_size[chan] = 10;
|
||||||
|
}
|
||||||
|
else if (lp_filter_size[chan] > MAX_FILTER_SIZE) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("gen_tone_init: unexpected, chan %d, lp_filter_size %d > %d\n", chan, lp_filter_size[chan], MAX_FILTER_SIZE);
|
||||||
|
lp_filter_size[chan] = MAX_FILTER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fc = (float)baud * lpf_baud / (float)samples_per_sec;
|
fc = (float)baud * lpf_baud / (float)samples_per_sec;
|
||||||
|
@ -358,6 +372,8 @@ void gen_tone_put_sample (int chan, int a, int sam) {
|
||||||
|
|
||||||
assert (save_audio_config_p->adev[a].bits_per_sample == 16);
|
assert (save_audio_config_p->adev[a].bits_per_sample == 16);
|
||||||
|
|
||||||
|
// TODO: Should print message telling user to reduce output level.
|
||||||
|
|
||||||
if (sam < -32767) sam = -32767;
|
if (sam < -32767) sam = -32767;
|
||||||
else if (sam > 32767) sam = 32767;
|
else if (sam > 32767) sam = 32767;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue