From 812d0f4d153480d6a324ef99f35f394a00f86b06 Mon Sep 17 00:00:00 2001
From: John Greb <hexameron@spam.no>
Date: Sat, 8 Nov 2014 23:42:43 +0000
Subject: [PATCH] Samplerate options.

---
 plugins/samplesource/rtlsdr/rtlsdrgui.cpp    | 25 +++++----
 plugins/samplesource/rtlsdr/rtlsdrgui.h      |  2 +-
 plugins/samplesource/rtlsdr/rtlsdrgui.ui     | 18 +++----
 plugins/samplesource/rtlsdr/rtlsdrinput.cpp  | 56 ++++++++++++--------
 plugins/samplesource/rtlsdr/rtlsdrinput.h    |  2 +-
 plugins/samplesource/rtlsdr/rtlsdrthread.cpp | 47 ++++++++--------
 plugins/samplesource/rtlsdr/rtlsdrthread.h   |  5 +-
 7 files changed, 79 insertions(+), 76 deletions(-)

diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
index 269fe1fdc..28caab7a3 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
+++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp
@@ -10,7 +10,7 @@ RTLSDRGui::RTLSDRGui(PluginAPI* pluginAPI, QWidget* parent) :
 	m_sampleSource(NULL)
 {
 	ui->setupUi(this);
-	ui->centerFrequency->setValueRange(7, 20000U, 2200000U);
+	ui->centerFrequency->setValueRange(7, 28900U, 1700000U);
 	connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
 	displaySettings();
 
@@ -95,7 +95,7 @@ bool RTLSDRGui::handleMessage(Message* message)
 void RTLSDRGui::displaySettings()
 {
 	ui->centerFrequency->setValue(m_generalSettings.m_centerFrequency / 1000);
-	ui->decimation->setValue(m_settings.m_decimation);
+	ui->samplerate->setValue(m_settings.m_samplerate);
 
 	if(m_gains.size() > 0) {
 		int dist = abs(m_settings.m_gain - m_gains[0]);
@@ -139,10 +139,12 @@ void RTLSDRGui::on_gain_valueChanged(int value)
 	sendSettings();
 }
 
-void RTLSDRGui::on_decimation_valueChanged(int value)
+void RTLSDRGui::on_samplerate_valueChanged(int value)
 {
-	ui->decimationText->setText(tr("1:%1").arg(1 << value));
-	m_settings.m_decimation = value;
+	int Rates[] = {288, 1024, 1536, 0};
+	int newrate = Rates[value];
+	ui->samplerateText->setText(tr("%1k").arg(newrate));
+	m_settings.m_samplerate = newrate * 1000;
 	sendSettings();
 }
 
@@ -159,19 +161,16 @@ void RTLSDRGui::on_checkBox_stateChanged(int state) {
 		ui->radioButton->setEnabled(true);
 		ui->radioButton_2->setEnabled(true);
 		ui->gain->setEnabled(false);
-		//ui->decimation->setMaximum(6);
-
-		ui->centerFrequency->setValueRange(5, 0U, 30000U);
-		ui->centerFrequency->setValue(0);
+		ui->centerFrequency->setValueRange(7, 1000U, 28700U);
+		ui->centerFrequency->setValue(27000);
 	}
 	else {
 		((RTLSDRInput*)m_sampleSource)->set_ds_mode(0);
 		ui->radioButton->setEnabled(false);
 		ui->radioButton_2->setEnabled(false);
 		ui->gain->setEnabled(true);
-		//ui->decimation->setMaximum(4);
-
-		ui->centerFrequency->setValueRange(7, 20000U, 2200000U);
+		ui->centerFrequency->setValueRange(7, 28900U, 1700000U);
+		ui->centerFrequency->setValue(29000);
 	}
 }
 
@@ -182,4 +181,4 @@ void RTLSDRGui::on_radioButton_toggled(bool checked){
 void RTLSDRGui::on_radioButton_2_toggled(bool checked){
 	if (checked)
 		((RTLSDRInput*)m_sampleSource)->set_ds_mode(2);
-}
\ No newline at end of file
+}
diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.h b/plugins/samplesource/rtlsdr/rtlsdrgui.h
index 1c7c269c9..19d23e05e 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrgui.h
+++ b/plugins/samplesource/rtlsdr/rtlsdrgui.h
@@ -45,7 +45,7 @@ private:
 private slots:
 	void on_centerFrequency_changed(quint64 value);
 	void on_gain_valueChanged(int value);
-	void on_decimation_valueChanged(int value);
+	void on_samplerate_valueChanged(int value);
 	void on_checkBox_stateChanged(int state);
 	void on_radioButton_toggled(bool checked);
 	void on_radioButton_2_toggled(bool checked);
diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.ui b/plugins/samplesource/rtlsdr/rtlsdrgui.ui
index aa67594e6..490027fc1 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrgui.ui
+++ b/plugins/samplesource/rtlsdr/rtlsdrgui.ui
@@ -106,12 +106,12 @@
       <number>3</number>
      </property>
      <item row="0" column="1">
-      <widget class="QSlider" name="decimation">
+      <widget class="QSlider" name="samplerate">
        <property name="toolTip">
-        <string>Signal decimation factor</string>
+        <string>Device Samplerate</string>
        </property>
        <property name="maximum">
-        <number>4</number>
+        <number>2</number>
        </property>
        <property name="pageStep">
         <number>1</number>
@@ -130,12 +130,12 @@
         </sizepolicy>
        </property>
        <property name="text">
-        <string>Zoom Out</string>
+        <string>Rate</string>
        </property>
       </widget>
      </item>
      <item row="0" column="2">
-      <widget class="QLabel" name="decimationText">
+      <widget class="QLabel" name="samplerateText">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -143,7 +143,7 @@
         </size>
        </property>
        <property name="text">
-        <string>1:1</string>
+        <string>288k</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -226,7 +226,7 @@
      <item>
       <widget class="QCheckBox" name="checkBox">
        <property name="text">
-        <string>ds</string>
+        <string>Direct Sampling: </string>
        </property>
       </widget>
      </item>
@@ -236,7 +236,7 @@
         <bool>false</bool>
        </property>
        <property name="text">
-        <string>i</string>
+        <string>I</string>
        </property>
        <property name="checkable">
         <bool>true</bool>
@@ -252,7 +252,7 @@
         <bool>false</bool>
        </property>
        <property name="text">
-        <string>q</string>
+        <string>Q</string>
        </property>
       </widget>
      </item>
diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
index 17feaf069..b6a74016d 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
+++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp
@@ -27,21 +27,21 @@ MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgReportRTLSDR, Message)
 
 RTLSDRInput::Settings::Settings() :
 	m_gain(0),
-	m_decimation(0)
+	m_samplerate(288000)
 {
 }
 
 void RTLSDRInput::Settings::resetToDefaults()
 {
 	m_gain = 0;
-	m_decimation = 0;
+	m_samplerate = 288000;
 }
 
 QByteArray RTLSDRInput::Settings::serialize() const
 {
 	SimpleSerializer s(1);
 	s.writeS32(1, m_gain);
-	s.writeS32(2, m_decimation);
+	s.writeS32(2, m_samplerate);
 	return s.final();
 }
 
@@ -56,7 +56,7 @@ bool RTLSDRInput::Settings::deserialize(const QByteArray& data)
 
 	if(d.getVersion() == 1) {
 		d.readS32(1, &m_gain, 0);
-		d.readS32(2, &m_decimation, 0);
+		d.readS32(2, &m_samplerate, 0);
 		return true;
 	} else {
 		resetToDefaults();
@@ -91,7 +91,7 @@ bool RTLSDRInput::startInput(int device)
 	int res;
 	int numberOfGains;
 
-	if(!m_sampleFifo.setSize(524288)) {
+	if(!m_sampleFifo.setSize(96000 * 4)) {
 		qCritical("Could not allocate SampleFifo");
 		return false;
 	}
@@ -111,8 +111,8 @@ bool RTLSDRInput::startInput(int device)
 	qWarning("RTLSDRInput open: %s %s, SN: %s", vendor, product, serial);
 	m_deviceDescription = QString("%1 (SN %2)").arg(product).arg(serial);
 
-	if((res = rtlsdr_set_sample_rate(m_dev, 1536000)) < 0) {
-		qCritical("could not set sample rate: %s", strerror(errno));
+	if((res = rtlsdr_set_sample_rate(m_dev, 288000)) < 0) {
+		qCritical("could not set sample rate: 288k S/s");
 		goto failed;
 	}
 
@@ -182,7 +182,10 @@ const QString& RTLSDRInput::getDeviceDescription() const
 
 int RTLSDRInput::getSampleRate() const
 {
-	return 96000 * (1 <<  m_settings.m_decimation);
+	int rate = m_settings.m_samplerate / 4;
+	if (rate < 200000)
+		return rate;
+	return (rate / 4);
 }
 
 quint64 RTLSDRInput::getCenterFrequency() const
@@ -207,14 +210,6 @@ bool RTLSDRInput::applySettings(const GeneralSettings& generalSettings, const Se
 {
 	QMutexLocker mutexLocker(&m_mutex);
 
-	if((m_generalSettings.m_centerFrequency != generalSettings.m_centerFrequency) || force) {
-		m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency;
-		if(m_dev != NULL) {
-			if(rtlsdr_set_center_freq(m_dev, m_generalSettings.m_centerFrequency
-								+ 384000) != 0)
-				qDebug("osmosdr_set_center_freq(%lld) failed", m_generalSettings.m_centerFrequency);
-		}
-	}
 	if((m_settings.m_gain != settings.m_gain) || force) {
 		m_settings.m_gain = settings.m_gain;
 		if(m_dev != NULL) {
@@ -222,15 +217,30 @@ bool RTLSDRInput::applySettings(const GeneralSettings& generalSettings, const Se
 				qDebug("rtlsdr_set_tuner_gain() failed");
 		}
 	}
-	if((m_settings.m_decimation != settings.m_decimation) || force) {
-		m_settings.m_decimation = settings.m_decimation;
-		if(m_dev != NULL)
-			m_rtlSDRThread->setDecimation(m_settings.m_decimation);
+
+	if((m_settings.m_samplerate != settings.m_samplerate) || force) {
+		if(m_dev != NULL) {
+			if( rtlsdr_set_sample_rate(m_dev, settings.m_samplerate) < 0)
+				qCritical("could not set sample rate: %d", settings.m_samplerate);
+			else {
+				m_settings.m_samplerate = settings.m_samplerate;
+				m_rtlSDRThread->setSamplerate(settings.m_samplerate);
+			}
+		}
 	}
+
+	m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency;
+	if(m_dev != NULL) {
+		if(rtlsdr_set_center_freq( m_dev, m_generalSettings.m_centerFrequency
+						+ (m_settings.m_samplerate / 4) ) != 0)
+			qDebug("osmosdr_set_center_freq(%lld) failed", m_generalSettings.m_centerFrequency);
+	}
+
 	return true;
 }
 
-
-void RTLSDRInput::set_ds_mode(int on){
+void RTLSDRInput::set_ds_mode(int on)
+{
 	rtlsdr_set_direct_sampling(m_dev, on);
-}
\ No newline at end of file
+}
+
diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.h b/plugins/samplesource/rtlsdr/rtlsdrinput.h
index b1c1ebf18..34dfb71a0 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrinput.h
+++ b/plugins/samplesource/rtlsdr/rtlsdrinput.h
@@ -28,7 +28,7 @@ class RTLSDRInput : public SampleSource {
 public:
 	struct Settings {
 		qint32 m_gain;
-		qint32 m_decimation;
+		qint32 m_samplerate;
 
 		Settings();
 		void resetToDefaults();
diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.cpp b/plugins/samplesource/rtlsdr/rtlsdrthread.cpp
index 4b0322d11..72ff6d5d5 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrthread.cpp
+++ b/plugins/samplesource/rtlsdr/rtlsdrthread.cpp
@@ -28,9 +28,8 @@ RTLSDRThread::RTLSDRThread(rtlsdr_dev_t* dev, SampleFifo* sampleFifo, QObject* p
 	m_dev(dev),
 	m_convertBuffer(BLOCKSIZE),
 	m_sampleFifo(sampleFifo),
-	m_decimation(2)
+	m_samplerate(288000)
 {
-	m_localdecimation = 0;
 }
 
 RTLSDRThread::~RTLSDRThread()
@@ -53,9 +52,9 @@ void RTLSDRThread::stopWork()
 	wait();
 }
 
-void RTLSDRThread::setDecimation(int decimation)
+void RTLSDRThread::setSamplerate(int samplerate)
 {
-	m_decimation = decimation;
+	m_samplerate = samplerate;
 }
 
 void RTLSDRThread::run()
@@ -136,43 +135,39 @@ void RTLSDRThread::decimate16(SampleVector::iterator* it, const quint8* buf, qin
 	}
 }
 
+
+/*
+  Decimate everything by 16x, except 288kHz
+  TODO : no offset tuning for direct sampling
+*/
+
 void RTLSDRThread::callback(const quint8* buf, qint32 len)
 {
 	qint16 xreal, yimag, phase;
 	SampleVector::iterator it = m_convertBuffer.begin();
-	int decimationFactor[] = {1, 1, 1, 2, 4, 0};
 
-	if (++m_localdecimation < decimationFactor[m_decimation]) return;
-	m_localdecimation = 0;
+	int mode = 0;
+	if (m_samplerate < 800000)
+		mode = 2;
+	// if (directsampling) mode++;
 
-	switch(4 - m_decimation) {
-		case 0: // 1:1 = no decimation
-			// just rotation
-			phase = -(1<<2);
-			for (int pos = 0; pos < len + 3; pos += 4) {
-				phase *= -1;
-				xreal = phase * (2 * buf[pos+0] - 255);
-				yimag = phase * (2 * buf[pos+1] - 255);
-				*it++ = Sample(xreal, yimag);
-				xreal = phase * (255 - 2 * buf[pos+3]);
-				yimag = phase * (2 * buf[pos+2] - 255);
-				*it++ = Sample(xreal, yimag);
-			}
+	switch(mode) {
+		case 0:
+			decimate16(&it, buf, len);
 			break;
-		case 1: // 1:2
-			decimate2(&it, buf, len);
+		case 1:
+			// no_rotate16(&it, buf, len);
 			break;
 
-		case 2: // 1:4
+		case 2:
 			decimate4(&it, buf, len);
 			break;
 
-		case 3: // 1:8
-			decimate8(&it, buf, len);
+		case 3:
+			// norotate4(&it, buf, len);
 			break;
 
 		default:
-		case 4: // 1:16
 			decimate16(&it, buf, len);
 			break;
 	}
diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.h b/plugins/samplesource/rtlsdr/rtlsdrthread.h
index 705dd0419..edb055a4c 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrthread.h
+++ b/plugins/samplesource/rtlsdr/rtlsdrthread.h
@@ -35,7 +35,7 @@ public:
 	void startWork();
 	void stopWork();
 
-	void setDecimation(int decimation);
+	void setSamplerate(int sanplerate);
 
 private:
 	QMutex m_startWaitMutex;
@@ -46,8 +46,7 @@ private:
 	SampleVector m_convertBuffer;
 	SampleFifo* m_sampleFifo;
 
-	int m_decimation;
-	int m_localdecimation;
+	int m_samplerate;
 
 	void run();