This commit is contained in:
Kurt Moraw 2020-11-01 01:21:52 +01:00
parent 9510186cb3
commit f72c347e30
436 changed files with 1642 additions and 1263 deletions

View File

@ -2,7 +2,7 @@
The purpose of this project is to transfer data (pictures...) via a 2,7kHz SSB channel on the narrow band transponder as fast as possible.
# this is work in progress
Version 0.1 is working on my linux PC and Odroid SBC.
Version 0.2 is working on my linux PC, Odroid SBC and Raspberry 4 (3B+)
# Prerequisites
* LINUX Desktop PC ... working

View File

@ -1,391 +0,0 @@
options:
parameters:
author: kurt
category: '[GRC Hier Blocks]'
cmake_opt: ''
comment: 'requires GNU Radio 3.8xxx
does NOT work with 3.7x'
copyright: ''
description: requires GNU Radio 3.8xxx
gen_cmake: 'Off'
gen_linking: dynamic
generate_options: no_gui
hier_block_src_path: '.:'
id: tx_8psk
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
run_options: run
sizing_mode: fixed
thread_safe_setters: ''
title: 8PSK Modem DJ0ABR
window_size: ''
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 8]
rotation: 0
state: enabled
blocks:
- name: mixf
id: variable
parameters:
comment: 'mid frequency
in the audio
spectrum. Set to get
lowest and highest
frequency within the
transceiver filter range.'
value: '1500'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [336, 12.0]
rotation: 0
state: enabled
- name: nfilts
id: variable
parameters:
comment: ''
value: '32'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [504, 12.0]
rotation: 0
state: enabled
- name: sps
id: variable
parameters:
comment: 'Samples/Symbol
fixed value,
do not change.
Used to adjust
bitrate vs. bandwidth'
value: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [944, 36.0]
rotation: 0
state: enabled
- name: analog_sig_source_x_0_0_0
id: analog_sig_source_x
parameters:
affinity: ''
alias: ''
amp: '1'
comment: 'the modulator output is in the baseband at 0 Hz.
Mix it with the required audio mid frequency.
cos and -sin are used to combine I and Q
into the final signal.'
freq: mixf
maxoutbuf: '0'
minoutbuf: '0'
offset: '0'
phase: '0'
samp_rate: samp_rate
type: complex
waveform: analog.GR_COS_WAVE
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [64, 484.0]
rotation: 0
state: enabled
- name: audio_sink_0_0
id: audio_sink
parameters:
affinity: ''
alias: ''
comment: 'send audio to
transceiver'
device_name: ''
num_inputs: '1'
ok_to_block: 'True'
samp_rate: samp_rate
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [840, 420.0]
rotation: 0
state: enabled
- name: blocks_add_xx_0
id: blocks_add_xx
parameters:
affinity: ''
alias: ''
comment: 'generate the analog
output signal.'
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '2'
type: float
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [568, 344.0]
rotation: 0
state: true
- name: blocks_complex_to_float_1
id: blocks_complex_to_float
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [400, 344.0]
rotation: 0
state: enabled
- name: blocks_multiply_const_vxx_0
id: blocks_multiply_const_vxx
parameters:
affinity: ''
alias: ''
comment: 'reduce level for the
audio output, improves
linearity'
const: '0.05'
maxoutbuf: '0'
minoutbuf: '0'
type: float
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [680, 420.0]
rotation: 0
state: true
- name: blocks_multiply_xx_0_0
id: blocks_multiply_xx
parameters:
affinity: ''
alias: ''
comment: "mix I und Q \nto the mid \nfrequency\nspecified in\n\"mixf\""
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '2'
type: complex
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [288, 344.0]
rotation: 0
state: enabled
- name: blocks_udp_source_0
id: blocks_udp_source
parameters:
affinity: ''
alias: ''
comment: "receive an UDP data stream\nwith the bitrate of (see \ncomment samp_rate)\n\
The stream is buffered, \nso send some bytes ahead\nto prefill the buffer\n\
and avoid underrun"
eof: 'False'
ipaddr: 127.0.0.1
maxoutbuf: '0'
minoutbuf: '0'
port: '40134'
psize: '258'
type: byte
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [736, 164.0]
rotation: 180
state: true
- name: digital_constellation_modulator_0
id: digital_constellation_modulator
parameters:
affinity: ''
alias: ''
comment: 'This modulator expects "Packed Bytes"
which are 8 bits within one byte.
The UDP source block deliveres bytes,
so it fits perfectly.'
constellation: digital.constellation_8psk_natural().base()
differential: 'True'
excess_bw: '0.25'
log: 'False'
maxoutbuf: '0'
minoutbuf: '0'
samples_per_symbol: resamprate
verbose: 'False'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [272, 172.0]
rotation: 180
state: enabled
- name: qtgui_freq_sink_x_0
id: qtgui_freq_sink_x
parameters:
affinity: ''
alias: ''
alpha1: '1.0'
alpha10: '1.0'
alpha2: '1.0'
alpha3: '1.0'
alpha4: '1.0'
alpha5: '1.0'
alpha6: '1.0'
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
autoscale: 'False'
average: '0.1'
axislabels: 'True'
bw: samp_rate
color1: '"blue"'
color10: '"dark blue"'
color2: '"red"'
color3: '"green"'
color4: '"black"'
color5: '"cyan"'
color6: '"magenta"'
color7: '"yellow"'
color8: '"dark red"'
color9: '"dark green"'
comment: ''
ctrlpanel: 'False'
fc: '0'
fftsize: '1024'
freqhalf: 'False'
grid: 'True'
gui_hint: ''
label: Relative Gain
label1: ''
label10: ''''''
label2: ''''''
label3: ''''''
label4: ''''''
label5: ''''''
label6: ''''''
label7: ''''''
label8: ''''''
label9: ''''''
legend: 'True'
maxoutbuf: '0'
minoutbuf: '0'
name: '""'
nconnections: '1'
showports: 'False'
tr_chan: '0'
tr_level: '0.0'
tr_mode: qtgui.TRIG_MODE_FREE
tr_tag: '""'
type: float
units: dB
update_time: '0.10'
width1: '1'
width10: '1'
width2: '1'
width3: '1'
width4: '1'
width5: '1'
width6: '1'
width7: '1'
width8: '1'
width9: '1'
wintype: firdes.WIN_BLACKMAN_hARRIS
ymax: '10'
ymin: '-140'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [552, 552.0]
rotation: 0
state: disabled
- name: resamprate
id: parameter
parameters:
alias: ''
comment: ''
hide: none
label: resamprate
short_id: r
type: intx
value: '24'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [808, 12.0]
rotation: 0
state: true
- name: samp_rate
id: parameter
parameters:
alias: ''
comment: Audio Rate
hide: none
label: samp_rate
short_id: s
type: intx
value: '48000'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [696, 12.0]
rotation: 0
state: true
connections:
- [analog_sig_source_x_0_0_0, '0', blocks_multiply_xx_0_0, '1']
- [blocks_add_xx_0, '0', blocks_multiply_const_vxx_0, '0']
- [blocks_add_xx_0, '0', qtgui_freq_sink_x_0, '0']
- [blocks_complex_to_float_1, '0', blocks_add_xx_0, '0']
- [blocks_complex_to_float_1, '1', blocks_add_xx_0, '1']
- [blocks_multiply_const_vxx_0, '0', audio_sink_0_0, '0']
- [blocks_multiply_xx_0_0, '0', blocks_complex_to_float_1, '0']
- [blocks_udp_source_0, '0', digital_constellation_modulator_0, '0']
- [digital_constellation_modulator_0, '0', blocks_multiply_xx_0_0, '0']
metadata:
file_format: 1

