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:
WB2OSZ 2016-03-26 21:04:28 -04:00
parent 8b9c6fcf4a
commit ccae7529bf
5 changed files with 77 additions and 27 deletions

16
audio.h
View File

@ -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
View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;