mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 12:30:20 -04:00 
			
		
		
		
	FCDPro: use Qt for FCD audio device handling. Fixes in FCDProPlus
This commit is contained in:
		
							parent
							
								
									f04201a528
								
							
						
					
					
						commit
						af9c693412
					
				| @ -34,7 +34,7 @@ const char *fcd_traits<ProPlus>::displayedName = "FunCube Dongle Pro+"; | ||||
| const char *fcd_traits<Pro>::pluginDisplayedName = "FunCube Pro Input"; | ||||
| const char *fcd_traits<ProPlus>::pluginDisplayedName = "FunCube Pro+ Input"; | ||||
| 
 | ||||
| const char *fcd_traits<Pro>::pluginVersion = "4.0.0"; | ||||
| const char *fcd_traits<Pro>::pluginVersion = "4.3.0"; | ||||
| const char *fcd_traits<ProPlus>::pluginVersion = "4.3.0"; | ||||
| 
 | ||||
| const int64_t fcd_traits<Pro>::loLowLimitFreq = 64000000L; | ||||
|  | ||||
| @ -31,9 +31,6 @@ | ||||
|   <property name="windowTitle"> | ||||
|    <string>FunCubeDongle</string> | ||||
|   </property> | ||||
|   <property name="toolTip"> | ||||
|    <string>start/stop acquisition</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|    <property name="spacing"> | ||||
|     <number>3</number> | ||||
| @ -61,6 +58,9 @@ | ||||
|         <layout class="QHBoxLayout" name="deviceButtonsLayout"> | ||||
|          <item> | ||||
|           <widget class="ButtonSwitch" name="startStop"> | ||||
|            <property name="toolTip"> | ||||
|             <string>start/stop acquisition</string> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string/> | ||||
|            </property> | ||||
| @ -287,7 +287,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="lnaEnhance"/> | ||||
|       <widget class="QComboBox" name="lnaEnhance"> | ||||
|        <property name="toolTip"> | ||||
|         <string>LNA enhancement</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="bandLabel"> | ||||
| @ -297,7 +301,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="band"/> | ||||
|       <widget class="QComboBox" name="band"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Band optimizations</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -311,7 +319,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="bias"/> | ||||
|       <widget class="QComboBox" name="bias"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Band bias</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="label_2"> | ||||
| @ -321,7 +333,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="mode"/> | ||||
|       <widget class="QComboBox" name="mode"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Mode ?</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -335,7 +351,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="lnaGain"/> | ||||
|       <widget class="QComboBox" name="lnaGain"> | ||||
|        <property name="toolTip"> | ||||
|         <string>LNA gain</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="rfFilterLabel"> | ||||
| @ -345,7 +365,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="rfFilter"/> | ||||
|       <widget class="QComboBox" name="rfFilter"> | ||||
|        <property name="toolTip"> | ||||
|         <string>RF filter selection</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -359,7 +383,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="mixGain"/> | ||||
|       <widget class="QComboBox" name="mixGain"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Mixer gain</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="mixFilterLabel"> | ||||
| @ -369,7 +397,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="mixFilter"/> | ||||
|       <widget class="QComboBox" name="mixFilter"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Mixer filter selection</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -383,7 +415,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain1"/> | ||||
|       <widget class="QComboBox" name="gain1"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #1</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="rcFilterLabel"> | ||||
| @ -393,7 +429,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="rcFilter"/> | ||||
|       <widget class="QComboBox" name="rcFilter"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Baseband RC filter selection</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -407,7 +447,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain2"/> | ||||
|       <widget class="QComboBox" name="gain2"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #2</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="gain3Label"> | ||||
| @ -417,7 +461,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain3"/> | ||||
|       <widget class="QComboBox" name="gain3"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #3</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -431,7 +479,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain4"/> | ||||
|       <widget class="QComboBox" name="gain4"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #4</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="label_3"> | ||||
| @ -441,7 +493,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="ifFilter"/> | ||||
|       <widget class="QComboBox" name="ifFilter"> | ||||
|        <property name="toolTip"> | ||||
|         <string>IF filter selection</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
| @ -455,7 +511,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain5"/> | ||||
|       <widget class="QComboBox" name="gain5"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #5</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QLabel" name="gain6Label"> | ||||
| @ -465,7 +525,11 @@ | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="gain6"/> | ||||
|       <widget class="QComboBox" name="gain6"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Gain block #6</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
 | ||||