View File

@ -1,383 +0,0 @@
options:
parameters:
author: DJ0ABR
category: '[GRC Hier Blocks]'
cmake_opt: ''
comment: 'requires GNU Radio 3.8xxx
does NOT work with 3.7x'
copyright: DJ0ABR
description: requires GNU Radio 3.8xxx
gen_cmake: 'On'
gen_linking: dynamic
generate_options: no_gui
hier_block_src_path: '.:'
id: qpsk_tx
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
run_options: run
sizing_mode: fixed
thread_safe_setters: ''
title: 'QPSK TX-Modem '
window_size: ''
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 8]
rotation: 0
state: enabled
blocks:
- name: mixf
id: variable
parameters:
comment: 'mid frequency
in the audio
spectrum. Set to get
lowest and highest
frequency within the
transceiver filter range.'
value: '1500'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [360, 12.0]
rotation: 0
state: enabled
- name: qpsk__constellation
id: variable_constellation_rect
parameters:
comment: 'alternative:
[0.707+0.707j, -0.707+0.707j, -0.707-0.707j, 0.707-0.707j]
does not make a difference'
const_points: '[1+1j, -1+1j, -1-1j, 1-1j]'
imag_sect: '2'
precision: '8'
real_sect: '2'
rot_sym: '4'
soft_dec_lut: None
sym_map: '[0, 1, 2, 3]'
w_imag_sect: '1'
w_real_sect: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 196.0]
rotation: 0
state: enabled
- name: analog_sig_source_x_0_0_0
id: analog_sig_source_x
parameters:
affinity: ''
alias: ''
amp: '1'
comment: 'the modulator output is in the baseband at 0 Hz.
Mix it with the required audio mid frequency.
cos and -sin are used to combine I and Q
into the final signal.'
freq: mixf
maxoutbuf: '0'
minoutbuf: '0'
offset: '0'
phase: '0'
samp_rate: samp_rate
type: complex
waveform: analog.GR_COS_WAVE
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [96, 476.0]
rotation: 0
state: enabled
- name: audio_sink_0_0
id: audio_sink
parameters:
affinity: ''
alias: ''
comment: 'send audio to
transceiver'
device_name: ''
num_inputs: '1'
ok_to_block: 'True'
samp_rate: samp_rate
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [928, 356.0]
rotation: 0
state: enabled
- name: blocks_add_xx_0
id: blocks_add_xx
parameters:
affinity: ''
alias: ''
comment: 'generate the analog
output signal: USB
(for LSB use substraction)'
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '2'
type: float
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [696, 376.0]
rotation: 0
state: true
- name: blocks_complex_to_float_1
id: blocks_complex_to_float
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [512, 376.0]
rotation: 0
state: enabled
- name: blocks_multiply_const_vxx_0
id: blocks_multiply_const_vxx
parameters:
affinity: ''
alias: ''
comment: 'reduce level for the
audio output, improves
linearity'
const: '0.05'
maxoutbuf: '0'
minoutbuf: '0'
type: float
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [784, 356.0]
rotation: 0
state: true
- name: blocks_multiply_xx_0_0
id: blocks_multiply_xx
parameters:
affinity: ''
alias: ''
comment: "mix I und Q \nto the mid \nfrequency\nspecified in\n\"mixf\""
maxoutbuf: '0'
minoutbuf: '0'
num_inputs: '2'
type: complex
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [400, 376.0]
rotation: 0
state: enabled
- name: blocks_udp_source_0
id: blocks_udp_source
parameters:
affinity: ''
alias: ''
comment: "receive an UDP data stream\nwith the bitrate of (see \ncomment samp_rate)\n\
The stream is buffered, \nso send some bytes ahead\nto prefill the buffer\n\
and avoid underrun"
eof: 'False'
ipaddr: 127.0.0.1
maxoutbuf: '0'
minoutbuf: '0'
port: '40134'
psize: '258'
type: byte
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [824, 148.0]
rotation: 180
state: enabled
- name: digital_constellation_modulator_0
id: digital_constellation_modulator
parameters:
affinity: ''
alias: ''
comment: 'unpack bytes to bits
make symbols 2bits/sym
make constellation'
constellation: qpsk__constellation
differential: 'False'
excess_bw: '0.35'
log: 'False'
maxoutbuf: '0'
minoutbuf: '0'
samples_per_symbol: resamprate
verbose: 'False'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [392, 180.0]
rotation: 180
state: enabled
- name: qtgui_freq_sink_x_0
id: qtgui_freq_sink_x
parameters:
affinity: ''
alias: ''
alpha1: '1.0'
alpha10: '1.0'
alpha2: '1.0'
alpha3: '1.0'
alpha4: '1.0'
alpha5: '1.0'
alpha6: '1.0'
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
autoscale: 'False'
average: '0.1'
axislabels: 'True'
bw: samp_rate
color1: '"blue"'
color10: '"dark blue"'
color2: '"red"'
color3: '"green"'
color4: '"black"'
color5: '"cyan"'
color6: '"magenta"'
color7: '"yellow"'
color8: '"dark red"'
color9: '"dark green"'
comment: ''
ctrlpanel: 'False'
fc: '0'
fftsize: '1024'
freqhalf: 'False'
grid: 'True'
gui_hint: ''
label: Relative Gain
label1: ''
label10: ''''''
label2: ''''''
label3: ''''''
label4: ''''''
label5: ''''''
label6: ''''''
label7: ''''''
label8: ''''''
label9: ''''''
legend: 'True'
maxoutbuf: '0'
minoutbuf: '0'
name: '""'
nconnections: '1'
showports: 'False'
tr_chan: '0'
tr_level: '0.0'
tr_mode: qtgui.TRIG_MODE_FREE
tr_tag: '""'
type: float
units: dB
update_time: '0.10'
width1: '1'
width10: '1'
width2: '1'
width3: '1'
width4: '1'
width5: '1'
width6: '1'
width7: '1'
width8: '1'
width9: '1'
wintype: firdes.WIN_BLACKMAN_hARRIS
ymax: '10'
ymin: '-140'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [880, 576.0]
rotation: 0
state: disabled
- name: resamprate
id: parameter
parameters:
alias: ''
comment: ''
hide: none
label: resamprate
short_id: r
type: intx
value: '20'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [776, 12.0]
rotation: 0
state: true
- name: samp_rate
id: parameter
parameters:
alias: ''
comment: Audio Rate
hide: none
label: samp_rate
short_id: s
type: intx
value: '44100'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [208, 12.0]
rotation: 0
state: true
connections:
- [analog_sig_source_x_0_0_0, '0', blocks_multiply_xx_0_0, '1']
- [blocks_add_xx_0, '0', blocks_multiply_const_vxx_0, '0']
- [blocks_add_xx_0, '0', qtgui_freq_sink_x_0, '0']
- [blocks_complex_to_float_1, '0', blocks_add_xx_0, '0']
- [blocks_complex_to_float_1, '1', blocks_add_xx_0, '1']
- [blocks_multiply_const_vxx_0, '0', audio_sink_0_0, '0']
- [blocks_multiply_xx_0_0, '0', blocks_complex_to_float_1, '0']
- [blocks_udp_source_0, '0', digital_constellation_modulator_0, '0']
- [digital_constellation_modulator_0, '0', blocks_multiply_xx_0_0, '0']
metadata:
file_format: 1

