kopia lustrzana https://github.com/Hamlib/Hamlib
git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1430 7ae35d74-ebe9-4afe-98af-79ac388436b8Hamlib-1.1.4
rodzic
f1143f49c0
commit
27c7db9b4b
|
@ -3,7 +3,7 @@
|
||||||
* Hamlib GNUradio backend - main file
|
* Hamlib GNUradio backend - main file
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: gnuradio.cc,v 1.3 2003-02-09 23:02:26 fillods Exp $
|
* $Id: gnuradio.cc,v 1.4 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -41,13 +41,19 @@
|
||||||
|
|
||||||
#include <VrConnect.h>
|
#include <VrConnect.h>
|
||||||
#include <VrMultiTask.h>
|
#include <VrMultiTask.h>
|
||||||
/* SSB */
|
#include <GrFreqXlatingFIRfilterSCF.h>
|
||||||
#include <GrSSBMod.h>
|
#include <GrFreqXlatingFIRfilterCCF.h>
|
||||||
#include <GrHilbert.h>
|
#include <GrFIRfilterFSF.h>
|
||||||
/* FM */
|
#include <GrFIRfilterFFF.h>
|
||||||
#include <VrComplexFIRfilter.h>
|
#include <VrQuadratureDemod.h> /* FM */
|
||||||
#include <VrQuadratureDemod.h>
|
//#include <VrAmplitudeDemod.h> /* AM */
|
||||||
#include <VrRealFIRfilter.h>
|
/* SSB mod */
|
||||||
|
//#include <GrSSBMod.h>
|
||||||
|
//#include <GrHilbert.h>
|
||||||
|
|
||||||
|
#include <gr_firdes.h>
|
||||||
|
#include <gr_fir_builderF.h>
|
||||||
|
|
||||||
|
|
||||||
/* Chirp param's */
|
/* Chirp param's */
|
||||||
#define CARRIER_FREQ 1.070e6 // AM 1070
|
#define CARRIER_FREQ 1.070e6 // AM 1070
|
||||||
|
@ -71,12 +77,19 @@
|
||||||
#include "gr_priv.h" // struct gnuradio_priv_data
|
#include "gr_priv.h" // struct gnuradio_priv_data
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: fft scope, with ext_level to display them
|
||||||
|
*/
|
||||||
|
|
||||||
#define TOK_TUNER_MODEL TOKEN_BACKEND(1)
|
#define TOK_TUNER_MODEL TOKEN_BACKEND(1)
|
||||||
|
|
||||||
const struct confparams gnuradio_cfg_params[] = {
|
const struct confparams gnuradio_cfg_params[] = {
|
||||||
{ TOK_TUNER_MODEL, "tuner_model", "Tuner model", "Hamlib rig tuner model number",
|
{ TOK_TUNER_MODEL, "tuner_model", "Tuner model", "Hamlib rig tuner model number",
|
||||||
"1" /* RIG_MODEL_DUMMY */, RIG_CONF_NUMERIC, { /* .n = */ { 0, INT_MAX, 1 } }
|
"1" /* RIG_MODEL_DUMMY */, RIG_CONF_NUMERIC, { /* .n = */ { 0, INT_MAX, 1 } }
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
* TODO: IF_center_freq, input_rate, etc.
|
||||||
|
*/
|
||||||
{ RIG_CONF_END, NULL, }
|
{ RIG_CONF_END, NULL, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,7 +144,7 @@ int gr_init(RIG *rig)
|
||||||
priv->need_fixer = 0;
|
priv->need_fixer = 0;
|
||||||
|
|
||||||
for (i=0; i<NUM_CHAN; i++) {
|
for (i=0; i<NUM_CHAN; i++) {
|
||||||
init_chan(rig, RIG_CTRL_BAND(RIG_CTRL_MAIN,i), &priv->chans[i]);
|
init_chan(rig, RIG_VFO_N(i), &priv->chans[i]);
|
||||||
priv->chans[i].levels[rig_setting2idx(RIG_LEVEL_AF)].f = 1.0;
|
priv->chans[i].levels[rig_setting2idx(RIG_LEVEL_AF)].f = 1.0;
|
||||||
priv->chans[i].levels[rig_setting2idx(RIG_LEVEL_RF)].f = 1.0;
|
priv->chans[i].levels[rig_setting2idx(RIG_LEVEL_RF)].f = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -256,9 +269,11 @@ int gr_open(RIG *rig)
|
||||||
|
|
||||||
// --> short
|
// --> short
|
||||||
|
|
||||||
|
priv->source = new VrFileSource<short>(priv->input_rate, "/tmp/fm95_5_half.dat", true);
|
||||||
// Chirp
|
// Chirp
|
||||||
if (!priv->source)
|
if (!priv->source)
|
||||||
priv->source = new VrSigSource<IOTYPE>(priv->input_rate, VR_SIN_WAVE, CARRIER_FREQ, AMPLITUDE);
|
priv->source = new VrSigSource<IOTYPE>(priv->input_rate, VR_SIN_WAVE, CARRIER_FREQ, AMPLITUDE);
|
||||||
|
//new VrChirpSource<IOTYPE>(priv->input_rate, AMPLITUDE, 4);
|
||||||
/* VrFileSource (double sampling_freq, const char *file, bool repeat = false) */
|
/* VrFileSource (double sampling_freq, const char *file, bool repeat = false) */
|
||||||
//priv->source = new VrFileSource<short>(priv->input_rate, "microtune_source.sw", true);
|
//priv->source = new VrFileSource<short>(priv->input_rate, "microtune_source.sw", true);
|
||||||
|
|
||||||
|
@ -280,6 +295,9 @@ int gr_open(RIG *rig)
|
||||||
|
|
||||||
/* or set it to MODE_NONE? */
|
/* or set it to MODE_NONE? */
|
||||||
//gr_set_mode(rig, RIG_VFO_CURR, RIG_MODE_WFM, RIG_PASSBAND_NORMAL);
|
//gr_set_mode(rig, RIG_VFO_CURR, RIG_MODE_WFM, RIG_PASSBAND_NORMAL);
|
||||||
|
if (priv->tuner_model == RIG_MODEL_DUMMY) {
|
||||||
|
gr_set_freq(rig, RIG_VFO_CURR, priv->IF_center_freq);
|
||||||
|
}
|
||||||
|
|
||||||
priv->do_process = 1;
|
priv->do_process = 1;
|
||||||
|
|
||||||
|
@ -300,7 +318,7 @@ int gr_open(RIG *rig)
|
||||||
|
|
||||||
|
|
||||||
/* TODO: error checking of new */
|
/* TODO: error checking of new */
|
||||||
static int mc4020_open(RIG *rig)
|
int mc4020_open(RIG *rig)
|
||||||
{
|
{
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data*)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
@ -314,7 +332,7 @@ static int mc4020_open(RIG *rig)
|
||||||
/*
|
/*
|
||||||
* sound card source override
|
* sound card source override
|
||||||
*/
|
*/
|
||||||
static int graudio_open(RIG *rig)
|
int graudio_open(RIG *rig)
|
||||||
{
|
{
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data*)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
@ -396,6 +414,57 @@ static int vfo2chan_num(RIG *rig, vfo_t vfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tuner_freq is the display freq on tuner of the IF in digital domain
|
||||||
|
* freq is the desired freq
|
||||||
|
*/
|
||||||
|
static int update_freq(RIG *rig, unsigned chan_num, freq_t tuner_freq, freq_t freq)
|
||||||
|
{
|
||||||
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
|
struct mod_data *mod = &priv->mods[chan_num];
|
||||||
|
double freq_offset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case the tuner is not a real tuner
|
||||||
|
*/
|
||||||
|
if (priv->tuner_model == RIG_MODEL_DUMMY)
|
||||||
|
tuner_freq = priv->IF_center_freq;
|
||||||
|
|
||||||
|
freq_offset = (double) (freq - tuner_freq);
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: %lld %lld freq_offset=%g\n",
|
||||||
|
__FUNCTION__, tuner_freq, freq, freq_offset);
|
||||||
|
|
||||||
|
if (freq_offset == 0)
|
||||||
|
return RIG_OK; /* nothing to do */
|
||||||
|
|
||||||
|
/* TODO: change mode plumbing (don't forget locking!)
|
||||||
|
* workaround?: set_mode(NONE), set_mode(previous)
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&priv->mutex_process);
|
||||||
|
switch (chan->mode) {
|
||||||
|
case RIG_MODE_WFM:
|
||||||
|
case RIG_MODE_FM:
|
||||||
|
case RIG_MODE_USB:
|
||||||
|
/* not so sure about if setCenter_Freq is the Right thing to do(tm). */
|
||||||
|
mod->chan_filter->setCenterFreq(priv->IF_center_freq + freq_offset);
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* set_freq for SSB mod
|
||||||
|
* mod->ssb.shifter->set_freq(2*M_PI*freq_offset/(double)priv->input_rate);
|
||||||
|
*/
|
||||||
|
case RIG_MODE_NONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_WARN, "%s: mode %s unimplemented!\n",
|
||||||
|
__FUNCTION__, strrmode(chan->mode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&priv->mutex_process);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rig_set_freq is a good candidate for the GNUradio GUI setFrequency callback?
|
* rig_set_freq is a good candidate for the GNUradio GUI setFrequency callback?
|
||||||
*/
|
*/
|
||||||
|
@ -404,14 +473,12 @@ int gr_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
int chan_num = vfo2chan_num(rig, vfo);
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
channel_t *chan = &priv->chans[chan_num];
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
union mod_data *mod = &priv->mods[chan_num];
|
|
||||||
freq_t tuner_freq;
|
freq_t tuner_freq;
|
||||||
double freq_offset;
|
int ret, i;
|
||||||
int ret;
|
|
||||||
char fstr[20];
|
char fstr[20];
|
||||||
|
|
||||||
sprintf_freq(fstr, freq);
|
sprintf_freq(fstr, freq);
|
||||||
rig_debug(RIG_DEBUG_VERBOSE,"%s called: %s %s\n",
|
rig_debug(RIG_DEBUG_TRACE,"%s called: %s %s\n",
|
||||||
__FUNCTION__, strvfo(vfo), fstr);
|
__FUNCTION__, strvfo(vfo), fstr);
|
||||||
|
|
||||||
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
||||||
|
@ -422,56 +489,35 @@ int gr_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
* TODO: with several VFO's, center the IF inbetween if out of window
|
* TODO: with several VFO's, center the IF inbetween if out of window
|
||||||
*/
|
*/
|
||||||
if (freq < tuner_freq ||
|
if (freq < tuner_freq ||
|
||||||
freq /* + mode_width */ > tuner_freq+priv->input_rate/2) {
|
freq /* + mode_width */ > tuner_freq+GR_MAX_FREQUENCY(priv)) {
|
||||||
|
/*
|
||||||
/* do not set tuner to freq, but center it */
|
* do not set tuner to freq, but center it
|
||||||
ret = rig_set_freq(priv->tuner, RIG_VFO_CURR, freq + priv->input_rate/4);
|
*/
|
||||||
|
ret = rig_set_freq(priv->tuner, RIG_VFO_CURR, freq + GR_MAX_FREQUENCY(priv)/2);
|
||||||
if (ret != RIG_OK)
|
if (ret != RIG_OK)
|
||||||
return ret;
|
return ret;
|
||||||
/* query freq right back, because wanted freq may not be real freq,
|
/*
|
||||||
* because of resolution of tuner */
|
* query freq right back, because wanted freq may not be real freq,
|
||||||
|
* because of resolution of tuner
|
||||||
|
*/
|
||||||
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
||||||
if (ret != RIG_OK)
|
if (ret != RIG_OK)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
/*
|
|
||||||
* In case the tuner is not a real tuner
|
|
||||||
*/
|
|
||||||
if (priv->tuner_model == RIG_MODEL_DUMMY)
|
|
||||||
tuner_freq = 0;
|
|
||||||
|
|
||||||
freq_offset = (double) (tuner_freq - freq);
|
/*
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: %lld %lld freq_offset=%g\n",
|
* tuner freq changed, so adjust frequency offset of other channels
|
||||||
__FUNCTION__, tuner_freq, freq, freq_offset);
|
*/
|
||||||
|
for (i = 0; i<NUM_CHAN; i++) {
|
||||||
/* TODO: change mode plumbing (don't forget locking!)
|
if (i != chan_num)
|
||||||
* workaround?: set_mode(NONE), set_mode(previous)
|
update_freq(rig, i, tuner_freq, priv->chans[i].freq);
|
||||||
*/
|
|
||||||
pthread_mutex_lock(&priv->mutex_process);
|
|
||||||
switch (chan->mode) {
|
|
||||||
case RIG_MODE_WFM:
|
|
||||||
case RIG_MODE_FM:
|
|
||||||
/* not so sure about if setCenter_Freq is the Right thing to do(tm). */
|
|
||||||
mod->fm.chan_filter_1->setCenter_Freq(priv->IF_center_freq - freq_offset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_MODE_USB:
|
|
||||||
{
|
|
||||||
mod->ssb.shifter->set_freq(2*M_PI*freq_offset/(double)priv->input_rate);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case RIG_MODE_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s: mode % unimplemented!\n",
|
|
||||||
__FUNCTION__, strrmode(chan->mode));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&priv->mutex_process);
|
|
||||||
|
|
||||||
chan->freq = freq;
|
ret = update_freq(rig, chan_num, tuner_freq, freq);
|
||||||
|
if (ret == RIG_OK)
|
||||||
|
chan->freq = freq;
|
||||||
|
|
||||||
return RIG_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,12 +543,14 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
int chan_num = vfo2chan_num(rig, vfo);
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
channel_t *chan = &priv->chans[chan_num];
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
union mod_data *mod = &priv->mods[chan_num];
|
struct mod_data *mod = &priv->mods[chan_num];
|
||||||
char buf[16];
|
char buf[16];
|
||||||
freq_t tuner_freq;
|
freq_t tuner_freq;
|
||||||
int ret = RIG_OK;
|
int ret = RIG_OK;
|
||||||
double freq_offset;
|
double freq_offset;
|
||||||
|
|
||||||
|
if (width == RIG_PASSBAND_NORMAL)
|
||||||
|
width = rig_passband_normal(rig, mode);
|
||||||
sprintf_freq(buf, width);
|
sprintf_freq(buf, width);
|
||||||
rig_debug(RIG_DEBUG_VERBOSE,"%s called: %s %s %s\n",
|
rig_debug(RIG_DEBUG_VERBOSE,"%s called: %s %s %s\n",
|
||||||
__FUNCTION__, strvfo(vfo), strrmode(mode), buf);
|
__FUNCTION__, strvfo(vfo), strrmode(mode), buf);
|
||||||
|
@ -510,6 +558,11 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
if (mode == chan->mode && width == chan->width)
|
if (mode == chan->mode && width == chan->width)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: check if only change in width
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq);
|
||||||
if (ret != RIG_OK)
|
if (ret != RIG_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -519,7 +572,7 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
if (priv->tuner_model == RIG_MODEL_DUMMY)
|
if (priv->tuner_model == RIG_MODEL_DUMMY)
|
||||||
tuner_freq = 0;
|
tuner_freq = 0;
|
||||||
|
|
||||||
freq_offset = (double) (tuner_freq - chan->freq);
|
freq_offset = (double) (chan->freq - tuner_freq);
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: freq_offset=%g\n",
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: freq_offset=%g\n",
|
||||||
__FUNCTION__, freq_offset);
|
__FUNCTION__, freq_offset);
|
||||||
|
|
||||||
|
@ -531,62 +584,209 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
switch (chan->mode) {
|
switch (chan->mode) {
|
||||||
case RIG_MODE_FM:
|
case RIG_MODE_FM:
|
||||||
case RIG_MODE_WFM:
|
case RIG_MODE_WFM:
|
||||||
delete mod->fm.audio_filter_1;
|
delete mod->demod.wfm.demod;
|
||||||
delete mod->fm.fm_demod_1;
|
delete mod->chan_filter;
|
||||||
delete mod->fm.chan_filter_1;
|
delete mod->audio_filter;
|
||||||
break;
|
break;
|
||||||
case RIG_MODE_USB:
|
case RIG_MODE_USB:
|
||||||
delete mod->ssb.hilb;
|
delete mod->audio_filter;
|
||||||
delete mod->ssb.shifter;
|
delete mod->chan_filter;
|
||||||
break;
|
break;
|
||||||
|
case RIG_MODE_AM:
|
||||||
|
delete mod->chan_filter;
|
||||||
|
delete mod->audio_filter;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: if same mode, but different width, then adapt */
|
/* TODO: if same mode, but different width, then adapt */
|
||||||
|
|
||||||
|
priv->m->stop();
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case RIG_MODE_FM: /* is there a difference ? */
|
case RIG_MODE_FM:
|
||||||
|
{
|
||||||
|
mod->CFIRdecimate = 20;
|
||||||
|
mod->CFIRdecimate2 = 25;
|
||||||
|
mod->RFIRdecimate = 5;
|
||||||
|
|
||||||
|
const float channelSpacing = 80e3;
|
||||||
|
const float demodBW = 3e3;
|
||||||
|
const float TAU = 75e-6; // 75us in US, 50us in EUR
|
||||||
|
|
||||||
|
const int quadRate = priv->input_rate / mod->CFIRdecimate / mod->CFIRdecimate2;
|
||||||
|
const int audioRate = quadRate / mod->RFIRdecimate;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// design first stage selection filter
|
||||||
|
//
|
||||||
|
|
||||||
|
// width of transition band.
|
||||||
|
//
|
||||||
|
// We make this twice as wide as you would think. This allows
|
||||||
|
// some aliasing, but it's outside our final bandwidth, determined
|
||||||
|
// by the next filter
|
||||||
|
|
||||||
|
float transition_width = (priv->input_rate / mod->CFIRdecimate - width);
|
||||||
|
|
||||||
|
vector<float> cs1_coeffs =
|
||||||
|
gr_firdes::low_pass (1.0, // gain
|
||||||
|
priv->input_rate, // sampling rate
|
||||||
|
width / 2, // low-pass cutoff freq
|
||||||
|
transition_width,
|
||||||
|
gr_firdes::WIN_HANN);
|
||||||
|
|
||||||
|
cerr << "Number of cs1_coeffs: " << cs1_coeffs.size () << endl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// design second stage channel selection filter
|
||||||
|
//
|
||||||
|
// This is the one that we tune
|
||||||
|
//
|
||||||
|
vector<float> cs2_coeffs =
|
||||||
|
gr_firdes::low_pass (1.0,
|
||||||
|
priv->input_rate / mod->CFIRdecimate,
|
||||||
|
width / 2,
|
||||||
|
(channelSpacing - width) / 2,
|
||||||
|
gr_firdes::WIN_HANN);
|
||||||
|
|
||||||
|
cerr << "Number of cs2_coeffs: " << cs2_coeffs.size () << endl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// design audio filter
|
||||||
|
//
|
||||||
|
vector<float> audio_coeffs =
|
||||||
|
gr_firdes::band_pass (1e3, // gain
|
||||||
|
quadRate, // sampling rate
|
||||||
|
300,
|
||||||
|
demodBW,
|
||||||
|
250,
|
||||||
|
gr_firdes::WIN_HAMMING);
|
||||||
|
|
||||||
|
cerr << "Number of audio_coeffs: " << audio_coeffs.size () << endl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// design demphasis filter
|
||||||
|
//
|
||||||
|
vector<double> fftaps = vector<double>(2);
|
||||||
|
vector<double> fbtaps = vector<double>(2);
|
||||||
|
|
||||||
|
fftaps[0] = 1 - exp(-1/(TAU*audioRate));
|
||||||
|
fftaps[1] = 0;
|
||||||
|
fbtaps[0] = 0;
|
||||||
|
fbtaps[1] = exp(-1/TAU/priv->input_rate*50);;
|
||||||
|
|
||||||
|
//
|
||||||
|
// now instantiate the modules
|
||||||
|
//
|
||||||
|
|
||||||
|
// short --> VrComplex
|
||||||
|
mod->chan_filter =
|
||||||
|
new GrFreqXlatingFIRfilterSCF (mod->CFIRdecimate,
|
||||||
|
cs1_coeffs,
|
||||||
|
priv->IF_center_freq - freq_offset);
|
||||||
|
|
||||||
|
// VrComplex --> VrComplex
|
||||||
|
mod->demod.fm.chan2_filter =
|
||||||
|
new GrFreqXlatingFIRfilterCCF (mod->CFIRdecimate2, cs2_coeffs, 0);
|
||||||
|
|
||||||
|
|
||||||
|
// VrComplex --> float
|
||||||
|
mod->demod.fm.demod = new VrQuadratureDemod<float>(1);
|
||||||
|
|
||||||
|
|
||||||
|
// float --> float
|
||||||
|
mod->audioF_filter = new GrFIRfilterFFF (mod->RFIRdecimate, audio_coeffs);
|
||||||
|
|
||||||
|
// float --> float
|
||||||
|
mod->demod.fm.deemph =
|
||||||
|
new GrIIRfilter<float,float,double> (1,fftaps,fbtaps);
|
||||||
|
|
||||||
|
// float --> short
|
||||||
|
mod->demod.fm.cfs = new GrConvertFS ();
|
||||||
|
|
||||||
|
//connect the modules together
|
||||||
|
|
||||||
|
NWO_CONNECT (GR_SOURCE(priv), mod->chan_filter);
|
||||||
|
NWO_CONNECT (mod->chan_filter, mod->demod.fm.chan2_filter);
|
||||||
|
NWO_CONNECT (mod->demod.fm.chan2_filter, mod->demod.fm.demod);
|
||||||
|
NWO_CONNECT (mod->demod.fm.demod, mod->audioF_filter);
|
||||||
|
NWO_CONNECT (mod->audioF_filter, mod->demod.fm.deemph);
|
||||||
|
NWO_CONNECT (mod->demod.fm.deemph, mod->demod.fm.cfs);
|
||||||
|
NWO_CONNECT (mod->demod.fm.cfs, priv->sink);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case RIG_MODE_WFM:
|
case RIG_MODE_WFM:
|
||||||
{
|
{
|
||||||
mod->fm.chanTaps = 75;
|
mod->CFIRdecimate = 125;
|
||||||
mod->fm.CFIRdecimate = 125;
|
mod->RFIRdecimate = 5;
|
||||||
mod->fm.chanGain = 2.0;
|
|
||||||
mod->fm.FMdemodGain = 2200;
|
const int quadRate = priv->input_rate / mod->CFIRdecimate;
|
||||||
mod->fm.RFIRdecimate = 5;
|
const int audioRate = quadRate / mod->RFIRdecimate;
|
||||||
mod->fm.ifTaps = 50;
|
|
||||||
mod->fm.ifGain = 1.0;
|
rig_debug(RIG_DEBUG_VERBOSE, "Input Sampling Rate: %d\n", priv->input_rate);
|
||||||
const int quadRate = priv->input_rate / mod->fm.CFIRdecimate;
|
rig_debug(RIG_DEBUG_VERBOSE, "Complex FIR decimation factor: %d\n", mod->CFIRdecimate);
|
||||||
const int audioRate = quadRate / mod->fm.RFIRdecimate;
|
rig_debug(RIG_DEBUG_VERBOSE, "QuadDemod Sampling Rate: %d\n", quadRate);
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "Real FIR decimation factor: %d\n", mod->RFIRdecimate);
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "Audio Sampling Rate: %d\n", audioRate);
|
||||||
|
|
||||||
|
|
||||||
|
// build channel filter
|
||||||
|
//
|
||||||
|
// note that the totally bogus transition width is because
|
||||||
|
// we don't have enough mips right now to really do the right thing.
|
||||||
|
// This results in a filter with 83 taps, which is just a few
|
||||||
|
// more than the original 75 in microtune_fm_demo.
|
||||||
|
vector<float> channel_coeffs =
|
||||||
|
gr_firdes::low_pass (1.0, // gain
|
||||||
|
priv->input_rate, // sampling rate
|
||||||
|
width, // low-pass cutoff: freq 250e3
|
||||||
|
8*100e3, // width of transition band
|
||||||
|
gr_firdes::WIN_HAMMING);
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "Number of channel_coeffs: %d\n", channel_coeffs.size ());
|
||||||
|
|
||||||
|
// short --> VrComplex
|
||||||
|
mod->chan_filter =
|
||||||
|
new GrFreqXlatingFIRfilterSCF(mod->CFIRdecimate, channel_coeffs,
|
||||||
|
priv->IF_center_freq - freq_offset);
|
||||||
|
|
||||||
|
|
||||||
|
// float --> short
|
||||||
|
double width_of_transition_band = audioRate / 32;
|
||||||
|
vector<float> audio_coeffs =
|
||||||
|
gr_firdes::low_pass (1.0, // gain
|
||||||
|
quadRate, // sampling rate
|
||||||
|
audioRate/2 - width_of_transition_band, // low-pass cutoff freq
|
||||||
|
width_of_transition_band,
|
||||||
|
gr_firdes::WIN_HAMMING);
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "Number of audio_coeffs: %d\n", audio_coeffs.size ());
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "Low-pass cutoff freq: %d\n", audioRate/2 - (int)width_of_transition_band);
|
||||||
|
|
||||||
|
mod->audio_filter =
|
||||||
|
new GrFIRfilterFSF(mod->RFIRdecimate, audio_coeffs);
|
||||||
|
|
||||||
|
mod->demod.wfm.FMdemodGain = 2200;
|
||||||
float volume = chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f;
|
float volume = chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f;
|
||||||
|
|
||||||
//
|
//
|
||||||
// setup Wide FM demodulator chain
|
// setup Wide FM demodulator chain
|
||||||
//
|
//
|
||||||
|
// VrComplex --> float
|
||||||
// short --> VrComplex
|
mod->demod.wfm.demod =
|
||||||
mod->fm.chan_filter_1 = new VrComplexFIRfilter<short>(mod->fm.CFIRdecimate, mod->fm.chanTaps,
|
new VrQuadratureDemod<float>(volume * mod->demod.wfm.FMdemodGain);
|
||||||
priv->IF_center_freq - freq_offset,
|
|
||||||
mod->fm.chanGain);
|
|
||||||
|
|
||||||
// VrComplex --> float
|
//connect the modules together
|
||||||
mod->fm.fm_demod_1 = new VrQuadratureDemod<float>(volume * mod->fm.FMdemodGain);
|
|
||||||
|
|
||||||
// float --> short
|
NWO_CONNECT (GR_SOURCE(priv), mod->chan_filter);
|
||||||
mod->fm.audio_filter_1 = new VrRealFIRfilter<float,short>(mod->fm.RFIRdecimate, audioRate/2,
|
NWO_CONNECT (mod->chan_filter, mod->demod.wfm.demod);
|
||||||
mod->fm.ifTaps, mod->fm.ifGain);
|
NWO_CONNECT (mod->demod.wfm.demod, mod->audio_filter);
|
||||||
|
NWO_CONNECT (mod->audio_filter, priv->sink);
|
||||||
//connect the modules together
|
|
||||||
|
|
||||||
NWO_CONNECT (GR_SOURCE(priv), mod->fm.chan_filter_1);
|
|
||||||
NWO_CONNECT (mod->fm.chan_filter_1, mod->fm.fm_demod_1);
|
|
||||||
NWO_CONNECT (mod->fm.fm_demod_1, mod->fm.audio_filter_1);
|
|
||||||
NWO_CONNECT (mod->fm.audio_filter_1, priv->sink);
|
|
||||||
|
|
||||||
priv->m->stop();
|
|
||||||
priv->m->add (priv->sink);
|
|
||||||
priv->m->start();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -595,26 +795,47 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
{
|
{
|
||||||
float rf_gain = chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f;
|
float rf_gain = chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f;
|
||||||
|
|
||||||
/* SSB is a WIP
|
|
||||||
* I guess we're missing a low pass filter?
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//SSB mod:
|
||||||
mod->ssb.hilb = new GrHilbert<short>(31); /* what's that 31? */
|
mod->ssb.hilb = new GrHilbert<short>(31); /* what's that 31? */
|
||||||
mod->ssb.shifter = new GrSSBMod<short>(2*M_PI*freq_offset/(double)priv->input_rate,
|
mod->ssb.shifter = new GrSSBMod<short>(2*M_PI*freq_offset/(double)priv->input_rate,
|
||||||
rf_gain);
|
rf_gain);
|
||||||
|
#endif
|
||||||
|
|
||||||
//connect the modules together
|
//connect the modules together
|
||||||
NWO_CONNECT (GR_SOURCE(priv), mod->ssb.hilb);
|
NWO_CONNECT (GR_SOURCE(priv), mod->chan_filter);
|
||||||
NWO_CONNECT (mod->ssb.hilb, mod->ssb.shifter);
|
NWO_CONNECT (mod->chan_filter, mod->demod.fm.demod);
|
||||||
NWO_CONNECT (mod->ssb.shifter, priv->sink);
|
NWO_CONNECT (mod->demod.fm.demod, mod->audio_filter);
|
||||||
|
NWO_CONNECT (mod->audio_filter, priv->sink);
|
||||||
priv->m->stop();
|
|
||||||
priv->m->add (priv->sink);
|
|
||||||
priv->m->start();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
case RIG_MODE_AM:
|
||||||
|
{
|
||||||
|
float volume = chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f;
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup Wide FM demodulator chain
|
||||||
|
//
|
||||||
|
|
||||||
|
// VrComplex --> float
|
||||||
|
mod->am.demod =
|
||||||
|
new VrAmplitudeDemod<float>(0.0, 0.05);
|
||||||
|
|
||||||
|
//connect the modules together
|
||||||
|
|
||||||
|
NWO_CONNECT (GR_SOURCE(priv), mod->chan_filter);
|
||||||
|
NWO_CONNECT (mod->chan_filter, mod->am.demod);
|
||||||
|
NWO_CONNECT (mod->am.demod, mod->audio_filter);
|
||||||
|
NWO_CONNECT (mod->audio_filter, priv->sink);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case RIG_MODE_NONE:
|
case RIG_MODE_NONE:
|
||||||
/* ez */
|
/* ez */
|
||||||
break;
|
break;
|
||||||
|
@ -623,6 +844,10 @@ int gr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
ret = -RIG_EINVAL;
|
ret = -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->m->add (priv->sink);
|
||||||
|
priv->m->start();
|
||||||
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&priv->mutex_process);
|
pthread_mutex_unlock(&priv->mutex_process);
|
||||||
|
|
||||||
if (ret == RIG_OK) {
|
if (ret == RIG_OK) {
|
||||||
|
@ -676,7 +901,7 @@ int gr_get_vfo(RIG *rig, vfo_t *vfo)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_rf_gain(RIG *rig, channel_t *chan, union mod_data *mod, float gain)
|
static int set_rf_gain(RIG *rig, channel_t *chan, struct mod_data *mod, float gain)
|
||||||
{
|
{
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
|
||||||
|
@ -684,16 +909,16 @@ static int set_rf_gain(RIG *rig, channel_t *chan, union mod_data *mod, float gai
|
||||||
switch (chan->mode) {
|
switch (chan->mode) {
|
||||||
case RIG_MODE_USB:
|
case RIG_MODE_USB:
|
||||||
{
|
{
|
||||||
mod->ssb.shifter->set_gain(gain);
|
//mod->ssb.shifter->set_gain(gain);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RIG_MODE_NONE:
|
case RIG_MODE_NONE:
|
||||||
break;
|
break;
|
||||||
case RIG_MODE_WFM:
|
case RIG_MODE_WFM:
|
||||||
case RIG_MODE_FM:
|
case RIG_MODE_FM:
|
||||||
/* chan_filter_1/VrComplexFIRfilter is missing a setGain method! */
|
/* chan_filter/VrComplexFIRfilter is missing a setGain method! */
|
||||||
default:
|
default:
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s: mode % unimplemented!\n",
|
rig_debug(RIG_DEBUG_WARN, "%s: mode %s unimplemented!\n",
|
||||||
__FUNCTION__, strrmode(chan->mode));
|
__FUNCTION__, strrmode(chan->mode));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +936,7 @@ int gnuradio_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
int chan_num = vfo2chan_num(rig, vfo);
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
channel_t *chan = &priv->chans[chan_num];
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
union mod_data *mod = &priv->mods[chan_num];
|
struct mod_data *mod = &priv->mods[chan_num];
|
||||||
char lstr[32];
|
char lstr[32];
|
||||||
int idx;
|
int idx;
|
||||||
int ret = RIG_OK;
|
int ret = RIG_OK;
|
||||||
|
@ -733,7 +958,7 @@ int gnuradio_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
ret = set_rf_gain(rig, chan, mod, val.f);
|
ret = set_rf_gain(rig, chan, mod, val.f);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s: level % unimplemented!\n",
|
rig_debug(RIG_DEBUG_WARN, "%s: level %s unimplemented!\n",
|
||||||
__FUNCTION__, strlevel(level));
|
__FUNCTION__, strlevel(level));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -759,6 +984,97 @@ int gnuradio_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: change BFO...
|
||||||
|
*/
|
||||||
|
int gnuradio_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit)
|
||||||
|
{
|
||||||
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
chan->rit = rit;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gnuradio_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit)
|
||||||
|
{
|
||||||
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
|
|
||||||
|
*rit = chan->rit;
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nothing much to be done but remembering
|
||||||
|
*/
|
||||||
|
int gnuradio_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts)
|
||||||
|
{
|
||||||
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||||
|
chan->tuning_step = ts;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gnuradio_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts)
|
||||||
|
{
|
||||||
|
struct gnuradio_priv_data *priv = (struct gnuradio_priv_data *)rig->state.priv;
|
||||||
|
int chan_num = vfo2chan_num(rig, vfo);
|
||||||
|
channel_t *chan = &priv->chans[chan_num];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||||
|
*ts = chan->tuning_step;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gnuradio_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op)
|
||||||
|
{
|
||||||
|
freq_t freq;
|
||||||
|
shortfreq_t ts;
|
||||||
|
int ret = RIG_OK;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE,"%s called: %s\n",__FUNCTION__,
|
||||||
|
strvfop(op));
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case RIG_OP_UP:
|
||||||
|
ret = gr_get_freq(rig, vfo, &freq);
|
||||||
|
if (ret != RIG_OK) break;
|
||||||
|
ret = gnuradio_get_ts(rig, vfo, &ts);
|
||||||
|
if (ret != RIG_OK) break;
|
||||||
|
ret = gr_set_freq(rig, vfo, freq+ts); /* up */
|
||||||
|
break;
|
||||||
|
case RIG_OP_DOWN:
|
||||||
|
ret = gr_get_freq(rig, vfo, &freq);
|
||||||
|
if (ret != RIG_OK) break;
|
||||||
|
ret = gnuradio_get_ts(rig, vfo, &ts);
|
||||||
|
if (ret != RIG_OK) break;
|
||||||
|
ret = gr_set_freq(rig, vfo, freq-ts); /* down */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int initrigs_gnuradio(void *be_handle)
|
int initrigs_gnuradio(void *be_handle)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "gnuradio: _init called\n");
|
rig_debug(RIG_DEBUG_VERBOSE, "gnuradio: _init called\n");
|
||||||
|
@ -770,3 +1086,57 @@ int initrigs_gnuradio(void *be_handle)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
VrGUI *guimain = 0;
|
||||||
|
VrGUILayout *horiz = 0;
|
||||||
|
VrGUILayout *vert = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (use_gui_p){
|
||||||
|
guimain = new VrGUI(argc, argv);
|
||||||
|
horiz = guimain->top->horizontal();
|
||||||
|
vert = horiz->vertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
VrSink<VrComplex> *fft_sink1 = 0;
|
||||||
|
VrSink<float> *fft_sink2 = 0;
|
||||||
|
VrSink<short> *fft_sink3 = 0;
|
||||||
|
|
||||||
|
if (use_gui_p){
|
||||||
|
// sink1 is channel filter output
|
||||||
|
fft_sink1 = new GrFFTSink<VrComplex>(vert, 50, 130, 512);
|
||||||
|
|
||||||
|
// sink2 is fm demod output
|
||||||
|
fft_sink2 = new GrFFTSink<float>(vert, 40, 140, 512);
|
||||||
|
|
||||||
|
// sink3 is audio output
|
||||||
|
fft_sink3 = new GrFFTSink<short>(horiz, 40, 140, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_gui_p)
|
||||||
|
NWO_CONNECT (chan_filter, fft_sink1);
|
||||||
|
|
||||||
|
if (use_gui_p)
|
||||||
|
NWO_CONNECT (demod, fft_sink2);
|
||||||
|
|
||||||
|
if (use_gui_p)
|
||||||
|
NWO_CONNECT (audio_filter, fft_sink3);
|
||||||
|
|
||||||
|
VrMultiTask *m = new VrMultiTask ();
|
||||||
|
if (use_gui_p){
|
||||||
|
m->add (fft_sink1);
|
||||||
|
m->add (fft_sink3);
|
||||||
|
m->add (fft_sink2);
|
||||||
|
}
|
||||||
|
|
||||||
|
m->add (final_sink);
|
||||||
|
|
||||||
|
if (use_gui_p)
|
||||||
|
guimain->start ();
|
||||||
|
|
||||||
|
|
||||||
|
while (1){
|
||||||
|
if (use_gui_p)
|
||||||
|
guimain->processEvents(10 /*ms*/);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib GNUradio backend - main header
|
* Hamlib GNUradio backend - main header
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: gnuradio.h,v 1.2 2003-02-09 22:47:03 fillods Exp $
|
* $Id: gnuradio.h,v 1.3 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -50,6 +50,12 @@ int gnuradio_get_conf(RIG *rig, token_t token, char *val);
|
||||||
int gnuradio_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
|
int gnuradio_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
|
||||||
int gnuradio_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
|
int gnuradio_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
|
||||||
|
|
||||||
|
int gnuradio_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op);
|
||||||
|
int gnuradio_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts);
|
||||||
|
int gnuradio_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts);
|
||||||
|
int gnuradio_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit);
|
||||||
|
int gnuradio_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit);
|
||||||
|
|
||||||
int mc4020_open(RIG *rig);
|
int mc4020_open(RIG *rig);
|
||||||
int graudio_open(RIG *rig);
|
int graudio_open(RIG *rig);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib GNUradio backend - main file
|
* Hamlib GNUradio backend - main file
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: gr.c,v 1.3 2003-02-09 22:49:33 fillods Exp $
|
* $Id: gr.c,v 1.4 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#define GR_FUNC RIG_FUNC_NONE
|
#define GR_FUNC RIG_FUNC_NONE
|
||||||
#define GR_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
#define GR_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
||||||
#define GR_PARM RIG_PARM_NONE
|
#define GR_PARM RIG_PARM_NONE
|
||||||
#define GR_VFO_OP RIG_OP_NONE
|
#define GR_VFO_OP (RIG_OP_UP|RIG_OP_DOWN)
|
||||||
#define GR_SCAN RIG_SCAN_NONE
|
#define GR_SCAN RIG_SCAN_NONE
|
||||||
|
|
||||||
#define GR_MODES (RIG_MODE_WFM|RIG_MODE_FM|RIG_MODE_SSB)
|
#define GR_MODES (RIG_MODE_WFM|RIG_MODE_FM|RIG_MODE_SSB)
|
||||||
|
@ -46,8 +46,8 @@
|
||||||
|
|
||||||
static const struct gnuradio_priv_caps gr_priv_caps = {
|
static const struct gnuradio_priv_caps gr_priv_caps = {
|
||||||
.tuner_model = RIG_MODEL_DUMMY,
|
.tuner_model = RIG_MODEL_DUMMY,
|
||||||
.input_rate = MHz(10), /* whatever */
|
.input_rate = MHz(20),
|
||||||
.IF_center_freq = MHz(5), /* whatever */
|
.IF_center_freq = MHz(5.75),
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct rig_caps gr_caps = {
|
const struct rig_caps gr_caps = {
|
||||||
|
@ -82,7 +82,16 @@ const struct rig_caps gr_caps = {
|
||||||
.low_power=-1,.high_power=-1,GR_VFO},
|
.low_power=-1,.high_power=-1,GR_VFO},
|
||||||
RIG_FRNG_END, },
|
RIG_FRNG_END, },
|
||||||
.tx_range_list2 = { RIG_FRNG_END, },
|
.tx_range_list2 = { RIG_FRNG_END, },
|
||||||
.tuning_steps = { {GR_MODES,1}, RIG_TS_END, },
|
.tuning_steps = { {GR_MODES,1}, {GR_MODES,RIG_TS_ANY}, RIG_TS_END, },
|
||||||
|
.filters = {
|
||||||
|
{RIG_MODE_SSB|RIG_MODE_CW, kHz(2.4)},
|
||||||
|
{RIG_MODE_AM, kHz(8)},
|
||||||
|
{RIG_MODE_FM, kHz(15)},
|
||||||
|
{RIG_MODE_WFM, kHz(230)},
|
||||||
|
{GR_MODES, RIG_FLT_ANY},
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
|
||||||
.priv = (void*)&gr_priv_caps,
|
.priv = (void*)&gr_priv_caps,
|
||||||
|
|
||||||
.rig_init = gr_init,
|
.rig_init = gr_init,
|
||||||
|
@ -90,6 +99,7 @@ const struct rig_caps gr_caps = {
|
||||||
.rig_open = gr_open,
|
.rig_open = gr_open,
|
||||||
.rig_close = gr_close,
|
.rig_close = gr_close,
|
||||||
|
|
||||||
|
.cfgparams = gnuradio_cfg_params,
|
||||||
.set_conf = gnuradio_set_conf,
|
.set_conf = gnuradio_set_conf,
|
||||||
.get_conf = gnuradio_get_conf,
|
.get_conf = gnuradio_get_conf,
|
||||||
|
|
||||||
|
@ -103,6 +113,12 @@ const struct rig_caps gr_caps = {
|
||||||
|
|
||||||
.set_level = gnuradio_set_level,
|
.set_level = gnuradio_set_level,
|
||||||
.get_level = gnuradio_get_level,
|
.get_level = gnuradio_get_level,
|
||||||
|
|
||||||
|
.set_rit = gnuradio_set_rit,
|
||||||
|
.get_rit = gnuradio_get_rit,
|
||||||
|
.set_ts = gnuradio_set_ts,
|
||||||
|
.get_ts = gnuradio_get_ts,
|
||||||
|
.vfo_op = gnuradio_vfo_op,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib GNUradio backend - gnuradio priv structure
|
* Hamlib GNUradio backend - gnuradio priv structure
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: gr_priv.h,v 1.3 2003-02-09 22:54:15 fillods Exp $
|
* $Id: gr_priv.h,v 1.4 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -27,13 +27,17 @@
|
||||||
#include <VrSink.h>
|
#include <VrSink.h>
|
||||||
#include <VrMultiTask.h>
|
#include <VrMultiTask.h>
|
||||||
#include <VrFixOffset.h>
|
#include <VrFixOffset.h>
|
||||||
/* FM */
|
#include <GrFreqXlatingFIRfilterSCF.h>
|
||||||
#include <VrComplexFIRfilter.h>
|
#include <GrFreqXlatingFIRfilterCCF.h>
|
||||||
#include <VrQuadratureDemod.h>
|
#include <GrFIRfilterFSF.h>
|
||||||
#include <VrRealFIRfilter.h>
|
#include <VrQuadratureDemod.h> /* FM */
|
||||||
/* SSB */
|
//#include <VrAmplitudeDemod.h> /* AM */
|
||||||
#include <GrSSBMod.h>
|
#include <GrIIRfilter.h>
|
||||||
#include <GrHilbert.h>
|
#include <GrConvertFS.h>
|
||||||
|
|
||||||
|
/* SSB mod */
|
||||||
|
//#include <GrSSBMod.h>
|
||||||
|
//#include <GrHilbert.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
@ -41,30 +45,42 @@
|
||||||
|
|
||||||
#define IOTYPE short
|
#define IOTYPE short
|
||||||
|
|
||||||
union mod_data {
|
struct mod_data {
|
||||||
|
union {
|
||||||
struct {
|
struct {
|
||||||
/* (W)FM demod */
|
/* FM demod */
|
||||||
VrComplexFIRfilter<short> *chan_filter_1;
|
VrQuadratureDemod<float> *demod;
|
||||||
VrQuadratureDemod<float> *fm_demod_1;
|
|
||||||
VrRealFIRfilter<float,short> *audio_filter_1;
|
|
||||||
|
|
||||||
/* these levels, if not in RIG_LEVEL's already,
|
|
||||||
* are good candidates for rig_set_ext_level
|
|
||||||
*/
|
|
||||||
int CFIRdecimate;
|
|
||||||
int chanTaps;
|
|
||||||
float chanGain;
|
|
||||||
float FMdemodGain;
|
float FMdemodGain;
|
||||||
int RFIRdecimate;
|
GrFreqXlatingFIRfilterCCF *chan2_filter;
|
||||||
int ifTaps;
|
GrIIRfilter<float,float,double> *deemph;
|
||||||
float ifGain; /* LEVEL_RF? */
|
GrConvertFS *cfs;
|
||||||
} fm;
|
} fm;
|
||||||
|
struct {
|
||||||
|
/* WFM demod */
|
||||||
|
VrQuadratureDemod<float> *demod;
|
||||||
|
float FMdemodGain;
|
||||||
|
} wfm;
|
||||||
|
#if 0
|
||||||
|
struct {
|
||||||
|
/* AM demod */
|
||||||
|
VrAmplitudeDemod<float> *demod;
|
||||||
|
} am;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/* SSB demod */
|
/* SSB mod */
|
||||||
|
#if 0
|
||||||
GrHilbert<short> *hilb;
|
GrHilbert<short> *hilb;
|
||||||
GrSSBMod<short> *shifter;
|
GrSSBMod<short> *shifter;
|
||||||
|
#endif
|
||||||
} ssb;
|
} ssb;
|
||||||
|
} demod;
|
||||||
|
int CFIRdecimate;
|
||||||
|
int CFIRdecimate2;
|
||||||
|
int RFIRdecimate;
|
||||||
|
GrFreqXlatingFIRfilterSCF *chan_filter;
|
||||||
|
GrFIRfilterFSF *audio_filter;
|
||||||
|
GrFIRfilterFFF *audioF_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_CHAN 2 /* VFO A and VFO B */
|
#define NUM_CHAN 2 /* VFO A and VFO B */
|
||||||
|
@ -93,9 +109,12 @@ struct gnuradio_priv_data {
|
||||||
pthread_mutex_t mutex_process;
|
pthread_mutex_t mutex_process;
|
||||||
volatile int do_process; /*< flag to tell process thread to stop */
|
volatile int do_process; /*< flag to tell process thread to stop */
|
||||||
|
|
||||||
union mod_data mods[NUM_CHAN]; /*< Modulation objects and stuff, one per channel */
|
struct mod_data mods[NUM_CHAN]; /*< Modulation objects and stuff, one per channel */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GR_SOURCE(priv) ((priv)->need_fixer?(priv)->offset_fixer:(priv)->source)
|
//#define GR_SOURCE(priv) ((priv)->need_fixer?(priv)->offset_fixer:(priv)->source)
|
||||||
|
#define GR_SOURCE(priv) ((priv)->offset_fixer)
|
||||||
|
|
||||||
|
#define GR_MAX_FREQUENCY(priv) ((priv)->input_rate/2)
|
||||||
|
|
||||||
#endif /* _GR_PRIV_H */
|
#endif /* _GR_PRIV_H */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib GNUradio backend - graudio/any rig
|
* Hamlib GNUradio backend - graudio/any rig
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: graudio.c,v 1.1 2003-02-09 22:46:00 fillods Exp $
|
* $Id: graudio.c,v 1.2 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -36,10 +36,13 @@
|
||||||
#define GRAUDIO_FUNC RIG_FUNC_NONE
|
#define GRAUDIO_FUNC RIG_FUNC_NONE
|
||||||
#define GRAUDIO_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
#define GRAUDIO_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
||||||
#define GRAUDIO_PARM RIG_PARM_NONE
|
#define GRAUDIO_PARM RIG_PARM_NONE
|
||||||
#define GRAUDIO_VFO_OP RIG_OP_NONE
|
#define GRAUDIO_VFO_OP (RIG_OP_UP|RIG_OP_DOWN)
|
||||||
#define GRAUDIO_SCAN RIG_SCAN_NONE
|
#define GRAUDIO_SCAN RIG_SCAN_NONE
|
||||||
|
|
||||||
#define GRAUDIO_MODES (RIG_MODE_WFM|RIG_MODE_FM|RIG_MODE_SSB)
|
/*
|
||||||
|
* GNU Radio Audio has no WFM mode because bandwidth is too wide!
|
||||||
|
*/
|
||||||
|
#define GRAUDIO_MODES (RIG_MODE_FM|RIG_MODE_SSB)
|
||||||
|
|
||||||
#define GRAUDIO_VFO (RIG_VFO_A|RIG_VFO_B)
|
#define GRAUDIO_VFO (RIG_VFO_A|RIG_VFO_B)
|
||||||
|
|
||||||
|
@ -82,7 +85,15 @@ const struct rig_caps graudio_caps = {
|
||||||
.low_power=-1,.high_power=-1,GRAUDIO_VFO},
|
.low_power=-1,.high_power=-1,GRAUDIO_VFO},
|
||||||
RIG_FRNG_END, },
|
RIG_FRNG_END, },
|
||||||
.tx_range_list2 = { RIG_FRNG_END, },
|
.tx_range_list2 = { RIG_FRNG_END, },
|
||||||
.tuning_steps = { {GRAUDIO_MODES,1}, RIG_TS_END, },
|
.tuning_steps = { {GRAUDIO_MODES,1}, {GRAUDIO_MODES,RIG_TS_ANY}, RIG_TS_END, },
|
||||||
|
.filters = {
|
||||||
|
{RIG_MODE_SSB|RIG_MODE_CW, kHz(2.4)},
|
||||||
|
{RIG_MODE_AM, kHz(8)},
|
||||||
|
{RIG_MODE_FM, kHz(15)},
|
||||||
|
{GRAUDIO_MODES, RIG_FLT_ANY},
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
|
||||||
.priv = (void*)&graudio_priv_caps,
|
.priv = (void*)&graudio_priv_caps,
|
||||||
|
|
||||||
.rig_init = gr_init,
|
.rig_init = gr_init,
|
||||||
|
@ -90,6 +101,7 @@ const struct rig_caps graudio_caps = {
|
||||||
.rig_open = graudio_open,
|
.rig_open = graudio_open,
|
||||||
.rig_close = gr_close,
|
.rig_close = gr_close,
|
||||||
|
|
||||||
|
.cfgparams = gnuradio_cfg_params,
|
||||||
.set_conf = gnuradio_set_conf,
|
.set_conf = gnuradio_set_conf,
|
||||||
.get_conf = gnuradio_get_conf,
|
.get_conf = gnuradio_get_conf,
|
||||||
|
|
||||||
|
@ -103,5 +115,11 @@ const struct rig_caps graudio_caps = {
|
||||||
|
|
||||||
.set_level = gnuradio_set_level,
|
.set_level = gnuradio_set_level,
|
||||||
.get_level = gnuradio_get_level,
|
.get_level = gnuradio_get_level,
|
||||||
|
|
||||||
|
.set_rit = gnuradio_set_rit,
|
||||||
|
.get_rit = gnuradio_get_rit,
|
||||||
|
.set_ts = gnuradio_set_ts,
|
||||||
|
.get_ts = gnuradio_get_ts,
|
||||||
|
.vfo_op = gnuradio_vfo_op,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib GNUradio backend - MC4020/eb4937
|
* Hamlib GNUradio backend - MC4020/eb4937
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: mc4020.c,v 1.1 2003-02-09 22:46:00 fillods Exp $
|
* $Id: mc4020.c,v 1.2 2003-04-06 18:50:21 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
#define MC4020_FUNC RIG_FUNC_NONE
|
#define MC4020_FUNC RIG_FUNC_NONE
|
||||||
#define MC4020_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
#define MC4020_LEVEL (RIG_LEVEL_AF|RIG_LEVEL_RF)
|
||||||
#define MC4020_PARM RIG_PARM_NONE
|
#define MC4020_PARM RIG_PARM_NONE
|
||||||
#define MC4020_VFO_OP RIG_OP_NONE
|
#define MC4020_VFO_OP (RIG_OP_UP|RIG_OP_DOWN)
|
||||||
#define MC4020_SCAN RIG_SCAN_NONE
|
#define MC4020_SCAN RIG_SCAN_NONE
|
||||||
|
|
||||||
#define MC4020_MODES (RIG_MODE_WFM|RIG_MODE_FM|RIG_MODE_SSB)
|
#define MC4020_MODES (RIG_MODE_WFM|RIG_MODE_FM|RIG_MODE_SSB)
|
||||||
|
@ -84,7 +84,16 @@ const struct rig_caps mc4020_caps = {
|
||||||
.tx_range_list2 = { {.start=MHz(5),.end=MHz(42),.modes=MC4020_MODES,
|
.tx_range_list2 = { {.start=MHz(5),.end=MHz(42),.modes=MC4020_MODES,
|
||||||
.low_power=mW(1),.high_power=W(1),MC4020_VFO}, /* FIXME: power */
|
.low_power=mW(1),.high_power=W(1),MC4020_VFO}, /* FIXME: power */
|
||||||
RIG_FRNG_END, },
|
RIG_FRNG_END, },
|
||||||
.tuning_steps = { {MC4020_MODES,1}, RIG_TS_END, },
|
.tuning_steps = { {MC4020_MODES,1}, {MC4020_MODES,RIG_TS_ANY}, RIG_TS_END, },
|
||||||
|
.filters = {
|
||||||
|
{RIG_MODE_SSB|RIG_MODE_CW, kHz(2.4)},
|
||||||
|
{RIG_MODE_AM, kHz(8)},
|
||||||
|
{RIG_MODE_FM, kHz(15)},
|
||||||
|
{RIG_MODE_WFM, kHz(230)},
|
||||||
|
{MC4020_MODES, RIG_FLT_ANY},
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
|
||||||
.priv = (void*)&mc4020_priv_caps,
|
.priv = (void*)&mc4020_priv_caps,
|
||||||
|
|
||||||
.rig_init = gr_init,
|
.rig_init = gr_init,
|
||||||
|
@ -92,6 +101,7 @@ const struct rig_caps mc4020_caps = {
|
||||||
.rig_open = mc4020_open,
|
.rig_open = mc4020_open,
|
||||||
.rig_close = gr_close,
|
.rig_close = gr_close,
|
||||||
|
|
||||||
|
.cfgparams = gnuradio_cfg_params,
|
||||||
.set_conf = gnuradio_set_conf,
|
.set_conf = gnuradio_set_conf,
|
||||||
.get_conf = gnuradio_get_conf,
|
.get_conf = gnuradio_get_conf,
|
||||||
|
|
||||||
|
@ -105,5 +115,11 @@ const struct rig_caps mc4020_caps = {
|
||||||
|
|
||||||
.set_level = gnuradio_set_level,
|
.set_level = gnuradio_set_level,
|
||||||
.get_level = gnuradio_get_level,
|
.get_level = gnuradio_get_level,
|
||||||
|
|
||||||
|
.set_rit = gnuradio_set_rit,
|
||||||
|
.get_rit = gnuradio_get_rit,
|
||||||
|
.set_ts = gnuradio_set_ts,
|
||||||
|
.get_ts = gnuradio_get_ts,
|
||||||
|
.vfo_op = gnuradio_vfo_op,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,9 @@ int main(int argc, char *argv[])
|
||||||
guimain->start();
|
guimain->start();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
pthread_mutex_lock(&priv->mutex_process);
|
||||||
guimain->processEvents(10 /*ms*/);
|
guimain->processEvents(10 /*ms*/);
|
||||||
|
pthread_mutex_unlock(&priv->mutex_process);
|
||||||
//priv->m->process();
|
//priv->m->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue