1 /* -*- c++ -*- */
2 /*
3 * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
4 * https://gqrx.dk/
5 *
6 * Copyright 2011-2013 Alexandru Csete OZ9AEC.
7 *
8 * Gqrx is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3, or (at your option)
11 * any later version.
12 *
13 * Gqrx is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Gqrx; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street,
21 * Boston, MA 02110-1301, USA.
22 */
23 #include <QDebug>
24 #include "demod_options.h"
25 #include "ui_demod_options.h"
26
27
28 /* convert between deemphasis time constant and combo-index */
29 const double tau_tbl[] = {
30 0.0, 25.0e-6, 50.0e-6, 75.0e-6, 100.0e-6, 250.0e-6, 530.0e-6, 1.0e-3
31 };
32 const int tau_tbl_maxidx = 7;
33
tau_from_index(int index)34 double tau_from_index(int index)
35 {
36 if (index < 0 || index > tau_tbl_maxidx)
37 return 0.0;
38
39 return tau_tbl[index];
40 }
41
tau_to_index(double tau)42 int tau_to_index(double tau)
43 {
44 int i;
45 for (i = 0; i < tau_tbl_maxidx; i++)
46 {
47 if (tau < (tau_tbl[i] + 0.5 * (tau_tbl[i+1] - tau_tbl[i])))
48 return i;
49 }
50 return 0;
51 }
52
53 /* convert betweenFM max dev and combo index */
maxdev_from_index(int index)54 float maxdev_from_index(int index)
55 {
56 switch(index)
57 {
58 case 0:
59 /* Voice 2.5k */
60 return 2500.0;
61 case 1:
62 /* Voice 5k */
63 return 5000.0;
64 case 2:
65 /* APT 17k */
66 return 17000.0;
67 case 3:
68 /* APT 25k (17k but need some margin for Doppler and freq error) */
69 return 25000.0;
70 default:
71 /* Voice 5k */
72 qDebug() << "Invalid max_dev index: " << index;
73 return 5000.0;
74 }
75 }
76
maxdev_to_index(float max_dev)77 int maxdev_to_index(float max_dev)
78 {
79 if (max_dev < 3000.0)
80 /* Voice 2.5k */
81 return 0;
82 else if (max_dev < 10000.0)
83 /* Voice 5k */
84 return 1;
85 else if (max_dev < 20000.0)
86 /* APT 17k */
87 return 2;
88 else
89 /* APT 25k */
90 return 3;
91 }
92
93 /* convert between synchronous AM PLL bandwidth and combo index */
pll_bw_from_index(int index)94 static float pll_bw_from_index(int index)
95 {
96 switch(index)
97 {
98 case 0:
99 /* Fast */
100 return 0.01;
101 case 1:
102 /* Medium */
103 return 0.001;
104 case 2:
105 /* Slow */
106 return 0.0001;
107 default:
108 qDebug() << "Invalid AM-Sync PLL BW index: " << index;
109 return 0.001;
110 }
111 }
112
pll_bw_to_index(float pll_bw)113 static int pll_bw_to_index(float pll_bw)
114 {
115 if (pll_bw < 0.00015)
116 /* Slow */
117 return 2;
118 else if (pll_bw < 0.0015)
119 /* Medium */
120 return 1;
121 else if (pll_bw < 0.015)
122 /* Fast */
123 return 0;
124 else
125 /* Medium */
126 return 1;
127 }
128
CDemodOptions(QWidget * parent)129 CDemodOptions::CDemodOptions(QWidget *parent) :
130 QDialog(parent),
131 ui(new Ui::CDemodOptions)
132 {
133 ui->setupUi(this);
134 }
135
~CDemodOptions()136 CDemodOptions::~CDemodOptions()
137 {
138 delete ui;
139 }
140
141
142 /*! \brief Catch window close events.
143 *
144 * This method is called when the user closes the demod options dialog
145 * window using the window close icon. We catch the event and hide the
146 * dialog but keep it around for later use.
147 */
closeEvent(QCloseEvent * event)148 void CDemodOptions::closeEvent(QCloseEvent *event)
149 {
150 hide();
151 event->ignore();
152 }
153
setCurrentPage(int index)154 void CDemodOptions::setCurrentPage(int index)
155 {
156 if (index < PAGE_NUM)
157 ui->demodOptions->setCurrentIndex(index);
158 }
159
currentPage() const160 int CDemodOptions::currentPage() const
161 {
162 return ui->demodOptions->currentIndex();
163 }
164
setCwOffset(int offset)165 void CDemodOptions::setCwOffset(int offset)
166 {
167 ui->cwOffsetSpin->setValue(offset);
168 }
169
getCwOffset(void) const170 int CDemodOptions::getCwOffset(void) const
171 {
172 return ui->cwOffsetSpin->value();
173 }
174
setMaxDev(float max_dev)175 void CDemodOptions::setMaxDev(float max_dev)
176 {
177 ui->maxdevSelector->setCurrentIndex(maxdev_to_index(max_dev));
178 }
179
getMaxDev(void) const180 float CDemodOptions::getMaxDev(void) const
181 {
182 return maxdev_from_index(ui->maxdevSelector->currentIndex());
183 }
184
setEmph(double tau)185 void CDemodOptions::setEmph(double tau)
186 {
187 ui->emphSelector->setCurrentIndex((tau_to_index(tau)));
188 }
189
getEmph(void) const190 double CDemodOptions::getEmph(void) const
191 {
192 return tau_from_index(ui->emphSelector->currentIndex());
193 }
194
on_maxdevSelector_activated(int index)195 void CDemodOptions::on_maxdevSelector_activated(int index)
196 {
197 emit fmMaxdevSelected(maxdev_from_index(index));
198 }
199
on_emphSelector_activated(int index)200 void CDemodOptions::on_emphSelector_activated(int index)
201 {
202 emit fmEmphSelected(tau_from_index(index));
203 }
204
on_dcrCheckBox_toggled(bool checked)205 void CDemodOptions::on_dcrCheckBox_toggled(bool checked)
206 {
207 emit amDcrToggled(checked);
208 }
209
on_cwOffsetSpin_valueChanged(int value)210 void CDemodOptions::on_cwOffsetSpin_valueChanged(int value)
211 {
212 emit cwOffsetChanged(value);
213 }
214
on_syncdcrCheckBox_toggled(bool checked)215 void CDemodOptions::on_syncdcrCheckBox_toggled(bool checked)
216 {
217 emit amSyncDcrToggled(checked);
218 }
219
setPllBw(float pll_bw)220 void CDemodOptions::setPllBw(float pll_bw)
221 {
222 ui->pllBwSelector->setCurrentIndex(pll_bw_to_index(pll_bw));
223 }
224
getPllBw(void) const225 float CDemodOptions::getPllBw(void) const
226 {
227 return pll_bw_from_index(ui->pllBwSelector->currentIndex());
228 }
229
on_pllBwSelector_activated(int index)230 void CDemodOptions::on_pllBwSelector_activated(int index)
231 {
232 emit amSyncPllBwSelected(pll_bw_from_index(index));
233 }
234