From 0528e8bbbe14399e662711b4318e69382888bae3 Mon Sep 17 00:00:00 2001
From: "James C. Ahlstrom"
Date: Wed, 8 Oct 2025 16:29:31 -0400
Subject: [PATCH] Quisk version 4.2.45
---
CHANGELOG.txt | 10 +
__init__.py | 2 +-
ac2yd/control_common.py | 2 +-
docs.html | 3 +-
freedv.c | 682 +------------------------------------
freedv.h | 25 +-
freedvpkg/README.txt | 130 +------
freedvpkg/libcodec2_64.dll | Bin 1904878 -> 0 bytes
freedvpkg/libcodec2_64.so | Bin 2194288 -> 0 bytes
microphone.c | 154 +--------
quisk.c | 131 +------
quisk.h | 22 +-
quisk.py | 139 +-------
quisk_conf_defaults.py | 17 -
setup.py | 2 +-
sound.c | 12 +-
sound_pulseaudio.c | 97 +++---
17 files changed, 97 insertions(+), 1331 deletions(-)
delete mode 100644 freedvpkg/libcodec2_64.dll
delete mode 100644 freedvpkg/libcodec2_64.so
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 3055b6b..2733dbf 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,13 @@
+Quisk Version 4.2.45 October 2025
+==================================
+The new FreeDV including RADE mode is now a built-in mode of Quisk. Just press "FDV" to talk FreeDV.
+In brief, install FreeDV-GUI from the web site. Then configure the usual Quisk digital input and
+output that you use for digital modes. In FreeDV-GUI use the digital input and output. For the
+speakers and microphone use the same ones as Quisk. Don't forget to configure your call sign in
+FreeDV so it works with FreeDV Reporter. For detailed instructions see http://james.ahlstrom.name/rade.html.
+
+The Quisk digital output device is now always active; a DGT mode is not required.
+
Quisk Version 4.2.44 September 2025
====================================
Quisk now has Pure Signal for the Hermes Lite2. This is baseband predistortion to reduce IMD products.
diff --git a/__init__.py b/__init__.py
index e9a2a64..24b9b9b 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,2 +1,2 @@
-#Quisk version 4.2.44
+#Quisk version 4.2.45
from .quisk import main
diff --git a/ac2yd/control_common.py b/ac2yd/control_common.py
index 24d8bdc..9e492d0 100644
--- a/ac2yd/control_common.py
+++ b/ac2yd/control_common.py
@@ -395,7 +395,7 @@ class ControlCommon(BaseHardware): # This is the Hardware class for the control
for idName in ("Mute", "NR2", "AGC", "Sqlch", "NB 1", "Notch", "Test 1", "Spot", "FDX", "PTT", "VOX"):
self.RemoteCtlSend("%s;%d\n" % (idName, app.idName2Button[idName].GetIndex()))
# Menus
- for menu in (app.NB_menu, app.split_menu, app.freedv_menu, app.smeter_menu):
+ for menu in (app.NB_menu, app.split_menu, app.smeter_menu):
if menu:
for nid in menu.id2data:
menu_item = menu.FindItemById(nid)
diff --git a/docs.html b/docs.html
index 61c4a67..50a5657 100644
--- a/docs.html
+++ b/docs.html
@@ -200,7 +200,8 @@ If you have Python 3 installed on your computer, just continue to use that versi
On Windows Quisk requires Python 3.8, 3.9, 3.10, 3.11, 3.12 or 3.13.
If you want to install a more recent version of Python, uninstall the old version first.
Running multiple versions of Python is possible but can be confusing and is not necessary.
-A Quisk installation is needed for each version of Python you have.
+A Quisk installation is needed for each version of Python you have. If you upgrade to a newer Python
+you must re-install Quisk. But your Quisk settings will be preserved.
Windows Initial Installation
diff --git a/freedv.c b/freedv.c
index bf5a72e..bf04050 100644
--- a/freedv.c
+++ b/freedv.c
@@ -1,681 +1 @@
-#include
-#include
-#include
-#include // Use native C99 complex type for fftw3
-#include
-
-#include "quisk.h"
-#include "freedv.h"
-#include
-
-int DEBUG;
-
-#define MAX_RECEIVERS 2
-
-typedef struct { // from comp.h
- float real;
- float imag;
-} COMP;
-
-struct freedv; // from freedv_api.h
-typedef void (*freedv_callback_rx)(void *, char);
-typedef char (*freedv_callback_tx)(void *);
-/* Protocol bits are packed MSB-first */
-/* Called when a frame containing protocol data is decoded */
-typedef void (*freedv_callback_protorx)(void *, char *);
-/* Called when a frame containing protocol data is to be sent */
-typedef void (*freedv_callback_prototx)(void *, char *);
-/* Data packet callbacks */
-/* Called when a packet has been received */
-typedef void (*freedv_callback_datarx)(void *, unsigned char *packet, size_t size);
-/* Called when a new packet can be send */
-typedef void (*freedv_callback_datatx)(void *, unsigned char *packet, size_t *size);
-
-/* advanced freedv open options required by some modes */
-struct freedv_advanced {
- int interleave_frames; // now unused but remains to prevent breaking API for
- // legacy apps
-
- // parameters for FREEDV_MODE_FSK_LDPC
- int M; // 2 or 4 FSK
- int Rs; // Symbol rate Hz
- int Fs; // Sample rate Hz
- int first_tone; // Freq of first tone Hz
- int tone_spacing; // Spacing between tones Hz
- char *codename; // LDPC codename, from codes listed in ldpc_codes.c
-};
-
-#ifdef MS_WINDOWS
-#include
-HMODULE hLib;
-#define GET_HANDLE1 hLib = LoadLibrary("libcodec2.dll")
-#define GET_HANDLE2 hLib = LoadLibrary(".\\freedvpkg\\libcodec2.dll")
-#define GET_HANDLE3 hLib = LoadLibrary(".\\freedvpkg\\libcodec2_32.dll")
-#define GET_HANDLE4 hLib = LoadLibrary(".\\freedvpkg\\libcodec2_64.dll")
-#define GET_ADDR(name) (void *)GetProcAddress(hLib, name)
-#define CLOSE_LIB FreeLibrary(hLib)
-#else
-#include
-void * hLib;
-#define GET_HANDLE1 hLib = dlopen("libcodec2.so", RTLD_LAZY)
-#define GET_HANDLE2 hLib = dlopen("./freedvpkg/libcodec2.so", RTLD_LAZY)
-#define GET_HANDLE3 hLib = dlopen("./freedvpkg/libcodec2_32.so", RTLD_LAZY)
-#define GET_HANDLE4 hLib = dlopen("./freedvpkg/libcodec2_64.so", RTLD_LAZY)
-#define GET_ADDR(name) dlsym(hLib, name)
-#define CLOSE_LIB dlclose(hLib)
-#endif
-
-static int requested_mode = -1; // requested mode
-int freedv_current_mode = -1; // the current running mode
-static int quisk_freedv_squelch;
-static int interleave_frames = 1;
-static int freedv_version = -1;
-static int quisk_set_tx_bpf = 1;
-static int handle_index = -1;
-// need access to these here and in quisk.c
-int n_speech_sample_rate = 8000;
-int n_modem_sample_rate = 8000;
-int n_max_modem_samples = 1000;
-
-#define SPEECH_BUF_SIZE 12000 // speech buffer size increased from 3000
-#define MAX_MODEM_SAMPLES 8192 // maximum of n_max_modem_samples for any mode
-#define MAX_SPEECH_SAMPLES 8192 // maximum of n_speech_samples for any mode
-static struct _rx_channel{
- struct freedv * hFreedv;
- short * demod_in;
- int rxdata_index;
- short speech_out[SPEECH_BUF_SIZE]; // output buffer
- int speech_available; // number of samples in output buffer
- int playing; // are we currently returning speech samples?
-} rx_channel[MAX_RECEIVERS] = { 0 }; // safe initialisation to 0
-
-// freedv_version is the library version number, or
-// -1 no library was found
-// -2 a library was found, but freedv_get_version is missing
-
-// FreeDV API functions:
-// open, close
-struct freedv * (*freedv_open)(int mode);
-struct freedv * (*freedv_open_advanced)(int mode, struct freedv_advanced *adv);
-void (*freedv_close)(struct freedv *freedv);
-// Transmit
-void (*freedv_tx)(struct freedv *freedv, short *, short *);
-void (*freedv_comptx)(struct freedv *freedv, COMP *, short *);
-// Receive
-int (*freedv_nin)(struct freedv *freedv);
-int (*freedv_rx)(struct freedv *freedv, short *, short demod_in[]);
-int (*freedv_floatrx)(struct freedv *freedv, short *, float demod_in[]);
-int (*freedv_comprx)(struct freedv *freedv, short *, COMP demod_in[]);
-// Set parameters
-void (*freedv_set_callback_txt) (struct freedv *freedv, freedv_callback_rx rx, freedv_callback_tx tx, void *callback_state);
-void (*freedv_set_test_frames) (struct freedv *freedv, int test_frames);
-void (*freedv_set_smooth_symbols) (struct freedv *freedv, int smooth_symbols);
-void (*freedv_set_squelch_en) (struct freedv *freedv, int squelch_en);
-void (*freedv_set_snr_squelch_thresh) (struct freedv *freedv, float snr_squelch_thresh);
-void (*freedv_set_tx_bpf) (struct freedv *freedv, int val);
-// Get parameters
-int (*freedv_get_version)(void);
-void (*freedv_get_modem_stats)(struct freedv *freedv, int *sync, float *snr_est);
-int (*freedv_get_test_frames) (struct freedv *freedv);
-int (*freedv_get_n_speech_samples) (struct freedv *freedv);
-int (*freedv_get_n_max_modem_samples) (struct freedv *freedv);
-int (*freedv_get_n_nom_modem_samples) (struct freedv *freedv);
-int (*freedv_get_total_bits) (struct freedv *freedv);
-int (*freedv_get_total_bit_errors) (struct freedv *freedv);
-int (*freedv_get_modem_sample_rate) (struct freedv *freedv);
-int (*freedv_get_speech_sample_rate) (struct freedv *freedv);
-//
-int (*freedv_get_sync) (struct freedv *freedv);
-void (*freedv_set_callback_protocol) (struct freedv *freedv, freedv_callback_protorx rx, freedv_callback_prototx tx, void *callback_state);
-void (*freedv_set_callback_data) (struct freedv *freedv, freedv_callback_datarx datarx, freedv_callback_datatx datatx, void *callback_state);
-
-//
-// checkAvxSupport
-//
-// This function was copied from freedv, file fdmdv2_main.cpp and tweaked for use here
-//
-// Tests the underlying platform for AVX support. 2020 needs AVX support to run
-// in real-time, and old processors do not offer AVX support
-//
-
-#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
-#include
-static int checkAvxSupport(void)
-{
-
- int isAvxPresent = 0;
- uint32_t eax, ebx, ecx, edx;
- eax = ebx = ecx = edx = 0;
- __cpuid(1, eax, ebx, ecx, edx);
-
- if (ecx & (1<<27) && ecx & (1<<28)) {
- // CPU supports XSAVE and AVX
- uint32_t xcr0, xcr0_high;
- asm("xgetbv" : "=a" (xcr0), "=d" (xcr0_high) : "c" (0));
- isAvxPresent = (xcr0 & 6) == 6; // AVX state saving enabled?
- }
- return isAvxPresent;
-}
-#else
-static int checkAvxSupport(void)
-{
- return 0;
-}
-#endif
-
-/* Called when a new packet can be sent */
-void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
- *size = 0;
-}
-
-static void GetAddrs(void)
-{
- handle_index = 1;
- GET_HANDLE1;
- if ( ! hLib) {
- handle_index = 2;
- GET_HANDLE2;
- if ( ! hLib) {
- handle_index = 4;
- GET_HANDLE4;
- }
- }
- if (hLib) {
- freedv_get_version = GET_ADDR("freedv_get_version");
- if (freedv_get_version != NULL) {
- freedv_version = freedv_get_version();
- if (DEBUG)
- printf("FreeDV codec2 library %d found, version %d\n", handle_index, freedv_version);
- }
- else {
- freedv_version = -2;
- if (DEBUG)
- printf("FreeDV codec2 library %d found, but no freedv_get_version() !!!\n", handle_index);
- CLOSE_LIB;
- return;
- }
- }
- else {
- handle_index = -1;
- if (DEBUG)
- printf("Could not find the FreeDV codec2 shared library\n");
- return;
- }
-
-// open, close
- freedv_open = GET_ADDR("freedv_open");
- freedv_open_advanced = GET_ADDR("freedv_open_advanced");
- freedv_close = GET_ADDR("freedv_close");
-// Transmit
- freedv_tx = GET_ADDR("freedv_tx");
- freedv_comptx = GET_ADDR("freedv_comptx");
-// Receive
- freedv_nin = GET_ADDR("freedv_nin");
- freedv_rx = GET_ADDR("freedv_rx");
- freedv_floatrx = GET_ADDR("freedv_floatrx");
- freedv_comprx = GET_ADDR("freedv_comprx");
-// Set parameters
- freedv_set_callback_txt = GET_ADDR("freedv_set_callback_txt");
- freedv_set_callback_protocol = GET_ADDR("freedv_set_callback_protocol");
- freedv_set_callback_data = GET_ADDR("freedv_set_callback_data");
- freedv_set_test_frames = GET_ADDR("freedv_set_test_frames");
- freedv_set_smooth_symbols = GET_ADDR("freedv_set_smooth_symbols");
- freedv_set_squelch_en = GET_ADDR("freedv_set_squelch_en");
- freedv_set_snr_squelch_thresh = GET_ADDR("freedv_set_snr_squelch_thresh");
- freedv_set_tx_bpf = GET_ADDR("freedv_set_tx_bpf");
-// Get parameters
- freedv_get_modem_stats = GET_ADDR("freedv_get_modem_stats");
- freedv_get_test_frames = GET_ADDR("freedv_get_test_frames");
- freedv_get_n_speech_samples = GET_ADDR("freedv_get_n_speech_samples");
- freedv_get_n_max_modem_samples = GET_ADDR("freedv_get_n_max_modem_samples");
- freedv_get_n_nom_modem_samples = GET_ADDR("freedv_get_n_nom_modem_samples");
- freedv_get_total_bits = GET_ADDR("freedv_get_total_bits");
- freedv_get_total_bit_errors = GET_ADDR("freedv_get_total_bit_errors");
- freedv_get_sync = GET_ADDR("freedv_get_sync"); // requires version 11
- if( freedv_version >= 11)
- freedv_get_modem_sample_rate = GET_ADDR("freedv_get_modem_sample_rate"); // requires version 11 or later
- if (freedv_version >= 12)
- freedv_get_speech_sample_rate = GET_ADDR("freedv_get_speech_sample_rate"); // requires version 12
- return;
-}
-
-static int quisk_freedv_rx(short * sSamples, double * dsamples, int count, int bank) // Called from the sound thread.
-{ // Input digital modulation is sSamples; decoded voice is dsamples. Each "bank" is a stream of audio.
- // caller will have decimated input audio down to n_modem_sample_rate and reduced block size to match reduction
- // output data will be returned at n_speech_sample_rate with corresponding block sizes
- int i, nout, need, have, sync;
- int n_speech_samples;
- struct freedv * hF;
- struct _rx_channel * pCh;
- int nCountOut = 1; // In case we have a higher (or lower) value for o/p count
-
- if (sSamples == NULL) { // shutdown
- for (i = 0; i < MAX_RECEIVERS; i++) {
- if (rx_channel[i].demod_in) {
- free(rx_channel[i].demod_in);
- rx_channel[i].demod_in = NULL;
- }
- }
- return 0;
- }
-
- if (bank < 0 || bank >= MAX_RECEIVERS)
- return 0;
- hF = rx_channel[bank].hFreedv;
- if ( ! hF)
- return 0;
- pCh = rx_channel + bank;
- n_speech_samples = freedv_get_n_speech_samples(hF);
- // if (say) input modem rate is the 2020 mode rate of 8000 sa/sec
- // and output rate is the corresponding 16000 sa/sec then for an input
- // block size of N, outbut 2N samples block size.
- // Apply a multiplier/divisor to 'count' for the output samples count
- if(n_speech_sample_rate >= n_modem_sample_rate ) {
- int nRatio = n_speech_sample_rate / n_modem_sample_rate;
- if( nRatio >= 1 && nRatio <= 6)
- nCountOut = nRatio * count;
- }
- else {
- int nRatio = n_modem_sample_rate / n_speech_sample_rate;
- if( nRatio >= 1 && nRatio <= 6)
- nCountOut = count / nRatio;
- }
- nout = 0;
- need = freedv_nin(hF);
- for (i = 0; i < count; i++) {
- pCh->demod_in[pCh->rxdata_index] = sSamples[i];
- pCh->rxdata_index++;
- if (pCh->rxdata_index >= need) {
- if (pCh->speech_available + n_speech_samples < SPEECH_BUF_SIZE) { // check for buffer space
- have = freedv_rx(hF, pCh->speech_out + pCh->speech_available, pCh->demod_in);
- if (freedv_version > 10)
- sync = freedv_get_sync(hF);
- else
- freedv_get_modem_stats(hF, &sync, NULL);
- if (freedv_current_mode == 0) { // mode 1600
- if (sync) // throw away speech if not in sync
- pCh->speech_available += have;
- }
- else if (pCh->speech_available < SPEECH_BUF_SIZE * 2 / 3) {
- pCh->speech_available += have; // keep speech if there is space
- }
- else {
- if (DEBUG) printf("Close to maximum in speech output buffer\n");
- }
- }
- else { // no space in buffer
- if (DEBUG) printf("Overflow in speech output buffer\n");
- }
- pCh->rxdata_index = 0;
- need = freedv_nin(hF);
- }
- }
- if ( ! pCh->playing) {
- if (pCh->speech_available >= 2 * n_speech_samples) {
- pCh->playing = 1;
- }
- else { // return zero samples
- for (i = 0; i < nCountOut; i++)
- dsamples[i] = 0;
- //if (DEBUG) printf("Rx buffer playing %d available %d\n", pCh->playing, pCh->speech_available);
- return nCountOut;
- }
- }
- for (nout = 0; nout < pCh->speech_available && nout < nCountOut; nout++)
- dsamples[nout] = pCh->speech_out[nout] * ((double)CLIP32 / CLIP16 * 0.99);
- if (nout) {
- pCh->speech_available -= nout;
- memmove(pCh->speech_out, pCh->speech_out + nout, (pCh->speech_available) * sizeof(short));
- }
- if ( ! pCh->speech_available) {
- pCh->playing = 0;
- while (nout < nCountOut)
- dsamples[nout++] = 0;
- }
- //if (DEBUG) printf("Rx buffer playing %d available %d\n", pCh->playing, pCh->speech_available);
- return nout;
-}
-
-static int quisk_freedv_tx(complex double * cSamples, double * dsamples, int count, int is_real) // Called from the sound thread.
-{ // Input voice samples are dsamples; output digital modulation is cSamples.
- int i, nout;
- int n_speech_samples;
- int n_nom_modem_samples;
- static COMP * mod_out = NULL;
- static short * speech_in = NULL;
- static int speech_index=0, mod_index=0;
- // g8kbb - add for 800XA
- static short *real_mod_out = NULL;
-
- if (dsamples == NULL) { // shutdown
- return 0; // nothing to do
- }
- if ( ! rx_channel[0].hFreedv)
- return 0;
- n_speech_samples = freedv_get_n_speech_samples(rx_channel[0].hFreedv);
- n_nom_modem_samples = freedv_get_n_nom_modem_samples(rx_channel[0].hFreedv);
- // find if need to output at faster rate
- int nRatio = n_modem_sample_rate / n_speech_sample_rate;
- if( nRatio < 1 || nRatio > 6 )
- nRatio = 1;
- if (mod_out == NULL) { // initialize
- mod_out = (COMP *)malloc(sizeof(COMP) * MAX_MODEM_SAMPLES);
- memset(mod_out, 0, sizeof(COMP) * MAX_MODEM_SAMPLES);
- speech_in = (short*)malloc(sizeof(short) * MAX_SPEECH_SAMPLES);
- speech_index=0;
- mod_index=0;
- real_mod_out = (short *)malloc(sizeof(short) * MAX_MODEM_SAMPLES);
- memset(real_mod_out, 0, sizeof(short) * MAX_MODEM_SAMPLES);
- //if( DEBUG ) printf("Initialise tx buffer size = %d, i/p sample size = %d\n", n_nom_modem_samples, n_speech_samples );
- }
- nout = 0;
- for (i = 0; i < count; i++) {
- speech_in[speech_index++] = (short)dsamples[i];
- if (speech_index >= n_speech_samples) {
- // Calculate a new block, but first write out the rest of the old block
- // 800xa uses real not complex
- if( is_real ) {
- for ( ; mod_index < n_nom_modem_samples; mod_index++)
- cSamples[nout++] = real_mod_out[mod_index];
- freedv_tx(rx_channel[0].hFreedv, real_mod_out, speech_in);
- }
- else {
- for ( ; mod_index < n_nom_modem_samples; mod_index++)
- cSamples[nout++] = mod_out[mod_index].real + I * mod_out[mod_index].imag;
- freedv_comptx(rx_channel[0].hFreedv, mod_out, speech_in);
- }
- //if( DEBUG ) printf("Block processed, speech index=%d, n_speech_samples=%d, count=%d\n", speech_index, n_speech_samples, count );
- mod_index = 0;
- speech_index = 0;
- }
- else { // write out samples
- for( int j=0; j= TX_MSG_SIZE)
- index = 0;
- if ( ! c) {
- index = 0;
- c = quisk_tx_msg[index++];
- }
- return c;
-}
-
-#define RX_MSG_SIZE 80
-static char quisk_rx_msg[RX_MSG_SIZE + 1];
-
-static void put_next_rx_char(void * callback_state, char ch)
-{
- if (ch == '\n' || ch == '\r')
- ch = ' ';
- if (ch < 32 || ch > 126) // printable characters
- return;
- if (strlen(quisk_rx_msg) < RX_MSG_SIZE)
- strncat(quisk_rx_msg, &ch, 1);
-}
-
-PyObject * quisk_freedv_get_rx_char(PyObject * self, PyObject * args) // Called from the GUI thread.
-{
- PyObject * txt;
-
- if (!PyArg_ParseTuple (args, ""))
- return NULL;
- txt = PyString_FromString(quisk_rx_msg);
- quisk_rx_msg[0] = 0;
- return txt;
-}
-
-static void CloseFreedv(void) // Called from the GUI thread or sound thread
-{
- int i;
-
- for (i = 0; i < MAX_RECEIVERS; i++) {
- if (rx_channel[i].hFreedv) {
- freedv_close(rx_channel[i].hFreedv);
- rx_channel[i].hFreedv = NULL;
- }
- }
- quisk_freedv_rx(NULL, NULL, 0, 0);
- quisk_freedv_tx(NULL, NULL, 0, 0);
- freedv_current_mode = -1;
-}
-
-static int OpenFreedv(void) // Called from the GUI thread or sound thread
-{
- int i;
- struct freedv * hF;
-
- if ( ! hLib)
- GetAddrs(); // Get the entry points for funtions in the codec2 library
- if (DEBUG) {
- switch (handle_index) {
- case 1:
- printf("freedv_open: system codec2 library found, version %d\n", freedv_version);
- break;
- case 2:
- printf("freedv_open: codec2 library freedvpkg/libcodec2.dll|so found, version %d\n", freedv_version);
- break;
- case 3:
- case 4:
- printf("freedv_open: codec2 library freedvpkg/libcodec2_64 found, version %d\n", freedv_version);
- break;
- default:
- printf("freedv_open: Could not find the FreeDV codec2 shared library\n");
- break;
- }
- }
- if (freedv_version < 10) {
- CloseFreedv();
- requested_mode = -1;
- if (DEBUG)
- printf("freedv_open: Failure because version is less than 10\n");
- return 0; // failure
- }
- if (requested_mode == FREEDV_MODE_2020) {
- if (checkAvxSupport() == 0) {
- CloseFreedv();
- requested_mode = -1;
- if (DEBUG)
- printf("freedv_open: Failure because mode 2020 requires Avx support\n");
- return 0; // failure
- }
- if (handle_index >= 3) { // Quisk provided codec2
- CloseFreedv();
- requested_mode = -1;
- if (DEBUG)
- printf("freedv_open: Failure because mode 2020 requires a system installation of codec2\n");
- return 0; // failure
- }
- }
-
- if ((requested_mode == FREEDV_MODE_700D || requested_mode == FREEDV_MODE_700E) && freedv_open_advanced) {
- struct freedv_advanced adv;
- memset(&adv, 0, sizeof(adv));
- adv.interleave_frames = interleave_frames;
- hF = freedv_open_advanced(requested_mode, &adv);
- }
- else {
- hF = freedv_open(requested_mode);
- }
- if (hF == NULL) {
- CloseFreedv();
- requested_mode = -1;
- return 0; // failure
- }
- rx_channel[0].hFreedv = hF;
- quisk_dvoice_freedv(&quisk_freedv_rx, &quisk_freedv_tx);
- if (quisk_tx_msg[0])
- freedv_set_callback_txt(hF, &put_next_rx_char, &get_next_tx_char, NULL);
- else
- freedv_set_callback_txt(hF, &put_next_rx_char, NULL, NULL);
- if (freedv_set_callback_protocol)
- freedv_set_callback_protocol(hF, NULL, NULL, NULL);
- if (freedv_set_callback_data)
- freedv_set_callback_data(hF, NULL, my_datatx, NULL);
- freedv_set_squelch_en(hF, quisk_freedv_squelch);
- if (freedv_set_tx_bpf)
- freedv_set_tx_bpf(hF, quisk_set_tx_bpf);
- n_max_modem_samples = freedv_get_n_max_modem_samples(hF);
- n_speech_sample_rate = 8000;
- if (freedv_version >= 12 && freedv_get_speech_sample_rate)
- n_speech_sample_rate = freedv_get_speech_sample_rate(hF);
- n_modem_sample_rate = 8000;
- if (freedv_version >= 11 && freedv_get_modem_sample_rate)
- n_modem_sample_rate = freedv_get_modem_sample_rate(hF);
- for (i = 0; i < MAX_RECEIVERS; i++) {
- rx_channel[i].rxdata_index = 0;
- rx_channel[i].speech_available = 0;
- rx_channel[i].playing = 0;
- if (rx_channel[i].demod_in)
- free(rx_channel[i].demod_in);
- rx_channel[i].demod_in = (short *)malloc(sizeof(short) * n_max_modem_samples);
- if( rx_channel[i].demod_in == NULL) {
- CloseFreedv();
- requested_mode = -1;
- return 0; // failure
- }
- if (i > 0) {
- rx_channel[i].hFreedv = freedv_open(requested_mode);
- if (rx_channel[i].hFreedv)
- freedv_set_squelch_en(rx_channel[i].hFreedv, quisk_freedv_squelch);
- }
- }
- if (DEBUG) printf("n_nom_modem_samples %d\n", freedv_get_n_nom_modem_samples(rx_channel[0].hFreedv));
- if (DEBUG) printf("n_speech_samples %d\n", freedv_get_n_speech_samples(rx_channel[0].hFreedv));
- if (DEBUG) printf("n_max_modem_samples %d\n", n_max_modem_samples);
- if (DEBUG) {
- if (freedv_version >= 11) printf("modem_sample_rate %d\n", n_modem_sample_rate);
- if (freedv_version >= 12) printf("speech_sample_rate %d\n", n_speech_sample_rate);
- }
- freedv_current_mode = requested_mode;
- return 1; // success
-}
-
-void quisk_check_freedv_mode(void)
-{ // see if we need to change the mode
- if (requested_mode == freedv_current_mode)
- return;
- if (DEBUG) printf("Change in mode to %d\n", requested_mode);
- CloseFreedv();
- if (requested_mode >= 0)
- OpenFreedv();
- else
- requested_mode = -1;
-}
-
-PyObject * quisk_freedv_open(PyObject * self, PyObject * args) // Called from the GUI thread before freedv is open
-{
- if (!PyArg_ParseTuple (args, ""))
- return NULL;
- return PyInt_FromLong(OpenFreedv());
-}
-
-PyObject * quisk_freedv_close(PyObject * self, PyObject * args) // Called from the GUI thread.
-{
- if (!PyArg_ParseTuple (args, ""))
- return NULL;
- requested_mode = -1; // request close
- Py_INCREF (Py_None);
- return Py_None;
-}
-
-PyObject * quisk_freedv_set_options(PyObject * self, PyObject * args, PyObject * keywds) // Called from the GUI thread.
-{ // Call with keyword arguments ONLY to change parameters. Call before quisk_freedv_open() to set an initial mode.
- int mode=-1; // Call again to change the mode.
- int bpf=-1;
- char * ptMsg=NULL;
- static char * kwlist[] = {"mode", "tx_msg", "DEBUG", "squelch", "interleave_frames", "set_tx_bpf", NULL} ;
-
- if (!PyArg_ParseTupleAndKeywords (args, keywds, "|isiiii", kwlist, &mode, &ptMsg, &DEBUG, &quisk_freedv_squelch, &interleave_frames, &bpf))
- return NULL;
- if (ptMsg)
- strMcpy(quisk_tx_msg, ptMsg, TX_MSG_SIZE);
- if (bpf != -1) {
- quisk_set_tx_bpf = bpf;
- if (freedv_set_tx_bpf && rx_channel[0].hFreedv)
- freedv_set_tx_bpf(rx_channel[0].hFreedv, quisk_set_tx_bpf);
- }
- if (mode == -1) { // mode was not entered
- ;
- }
- else if (mode == FREEDV_MODE_700E && freedv_version >= 14) {
- requested_mode = mode;
- }
- else if (mode == FREEDV_MODE_2020) {
- if (checkAvxSupport() && handle_index <= 2 && freedv_version >= 13)
- requested_mode = mode;
- }
- else if (freedv_version == 10) {
- if (mode == 0)
- requested_mode = mode;
- }
- else if (freedv_version == 11) {
- if (mode <= 2)
- requested_mode = mode;
- }
- else {
- requested_mode = mode;
- }
- return PyInt_FromLong(requested_mode); // Return the mode
-}
-
-PyObject * quisk_freedv_get_snr(PyObject * self, PyObject * args) // Called from the GUI thread.
-{
- float snr_est = 0.0;
-
- if (!PyArg_ParseTuple (args, ""))
- return NULL;
- if (rx_channel[0].hFreedv)
- freedv_get_modem_stats(rx_channel[0].hFreedv, NULL, &snr_est);
- return PyFloat_FromDouble(snr_est);
-}
-
-PyObject * quisk_freedv_get_version(PyObject * self, PyObject * args) // Called from the GUI thread.
-{
- if (!PyArg_ParseTuple (args, ""))
- return NULL;
- if ( ! hLib)
- GetAddrs(); // Get the entry points for funtions in the codec2 library
- return PyInt_FromLong(freedv_version);
-}
-
-PyObject * quisk_freedv_set_squelch_en(PyObject * self, PyObject * args) // Called from the GUI thread.
-{
- int i,state;
-
- if (!PyArg_ParseTuple (args, "i", &state))
- return NULL;
- quisk_freedv_squelch = state;
- for (i = 0; i < MAX_RECEIVERS; i++) {
- if( rx_channel[i].hFreedv )
- freedv_set_squelch_en(rx_channel[i].hFreedv, state);
- }
- return PyInt_FromLong(state);
-}
-
-
+// This file is no longer used.
diff --git a/freedv.h b/freedv.h
index c894c7c..f5df7e1 100644
--- a/freedv.h
+++ b/freedv.h
@@ -1,24 +1 @@
-extern int freedv_current_mode; // the current FreeDV running mode
-
-// available speech modes
-#define FREEDV_MODE_1600 0
-#define FREEDV_MODE_2400A 3
-#define FREEDV_MODE_2400B 4
-#define FREEDV_MODE_800XA 5
-#define FREEDV_MODE_700C 6
-#define FREEDV_MODE_700D 7
-#define FREEDV_MODE_700E 13
-#define FREEDV_MODE_2020 8
-#define FREEDV_MODE_2020B 16
-
-// available data modes
-#define FREEDV_MODE_FSK_LDPC 9
-#define FREEDV_MODE_DATAC1 10
-#define FREEDV_MODE_DATAC3 12
-#define FREEDV_MODE_DATAC0 14
-#define FREEDV_MODE_DATAC4 18
-#define FREEDV_MODE_DATAC13 19
-
-// Sample rates used
-#define FREEDV_FS_8000 8000
-#define FREEDV_FS_16000 16000
+// This header file is no longer used.
diff --git a/freedvpkg/README.txt b/freedvpkg/README.txt
index bf20708..68769c7 100644
--- a/freedvpkg/README.txt
+++ b/freedvpkg/README.txt
@@ -1,129 +1 @@
-
-Note: The directory freedvpkg no longer contains source files. It only contains copies of
- the codec2 libraries for use by Quisk. If any other files are present, delete them.
-
-FreeDV and Directory freedvpkg
-==============================
-
-FreeDV is the combination of the codec2 codec and the fdmdv modem. It provides digital voice
-suitable for HF and VHF transmission. Quisk has native (built-in) support for
-FreeDV. Just push the FDV mode and talk. This freedvpkg directory contains copies of the
-codec2 libraries for use by Quisk.
-
-You can also use the separate FreeDV program available at freedv.org, and the Quisk DGT-U mode
-which attaches to external digital programs. The setup is identical to fldigi and other external
-digital programs.
-
-Quisk will add the FDV button if specified on the Config/radio/Controls tab.
-If there is a problem with the freedv module, the button will be grayed out.
-
-The freedv module requires the codec2 library. This library is included for Windows and for
-Ubuntu 18.04 LTS 32-bit and 64-bit. For other systems (such as ARM) you will need to build another
-codec2. Just try the FDV mode and see if it works. It should always work on Windows, and may work
-on Linux. If the FDV button is grayed out, you need a different codec2 than the one included. Make
-a new codec2 library, and copy it to freedvpkg or to the correct system directory.
-
-2020 mode
-=========
-You can now use 2020 mode with Quisk. Note however that 2020 mode requires a processor with AVX.
-Also note a Raspberry PI (model 4B) does not have enough processing power even if neon is used
-and it is overclocked.
-
-There are two parts to this:
-1. build LPCNet
-2. rebuild codec2
-The details are found here: https://github.com/drowe67/codec2#freedv-2020-support-building-with-lpcnet
-
-Both liblpcnetfreedv and libcodec2 are needed. If you are running under windows, the resultant
-liblpcnetfreedv.dll file needs to be placed in the quisk folder. Libcodec2 may be placed in the
-quisk freedvpkg folder. Or install the DLL's in the correct system folders.
-
-Search Order
-============
-
-Quisk will search for a valid codec2 library in this order on Windows:
-1. The system codec2 library installed outside of Quisk by another program.
-2. freedvpkg/libcodec2.dll. Not included. You can copy your own codec2 here but a system-wide installation is better.
-3. freedvpkg/libcodec2_32.dll. The 32-bit codec2 shipped with Quisk.
-4. freedvpkg/libcodec2_64.dll. The 64-bit codec2 shipped with Quisk.
-
-Quisk will search for a valid codec2 library in this order on Linux:
-1. The system codec2 library installed outside of Quisk by another program.
-2. freedvpkg/libcodec2.so. Not included. You can copy your own codec2 here but a system-wide installation is better.
-3. freedvpkg/libcodec2_32.so. The 32-bit codec2 shipped with Quisk.
-4. freedvpkg/libcodec2_64.so. The 64-bit codec2 shipped with Quisk.
-
-How to Build a New codec2
-=========================
-
-The source for codec2 is available on github. Or google for other sources or perhaps a pre-built library.
-If you need to compile codec2 from source, first change to a suitable directory (not the Quisk directory)
-and download the source with git:
-
- git clone https://github.com/drowe67/codec2.git
-
-Then build codec2 using the directions found at https://github.com/drowe67/codec2/blob/master/INSTALL.
-The directions given below are current as of June 2020, but check for changes.
-Then copy the codec2 library to the freedvpkg directory under Quisk.
-
-Build a New codec2 on Linux
-===========================
-Create the codec2 shared library. This assumes a 64-bit linux. Change the directory
-name from build_linux64 to build_linux32 for 32-bit linux. Note the "../".
-
- cd codec2
- mkdir build_linux64
- cd build_linux64
- cmake -DCMAKE_BUILD_TYPE=Release ../
- make
- cd src
- cp libcodec2.so my-quisk-directory/freedvpkg
-
-Build a New 32-bit codec2 on 64-bit Linux
-=========================================
-Make sure package libc6-dev-i386 is installed.
-Create the codec2 shared library. Note the "../".
-
- cd codec2
- mkdir build_linux32
- cd build_linux32
- export CFLAGS=-m32
- cmake -DCMAKE_BUILD_TYPE=Release ../
- make
- cd src
- cp libcodec2.so my-quisk-directory/freedvpkg
-
-Build a New codec2 on Windows
-=============================
-For Windows you need to install MinGW-w64, MSYS2, and g++. Use the mingw shell. The Speex libraries
-are not needed by codec2, but are required for the Unit Test modules. To build the Unit Test modules,
-you need to install Speex and add -DSPEEXDSP_INCLUDE_DIR=../speex/include/speex -DSPEEXDSP_LIBRARY=../speex/bin.
-
- # Use mingw32.exe 32-bit shell:
- cd codec2
- mkdir build_win32
- cd build_win32
- cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DUNITTEST=OFF ../
- make codec2
- cd src
- cp libcodec2.dll my-quisk-directory/freedvpkg
-
- # Use mingw64.exe 64-bit shell:
- cd codec2
- mkdir build_win64
- cd build_win64
- cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DUNITTEST=OFF -DCMAKE_SYSTEM_PROCESSOR=x86_64 ../
- make codec2
- cd src
- cp libcodec2.dll my-quisk-directory/freedvpkg
-
-Testing
-=======
-You can just start Quisk and see if the FDV button is not grayed out, and FDV works. Or you can
-test the import of freedv and look for error messages.
-
- cd my-quisk-directory
- python # Use the correct Python 2 or 3 in 32 or 64 bit
- import _quisk
- _quisk.freedv_get_version() # This should return 13 or higher for a recent codec2
-
+This directory is no longer used by FreeDV. Please see the documentation.
diff --git a/freedvpkg/libcodec2_64.dll b/freedvpkg/libcodec2_64.dll
deleted file mode 100644
index 5c6ee525c015140f49fd550d57b6b748bac9f38d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1904878
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