| // written by Christian Daniel                                                   //
 | ||||
| // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB                              //
 | ||||
| //                                                                               //
 | ||||
| // 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          //
 | ||||
| @ -15,8 +14,6 @@ | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| // FIXME: FCD is handled very badly!
 | ||||
| 
 | ||||
| #include <QDebug> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| @ -27,10 +24,9 @@ | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/dspengine.h" | ||||
| #include "dsp/filerecord.h" | ||||
| #include "device/devicesourceapi.h" | ||||
| 
 | ||||
| #include "fcdproinput.h" | ||||
| 
 | ||||
| #include <device/devicesourceapi.h> | ||||
| 
 | ||||
| #include "fcdprothread.h" | ||||
| #include "fcdtraits.h" | ||||
| #include "fcdproconst.h" | ||||
| @ -47,6 +43,7 @@ FCDProInput::FCDProInput(DeviceSourceAPI *deviceAPI) : | ||||
| 	m_deviceDescription(fcd_traits<Pro>::displayedName), | ||||
| 	m_running(false) | ||||
| { | ||||
|     m_fcdFIFO.setSize(20*fcd_traits<Pro>::convBufSize); | ||||
|     openDevice(); | ||||
|     m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); | ||||
|     m_deviceAPI->addSink(m_fileSink); | ||||
| @ -54,9 +51,13 @@ FCDProInput::FCDProInput(DeviceSourceAPI *deviceAPI) : | ||||
| 
 | ||||
| FCDProInput::~FCDProInput() | ||||
| { | ||||
|     if (m_running) stop(); | ||||
|     if (m_running) { | ||||
|         stop(); | ||||
|     } | ||||
| 
 | ||||
|     m_deviceAPI->removeSink(m_fileSink); | ||||
|     delete m_fileSink; | ||||
| 
 | ||||
|     closeDevice(); | ||||
| } | ||||
| 
 | ||||
| @ -67,15 +68,12 @@ void FCDProInput::destroy() | ||||
| 
 | ||||
