diff --git a/.gitignore b/.gitignore index 8e7347a..99c0e5d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ TODO *.s16 *.data .DS_Store +build +dist diff --git a/README.md b/README.md index 28333c6..1905f5f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,163 @@ -Work in progress +A KISS TNC using the freedv data modems. -Untested instructions: -1. Update `include_dirs` and `library_dirs` in `freedvtnc2/freedv_build.py` to point to codec2 -2. Create venv / activate -3. cd into freedvtnc2 -3. `pip install -r requirements.txt` -3. run `python freedv_build.py` -4. cd back to the main project dir -5. run `python -m freedvtnc2 --help` +![Screenshot of the freedvtnc2 modem cli showing the chat feature and a file being transfered](screenshot.png) + +## Features + - KISS interface (virtual serial, or TCP) + - Chat + - DATAC1, DATAC3 and DATAC4 modes + +## Unsupported + - Windows + +## Requirements + - hamlib + - portaudio / pyaudio + - c build tools + +## Install + +Instructions for a raspberrypi. Requires bookworm or python 3.11 to be installed. + +```sh +# install required system packages +sudo apt-get update +sudo apt install git build-essential cmake portaudio19-dev python3 python3-dev libhamlib-utils python3-venv + +# install pipx - either like this +python3 -m pip install --user pipx +python3 -m pipx ensurepath +# or +sudo apt install pipx +pipx ensurepath + +# make sure the PATH is set correctly +source ~/.profile + +# install codec2 (the debian packaged versions do not contain DATAC4 modem) +git clone https://github.com/drowe67/codec2.git +cd codec2 +mkdir build_linux +cd build_linux +cmake .. +make +sudo make install + +# install freedvtnc2 +pipx install freedvtnc2 + + +``` + +If libcodec2 is installed somewhere else you can use `CFLAGS="-I/path/to/headers/ -L/path/to/lib/"` during to ensure that we can find libcodec2 during the install + +## Running +``` +# Run rigctld in background. See rigctld --help on how to configure your rig +rigctld -m 1 -r /dev/null & + +# Test to make sure rigctl works +rigctl -m 2 T 1 # enable PTT +rigctl -m 2 T 0 # disable PTT + +# Get argument help +freedvtnc2 --help + +#list audio devices +freedvtnc2 --list-audio-devices + +freedvtnc2 --output-device 0 --input-device 0 --log-level DEBUG # it's useful to have debug turned on when first testing +``` + +The connect your favorite kiss tools up to the TNC over TCP port 8001 or PTS interface if enabled + +## Testing + +The CLI has a handy `test_ptt` to make test that PTT and sound output is working. + +## Command line arguments +``` +usage: freedvtnc2 [-h] [-c C] [--no-cli] [--list-audio-devices] [--log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}] [--input-device INPUT_DEVICE] [--output-device OUTPUT_DEVICE] + [--output-volume OUTPUT_VOLUME] [--mode {DATAC1,DATAC3,DATAC4}] [--follow] [--max-packets-combined MAX_PACKETS_COMBINED] [--pts] [--kiss-tcp-port KISS_TCP_PORT] + [--kiss-tcp-address KISS_TCP_ADDRESS] [--rigctld-port RIGCTLD_PORT] [--rigctld-host RIGCTLD_HOST] [--ptt-on-delay-ms PTT_ON_DELAY_MS] [--ptt-off-delay-ms PTT_OFF_DELAY_MS] + [--callsign CALLSIGN] + +options: + -h, --help show this help message and exit + -c C, -config C config file path + --no-cli [env var: FREEDVTNC2_CLI] + --list-audio-devices + --log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET} + [env var: FREEDVTNC2_LOG_LEVEL] + --input-device INPUT_DEVICE + [env var: FREEDVTNC2_INPUT_DEVICE] + --output-device OUTPUT_DEVICE + [env var: FREEDVTNC2_OUTPUT_DEVICE] + --output-volume OUTPUT_VOLUME + in db. postive = louder, negative = quiter [env var: FREEDVTNC2_OUTPUT_DB] + --mode {DATAC1,DATAC3,DATAC4} + The TX mode for the modem. The modem will receive all modes at once + --follow When enabled change TX mode to the mode being received. This is useful for stations operating automatically. [env var: FREEDVTNC2_FOLLOW] + --max-packets-combined MAX_PACKETS_COMBINED + How many kiss packets to combine into a single transmission [env var: FREEDVTNC2_MAX_PACKETS] + --pts Disables TCP and instead creates a PTS 'fake serial' interface [env var: FREEDVTNC2_PTS] + --kiss-tcp-port KISS_TCP_PORT + [env var: FREEDVTNC2_KISS_TCP_PORT] + --kiss-tcp-address KISS_TCP_ADDRESS + [env var: FREEDVTNC2_KISS_TCP_ADDRESS] + --rigctld-port RIGCTLD_PORT + TCP port for rigctld - set to 0 to disable rigctld support [env var: FREEDVTNC2_RIGTCTLD_PORT] + --rigctld-host RIGCTLD_HOST + Host for rigctld [env var: FREEDVTNC2_RIGTCTLD_HOST] + --ptt-on-delay-ms PTT_ON_DELAY_MS + Delay after triggering PTT before sending data [env var: FREEDVTNC2_PTT_ON_DELAY_MS] + --ptt-off-delay-ms PTT_OFF_DELAY_MS + Delay after sending data before releasing PTT [env var: FREEDVTNC2_PTT_OFF_DELAY_MS] + --callsign CALLSIGN Currently only used for chat [env var: FREEDVTNC2_CALLSIGN] + +Args that start with '--' can also be set in a config file (~/.freedvtnc2.conf or specified via -c). Config file syntax allows: key=value, flag=true, stuff=[a,b,c] (for details, see syntax at +https://goo.gl/R74nmi). In general, command-line values override environment variables which override config file values which override defaults. +``` + +## CLI commands +``` +FreeDVTNC2 Help^ +--------------- +callsign + Sets callsign - example: callsign N0CALL +clear + Clears TX queues +debug + Open the debug shell +exception + Raises and exemption to test the shell +exit + Exits FreeDVTNC2 +follow + Allows the tx modem to change to the mode last received - follow on +help + This help +list_audio_devices + Lists audio device parameters +log_level + Set the log level +max_packets_combined + Set the max number of packets to combine together for a single transmission +mode + Change TX Mode: mode [DATAC1, DATAC3, DATAC4] +msg + Send a message +save_config + Save a config file to ~/.freedvtnc2.conf. Warning this will override your current config +send_string + Sends string over the modem +test_ptt + Turns on PTT for 2 seconds +volume + Set the volume gain in db for output level - you probably want to use soundcard configuration or radio configuration rather than this. + +``` + +Credits +-- +David Rowe and the FreeDV team for developing the modem and libraries \ No newline at end of file diff --git a/build_lib.py b/build_lib.py new file mode 100644 index 0000000..7737fe2 --- /dev/null +++ b/build_lib.py @@ -0,0 +1,9 @@ +from setuptools import setup + +import freedvtnc2.freedv_build as freedv_build + + +def build(a): + setup( + ext_modules=[freedv_build.ffibuilder.distutils_extension()], + ) diff --git a/freedvtnc2/__main__.py b/freedvtnc2/__main__.py index 4bdcbd8..77da5a3 100644 --- a/freedvtnc2/__main__.py +++ b/freedvtnc2/__main__.py @@ -11,7 +11,7 @@ from prompt_toolkit.formatted_text import HTML, to_formatted_text logging.basicConfig() -if __name__ == '__main__': +def main(): p = configargparse.ArgParser(default_config_files=['~/.freedvtnc2.conf'], config_file_parser_class=configargparse.DefaultConfigFileParser) p.add('-c', '-config', required=False, is_config_file=True, help='config file path') @@ -193,6 +193,9 @@ if __name__ == '__main__': time.sleep(0.1) except KeyboardInterrupt: log_handler.shell = None - rig.ptt_disable() + if "rig" in locals(): + rig.ptt_disable() input_device.close() - output_device.close() \ No newline at end of file + output_device.close() +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/freedvtnc2/audio.py b/freedvtnc2/audio.py index 270e7f6..ff2b3f8 100644 --- a/freedvtnc2/audio.py +++ b/freedvtnc2/audio.py @@ -94,10 +94,8 @@ class InputDevice(): logging.debug(f"Opening {self.device.name} for input") - if self.device.input_channels > 2: - raise NotImplementedError("Inputs with greater than 2 channels not supported") - if self.device.input_channels == 2: - logging.warning("Stereo input detected - Only the left channel will be used") + if self.device.input_channels >= 2: + logging.warning("Stereo (or more) input detected - Only the first/left channel will be used") if self.device.sample_rate < sample_rate: logging.critical(f"Input audio device sample rate {self.device.sample_rate} is less than modems sample rate {sample_rate} - this will cause problems") @@ -204,12 +202,17 @@ class OutputDevice(): logging.debug(f"Opening {self.device.name} for output") - if self.device.input_channels > 2: - raise NotImplementedError("Inputs with greater than 2 channels not supported") + if self.device.output_channels > 2: + logging.warning("Output detected with more than 2 channels. We'll try to open the device with 2 channels") + self.device.output_channels = 2 if self.device.sample_rate < sample_rate: logging.critical(f"Output audio device sample rate {self.device.sample_rate} is less than modems sample rate {sample_rate} - this will cause problems") + self.ptt_trigger = ptt_trigger + self.ptt_release = ptt_release + self.ptt = False + self.stream = p.open(format=FORMAT, channels=self.device.output_channels, rate=self.device.sample_rate, @@ -220,9 +223,7 @@ class OutputDevice(): frames_per_buffer=4096 ) - self.ptt_trigger = ptt_trigger - self.ptt_release = ptt_release - self.ptt = False + def write_raw(self,data:bytes): if self.device.sample_rate != self.sample_rate: diff --git a/freedvtnc2/freedv.h b/freedvtnc2/freedv.h deleted file mode 100644 index def2e6e..0000000 --- a/freedvtnc2/freedv.h +++ /dev/null @@ -1,291 +0,0 @@ - -typedef struct { - float real; - float imag; -} COMP; - - - -// 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 - -// peak (complex) sample value from Tx modulator -#define FREEDV_PEAK 16384 - -// Return code flags for freedv_get_rx_status() function -#define FREEDV_RX_TRIAL_SYNC 0x1 // demodulator has trial sync -#define FREEDV_RX_SYNC 0x2 // demodulator has sync -#define FREEDV_RX_BITS 0x4 // data bits have been returned -#define FREEDV_RX_BIT_ERRORS \ - 0x8 // FEC may not have corrected all bit errors (not all parity checks OK) - -// optional operator control of OFDM modem state machine -#define FREEDV_SYNC_UNSYNC \ - 0 // force sync state machine to lose sync, and search for new sync -#define FREEDV_SYNC_AUTO 1 // falls out of sync automatically -#define FREEDV_SYNC_MANUAL 2 // fall out of sync only under operator control - -#define FREEDV_VARICODE_MAX_BITS 12 // max bits for each ASCII character - -// These macros allow us to disable unwanted modes at compile tine, for example -// to save memory on embedded systems or the remove need to link other -// libraries. By default we enable all modes. Disable during compile time e.g -// -DFREEDV_MODE_1600_EN=0 will enable all but FreeDV 1600. Or the other way -// round -DFREEDV_MODE_EN_DEFAULT=0 -DFREEDV_MODE_1600_EN=1 will enable only -// FreeDV 1600 - - - -// struct that hold state information for one freedv instance -struct freedv; - -// Some modes allow extra configuration parameters -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 -}; - -// Called when text message char is decoded -typedef void (*freedv_callback_rx)(void *, char); -// Called when new text message char is needed -typedef char (*freedv_callback_tx)(void *); -typedef void (*freedv_calback_error_pattern)(void *error_pattern_callback_state, - short error_pattern[], - int sz_error_pattern); - -// 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); - -/*---------------------------------------------------------------------------*\ - - FreeDV API functions - -\*---------------------------------------------------------------------------*/ - -// open, close ---------------------------------------------------------------- - -struct freedv *freedv_open_advanced(int mode, struct freedv_advanced *adv); -struct freedv *freedv_open(int mode); -void freedv_close(struct freedv *freedv); - -// Transmit ------------------------------------------------------------------- - -void freedv_tx(struct freedv *freedv, short mod_out[], short speech_in[]); -void freedv_comptx(struct freedv *freedv, COMP mod_out[], short speech_in[]); -void freedv_datatx(struct freedv *f, short mod_out[]); -int freedv_data_ntxframes(struct freedv *freedv); -void freedv_rawdatatx(struct freedv *f, short mod_out[], - unsigned char *packed_payload_bits); -void freedv_rawdatacomptx(struct freedv *f, COMP mod_out[], - unsigned char *packed_payload_bits); -int freedv_rawdatapreambletx(struct freedv *f, short mod_out[]); -int freedv_rawdatapreamblecomptx(struct freedv *f, COMP mod_out[]); -int freedv_rawdatapostambletx(struct freedv *f, short mod_out[]); -int freedv_rawdatapostamblecomptx(struct freedv *f, COMP mod_out[]); - -// Receive ------------------------------------------------------------------- - -int freedv_nin(struct freedv *freedv); -int freedv_rx(struct freedv *freedv, short speech_out[], short demod_in[]); -int freedv_shortrx(struct freedv *freedv, short speech_out[], short demod_in[], - float gain); -int freedv_floatrx(struct freedv *freedv, short speech_out[], float demod_in[]); -int freedv_comprx(struct freedv *freedv, short speech_out[], COMP demod_in[]); -int freedv_rawdatarx(struct freedv *freedv, unsigned char *packed_payload_bits, - short demod_in[]); -int freedv_rawdatacomprx(struct freedv *freedv, - unsigned char *packed_payload_bits, COMP demod_in[]); - -// Helper functions -// ------------------------------------------------------------------- - -int freedv_codec_frames_from_rawdata(struct freedv *freedv, - unsigned char *codec_frames, - unsigned char *rawdata); -int freedv_rawdata_from_codec_frames(struct freedv *freedv, - unsigned char *rawdata, - unsigned char *codec_frames); -unsigned short freedv_gen_crc16(unsigned char *bytes, int nbytes); -void freedv_pack(unsigned char *bytes, unsigned char *bits, int nbits); -void freedv_unpack(unsigned char *bits, unsigned char *bytes, int nbits); -unsigned short freedv_crc16_unpacked(unsigned char *bits, int nbits); -int freedv_check_crc16_unpacked(unsigned char *unpacked_bits, int nbits); - -// Set parameters ------------------------------------------------------------ - -void freedv_set_callback_txt(struct freedv *freedv, freedv_callback_rx rx, - freedv_callback_tx tx, void *callback_state); -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); -void freedv_set_test_frames(struct freedv *freedv, int test_frames); -void freedv_set_test_frames_diversity(struct freedv *freedv, - int test_frames_diversity); -void freedv_set_squelch_en(struct freedv *freedv, bool squelch_en); -void freedv_set_snr_squelch_thresh(struct freedv *freedv, - float snr_squelch_thresh); -void freedv_set_clip(struct freedv *freedv, bool val); -void freedv_set_total_bit_errors(struct freedv *freedv, int val); -void freedv_set_total_bits(struct freedv *freedv, int val); -void freedv_set_total_bit_errors_coded(struct freedv *freedv, int val); -void freedv_set_total_bits_coded(struct freedv *freedv, int val); -void freedv_set_total_packets(struct freedv *freedv, int val); -void freedv_set_total_packet_errors(struct freedv *freedv, int val); -void freedv_set_callback_error_pattern(struct freedv *freedv, - freedv_calback_error_pattern cb, - void *state); -void freedv_set_varicode_code_num(struct freedv *freedv, int val); -void freedv_set_data_header(struct freedv *freedv, unsigned char *header); -void freedv_set_carrier_ampl(struct freedv *freedv, int c, float ampl); -void freedv_set_sync(struct freedv *freedv, int sync_cmd); -void freedv_set_verbose(struct freedv *freedv, int verbosity); -void freedv_set_tx_bpf(struct freedv *freedv, int val); -void freedv_set_tx_amp(struct freedv *freedv, float amp); -void freedv_set_ext_vco(struct freedv *f, int val); -void freedv_set_phase_est_bandwidth_mode(struct freedv *f, int val); -void freedv_set_eq(struct freedv *f, bool val); -void freedv_set_frames_per_burst(struct freedv *f, int framesperburst); -void freedv_passthrough_gain(struct freedv *f, float g); -int freedv_set_tuning_range(struct freedv *freedv, float val_fmin, - float val_fmax); - -// Get parameters -// ------------------------------------------------------------------------- - -struct MODEM_STATS; - -int freedv_get_version(void); -char *freedv_get_hash(void); -int freedv_get_mode(struct freedv *freedv); -void freedv_get_modem_stats(struct freedv *freedv, int *sync, float *snr_est); -void freedv_get_modem_extended_stats(struct freedv *freedv, - struct MODEM_STATS *stats); -int freedv_get_test_frames(struct freedv *freedv); - -int freedv_get_speech_sample_rate(struct freedv *freedv); -int freedv_get_n_speech_samples(struct freedv *freedv); -int freedv_get_n_max_speech_samples(struct freedv *freedv); - -int freedv_get_modem_sample_rate(struct freedv *freedv); -int freedv_get_modem_symbol_rate(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_n_tx_modem_samples(struct freedv *freedv); -int freedv_get_n_tx_preamble_modem_samples(struct freedv *freedv); -int freedv_get_n_tx_postamble_modem_samples(struct freedv *freedv); - -// bit error rate stats -int freedv_get_total_bits(struct freedv *freedv); -int freedv_get_total_bit_errors(struct freedv *freedv); -int freedv_get_total_bits_coded(struct freedv *freedv); -int freedv_get_total_bit_errors_coded(struct freedv *freedv); -int freedv_get_total_packets(struct freedv *freedv); -int freedv_get_total_packet_errors(struct freedv *freedv); - -int freedv_get_rx_status(struct freedv *freedv); -void freedv_get_fsk_S_and_N(struct freedv *freedv, float *S, float *N); - -int freedv_get_sync(struct freedv *freedv); -int freedv_get_sync_interleaver(struct freedv *freedv); - -// access to speech codec states -struct FSK *freedv_get_fsk(struct freedv *f); -struct CODEC2 *freedv_get_codec2(struct freedv *freedv); - -int freedv_get_bits_per_codec_frame(struct freedv *freedv); -int freedv_get_bits_per_modem_frame(struct freedv *freedv); -int freedv_get_sz_error_pattern(struct freedv *freedv); -int freedv_get_protocol_bits(struct freedv *freedv); - - - - - - - -// #define MODEM_STATS_NC_MAX 50 -// #define MODEM_STATS_NR_MAX 320 -// #define MODEM_STATS_ET_MAX 8 -// #define MODEM_STATS_EYE_IND_MAX 160 -// #define MODEM_STATS_NSPEC 512 -// #define MODEM_STATS_MAX_F_HZ 4000 -// #define MODEM_STATS_MAX_F_EST 4 - -// struct MODEM_STATS { -// int Nc; -// float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ -// COMP rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX + 1]; -// /* latest received symbols, for scatter plot */ -// int nr; /* number of rows in rx_symbols */ -// int sync; /* demod sync state */ -// float foff; /* estimated freq offset in Hz */ -// float rx_timing; /* estimated optimum timing offset in samples */ -// float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ -// float sync_metric; /* number between 0 and 1 indicating quality of sync */ -// int pre, post; /* preamble/postamble det counters for burst data */ -// int uw_fails; /* Failed to detect Unique word (burst data) */ - -// /* FSK eye diagram traces */ -// /* Eye diagram plot -- first dim is trace number, second is the trace idx */ -// float rx_eye[MODEM_STATS_ET_MAX][MODEM_STATS_EYE_IND_MAX]; -// int neyetr; /* How many eye traces are plotted */ -// int neyesamp; /* How many samples in the eye diagram */ - -// /* optional for FSK modems - est tone freqs */ - -// float f_est[MODEM_STATS_MAX_F_EST]; - -// /* Buf for FFT/waterfall */ - -// float fft_buf[2 * MODEM_STATS_NSPEC]; -// void *fft_cfg; -// }; - -// void modem_stats_open(struct MODEM_STATS *f); -// void modem_stats_close(struct MODEM_STATS *f); -// void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], -// COMP rx_fdm[], int nin); diff --git a/freedvtnc2/freedv_build.py b/freedvtnc2/freedv_build.py index 5ca139e..d737520 100644 --- a/freedvtnc2/freedv_build.py +++ b/freedvtnc2/freedv_build.py @@ -3,7 +3,302 @@ ffibuilder = FFI() # cdef() expects a single string declaring the C types, functions and # globals needed to use the shared object. It must be in valid C syntax. -ffibuilder.cdef(open("freedv.h").read()) +ffibuilder.cdef( +""" + +typedef struct { + float real; + float imag; +} COMP; + + + +// 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 + +// peak (complex) sample value from Tx modulator +#define FREEDV_PEAK 16384 + +// Return code flags for freedv_get_rx_status() function +#define FREEDV_RX_TRIAL_SYNC 0x1 // demodulator has trial sync +#define FREEDV_RX_SYNC 0x2 // demodulator has sync +#define FREEDV_RX_BITS 0x4 // data bits have been returned +#define FREEDV_RX_BIT_ERRORS \ + 0x8 // FEC may not have corrected all bit errors (not all parity checks OK) + +// optional operator control of OFDM modem state machine +#define FREEDV_SYNC_UNSYNC \ + 0 // force sync state machine to lose sync, and search for new sync +#define FREEDV_SYNC_AUTO 1 // falls out of sync automatically +#define FREEDV_SYNC_MANUAL 2 // fall out of sync only under operator control + +#define FREEDV_VARICODE_MAX_BITS 12 // max bits for each ASCII character + +// These macros allow us to disable unwanted modes at compile tine, for example +// to save memory on embedded systems or the remove need to link other +// libraries. By default we enable all modes. Disable during compile time e.g +// -DFREEDV_MODE_1600_EN=0 will enable all but FreeDV 1600. Or the other way +// round -DFREEDV_MODE_EN_DEFAULT=0 -DFREEDV_MODE_1600_EN=1 will enable only +// FreeDV 1600 + + + +// struct that hold state information for one freedv instance +struct freedv; + +// Some modes allow extra configuration parameters +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 +}; + +// Called when text message char is decoded +typedef void (*freedv_callback_rx)(void *, char); +// Called when new text message char is needed +typedef char (*freedv_callback_tx)(void *); +typedef void (*freedv_calback_error_pattern)(void *error_pattern_callback_state, + short error_pattern[], + int sz_error_pattern); + +// 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); + +/*---------------------------------------------------------------------------*\ + + FreeDV API functions + +\*---------------------------------------------------------------------------*/ + +// open, close ---------------------------------------------------------------- + +struct freedv *freedv_open_advanced(int mode, struct freedv_advanced *adv); +struct freedv *freedv_open(int mode); +void freedv_close(struct freedv *freedv); + +// Transmit ------------------------------------------------------------------- + +void freedv_tx(struct freedv *freedv, short mod_out[], short speech_in[]); +void freedv_comptx(struct freedv *freedv, COMP mod_out[], short speech_in[]); +void freedv_datatx(struct freedv *f, short mod_out[]); +int freedv_data_ntxframes(struct freedv *freedv); +void freedv_rawdatatx(struct freedv *f, short mod_out[], + unsigned char *packed_payload_bits); +void freedv_rawdatacomptx(struct freedv *f, COMP mod_out[], + unsigned char *packed_payload_bits); +int freedv_rawdatapreambletx(struct freedv *f, short mod_out[]); +int freedv_rawdatapreamblecomptx(struct freedv *f, COMP mod_out[]); +int freedv_rawdatapostambletx(struct freedv *f, short mod_out[]); +int freedv_rawdatapostamblecomptx(struct freedv *f, COMP mod_out[]); + +// Receive ------------------------------------------------------------------- + +int freedv_nin(struct freedv *freedv); +int freedv_rx(struct freedv *freedv, short speech_out[], short demod_in[]); +int freedv_shortrx(struct freedv *freedv, short speech_out[], short demod_in[], + float gain); +int freedv_floatrx(struct freedv *freedv, short speech_out[], float demod_in[]); +int freedv_comprx(struct freedv *freedv, short speech_out[], COMP demod_in[]); +int freedv_rawdatarx(struct freedv *freedv, unsigned char *packed_payload_bits, + short demod_in[]); +int freedv_rawdatacomprx(struct freedv *freedv, + unsigned char *packed_payload_bits, COMP demod_in[]); + +// Helper functions +// ------------------------------------------------------------------- + +int freedv_codec_frames_from_rawdata(struct freedv *freedv, + unsigned char *codec_frames, + unsigned char *rawdata); +int freedv_rawdata_from_codec_frames(struct freedv *freedv, + unsigned char *rawdata, + unsigned char *codec_frames); +unsigned short freedv_gen_crc16(unsigned char *bytes, int nbytes); +void freedv_pack(unsigned char *bytes, unsigned char *bits, int nbits); +void freedv_unpack(unsigned char *bits, unsigned char *bytes, int nbits); +unsigned short freedv_crc16_unpacked(unsigned char *bits, int nbits); +int freedv_check_crc16_unpacked(unsigned char *unpacked_bits, int nbits); + +// Set parameters ------------------------------------------------------------ + +void freedv_set_callback_txt(struct freedv *freedv, freedv_callback_rx rx, + freedv_callback_tx tx, void *callback_state); +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); +void freedv_set_test_frames(struct freedv *freedv, int test_frames); +void freedv_set_test_frames_diversity(struct freedv *freedv, + int test_frames_diversity); +void freedv_set_squelch_en(struct freedv *freedv, bool squelch_en); +void freedv_set_snr_squelch_thresh(struct freedv *freedv, + float snr_squelch_thresh); +void freedv_set_clip(struct freedv *freedv, bool val); +void freedv_set_total_bit_errors(struct freedv *freedv, int val); +void freedv_set_total_bits(struct freedv *freedv, int val); +void freedv_set_total_bit_errors_coded(struct freedv *freedv, int val); +void freedv_set_total_bits_coded(struct freedv *freedv, int val); +void freedv_set_total_packets(struct freedv *freedv, int val); +void freedv_set_total_packet_errors(struct freedv *freedv, int val); +void freedv_set_callback_error_pattern(struct freedv *freedv, + freedv_calback_error_pattern cb, + void *state); +void freedv_set_varicode_code_num(struct freedv *freedv, int val); +void freedv_set_data_header(struct freedv *freedv, unsigned char *header); +void freedv_set_carrier_ampl(struct freedv *freedv, int c, float ampl); +void freedv_set_sync(struct freedv *freedv, int sync_cmd); +void freedv_set_verbose(struct freedv *freedv, int verbosity); +void freedv_set_tx_bpf(struct freedv *freedv, int val); +void freedv_set_tx_amp(struct freedv *freedv, float amp); +void freedv_set_ext_vco(struct freedv *f, int val); +void freedv_set_phase_est_bandwidth_mode(struct freedv *f, int val); +void freedv_set_eq(struct freedv *f, bool val); +void freedv_set_frames_per_burst(struct freedv *f, int framesperburst); +void freedv_passthrough_gain(struct freedv *f, float g); +int freedv_set_tuning_range(struct freedv *freedv, float val_fmin, + float val_fmax); + +// Get parameters +// ------------------------------------------------------------------------- + +struct MODEM_STATS; + +int freedv_get_version(void); +char *freedv_get_hash(void); +int freedv_get_mode(struct freedv *freedv); +void freedv_get_modem_stats(struct freedv *freedv, int *sync, float *snr_est); +void freedv_get_modem_extended_stats(struct freedv *freedv, + struct MODEM_STATS *stats); +int freedv_get_test_frames(struct freedv *freedv); + +int freedv_get_speech_sample_rate(struct freedv *freedv); +int freedv_get_n_speech_samples(struct freedv *freedv); +int freedv_get_n_max_speech_samples(struct freedv *freedv); + +int freedv_get_modem_sample_rate(struct freedv *freedv); +int freedv_get_modem_symbol_rate(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_n_tx_modem_samples(struct freedv *freedv); +int freedv_get_n_tx_preamble_modem_samples(struct freedv *freedv); +int freedv_get_n_tx_postamble_modem_samples(struct freedv *freedv); + +// bit error rate stats +int freedv_get_total_bits(struct freedv *freedv); +int freedv_get_total_bit_errors(struct freedv *freedv); +int freedv_get_total_bits_coded(struct freedv *freedv); +int freedv_get_total_bit_errors_coded(struct freedv *freedv); +int freedv_get_total_packets(struct freedv *freedv); +int freedv_get_total_packet_errors(struct freedv *freedv); + +int freedv_get_rx_status(struct freedv *freedv); +void freedv_get_fsk_S_and_N(struct freedv *freedv, float *S, float *N); + +int freedv_get_sync(struct freedv *freedv); +int freedv_get_sync_interleaver(struct freedv *freedv); + +// access to speech codec states +struct FSK *freedv_get_fsk(struct freedv *f); +struct CODEC2 *freedv_get_codec2(struct freedv *freedv); + +int freedv_get_bits_per_codec_frame(struct freedv *freedv); +int freedv_get_bits_per_modem_frame(struct freedv *freedv); +int freedv_get_sz_error_pattern(struct freedv *freedv); +int freedv_get_protocol_bits(struct freedv *freedv); + + + + + + + +// #define MODEM_STATS_NC_MAX 50 +// #define MODEM_STATS_NR_MAX 320 +// #define MODEM_STATS_ET_MAX 8 +// #define MODEM_STATS_EYE_IND_MAX 160 +// #define MODEM_STATS_NSPEC 512 +// #define MODEM_STATS_MAX_F_HZ 4000 +// #define MODEM_STATS_MAX_F_EST 4 + +// struct MODEM_STATS { +// int Nc; +// float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ +// COMP rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX + 1]; +// /* latest received symbols, for scatter plot */ +// int nr; /* number of rows in rx_symbols */ +// int sync; /* demod sync state */ +// float foff; /* estimated freq offset in Hz */ +// float rx_timing; /* estimated optimum timing offset in samples */ +// float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ +// float sync_metric; /* number between 0 and 1 indicating quality of sync */ +// int pre, post; /* preamble/postamble det counters for burst data */ +// int uw_fails; /* Failed to detect Unique word (burst data) */ + +// /* FSK eye diagram traces */ +// /* Eye diagram plot -- first dim is trace number, second is the trace idx */ +// float rx_eye[MODEM_STATS_ET_MAX][MODEM_STATS_EYE_IND_MAX]; +// int neyetr; /* How many eye traces are plotted */ +// int neyesamp; /* How many samples in the eye diagram */ + +// /* optional for FSK modems - est tone freqs */ + +// float f_est[MODEM_STATS_MAX_F_EST]; + +// /* Buf for FFT/waterfall */ + +// float fft_buf[2 * MODEM_STATS_NSPEC]; +// void *fft_cfg; +// }; + +// void modem_stats_open(struct MODEM_STATS *f); +// void modem_stats_close(struct MODEM_STATS *f); +// void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], +// COMP rx_fdm[], int nin); + +""" +) # set_source() gives the name of the python extension module to # produce, and some C source code as a string. This C code needs @@ -12,11 +307,10 @@ ffibuilder.cdef(open("freedv.h").read()) ffibuilder.set_source("_freedv_cffi", """ #include "freedv_api.h" // the C header of the library - #include "modem_stats.h" // the C header of the library """, libraries=['codec2'], - include_dirs = [ "/Users/mwheeler/src/codec2/src/"], - library_dirs = ["/Users/mwheeler/src/codec2/build_linux/src/"] + include_dirs = [ "/usr/include/codec2/", "/usr/local/include/codec2/", "/opt/homebrew/include/codec2/"], + library_dirs = ["/lib", "/usr/lib", "/usr/local/lib/", "/opt/homebrew/lib/"] ) # library name, for the linker if __name__ == "__main__": diff --git a/freedvtnc2/modem.py b/freedvtnc2/modem.py index b59972c..7898bcd 100644 --- a/freedvtnc2/modem.py +++ b/freedvtnc2/modem.py @@ -1,4 +1,4 @@ -from ._freedv_cffi import ffi, lib +from _freedv_cffi import ffi, lib from typing import Callable from dataclasses import dataclass diff --git a/freedvtnc2/requirements.txt b/freedvtnc2/requirements.txt deleted file mode 100644 index 3a55cf3..0000000 --- a/freedvtnc2/requirements.txt +++ /dev/null @@ -1,83 +0,0 @@ -cffi==1.16.0 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \ - --hash=sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a \ - --hash=sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417 \ - --hash=sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab \ - --hash=sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520 \ - --hash=sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36 \ - --hash=sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743 \ - --hash=sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8 \ - --hash=sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed \ - --hash=sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684 \ - --hash=sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56 \ - --hash=sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324 \ - --hash=sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d \ - --hash=sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235 \ - --hash=sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e \ - --hash=sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088 \ - --hash=sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000 \ - --hash=sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7 \ - --hash=sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e \ - --hash=sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673 \ - --hash=sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c \ - --hash=sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe \ - --hash=sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2 \ - --hash=sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098 \ - --hash=sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8 \ - --hash=sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a \ - --hash=sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0 \ - --hash=sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b \ - --hash=sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896 \ - --hash=sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e \ - --hash=sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9 \ - --hash=sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2 \ - --hash=sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b \ - --hash=sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6 \ - --hash=sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404 \ - --hash=sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f \ - --hash=sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0 \ - --hash=sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4 \ - --hash=sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc \ - --hash=sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936 \ - --hash=sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba \ - --hash=sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872 \ - --hash=sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb \ - --hash=sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614 \ - --hash=sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1 \ - --hash=sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d \ - --hash=sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969 \ - --hash=sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b \ - --hash=sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4 \ - --hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \ - --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ - --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 -configargparse==1.7 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:d249da6591465c6c26df64a9f73d2536e743be2f244eb3ebe61114af2f94f86b \ - --hash=sha256:e7067471884de5478c58a511e529f0f9bd1c66bfef1dea90935438d6c23306d1 -kissfix==7.0.11 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:6d17a27c152a06be0329c701c2f32e1f5bdbc2c1a8361ae1af4c92e4d406baa8 \ - --hash=sha256:aa2a90d19549eba1ad08adb83cca7b9d147ec805918c208cfbb85dc834e2eeb8 -pyaudio==0.2.14 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:009f357ee5aa6bc8eb19d69921cd30e98c42cddd34210615d592a71d09c4bd57 \ - --hash=sha256:126065b5e82a1c03ba16e7c0404d8f54e17368836e7d2d92427358ad44fefe61 \ - --hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \ - --hash=sha256:2a166fc88d435a2779810dd2678354adc33499e9d4d7f937f28b20cc55893e83 \ - --hash=sha256:2dac0d6d675fe7e181ba88f2de88d321059b69abd52e3f4934a8878e03a7a074 \ - --hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \ - --hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \ - --hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \ - --hash=sha256:858caf35b05c26d8fc62f1efa2e8f53d5fa1a01164842bd622f70ddc41f55000 \ - --hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903 \ - --hash=sha256:f745109634a7c19fa4d6b8b7d6967c3123d988c9ade0cd35d4295ee1acdb53e9 -pycparser==2.21 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ - --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 -pydub==0.25.1 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6 \ - --hash=sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f -pyserial==3.5 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb \ - --hash=sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 -tabulate==0.9.0 ; python_version >= "3.11" and python_version < "4.0" \ - --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ - --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f diff --git a/freedvtnc2/poetry.lock b/poetry.lock similarity index 90% rename from freedvtnc2/poetry.lock rename to poetry.lock index 151f5d6..a10a6be 100644 --- a/freedvtnc2/poetry.lock +++ b/poetry.lock @@ -166,6 +166,22 @@ files = [ [package.extras] cp2110 = ["hidapi"] +[[package]] +name = "setuptools" +version = "69.0.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "tabulate" version = "0.9.0" @@ -194,4 +210,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "04edbe4763c33088c098a98a234e973ec663bd489f67383785eacd5b74b242d3" +content-hash = "757c17914cf4ba280ceed0cddb4fd9d9cf419984a6a2310962c41c352c6b5bc6" diff --git a/freedvtnc2/pyproject.toml b/pyproject.toml similarity index 56% rename from freedvtnc2/pyproject.toml rename to pyproject.toml index f69ba2d..1de511e 100644 --- a/freedvtnc2/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,14 @@ [tool.poetry] name = "freedvtnc2" -version = "0.1.0" +version = "0.0.1" description = "" authors = ["xssfox "] readme = "README.md" +[tool.poetry.build] +script = "build_lib.py" +generate-setup-file = true + [tool.poetry.dependencies] python = "^3.11" cffi = "^1.16.0" @@ -14,8 +18,15 @@ tabulate = "^0.9.0" pydub = "^0.25.1" kissfix = "^7.0.11" prompt-toolkit = "^3.0.43" +setuptools = "^69.0.3" +[tool.poetry.group.dev.dependencies] +setuptools = "^69.0.3" + [build-system] -requires = ["poetry-core"] +requires = ["poetry-core","setuptools","cffi"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +freedvtnc2 = 'freedvtnc2:__main__.main' \ No newline at end of file diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..1f25cc2 Binary files /dev/null and b/screenshot.png differ