View File

@ -1,8 +1,11 @@
# Makefile for qo100modem
# =======================
CFLAGS=-O3 -Wall
LDLIBS= -L. -lpthread -lfftw3 -lm -lzip
LDLIBS= -L. -lpthread -lfftw3 -lm -lzip -lfftw3_threads -lsndfile -lasound -lbass -lliquid
CC=c++
PROGNAME=qo100modem
OBJ=qo100modem.o main_helper.o udp.o frame_packer.o scrambler.o crc16.o fec.o fft.o constellation.o arraysend.o
OBJ=qo100modem.o main_helper.o udp.o frame_packer.o scrambler.o crc16.o fec.o fft.o constellation.o arraysend.o audio.o liquid_if.o
all: qo100modem

View File

@ -120,7 +120,12 @@ void doArraySend()
{
// send first frame
printf("Start Array Send %d\n",getSending());
toGR_Preamble();
// preamble
int numframespreamble = 3* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1;
for(int i=0; i<numframespreamble; i++)
toGR_sendData(TXarray, txtype, filestat);
if(txlen <= PAYLOADLEN)
{
// we just need to send one frame

245
modem/audio.c Normal file
View File

@ -0,0 +1,245 @@
/*
* High Speed modem to transfer data in a 2,7kHz SSB channel
* =========================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* audio.c ... functions to handle audio in/out via a soundcard
* uses the "BASS" library
*
* captures samples from the sound card.
* Samples are 32-bit floats in a range of -1 to +1
* get these samples from the thread safe fifo: cap_read_fifo(&floatvariable)
*
* plays samples to the sound card
* Samples are 32-bit floats in a range of -1 to +1
* play the samples by calling the thread save function: pb_write_fifo(floatsample)
*
*/
#include "qo100modem.h"
//BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user);
DWORD CALLBACK WriteStream(HSTREAM handle, float *buffer, DWORD length, void *user);
int pb_read_fifo(float *data, int elements);
void close_audio();
#define CHANNELS 1 // no of channels used
HRECORD rchan = 0; // recording channel
BASS_INFO info;
HSTREAM stream = 0;
int init_audio()
{
close_audio();
printf("init audio, caprate:%d\n",caprate);
// check the correct BASS was loaded
if (HIWORD(BASS_GetVersion()) != BASSVERSION)
{
printf("An incorrect version of BASS was loaded\n");
return -1;
}
/*
// initalize default recording device
if (!BASS_RecordInit(-1))
{
printf("Can't initialize recording device\n");
return -1;
}
*/
// initialize default output device
if (!BASS_Init(-1, caprate, 0, NULL, NULL))
{
printf("Can't initialize output device\n");
return -1;
}
/*
// set capture callback
rchan = BASS_RecordStart(caprate, CHANNELS, BASS_SAMPLE_FLOAT, RecordingCallback, 0);
if (!rchan) {
printf("Can't start capturing\n");
return -1;
}
*/
// set play callback
BASS_GetInfo(&info);
stream = BASS_StreamCreate(info.freq, CHANNELS, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream, 0); // sample: 32 bit float
BASS_ChannelSetAttribute(stream, BASS_ATTRIB_BUFFER, 0); // no buffering for minimum latency
BASS_ChannelPlay(stream, FALSE); // start it
return 0;
}
void close_audio()
{
if(stream != 0)
{
//BASS_RecordFree();
int r = BASS_Free();
if(!r)
printf("Bass_free error: %d\n", BASS_ErrorGetCode());
stream = 0;
}
}
/*
// capture callback
// length: bytes. short=2byte, 2channels, so it requests samples*4
BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user)
{
//printf("captured %ld samples\n",length/sizeof(float));
float *fbuffer = (float *)buffer;
//printf("w:%ld ",length/sizeof(float));
for(int i=0; i<(length/sizeof(float)); i+=CHANNELS)
{
//printf("%f\n",fbuffer[i]);
cap_write_fifo(fbuffer[i]);
}
return TRUE; // continue recording
}
*/
// play callback
// length: bytes. float=4byte, 2channels, so it requests samples*8
DWORD CALLBACK WriteStream(HSTREAM handle, float *buffer, DWORD length, void *user)
{
int ret = pb_read_fifo(buffer,length/sizeof(float));
if(ret == 0)
{
// fifo empty, send 00
memset(buffer,0,length);
}
return length;
}
// ================ thread safe fifo for audio callback routines ===============
pthread_mutex_t cap_crit_sec;
pthread_mutex_t pb_crit_sec;
#define CAP_LOCK pthread_mutex_lock(&cap_crit_sec)
#define CAP_UNLOCK pthread_mutex_unlock(&cap_crit_sec)
#define PB_LOCK pthread_mutex_lock(&pb_crit_sec)
#define PB_UNLOCK pthread_mutex_unlock(&pb_crit_sec)
#define AUDIO_BUFFERMAXTIME 2 // fifo can buffer this time in [s]
#define AUDIO_PLAYBACK_BUFLEN (48000 * 10) // space for 10 seconds of samples
/*#define AUDIO_CAPTURE_BUFLEN (48000*CHANNELS*AUDIO_BUFFERMAXTIME*UPSAMPLING)
int cap_wridx=0;
int cap_rdidx=0;
float cap_buffer[AUDIO_CAPTURE_BUFLEN];
*/
int pb_wridx=0;
int pb_rdidx=0;
float pb_buffer[AUDIO_PLAYBACK_BUFLEN];
/*
// write one sample into the fifo
// overwrite old data if the fifo is full
void cap_write_fifo(float sample)
{
CAP_LOCK;
cap_buffer[cap_wridx] = sample;
if(++cap_wridx >= AUDIO_CAPTURE_BUFLEN) cap_wridx = 0;
CAP_UNLOCK;
}
int cap_read_fifo(float *data)
{
CAP_LOCK;
if (cap_rdidx == cap_wridx)
{
// Fifo empty, no data available
CAP_UNLOCK;
return 0;
}
*data = cap_buffer[cap_rdidx];
if(++cap_rdidx >= AUDIO_CAPTURE_BUFLEN) cap_rdidx = 0;
CAP_UNLOCK;
return 1;
}
*/
void pb_write_fifo(float sample)
{
PB_LOCK;
// check if there is free space in fifo
if(pb_fifo_freespace(1) == 0)
{
PB_UNLOCK;
printf("************* pb fifo full\n");
return;
}
pb_buffer[pb_wridx] = sample;
if(++pb_wridx >= AUDIO_PLAYBACK_BUFLEN) pb_wridx = 0;
PB_UNLOCK;
//printf("write: pbw:%d pbr:%d\n",pb_wridx,pb_rdidx);
}
int pb_fifo_freespace(int nolock)
{
int freebuf = 0;
if(nolock == 0) PB_LOCK;
/*freebuf = AUDIO_PLAYBACK_BUFLEN - ((pb_wridx+AUDIO_PLAYBACK_BUFLEN+1 - pb_rdidx)%AUDIO_PLAYBACK_BUFLEN);
freebuf %= AUDIO_PLAYBACK_BUFLEN;*/
int elemInFifo = (pb_wridx + AUDIO_PLAYBACK_BUFLEN - pb_rdidx) % AUDIO_PLAYBACK_BUFLEN;
freebuf = AUDIO_PLAYBACK_BUFLEN - elemInFifo;
if(nolock == 0) PB_UNLOCK;
//printf("fifolen:%d check: pbw:%d pbr:%d freebuf:%d\n",AUDIO_PLAYBACK_BUFLEN,pb_wridx,pb_rdidx,freebuf);
return freebuf;
}
// read elements floats from fifo or return 0 if not enough floats are available
int pb_read_fifo(float *data, int elements)
{
//printf("pb read fifo: %d\n",elements);
PB_LOCK;
int e = AUDIO_PLAYBACK_BUFLEN - pb_fifo_freespace(1);
//if (pb_rdidx == pb_wridx)
if(e < elements)
{
// Fifo empty, no data available
PB_UNLOCK;
//printf("pb fifo empty, need:%d have:%d size:%d\n",elements,e,AUDIO_PLAYBACK_BUFLEN);
return 0;
}
for(int i=0; i<elements; i++)
{
data[i] = pb_buffer[pb_rdidx];
if(++pb_rdidx >= AUDIO_PLAYBACK_BUFLEN) pb_rdidx = 0;
}
//printf("read %d floats\n",elements);
PB_UNLOCK;
return 1;
}

1160
modem/bass.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
/*
* High Speed modem to transfer data in a 2,7kHz SSB channel
* =========================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "qo100modem.h"
#include "liquid.h"
fec fecobjTX;
fec fecobjRX;
fec_scheme fs = LIQUID_FEC_SECDED3932; // error-correcting scheme
uint8_t encoded_message[UdpBlocklen];
uint8_t decoded_message[PayloadLen+framenumlen+CRClen];
uint8_t *cfec_Reconstruct(uint8_t *darr)
{
memset(decoded_message,0,(PayloadLen+framenumlen+CRClen));
fec_decode(fecobjRX, (PayloadLen+framenumlen+CRClen), darr, decoded_message);
return decoded_message;
}
uint8_t *GetFEC(uint8_t *txblock, int len)
{
if(len != (PayloadLen+framenumlen+CRClen))
{
printf("wrong FEC encode length, len:%d Payloadlen:%d\n",len,PayloadLen);
exit(0);
}
fec_encode(fecobjTX, len, txblock, encoded_message);
return encoded_message;
}
void initFEC()
{
int n_enc = fec_get_enc_msg_length(fs,(PayloadLen+framenumlen+CRClen));
if(n_enc != UdpBlocklen)
{
printf("wrong FEC init length\n");
exit(0);
}
fecobjTX = fec_create(fs,NULL);
fecobjRX = fec_create(fs,NULL);
}

View File

@ -138,7 +138,7 @@ uint8_t *Pack(uint8_t *payload, int type, int status, int *plen)
}
}*/
#define MAXHEADERRS 0
#define MAXHEADERRS 3
/*
* Header erros will not cause any data errors because the CRC will filter out
@ -298,7 +298,7 @@ uint8_t *getPayload(uint8_t *rxb)
int framenumrx = (frame.status & 0xc0)>>6; // frame counter MSB
framenumrx <<= 8;
framenumrx += frame.counter_LSB; // frame counter LSB
//printf("Frame no.: %d\n",framenumrx);
if (lastframenum != framenumrx) rx_status |= 4;
lastframenum = framenumrx;
if (++lastframenum >= 1024) lastframenum = 0; // 1024 = 2^10 (10 bit frame number)
@ -317,6 +317,8 @@ uint8_t *getPayload(uint8_t *rxb)
payload[8] = 0;
payload[9] = 0;
//printf("Frame no.: %d, type:%d, minfo:%d\n",framenumrx,payload[0],payload[3]);
memcpy(payload+10,frame.payload,PAYLOADLEN);
return payload;

9
modem/liquid-dsp-install Executable file
View File

@ -0,0 +1,9 @@
sudo apt install git autoconf libsndfile-dev libasound-dev
git clone git://github.com/jgaeddert/liquid-dsp.git
cd liquid-dsp
./bootstrap.sh
./configure
make -j 8
sudo make install
sudo ldconfig

171
modem/liquid_if.c Normal file
View File

@ -0,0 +1,171 @@
/*
* High Speed modem to transfer data in a 2,7kHz SSB channel
* =========================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* liquid_dsp_interface.c ... functions using liquid-dsp
*
* liquid-dsp must be previously installed by running ./liquid-dsp-install (under linux)
*
*/
#include "qo100modem.h"
void modulator(uint8_t sym_in);
void close_dsp();
// modem objects
modulation_scheme ms = LIQUID_MODEM_QPSK;
modem mod = NULL;
// NCOs for mixing baseband <-> 1500 Hz
#define FREQUENCY 1500
int type = LIQUID_NCO; // nco type
nco_crcf upnco = NULL;
// TX-Interpolator Filter Parameters
// 44100 input rate for 2205 Sym/s = 20
// change for other rates
firinterp_crcf TX_interpolator = NULL;
unsigned int k_SampPerSymb = 20; // 44100 / (4410/2)
unsigned int m_filterDelay_Symbols = 15; // not too short for good filter
float beta_excessBW = 0.3f; // filter excess bandwidth factor
float tau_FracSymbOffset = -0.2f; // fractional symbol offset
int init_dsp()
{
close_dsp();
printf("create DSP\n");
k_SampPerSymb = txinterpolfactor;
if(bitsPerSymbol == 2)
ms = LIQUID_MODEM_QPSK;
else
ms = LIQUID_MODEM_DPSK8;
// create modulator
mod = modem_create(ms);
// create NCO for upmixing to 1500 Hz
double RADIANS_PER_SAMPLE = ((2.0*M_PI*(double)FREQUENCY)/(float)caprate);
upnco = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_phase(upnco, 0.0f);
nco_crcf_set_frequency(upnco, RADIANS_PER_SAMPLE);
// TX: Interpolator Filter
// compute delay
while (tau_FracSymbOffset < 0) tau_FracSymbOffset += 1.0f; // ensure positive tau
float g = k_SampPerSymb*tau_FracSymbOffset; // number of samples offset
int ds=floorf(g); // additional symbol delay
float dt = (g - (float)ds); // fractional sample offset
// force dt to be in [0.5,0.5]
if (dt > 0.5f)
{
dt -= 1.0f;
ds++;
}
// calculate filter coeffs
unsigned int h_len_NumFilterCoeefs = 2 * k_SampPerSymb * m_filterDelay_Symbols + 1;
float h[h_len_NumFilterCoeefs];
liquid_firdes_prototype( LIQUID_FIRFILT_RRC,
k_SampPerSymb,
m_filterDelay_Symbols,
beta_excessBW,
dt,
h);
// create the filter
TX_interpolator = firinterp_crcf_create(k_SampPerSymb,h,h_len_NumFilterCoeefs);
printf("DSP created\n");
return 1;
}
void close_dsp()
{
if(mod != NULL) modem_destroy(mod);
if(upnco != NULL) nco_crcf_destroy(upnco);
if(TX_interpolator != NULL) firinterp_crcf_destroy(TX_interpolator);
mod = NULL;
upnco = NULL;
TX_interpolator = NULL;
}
// d ... symbols to send
// len ... number of symbols in d
void sendToModulator(uint8_t *d, int len)
{
//printf("sendToModulator %d bytes\n",len);
int symanz = len * 8 / bitsPerSymbol;
uint8_t syms[symanz];
if(bitsPerSymbol == 2)
convertBytesToSyms_QPSK(d, syms, len);
else
convertBytesToSyms_8PSK(d, syms, len);
for(int i=0; i<symanz; i++)
{
// remove gray code
// this adds gray code, liquid adds it again which removes it
syms[i] ^= (syms[i]>>1);
modulator(syms[i]);
}
}
// call for every symbol
// modulates, filters and upmixes symbols and send it to soundcard
void modulator(uint8_t sym_in)
{
liquid_float_complex sample;
modem_modulate(mod, sym_in, &sample);
//printf("TX ================= sample: %f + i%f\n", sample.real, sample.imag);
// interpolate by k_SampPerSymb
liquid_float_complex y[k_SampPerSymb];
firinterp_crcf_execute(TX_interpolator, sample, y);
for(unsigned int i=0; i<k_SampPerSymb; i++)
{
// move sample to 1,5kHz carrier
nco_crcf_step(upnco);
float minus_sine = -nco_crcf_sin(upnco);
float cosinus = nco_crcf_cos(upnco);
float re = y[i].real * cosinus;
float im = y[i].imag * minus_sine;
float usb = re + im;
// value is -1 .. +1
// adapt speed to soundcard samplerate
int fs;
while(1)
{
fs = pb_fifo_freespace(0);
if(fs) break;
usleep(10000);
}
pb_write_fifo(usb * 0.2); // reduce volume and send to soundcard
}
}

View File

@ -37,6 +37,7 @@ int isRunning(char *prgname)
return 0;
}
// signal handler
void sighandler(int signum)
{

View File

@ -59,7 +59,6 @@ int speedmode = 4;
int bitsPerSymbol = 2; // QPSK=2, 8PSK=3
int constellationSize = 4; // QPSK=4, 8PSK=8
char localIP[]={"127.0.0.1"};
char ownfilename[]={"qo100modem"};
char myIP[20];
@ -68,6 +67,9 @@ int fixappIP = 0;
int restart_modems = 0;
int doNotLoadModems = 0;
int caprate = 44100;
int txinterpolfactor = 20;
int main(int argc, char *argv[])
{
int opt = 0;
@ -99,7 +101,7 @@ char *modemip = NULL;
}
}
if(isRunning(ownfilename) == 1)
if(doNotLoadModems == 0 && isRunning(ownfilename) == 1)
exit(0);
install_signal_handler();
@ -107,10 +109,11 @@ char *modemip = NULL;
init_packer();
initFEC();
init_fft();
init_audio();
// start udp RX to listen for broadcast search message from Application
UdpRxInit(&BC_sock_AppToModem, UdpBCport_AppToModem, &bc_rxdata, &keeprunning);
// start udp RX for data from application
UdpRxInit(&DATA_sock_AppToModem, UdpDataPort_AppToModem, &appdata_rxdata, &keeprunning);
@ -169,7 +172,6 @@ SPEEDRATE sr[9] = {
void startModem()
{
char stx[512];
char srx[512];
if(speedmode >= 0 && speedmode <=5)
@ -183,30 +185,24 @@ char srx[512];
constellationSize = (1<<bitsPerSymbol); // QPSK=4, 8PSK=8
}
caprate = sr[speedmode].audio;
txinterpolfactor = sr[speedmode].tx;
if(doNotLoadModems == 1) return;
if(speedmode >= 0 && speedmode <=5)
{
sprintf(stx,"python3 qpsk_tx.py -r %d -s %d &",sr[speedmode].tx,sr[speedmode].audio);
sprintf(srx,"python3 qpsk_rx.py -r %d -s %d &",sr[speedmode].rx,sr[speedmode].audio);
}
else if(speedmode >= 6 && speedmode <=7)
{
sprintf(stx,"python3 tx_8psk.py -r %d -s %d &",sr[speedmode].tx,sr[speedmode].audio);
sprintf(srx,"python3 rx_8psk.py -r %d -s %d &",sr[speedmode].rx,sr[speedmode].audio);
}
else
{
printf("wrong modem number\n");
exit(0);
}
// the TX modem needs the local IP address as a parameter -i ip
if(run_console_program(stx) == -1)
{
printf("cannot start TX modem\n");
exit(0);
}
// int TX audio and modulator
init_dsp();
init_audio();
// the RX modem needs the app's IP address as a parameter -i ip
if(run_console_program(srx) == -1)
@ -354,13 +350,22 @@ void appdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock)
int r = system("sudo shutdown now");
exit(r);
}
if(getSending() == 1) return; // already sending (Array sending)
if(minfo == 0)
{
toGR_Preamble(); // first transmission of a data block, send preamble
toGR_sendData(pdata+2, type, minfo);
// this is the first frame of a larger file
// send it multiple times, like a preamble, to give the
// receiver some time for synchronisation
// duration: 3 seconds
// caprate: samples/s. This are symbols: caprate/txinterpolfactor
// and bits: symbols * bitsPerSymbol
// and bytes/second: bits/8 = (caprate/txinterpolfactor) * bitsPerSymbol / 8
// one frame has 258 bytes, so we need for 5s: 5* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1 frames
int numframespreamble = 3* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1;
for(int i=0; i<numframespreamble; i++)
toGR_sendData(pdata+2, type, minfo);
}
else if((len-2) < PAYLOADLEN)
{
@ -376,37 +381,15 @@ void appdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock)
}
}
void toGR_Preamble()
{
srand(123);
// send random data, rx can sync
uint8_t data[UDPBLOCKLEN];
// 1byte 1,8ms (about 2ms)
int timeforframe = 2 * UDPBLOCKLEN; // 160 ms
int repeats = 8000 /timeforframe; // for 8000ms = 8s
for(int i=0; i<repeats; i++)
{
for(int j=0; j<UDPBLOCKLEN; j++)
data[j] = rand();
sendUDP(localIP,UdpDataPort_toGR,data,UDPBLOCKLEN);
usleep(300000);
}
}
void toGR_sendData(uint8_t *data, int type, int status)
{
int len = 0;
uint8_t *txdata = Pack(data,type,status,&len);
//printf("senddata %d\n",len);
//showbytestring((char *)"BERtx: ", txdata, len);
if(txdata != NULL)
{
sendUDP(localIP,UdpDataPort_toGR,txdata,len);
}
sendToModulator(txdata,len);
}
#define SPEEDMEAN 3
@ -469,7 +452,7 @@ void measure_speed(int len)
meansumbytes = 0;
}
// called by UDP RX thread for data from GR
// called by UDP RX thread for data from GnuRadio Receiver
void GRdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock)
{
// raw symbols

View File

@ -28,6 +28,8 @@
#include "frameformat.h"
#include "main_helper.h"
#include "udp.h"
#include "bass.h"
#include <liquid/liquid.h>
#define jpg_tempfilename "rxdata.jpg"
@ -45,7 +47,6 @@ int cfec_Reconstruct(uint8_t *darr, uint8_t *destination);
uint8_t *Pack(uint8_t *payload, int type, int status, int *plen);
void GetFEC(uint8_t *txblock, int len, uint8_t *destArray);
void initFEC();
void toGR_Preamble();
void toGR_sendData(uint8_t *data, int type, int status);
uint16_t *make_waterfall(uint8_t *pdata, int len, int *retlen);
void init_fft();
@ -62,12 +63,17 @@ void convertBytesToSyms_8PSK(uint8_t *bytes, uint8_t *syms, int bytenum);
void rotate8PSKsyms(uint8_t *src, uint8_t *dst, int len);
uint8_t * rotateBack8PSK(uint8_t *buf, int len, int rotations);
void setSending(uint8_t onoff);
void toGR_Preamble();
int getSending();
void doArraySend();
int arraySend(uint8_t *data, int length, uint8_t type, char *filename);
void shiftleft(uint8_t *data, int shiftnum, int len);
void showbytestring16(char *title, uint16_t *data, int anz);
int isTXRunning(char *prgname);
int pb_fifo_freespace(int nolock);
int init_audio();
void sendToModulator(uint8_t *d, int len);
void pb_write_fifo(float sample);
int init_dsp();
extern int keeprunning;
@ -76,7 +82,8 @@ extern int speed;
extern int speedmode;
extern int bitsPerSymbol;
extern int constellationSize;
extern int caprate;
extern int txinterpolfactor;
/*
* Constellation as produced by the GR Constellation Decoder:

View File

@ -42,8 +42,8 @@ class qpsk_rx(gr.top_block):
self.qpsk__constellation = qpsk__constellation = digital.constellation_rect([0.707+0.707j, -0.707+0.707j, -0.707-0.707j, 0.707-0.707j], [0, 1, 2, 3],
4, 2, 2, 1, 1).base()
self.qpsk__constellation.gen_soft_dec_lut(8)
self.outputsps = outputsps = 7
self.nfilts = nfilts = 32
self.outputsps = outputsps = 8
self.nfilts = nfilts = 15
self.mixf = mixf = 1500
##################################################

View File

@ -1,140 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: QPSK TX-Modem
# Author: DJ0ABR
# Copyright: DJ0ABR
# Description: requires GNU Radio 3.8xxx
# GNU Radio version: 3.8.2.0
from gnuradio import analog
from gnuradio import audio
from gnuradio import blocks
from gnuradio import digital
from gnuradio import gr
from gnuradio.filter import firdes
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
class qpsk_tx(gr.top_block):
def __init__(self, resamprate=20, samp_rate=44100):
gr.top_block.__init__(self, "QPSK TX-Modem ")
##################################################
# Parameters
##################################################
self.resamprate = resamprate
self.samp_rate = samp_rate
##################################################
# Variables
##################################################
self.qpsk__constellation = qpsk__constellation = digital.constellation_rect([1+1j, -1+1j, -1-1j, 1-1j], [0, 1, 2, 3],
4, 2, 2, 1, 1).base()
self.mixf = mixf = 1500
##################################################
# Blocks
##################################################
self.digital_constellation_modulator_0 = digital.generic_mod(
constellation=qpsk__constellation,
differential=False,
samples_per_symbol=resamprate,
pre_diff_code=True,
excess_bw=0.35,
verbose=False,
log=False)
self.blocks_udp_source_0 = blocks.udp_source(gr.sizeof_char*1, '127.0.0.1', 40134, 258, False)
self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1)
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_ff(0.05)
self.blocks_complex_to_float_1 = blocks.complex_to_float(1)
self.blocks_add_xx_0 = blocks.add_vff(1)
self.audio_sink_0_0 = audio.sink(samp_rate, '', True)
self.analog_sig_source_x_0_0_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, mixf, 1, 0, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0_0_0, 0), (self.blocks_multiply_xx_0_0, 1))
self.connect((self.blocks_add_xx_0, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.blocks_complex_to_float_1, 0), (self.blocks_add_xx_0, 0))
self.connect((self.blocks_complex_to_float_1, 1), (self.blocks_add_xx_0, 1))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.audio_sink_0_0, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.blocks_complex_to_float_1, 0))
self.connect((self.blocks_udp_source_0, 0), (self.digital_constellation_modulator_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.blocks_multiply_xx_0_0, 0))
def get_resamprate(self):
return self.resamprate
def set_resamprate(self, resamprate):
self.resamprate = resamprate
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.analog_sig_source_x_0_0_0.set_sampling_freq(self.samp_rate)
def get_qpsk__constellation(self):
return self.qpsk__constellation
def set_qpsk__constellation(self, qpsk__constellation):
self.qpsk__constellation = qpsk__constellation
def get_mixf(self):
return self.mixf
def set_mixf(self, mixf):
self.mixf = mixf
self.analog_sig_source_x_0_0_0.set_frequency(self.mixf)
def argument_parser():
description = 'requires GNU Radio 3.8xxx'
parser = ArgumentParser(description=description)
parser.add_argument(
"-r", "--resamprate", dest="resamprate", type=intx, default=20,
help="Set resamprate [default=%(default)r]")
parser.add_argument(
"-s", "--samp-rate", dest="samp_rate", type=intx, default=44100,
help="Set samp_rate [default=%(default)r]")
return parser
def main(top_block_cls=qpsk_tx, options=None):
if options is None:
options = argument_parser().parse_args()
tb = top_block_cls(resamprate=options.resamprate, samp_rate=options.samp_rate)
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
tb.wait()
if __name__ == '__main__':
main()

View File

@ -1,145 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: 8PSK Modem DJ0ABR
# Author: kurt
# Description: requires GNU Radio 3.8xxx
# GNU Radio version: 3.8.2.0
from gnuradio import analog
from gnuradio import audio
from gnuradio import blocks
from gnuradio import digital
from gnuradio import gr
from gnuradio.filter import firdes
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
class tx_8psk(gr.top_block):
def __init__(self, resamprate=24, samp_rate=48000):
gr.top_block.__init__(self, "8PSK Modem DJ0ABR")
##################################################
# Parameters
##################################################
self.resamprate = resamprate
self.samp_rate = samp_rate
##################################################
# Variables
##################################################
self.sps = sps = 1
self.nfilts = nfilts = 32
self.mixf = mixf = 1500
##################################################
# Blocks
##################################################
self.digital_constellation_modulator_0 = digital.generic_mod(
constellation=digital.constellation_8psk_natural().base(),
differential=True,
samples_per_symbol=resamprate,
pre_diff_code=True,
excess_bw=0.25,
verbose=False,
log=False)
self.blocks_udp_source_0 = blocks.udp_source(gr.sizeof_char*1, '127.0.0.1', 40134, 258, False)
self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1)
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_ff(0.05)
self.blocks_complex_to_float_1 = blocks.complex_to_float(1)
self.blocks_add_xx_0 = blocks.add_vff(1)
self.audio_sink_0_0 = audio.sink(samp_rate, '', True)
self.analog_sig_source_x_0_0_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, mixf, 1, 0, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0_0_0, 0), (self.blocks_multiply_xx_0_0, 1))
self.connect((self.blocks_add_xx_0, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.blocks_complex_to_float_1, 0), (self.blocks_add_xx_0, 0))
self.connect((self.blocks_complex_to_float_1, 1), (self.blocks_add_xx_0, 1))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.audio_sink_0_0, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.blocks_complex_to_float_1, 0))
self.connect((self.blocks_udp_source_0, 0), (self.digital_constellation_modulator_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.blocks_multiply_xx_0_0, 0))
def get_resamprate(self):
return self.resamprate
def set_resamprate(self, resamprate):
self.resamprate = resamprate
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.analog_sig_source_x_0_0_0.set_sampling_freq(self.samp_rate)
def get_sps(self):
return self.sps
def set_sps(self, sps):
self.sps = sps
def get_nfilts(self):
return self.nfilts
def set_nfilts(self, nfilts):
self.nfilts = nfilts
def get_mixf(self):
return self.mixf
def set_mixf(self, mixf):
self.mixf = mixf
self.analog_sig_source_x_0_0_0.set_frequency(self.mixf)
def argument_parser():
description = 'requires GNU Radio 3.8xxx'
parser = ArgumentParser(description=description)
parser.add_argument(
"-r", "--resamprate", dest="resamprate", type=intx, default=24,
help="Set resamprate [default=%(default)r]")
parser.add_argument(
"-s", "--samp-rate", dest="samp_rate", type=intx, default=48000,
help="Set samp_rate [default=%(default)r]")
return parser
def main(top_block_cls=tx_8psk, options=None):
if options is None:
options = argument_parser().parse_args()
tb = top_block_cls(resamprate=options.resamprate, samp_rate=options.samp_rate)
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
tb.wait()
if __name__ == '__main__':
main()

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
</configuration>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More