| bool FCDProInput::openDevice() | ||||
| { | ||||
|     int device = m_deviceAPI->getSampleSourceSequence(); | ||||
| 
 | ||||
|     if (m_dev != 0) | ||||
|     { | ||||
|     if (m_dev != 0) { | ||||
|         closeDevice(); | ||||
|     } | ||||
| 
 | ||||
|     int device = m_deviceAPI->getSampleSourceSequence(); | ||||
|     qDebug() << "FCDProInput::openDevice with device #" << device; | ||||
| 
 | ||||
|     m_dev = fcdOpen(fcd_traits<Pro>::vendorId, fcd_traits<Pro>::productId, device); | ||||
| 
 | ||||
|     if (m_dev == 0) | ||||
| @ -117,7 +115,17 @@ bool FCDProInput::start() | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	m_FCDThread = new FCDProThread(&m_sampleFifo); | ||||
|     if (!openFCDAudio(fcd_traits<Pro>::qtDeviceName)) | ||||
|     { | ||||
|         qCritical("FCDProInput::start: could not open FCD audio source"); | ||||
|         return false; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         qDebug("FCDProInput::start: FCD audio source opened"); | ||||
|     } | ||||
| 
 | ||||
| 	m_FCDThread = new FCDProThread(&m_sampleFifo, &m_fcdFIFO); | ||||
| 	m_FCDThread->startWork(); | ||||
| 
 | ||||
| //	mutexLocker.unlock();
 | ||||
| @ -139,6 +147,35 @@ void FCDProInput::closeDevice() | ||||
|     m_dev = 0; | ||||
| } | ||||
| 
 | ||||
| bool FCDProInput::openFCDAudio(const char* cardname) | ||||
| { | ||||
|     AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); | ||||
|     const QList<QAudioDeviceInfo>& audioList = audioDeviceManager->getInputDevices(); | ||||
| 
 | ||||
|     for (const auto &itAudio : audioList) | ||||
|     { | ||||
|         if (itAudio.deviceName().contains(QString(cardname))) | ||||
|         { | ||||
|             int fcdDeviceIndex = audioDeviceManager->getInputDeviceIndex(itAudio.deviceName()); | ||||
|             m_fcdAudioInput.start(fcdDeviceIndex, fcd_traits<Pro>::sampleRate); | ||||
|             int fcdSampleRate = m_fcdAudioInput.getRate(); | ||||
|             qDebug("FCDProPlusInput::openFCDAudio: %s index %d at %d S/s", | ||||
|                     itAudio.deviceName().toStdString().c_str(), fcdDeviceIndex, fcdSampleRate); | ||||
|             m_fcdAudioInput.addFifo(&m_fcdFIFO); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     qCritical("FCDProInput::openFCDAudio: device with name %s not found", cardname); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void FCDProInput::closeFCDAudio() | ||||
| { | ||||
|     m_fcdAudioInput.removeFifo(&m_fcdFIFO); | ||||
|     m_fcdAudioInput.stop(); | ||||
| } | ||||
| 
 | ||||
| void FCDProInput::stop() | ||||
| { | ||||
| //	QMutexLocker mutexLocker(&m_mutex);
 | ||||
| @ -148,7 +185,8 @@ void FCDProInput::stop() | ||||
| 		m_FCDThread->stopWork(); | ||||
| 		// wait for thread to quit ?
 | ||||
| 		delete m_FCDThread; | ||||
| 		m_FCDThread = 0; | ||||
| 		m_FCDThread = nullptr; | ||||
| 		closeFCDAudio(); | ||||
| 	} | ||||
| 
 | ||||
| 	m_running = false; | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
 | ||||
| // written by Christian Daniel                                                   //
 | ||||
| // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB                              //
 | ||||
| //                                                                               //
 | ||||
| // 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          //
 | ||||
| @ -22,7 +21,10 @@ | ||||
| #include <QByteArray> | ||||
| #include <inttypes.h> | ||||
| 
 | ||||
| #include <dsp/devicesamplesource.h> | ||||
| #include "dsp/devicesamplesource.h" | ||||
| #include "audio/audioinput.h" | ||||
| #include "audio/audiofifo.h" | ||||
| 
 | ||||
| #include "fcdprosettings.h" | ||||
| #include "fcdhid.h" | ||||
| 
 | ||||
| @ -158,6 +160,8 @@ public: | ||||
| private: | ||||
|     bool openDevice(); | ||||
|     void closeDevice(); | ||||
|     bool openFCDAudio(const char *filename); | ||||
|     void closeFCDAudio(); | ||||
| 	void applySettings(const FCDProSettings& settings, bool force); | ||||
| 	void set_lo_ppm(); | ||||
| 
 | ||||
| @ -165,6 +169,8 @@ private: | ||||
| 
 | ||||
| 	DeviceSourceAPI *m_deviceAPI; | ||||
| 	hid_device *m_dev; | ||||
|     AudioInput m_fcdAudioInput; | ||||
|     AudioFifo m_fcdFIFO; | ||||
| 	QMutex m_mutex; | ||||
| 	FCDProSettings m_settings; | ||||
| 	FCDProThread* m_FCDThread; | ||||
|  | ||||
| @ -18,16 +18,19 @@ | ||||
| #include <QDebug> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include "fcdprothread.h" | ||||
| #include <chrono> | ||||
| #include <thread> | ||||
| 
 | ||||
| #include "dsp/samplesinkfifo.h" | ||||
| #include "fcdtraits.h" | ||||
| #include "audio/audiofifo.h" | ||||
| 
 | ||||
| FCDProThread::FCDProThread(SampleSinkFifo* sampleFifo, QObject* parent) : | ||||
| #include "fcdprothread.h" | ||||
| 
 | ||||
| FCDProThread::FCDProThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent) : | ||||
| 	QThread(parent), | ||||
| 	fcd_handle(NULL), | ||||
| 	m_fcdFIFO(fcdFIFO), | ||||
| 	m_running(false), | ||||
| 	m_convertBuffer(fcd_traits<Pro>::convBufSize), | ||||
| 	m_convertBuffer(fcd_traits<Pro>::convBufSize), // nb samples
 | ||||
| 	m_sampleFifo(sampleFifo) | ||||
| { | ||||
| 	start(); | ||||
| @ -59,107 +62,23 @@ void FCDProThread::stopWork() | ||||
| 
 | ||||
| void FCDProThread::run() | ||||
| { | ||||
| 	if ( !OpenSource(fcd_traits<Pro>::alsaDeviceName) ) | ||||
| 	{ | ||||
| 		qCritical() << "FCDThread::run: cannot open FCD sound card"; | ||||
| 		return; | ||||
| 	} | ||||
| 	// TODO: fallback to original fcd
 | ||||
| 
 | ||||
|     m_running = true; | ||||
|     qDebug("FCDProThread::run: start running loop"); | ||||
| 
 | ||||
|     while (m_running) | ||||
|     { | ||||
| 		if (work(fcd_traits<Pro>::convBufSize) < 0) | ||||
|         work(fcd_traits<Pro>::convBufSize); | ||||
|         std::this_thread::sleep_for(std::chrono::microseconds(200)); | ||||
|     } | ||||
| 
 | ||||
|     qDebug("FCDProThread::run: running loop stopped"); | ||||
|     m_running = false; | ||||
| } | ||||
| 
 | ||||
| void FCDProThread::work(unsigned int n_items) | ||||
| { | ||||
| 			break; | ||||
|     uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
 | ||||
|     SampleVector::iterator it = m_convertBuffer.begin(); | ||||
|     m_decimators.decimate1(&it, m_buf, 2*nbRead); | ||||
|     m_sampleFifo->write(m_convertBuffer.begin(), it); | ||||
| } | ||||
| 	} | ||||
| 
 | ||||
| 	CloseSource(); | ||||
| } | ||||
| 
 | ||||
| bool FCDProThread::OpenSource(const char* cardname) | ||||
| { | ||||
| 	bool fail = false; | ||||
| 	snd_pcm_hw_params_t* params; | ||||
| 	//fcd_rate = FCDPP_RATE;
 | ||||
| 	//fcd_channels =2;
 | ||||
| 	//fcd_format = SND_PCM_SFMT_U16_LE;
 | ||||
| 	snd_pcm_stream_t fcd_stream = SND_PCM_STREAM_CAPTURE; | ||||
| 
 | ||||
| 	if (fcd_handle) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (snd_pcm_open(&fcd_handle, cardname, fcd_stream, 0) < 0) | ||||
| 	{ | ||||
| 		qCritical("FCDThread::OpenSource: cannot open %s", cardname); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	snd_pcm_hw_params_alloca(¶ms); | ||||
| 
 | ||||
| 	if (snd_pcm_hw_params_any(fcd_handle, params) < 0) | ||||
| 	{ | ||||
| 		qCritical("FCDThread::OpenSource: snd_pcm_hw_params_any failed"); | ||||
| 		fail = true; | ||||
| 	} | ||||
| 	else if (snd_pcm_hw_params(fcd_handle, params) < 0) | ||||
| 	{ | ||||
| 		qCritical("FCDThread::OpenSource: snd_pcm_hw_params failed"); | ||||
| 		fail = true; | ||||
| 		// TODO: check actual samplerate, may be crippled firmware
 | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if (snd_pcm_start(fcd_handle) < 0) | ||||
| 		{ | ||||
| 			qCritical("FCDThread::OpenSource: snd_pcm_start failed"); | ||||
| 			fail = true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (fail) | ||||
| 	{ | ||||
| 		snd_pcm_close( fcd_handle ); | ||||
| 		return false; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		qDebug("FCDThread::OpenSource: Funcube stream started"); | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void FCDProThread::CloseSource() | ||||
| { | ||||
| 	if (fcd_handle) | ||||
| 	{ | ||||
| 		snd_pcm_close( fcd_handle ); | ||||
| 	} | ||||
| 
 | ||||
| 	fcd_handle = NULL; | ||||
| } | ||||
| 
 | ||||
| int FCDProThread::work(int n_items) | ||||
| { | ||||
| 	int l; | ||||
| 	SampleVector::iterator it; | ||||
| 	void *out; | ||||
| 
 | ||||
| 	it = m_convertBuffer.begin(); | ||||
| 	out = (void *)&it[0]; | ||||
| 	l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); | ||||
| 	if (l > 0) | ||||
| 		m_sampleFifo->write(it, it + l); | ||||
| 	if (l == -EPIPE) { | ||||
| 		qDebug("FCD: Overrun detected"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return l; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2015 Edouard Griffiths, F4EXB                                   //
 | ||||
| // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB                              //
 | ||||
| //                                                                               //
 | ||||
| // 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          //
 | ||||
| @ -20,33 +20,37 @@ | ||||
| #include <QThread> | ||||
| #include <QMutex> | ||||
| #include <QWaitCondition> | ||||
| #include "dsp/inthalfbandfilter.h" | ||||
| #include <alsa/asoundlib.h> | ||||
| 
 | ||||
| #include "dsp/samplesinkfifo.h" | ||||
| #include "dsp/decimators.h" | ||||
| #include "fcdtraits.h" | ||||
| 
 | ||||
| class AudioFifo; | ||||
| 
 | ||||
| class FCDProThread : public QThread { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
| 	FCDProThread(SampleSinkFifo* sampleFifo, QObject* parent = NULL); | ||||
| 	FCDProThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent = nullptr); | ||||
| 	~FCDProThread(); | ||||
| 
 | ||||
| 	void startWork(); | ||||
| 	void stopWork(); | ||||
| 	bool OpenSource(const char *filename); | ||||
| 	void CloseSource(); | ||||
| 
 | ||||
| private: | ||||
| 	snd_pcm_t* fcd_handle; | ||||
| 	AudioFifo* m_fcdFIFO; | ||||
| 
 | ||||
| 	QMutex m_startWaitMutex; | ||||
| 	QWaitCondition m_startWaiter; | ||||
| 	bool m_running; | ||||
| 
 | ||||
|     qint16 m_buf[fcd_traits<Pro>::convBufSize*2]; // stereo (I, Q)
 | ||||
| 	SampleVector m_convertBuffer; | ||||
| 	SampleSinkFifo* m_sampleFifo; | ||||
| 	Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16> m_decimators; | ||||
| 
 | ||||
| 	void run(); | ||||
| 	int work(int n_items); | ||||
| 	void work(unsigned int n_items); | ||||
| }; | ||||
| 
 | ||||
| #endif // INCLUDE_FCDPROTHREAD_H
 | ||||
|  | ||||
| @ -23,11 +23,10 @@ | ||||
| 
 | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/dspengine.h" | ||||
| #include <dsp/filerecord.h> | ||||
| #include "dsp/filerecord.h" | ||||
| #include "device/devicesourceapi.h" | ||||
| 
 | ||||
| #include "fcdproplusinput.h" | ||||
| 
 | ||||
| #include <device/devicesourceapi.h> | ||||
| 
 | ||||
| #include "fcdproplusthread.h" | ||||
| #include "fcdtraits.h" | ||||
| #include "fcdproplusconst.h" | ||||
| @ -39,7 +38,6 @@ MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgFileRecord, Message) | ||||
| FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : | ||||
|     m_deviceAPI(deviceAPI), | ||||
| 	m_dev(0), | ||||
| 	fcd_handle(0), | ||||
| 	m_settings(), | ||||
| 	m_FCDThread(0), | ||||
| 	m_deviceDescription(fcd_traits<ProPlus>::displayedName), | ||||
| @ -53,9 +51,13 @@ FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : | ||||
| 
 | ||||
| FCDProPlusInput::~FCDProPlusInput() | ||||
| { | ||||
|     if (m_running) stop(); | ||||
|     if (m_running) { | ||||
|         stop(); | ||||
|     } | ||||
| 
 | ||||
|     m_deviceAPI->removeSink(m_fileSink); | ||||
|     delete m_fileSink; | ||||
| 
 | ||||
|     closeDevice(); | ||||
| } | ||||
| 
 | ||||
| @ -66,9 +68,12 @@ void FCDProPlusInput::destroy() | ||||
| 
 | ||||
| bool FCDProPlusInput::openDevice() | ||||
| { | ||||
|     if (m_dev != 0) { | ||||
|         closeDevice(); | ||||
|     } | ||||
| 
 | ||||
|     int device = m_deviceAPI->getSampleSourceSequence(); | ||||
|     qDebug() << "FCDProPlusInput::openDevice with device #" << device; | ||||
| 
 | ||||
|     m_dev = fcdOpen(fcd_traits<ProPlus>::vendorId, fcd_traits<ProPlus>::productId, device); | ||||
| 
 | ||||
|     if (m_dev == 0) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2016 Edouard Griffiths, F4EXB                                   //
 | ||||
| // Copyright (C) 2016-2018 Edouard Griffiths, F4EXB                              //
 | ||||
| //                                                                               //
 | ||||
| // 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          //
 | ||||
| @ -21,8 +21,6 @@ | ||||
| #include <QByteArray> | ||||
| #include <inttypes.h> | ||||
| 
 | ||||
| #include <alsa/asoundlib.h> | ||||
| 
 | ||||
| #include "dsp/devicesamplesource.h" | ||||
| #include "audio/audioinput.h" | ||||
| #include "audio/audiofifo.h" | ||||
| @ -161,7 +159,6 @@ private: | ||||
| 	hid_device *m_dev; | ||||
| 	AudioInput m_fcdAudioInput; | ||||
| 	AudioFifo m_fcdFIFO; | ||||
| 	snd_pcm_t* fcd_handle; | ||||
| 	QMutex m_mutex; | ||||
| 	FCDProPlusSettings m_settings; | ||||
| 	FCDProPlusThread* m_FCDThread; | ||||
|  | ||||
| @ -17,11 +17,14 @@ | ||||
| #include <QDebug> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include "fcdproplusthread.h" | ||||
| #include <chrono> | ||||
| #include <thread> | ||||
| 
 | ||||
| #include "dsp/samplesinkfifo.h" | ||||
| #include "audio/audiofifo.h" | ||||
| 
 | ||||
| #include "fcdproplusthread.h" | ||||
| 
 | ||||
| FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent) : | ||||
| 	QThread(parent), | ||||
| 	m_fcdFIFO(fcdFIFO), | ||||
| @ -61,8 +64,10 @@ void FCDProPlusThread::run() | ||||
| 	m_running = true; | ||||
| 	qDebug("FCDThread::run: start running loop"); | ||||
| 
 | ||||
| 	while (m_running) { | ||||
| 	while (m_running) | ||||
| 	{ | ||||
| 	    work(fcd_traits<ProPlus>::convBufSize); | ||||
| 	    std::this_thread::sleep_for(std::chrono::microseconds(100)); | ||||
| 	} | ||||
| 
 | ||||
| 	qDebug("FCDThread::run: running loop stopped"); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user