From 30dc79074ca022366a27d705b8023011d9600339 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Tue, 15 Aug 2023 05:54:48 -0400 Subject: [PATCH] DSTAR Single Frequency Tone Support; --- CHANGELOG | 7 ++++-- README.md | 4 ++-- ambe3600x2400.c | 20 ++++++++++++----- libmbe.pc.in | 2 +- mbelib.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ mbelib.h | 3 ++- 6 files changed, 82 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c41ba1c..2b22aa7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,11 @@ +1.3.4: + Add Single Frequency Tone support for DSTAR AMBE based on previous code writers guesswork + 1.3.3T: Add AMBE+2 tones (adapted from Boatbod OP25) - 1.3.2: - Disable/Remove Tests +1.3.2: +Disable/Remove Tests 1.3.1: Redirect all printf to stderr ( Change all printf to fprintf(stderr,) ) diff --git a/README.md b/README.md index ceff049..bd35f0f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Readers are strongly advised to check for any patent restrictions or licencing requirements before compiling or using this source code. ``` -mbelib 1.3.3T w/ AMBE+2 Tone Synthesis +mbelib 1.3.4 w/ AMBE and AMBE+2 Tone Synthesis ``` mbelib supports the 7200x4400 bit/s codec used in P25 Phase 1, @@ -30,4 +30,4 @@ make sudo make install ``` -To Disable AMBE+2 Tones, run cmake with option `cmake -DNOTONES=ON ..` when building. \ No newline at end of file +To Disable AMBE and AMBE+2 Tones, run cmake with option `cmake -DNOTONES=ON ..` when building. \ No newline at end of file diff --git a/ambe3600x2400.c b/ambe3600x2400.c index 73d11fc..fba9caa 100644 --- a/ambe3600x2400.c +++ b/ambe3600x2400.c @@ -213,29 +213,30 @@ mbe_decodeAmbe2400Parms (char *ambe_d, mbe_parms * cur_mp, mbe_parms * prev_mp) b2 |= ambe_d[17]; //v0 1 a guess based on data // the order of the last 3 bits may really be 17,44,45 not 44,45,17 as above - fprintf(stderr,"Tone volume: %d; ", b2); + // fprintf(stderr,"Tone volume: %d; ", b2); if (b1 < 5) { - fprintf(stderr, "index: %d, was <5, invalid!\n", b1); + // fprintf(stderr, "index: %d, was <5, invalid!\n", b1); silence = 1; } else if ((b1 >= 5) && (b1 <= 122)) { - fprintf(stderr, "index: %d, Single tone hz: %f\n", b1, (float)b1*31.25); + // fprintf(stderr, "index: %d, Single tone hz: %f\n", b1, (float)b1*31.25); + return (b1); //use the return value to play a single frquency valid tone } else if ((b1 > 122) && (b1 < 128)) { - fprintf(stderr, "index: %d, was >122 and <128, invalid!\n", b1); + // fprintf(stderr, "index: %d, was >122 and <128, invalid!\n", b1); silence = 1; } else if ((b1 >= 128) && (b1 <= 163)) { - fprintf(stderr, "index: %d, Dual tone\n", b1); + // fprintf(stderr, "index: %d, Dual tone\n", b1); // note: dual tone index is different on ambe(dstar) and ambe2+ } else { - fprintf(stderr, "index: %d, was >163, invalid!\n", b1); + // fprintf(stderr, "index: %d, was >163, invalid!\n", b1); silence = 1; } @@ -677,6 +678,13 @@ mbe_processAmbe2400Dataf (float *aout_buf, int *errs, int *errs2, char *err_str, err_str++; cur_mp->repeat = 0; } + //if we have a 'seemingly' valid single frequency tone and errors are within margin + else if ( (bad >= 7) && (bad <= 122) && (*errs < 2) && (*errs2 < 3)) //&& (*errs < 2) && (*errs2 < 3) + { + //synthesize single frequency tone based on previous code writers guessword, 'bad' is the tone ID value + mbe_synthesizeTonefdstar (aout_buf, ambe_d, cur_mp, bad); + mbe_moveMbeParms (cur_mp, prev_mp); + } else if (*errs2 > 3) { mbe_useLastMbeParms (cur_mp, prev_mp); diff --git a/libmbe.pc.in b/libmbe.pc.in index 4f8299e..83d44f0 100644 --- a/libmbe.pc.in +++ b/libmbe.pc.in @@ -3,7 +3,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: libMBE Description: AMBE and IMBE vocoder -Version: 1.3.3T +Version: 1.3.4 Libs: -L${libdir} -lmbe Libs.private: -lm diff --git a/mbelib.c b/mbelib.c index 2accdf2..05641af 100644 --- a/mbelib.c +++ b/mbelib.c @@ -385,6 +385,64 @@ void mbe_synthesizeTonef (float *aout_buf, char *ambe_d, mbe_parms * cur_mp) } return; } + + //debug + // fprintf (stderr, "TONE ID = %d AD = %d \n", ID1, AD); + + // Synthesize tones + step1 = 2 * M_PI * freq1 / 8000.0f; + step2 = 2 * M_PI * freq2 / 8000.0f; + amplitude = AD * 75.0f; // + aout_buf_p = aout_buf; + for (n = 0; n < 160; n++) + { + *aout_buf_p = (float) ( amplitude * (sin((cur_mp->swn) * step1)/2 + sin((cur_mp->swn) * step2)/2) ); + *aout_buf_p = *aout_buf_p / 6.0f; + aout_buf_p++; + cur_mp->swn++; + } +} + +//simplified version for single frequency dstar based on previous code writers guessword +void mbe_synthesizeTonefdstar (float *aout_buf, char *ambe_d, mbe_parms * cur_mp, int ID1) +{ + int i, n; + float *aout_buf_p; + + int AD = 103; //amplitude, just using a value I've seen in other tones + float step1, step2, sample, amplitude; + float freq1 = 0, freq2 = 0; + + #ifdef DISABLE_AMBE_TONES //generate silence if tones disabled + aout_buf_p = aout_buf; + for (n = 0; n < 160; n++) + { + *aout_buf_p = (float) 0; + aout_buf_p++; + } + return; + #endif + + switch(ID1) + { + // single tones, set frequency + case 5: + freq1 = 156.25; freq2 = freq1; + break; + case 6: + freq1 = 187.5; freq2 = freq1; + break; + // single tones, calculated frequency + default: + if ((ID1 >= 7) && (ID1 <= 122)) + { + freq1 = 31.25 * ID1; freq2 = freq1; + } + } + + //debug + // fprintf (stderr, "TONE ID = %d AD = %d \n", ID1, AD); + // Synthesize tones step1 = 2 * M_PI * freq1 / 8000.0f; step2 = 2 * M_PI * freq2 / 8000.0f; diff --git a/mbelib.h b/mbelib.h index acb81a5..dfc5f61 100644 --- a/mbelib.h +++ b/mbelib.h @@ -17,7 +17,7 @@ #ifndef _MBELIB_H #define _MBELIB_H -#define MBELIB_VERSION "1.3.3T" +#define MBELIB_VERSION "1.3.4" struct mbe_parameters { @@ -105,6 +105,7 @@ void mbe_useLastMbeParms (mbe_parms * cur_mp, mbe_parms * prev_mp); void mbe_initMbeParms (mbe_parms * cur_mp, mbe_parms * prev_mp, mbe_parms * prev_mp_enhanced); void mbe_spectralAmpEnhance (mbe_parms * cur_mp); void mbe_synthesizeTonef (float *aout_buf, char *ambe_d, mbe_parms * cur_mp); +void mbe_synthesizeTonefdstar (float *aout_buf, char *ambe_d, mbe_parms * cur_mp, int ID1); void mbe_synthesizeSilencef (float *aout_buf); void mbe_synthesizeSilence (short *aout_buf); void mbe_synthesizeSpeechf (float *aout_buf, mbe_parms * cur_mp, mbe_parms * prev_mp, int uvquality);