diff --git a/demod.c b/demod.c index 8daf6d9..808928b 100644 --- a/demod.c +++ b/demod.c @@ -403,8 +403,8 @@ int demod_init (struct audio_s *pa) /* For signal level reporting, we want a longer term view. */ // TODO: Should probably move this into the init functions. - D->quick_attack = D->agc_fast_attack * 0.2; - D->sluggish_decay = D->agc_slow_decay * 0.2; + D->quick_attack = D->agc_fast_attack * 0.2f; + D->sluggish_decay = D->agc_slow_decay * 0.2f; } } else if (have_plus) { @@ -458,8 +458,8 @@ int demod_init (struct audio_s *pa) /* For signal level reporting, we want a longer term view. */ - D->quick_attack = D->agc_fast_attack * 0.2; - D->sluggish_decay = D->agc_slow_decay * 0.2; + D->quick_attack = D->agc_fast_attack * 0.2f; + D->sluggish_decay = D->agc_slow_decay * 0.2f; } else { int d; @@ -511,8 +511,8 @@ int demod_init (struct audio_s *pa) /* For signal level reporting, we want a longer term view. */ - D->quick_attack = D->agc_fast_attack * 0.2; - D->sluggish_decay = D->agc_slow_decay * 0.2; + D->quick_attack = D->agc_fast_attack * 0.2f; + D->sluggish_decay = D->agc_slow_decay * 0.2f; } /* for each freq pair */ } @@ -687,7 +687,7 @@ int demod_init (struct audio_s *pa) 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); + (double)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"); @@ -718,8 +718,8 @@ int demod_init (struct audio_s *pa) /* For signal level reporting, we want a longer term view. */ - D->quick_attack = D->agc_fast_attack * 0.2; - D->sluggish_decay = D->agc_slow_decay * 0.2; + D->quick_attack = D->agc_fast_attack * 0.2f; + D->sluggish_decay = D->agc_slow_decay * 0.2f; } break; diff --git a/demod_9600.c b/demod_9600.c index 8670257..be1826d 100644 --- a/demod_9600.c +++ b/demod_9600.c @@ -87,21 +87,21 @@ __attribute__((hot)) __attribute__((always_inline)) static inline float agc (float in, float fast_attack, float slow_decay, float *ppeak, float *pvalley) { if (in >= *ppeak) { - *ppeak = in * fast_attack + *ppeak * (1. - fast_attack); + *ppeak = in * fast_attack + *ppeak * (1.0f - fast_attack); } else { - *ppeak = in * slow_decay + *ppeak * (1. - slow_decay); + *ppeak = in * slow_decay + *ppeak * (1.0f - slow_decay); } if (in <= *pvalley) { - *pvalley = in * fast_attack + *pvalley * (1. - fast_attack); + *pvalley = in * fast_attack + *pvalley * (1.0f - fast_attack); } else { - *pvalley = in * slow_decay + *pvalley * (1. - slow_decay); + *pvalley = in * slow_decay + *pvalley * (1.0f - slow_decay); } if (*ppeak > *pvalley) { - return ((in - 0.5 * (*ppeak + *pvalley)) / (*ppeak - *pvalley)); + return ((in - 0.5f * (*ppeak + *pvalley)) / (*ppeak - *pvalley)); } return (0.0); } @@ -144,8 +144,8 @@ void demod_9600_init (int samples_per_sec, int baud, struct demodulator_state_s D->lp_filter_len_bits = 76 * 9600.0 / (44100.0 * 2.0); // Works best with odd number in some tests. Even is better in others. - //D->lp_filter_size = ((int) (0.5 * ( D->lp_filter_len_bits * (float)samples_per_sec / (float)baud ))) * 2 + 1; - D->lp_filter_size = (int) (( D->lp_filter_len_bits * (float)samples_per_sec / baud) + 0.5); + //D->lp_filter_size = ((int) (0.5f * ( D->lp_filter_len_bits * (float)samples_per_sec / (float)baud ))) * 2 + 1; + D->lp_filter_size = (int) (( D->lp_filter_len_bits * (float)samples_per_sec / baud) + 0.5f); D->lp_window = BP_WINDOW_HAMMING; D->lpf_baud = 0.62; @@ -199,7 +199,7 @@ void demod_9600_init (int samples_per_sec, int baud, struct demodulator_state_s /* Version 1.2: Experiment with different slicing levels. */ for (j = 0; j < MAX_SUBCHANS; j++) { - slice_point[j] = 0.02 * (j - 0.5 * (MAX_SUBCHANS-1)); + slice_point[j] = 0.02f * (j - 0.5f * (MAX_SUBCHANS-1)); //dw_printf ("slice_point[%d] = %+5.2f\n", j, slice_point[j]); } @@ -333,17 +333,17 @@ void demod_9600_process_sample (int chan, int sam, struct demodulator_state_s *D // TODO: probably no need for this. Just use D->m_peak, D->m_valley if (amp >= D->alevel_mark_peak) { - D->alevel_mark_peak = amp * D->quick_attack + D->alevel_mark_peak * (1. - D->quick_attack); + D->alevel_mark_peak = amp * D->quick_attack + D->alevel_mark_peak * (1.0f - D->quick_attack); } else { - D->alevel_mark_peak = amp * D->sluggish_decay + D->alevel_mark_peak * (1. - D->sluggish_decay); + D->alevel_mark_peak = amp * D->sluggish_decay + D->alevel_mark_peak * (1.0f - D->sluggish_decay); } if (amp <= D->alevel_space_peak) { - D->alevel_space_peak = amp * D->quick_attack + D->alevel_space_peak * (1. - D->quick_attack); + D->alevel_space_peak = amp * D->quick_attack + D->alevel_space_peak * (1.0f - D->quick_attack); } else { - D->alevel_space_peak = amp * D->sluggish_decay + D->alevel_space_peak * (1. - D->sluggish_decay); + D->alevel_space_peak = amp * D->sluggish_decay + D->alevel_space_peak * (1.0f - D->sluggish_decay); } /* @@ -544,10 +544,10 @@ static void inline nudge_pll (int chan, int subchan, int slice, float demod_out_ fprintf (demod_log_fp, "Audio, Peak, Valley, Demod, SData, Descram, Clock\n"); } fprintf (demod_log_fp, "%.3f, %.3f, %.3f, %.3f, %.2f, %.2f, %.2f\n", - 0.5 * fsam + 3.5, - 0.5 * D->m_peak + 3.5, - 0.5 * D->m_valley + 3.5, - 0.5 * demod_out + 2.0, + 0.5f * fsam + 3.5, + 0.5f * D->m_peak + 3.5, + 0.5f * D->m_valley + 3.5, + 0.5f * demod_out + 2.0, demod_data ? 1.35 : 1.0, descram ? .9 : .55, (D->data_clock_pll & 0x80000000) ? .1 : .45); diff --git a/demod_afsk.c b/demod_afsk.c index 96d9e45..67499a4 100644 --- a/demod_afsk.c +++ b/demod_afsk.c @@ -528,7 +528,7 @@ void demod_afsk_init (int samples_per_sec, int baud, int mark_freq, for (j=0; jms_filter_size; j++) { float am; float center; - float shape = 1; /* Shape is an attempt to smooth out the */ + float shape = 1.0f; /* Shape is an attempt to smooth out the */ /* abrupt edges in hopes of reducing */ /* overshoot and ringing. */ /* My first thought was to use a cosine shape. */ @@ -536,16 +536,16 @@ void demod_afsk_init (int samples_per_sec, int baud, int mark_freq, /* windows mentioned in the literature. */ /* http://en.wikipedia.org/wiki/Window_function */ - center = 0.5 * (D->ms_filter_size - 1); - am = ((float)(j - center) / (float)samples_per_sec) * ((float)mark_freq) * (2 * M_PI); + center = 0.5f * (D->ms_filter_size - 1); + am = ((float)(j - center) / (float)samples_per_sec) * ((float)mark_freq) * (2.0f * (float)M_PI); shape = window (D->ms_window, D->ms_filter_size, j); - D->m_sin_table[j] = sin(am) * shape; - D->m_cos_table[j] = cos(am) * shape; + D->m_sin_table[j] = sinf(am) * shape; + D->m_cos_table[j] = cosf(am) * shape; - Gs += D->m_sin_table[j] * sin(am); - Gc += D->m_cos_table[j] * cos(am); + Gs += D->m_sin_table[j] * sinf(am); + Gc += D->m_cos_table[j] * cosf(am); #if DEBUG1 dw_printf ("%6d %6.2f %6.2f %6.2f\n", j, shape, D->m_sin_table[j], D->m_cos_table[j]) ; @@ -576,18 +576,18 @@ void demod_afsk_init (int samples_per_sec, int baud, int mark_freq, for (j=0; jms_filter_size; j++) { float as; float center; - float shape = 1; + float shape = 1.0f; center = 0.5 * (D->ms_filter_size - 1); - as = ((float)(j - center) / (float)samples_per_sec) * ((float)space_freq) * (2 * M_PI); + as = ((float)(j - center) / (float)samples_per_sec) * ((float)space_freq) * (2.0f * (float)M_PI); shape = window (D->ms_window, D->ms_filter_size, j); - D->s_sin_table[j] = sin(as) * shape; - D->s_cos_table[j] = cos(as) * shape; + D->s_sin_table[j] = sinf(as) * shape; + D->s_cos_table[j] = cosf(as) * shape; - Gs += D->s_sin_table[j] * sin(as); - Gc += D->s_cos_table[j] * cos(as); + Gs += D->s_sin_table[j] * sinf(as); + Gc += D->s_cos_table[j] * cosf(as); #if DEBUG1 dw_printf ("%6d %6.2f %6.2f %6.2f\n", j, shape, D->s_sin_table[j], D->s_cos_table[j] ) ; diff --git a/demod_psk.c b/demod_psk.c index 013b4d1..940c115 100644 --- a/demod_psk.c +++ b/demod_psk.c @@ -293,9 +293,9 @@ void demod_psk_init (enum modem_t modem_type, int samples_per_sec, int bps, char D->ms_filter_len_bits = 1.25; // Delay line > 13/12 * symbol period - D->coffs = (int) round( (11. / 12.) * (float)samples_per_sec / (float)correct_baud ); + D->coffs = (int) round( (11.f / 12.f) * (float)samples_per_sec / (float)correct_baud ); D->boffs = (int) round( (float)samples_per_sec / (float)correct_baud ); - D->soffs = (int) round( (13. / 12.) * (float)samples_per_sec / (float)correct_baud ); + D->soffs = (int) round( (13.f / 12.f) * (float)samples_per_sec / (float)correct_baud ); } else { @@ -380,18 +380,18 @@ void demod_psk_init (enum modem_t modem_type, int samples_per_sec, int bps, char D->ms_filter_len_bits = 1.25; // Delay line > 10/9 * symbol period - D->coffs = (int) round( (8. / 9.) * (float)samples_per_sec / (float)correct_baud ); + D->coffs = (int) round( (8.f / 9.f) * (float)samples_per_sec / (float)correct_baud ); D->boffs = (int) round( (float)samples_per_sec / (float)correct_baud ); - D->soffs = (int) round( (10. / 9.) * (float)samples_per_sec / (float)correct_baud ); + D->soffs = (int) round( (10.f / 9.f) * (float)samples_per_sec / (float)correct_baud ); } if (D->psk_use_lo) { - D->lo_step = (int) round( 256. * 256. * 256. * 256. * carrier_freq / (float)samples_per_sec); + D->lo_step = (int) round( 256. * 256. * 256. * 256. * carrier_freq / (double)samples_per_sec); assert (MAX_FILTER_SIZE >= 256); for (j = 0; j < 256; j++) { - D->m_sin_table[j] = sinf(2. * M_PI * j / 256.); + D->m_sin_table[j] = sinf(2.f * (float)M_PI * j / 256.f); } } @@ -491,11 +491,11 @@ void demod_psk_init (enum modem_t modem_type, int samples_per_sec, int bps, char f2 = carrier_freq + D->prefilter_baud * correct_baud; #if 0 text_color_set(DW_COLOR_DEBUG); - dw_printf ("Generating prefilter %.0f to %.0f Hz.\n", f1, f2); + dw_printf ("Generating prefilter %.0f to %.0f Hz.\n", (double)f1, (double)f2); #endif if (f1 <= 0) { text_color_set (DW_COLOR_ERROR); - dw_printf ("Prefilter of %.0f to %.0f Hz doesn't make sense.\n", f1, f2); + dw_printf ("Prefilter of %.0f to %.0f Hz doesn't make sense.\n", (double)f1, (double)f2); f1 = 10; } @@ -642,7 +642,7 @@ void demod_psk_process_sample (int chan, int subchan, int sam, struct demodulato /* 256 units/cycle makes modulo processing easier. */ /* Make sure it is positive before truncating to integer. */ - id = ((int)((delta / (2.f * M_PI) + 1.f) * 256.f)) & 0xff; + id = ((int)((delta / (2.f * (float)M_PI) + 1.f) * 256.f)) & 0xff; if (D->modem_type == MODEM_QPSK) { demod_phase_shift = ((id + 32) >> 6) & 0x3; @@ -686,7 +686,7 @@ void demod_psk_process_sample (int chan, int subchan, int sam, struct demodulato } #else a = my_atan2f(I,Q); - int id = ((int)((a / (2.f * M_PI) + 1.f) * 256.f)) & 0xff; + int id = ((int)((a / (2.f * (float)M_PI) + 1.f) * 256.f)) & 0xff; // 128 compensates for 180 degree phase shift due // to 1 1/2 carrier cycles per symbol period. demod_phase_shift = ((id + 128) >> 6) & 0x3; @@ -697,7 +697,7 @@ void demod_psk_process_sample (int chan, int subchan, int sam, struct demodulato int idelta; a = my_atan2f(I,Q); - idelta = ((int)((a / (2.f * M_PI) + 1.f) * 256.f)) & 0xff; + idelta = ((int)((a / (2.f * (float)M_PI) + 1.f) * 256.f)) & 0xff; // 32 (90 degrees) compensates for 1800 carrier vs. 1800 baud. // 16 is to set threshold between constellation points. demod_phase_shift = ((idelta - 32 - 16) >> 5) & 0x7; @@ -827,16 +827,20 @@ static void inline nudge_pll (int chan, int subchan, int slice, int demod_bits, /* * If demodulated data has changed, - * pull the PLL phase closer to zero. + * Pull the PLL phase closer to zero. + * Use "floor" instead of simply casting so the sign won't flip. + * For example if we had -0.7 we want to end up with -1 rather than 0. */ +// TODO: demod_9600 has an improved technique. Would it help us here? + if (demod_bits != D->slicer[slice].prev_demod_data) { if (hdlc_rec_gathering (chan, subchan, slice)) { - D->slicer[slice].data_clock_pll = (int)floor((double)(D->slicer[slice].data_clock_pll) * D->pll_locked_inertia); + D->slicer[slice].data_clock_pll = (int)floorf((float)(D->slicer[slice].data_clock_pll) * D->pll_locked_inertia); } else { - D->slicer[slice].data_clock_pll = (int)floor((double)(D->slicer[slice].data_clock_pll) * D->pll_searching_inertia); + D->slicer[slice].data_clock_pll = (int)floorf((float)(D->slicer[slice].data_clock_pll) * D->pll_searching_inertia); } } diff --git a/doc/APRS-Telemetry-Toolkit.pdf b/doc/APRS-Telemetry-Toolkit.pdf index 1fa97bc..b88f8f4 100644 Binary files a/doc/APRS-Telemetry-Toolkit.pdf and b/doc/APRS-Telemetry-Toolkit.pdf differ diff --git a/morse.c b/morse.c index 1319501..85a0890 100644 --- a/morse.c +++ b/morse.c @@ -272,6 +272,8 @@ int morse_send (int chan, char *str, int wpm, int txdelay, int txtail) time_units, morse_units_str(str)); } + audio_flush(ACHAN2ADEV(chan)); + return (txdelay + (int) (TIME_UNITS_TO_MS(time_units, wpm) + 0.5) + txtail); diff --git a/telemetry.c b/telemetry.c index 711f3d1..df28543 100644 --- a/telemetry.c +++ b/telemetry.c @@ -835,7 +835,16 @@ void telemetry_bit_sense_message (char *station, char *msg, int quiet) } } -/* Skip comma if first character of comment field. */ +/* + * Skip comma if first character of comment field. + * + * The protocol spec is inconsistent here. + * The definition shows the Project Title immediately after a fixed width field of 8 binary digits. + * The example has a comma in there. + * + * The toolkit telem-bits.pl script does insert the comma because it seems more sensible. + * Here we accept it either way. i.e. Discard first character after data values if it is comma. + */ if (msg[n] == ',') n++; diff --git a/tocalls.txt b/tocalls.txt index b27dbb5..3398186 100644 --- a/tocalls.txt +++ b/tocalls.txt @@ -1,6 +1,7 @@ -APRS TO-CALL VERSION NUMBERS 14 Nov 2016 +APRS TO-CALL VERSION NUMBERS 6 Dec 2016 ------------------------------------------------------------------- WB4APR +16 Dec 16 added APYSxx for W2GMD's Python APRS 14 Nov 16 Added APINxx for PinPoint by AB0WV 09 Nov 16 added APNICx for SQ5EKU http://sq5eku.blogspot.com/ 24 Oct 16 added APTKPT TrackPoint N0LP, removed APZTKP @@ -137,7 +138,7 @@ a TOCALL number series: APRRTx RPC electronics APRS Generic, (obsolete. Digis should use APNxxx instead) APRXxx >40 APRSmax - APRXxx <39 for OH2MQK's RX-igate + APRXxx <39 for OH2MQK's igate APRTLM used in MIM's and Mic-lites, etc APRtfc APRStraffic APRSTx APRStt (Touch tone) @@ -176,6 +177,7 @@ a TOCALL number series: APY008 Yaesu VX-8 series APY350 Yaesu FTM-350 series APYTxx for YagTracker + APYSxx for W2GMD's Python APRS APZ APZxxx Experimental APZ247 for UPRS NR0Q APZ0xx Xastir (old versions. See APX)