1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-28 15:56:33 -04:00

MIMO: test MI source: implemented file record

This commit is contained in:
f4exb 2019-05-28 08:56:36 +02:00
parent f9a8523714
commit bb8366bfde
8 changed files with 70 additions and 25 deletions

View File

@ -49,11 +49,9 @@ TestMI::TestMI(DeviceAPI *deviceAPI) :
m_running(false), m_running(false),
m_masterTimer(deviceAPI->getMasterTimer()) m_masterTimer(deviceAPI->getMasterTimer())
{ {
m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
m_deviceAPI->setNbSourceStreams(2); m_deviceAPI->setNbSourceStreams(2);
m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs
m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs
//m_deviceAPI->addAncillarySink(m_fileSink); TODO: implement when active
m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4)); m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4));
m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4)); m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4));
m_networkManager = new QNetworkAccessManager(); m_networkManager = new QNetworkAccessManager();
@ -69,10 +67,17 @@ TestMI::~TestMI()
stop(); stop();
} }
m_deviceAPI->removeAncillarySink(m_fileSink); std::vector<FileRecord*>::iterator it = m_fileSinks.begin();
int istream = 0;
for (; it != m_fileSinks.end(); ++it, istream++)
{
m_deviceAPI->removeAncillarySink(*it, istream);
delete *it;
}
m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine
m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine
delete m_fileSink;
} }
void TestMI::destroy() void TestMI::destroy()
@ -82,6 +87,11 @@ void TestMI::destroy()
void TestMI::init() void TestMI::init()
{ {
m_fileSinks.push_back(new FileRecord(QString("test_0_%1.sdriq").arg(m_deviceAPI->getDeviceUID())));
m_fileSinks.push_back(new FileRecord(QString("test_1_%1.sdriq").arg(m_deviceAPI->getDeviceUID())));
m_deviceAPI->addAncillarySink(m_fileSinks[0], 0);
m_deviceAPI->addAncillarySink(m_fileSinks[1], 1);
applySettings(m_settings, true); applySettings(m_settings, true);
} }
@ -216,20 +226,21 @@ bool TestMI::handleMessage(const Message& message)
{ {
MsgFileRecord& conf = (MsgFileRecord&) message; MsgFileRecord& conf = (MsgFileRecord&) message;
qDebug() << "TestMI::handleMessage: MsgFileRecord: " << conf.getStartStop(); qDebug() << "TestMI::handleMessage: MsgFileRecord: " << conf.getStartStop();
int istream = conf.getStreamIndex();
if (conf.getStartStop()) if (conf.getStartStop())
{ {
if (m_settings.m_fileRecordName.size() != 0) { if (m_settings.m_fileRecordName.size() != 0) {
m_fileSink->setFileName(m_settings.m_fileRecordName); m_fileSinks[istream]->setFileName(m_settings.m_fileRecordName + "_0.sdriq");
} else { } else {
m_fileSink->genUniqueFileName(m_deviceAPI->getDeviceUID()); m_fileSinks[istream]->genUniqueFileName(m_deviceAPI->getDeviceUID(), istream);
} }
m_fileSink->startRecording(); m_fileSinks[istream]->startRecording();
} }
else else
{ {
m_fileSink->stopRecording(); m_fileSinks[istream]->stopRecording();
} }
return true; return true;
@ -421,7 +432,7 @@ bool TestMI::applySettings(const TestMISettings& settings, bool force)
{ {
int sampleRate = settings.m_streams[istream].m_sampleRate/(1<<settings.m_streams[istream].m_log2Decim); int sampleRate = settings.m_streams[istream].m_sampleRate/(1<<settings.m_streams[istream].m_log2Decim);
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_streams[istream].m_centerFrequency); DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_streams[istream].m_centerFrequency);
m_fileSink->handleMessage(*notif); // forward to file sink m_fileSinks[istream]->handleMessage(*notif); // forward to file sink
DSPDeviceMIMOEngine::SignalNotification *engineNotif = new DSPDeviceMIMOEngine::SignalNotification( DSPDeviceMIMOEngine::SignalNotification *engineNotif = new DSPDeviceMIMOEngine::SignalNotification(
sampleRate, settings.m_streams[istream].m_centerFrequency, true, 0); sampleRate, settings.m_streams[istream].m_centerFrequency, true, 0);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(engineNotif); m_deviceAPI->getDeviceEngineInputMessageQueue()->push(engineNotif);
@ -820,3 +831,12 @@ void TestMI::networkManagerFinished(QNetworkReply *reply)
answer.chop(1); // remove last \n answer.chop(1); // remove last \n
qDebug("TestMI::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); qDebug("TestMI::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
} }
bool TestMI::isRecording(unsigned int istream) const
{
if (istream < m_fileSinks.size()) {
return m_fileSinks[istream]->isRecording();
} else {
return false;
}
}

View File

@ -63,17 +63,20 @@ public:
public: public:
bool getStartStop() const { return m_startStop; } bool getStartStop() const { return m_startStop; }
int getStreamIndex() const { return m_streamIndex; }
static MsgFileRecord* create(bool startStop) { static MsgFileRecord* create(bool startStop, int streamIndex) {
return new MsgFileRecord(startStop); return new MsgFileRecord(startStop, streamIndex);
} }
protected: protected:
bool m_startStop; bool m_startStop;
int m_streamIndex;
MsgFileRecord(bool startStop) : MsgFileRecord(bool startStop, int streamIndex) :
Message(), Message(),
m_startStop(startStop) m_startStop(startStop),
m_streamIndex(streamIndex)
{ } { }
}; };
@ -141,6 +144,8 @@ public:
SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGDeviceState& response,
QString& errorMessage); QString& errorMessage);
bool isRecording(unsigned int istream) const;
private: private:
struct DeviceSettingsKeys struct DeviceSettingsKeys
{ {
@ -149,7 +154,7 @@ private:
}; };
DeviceAPI *m_deviceAPI; DeviceAPI *m_deviceAPI;
FileRecord *m_fileSink; //!< File sink to record device I/Q output std::vector<FileRecord *> m_fileSinks; //!< File sinks to record device I/Q output
QMutex m_mutex; QMutex m_mutex;
TestMISettings m_settings; TestMISettings m_settings;
std::vector<TestMIThread*> m_testSourceThreads; std::vector<TestMIThread*> m_testSourceThreads;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB // // Copyright (C) 2019 Edouard Griffiths, F4EXB //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -145,6 +145,7 @@ void TestMIGui::on_startStop_toggled(bool checked)
void TestMIGui::on_streamIndex_currentIndexChanged(int index) void TestMIGui::on_streamIndex_currentIndexChanged(int index)
{ {
m_streamIndex = index; m_streamIndex = index;
updateFileRecordStatus();
displaySettings(); displaySettings();
} }
@ -296,7 +297,7 @@ void TestMIGui::on_record_toggled(bool checked)
ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
TestMI::MsgFileRecord* message = TestMI::MsgFileRecord::create(checked); TestMI::MsgFileRecord* message = TestMI::MsgFileRecord::create(checked, m_streamIndex);
m_sampleMIMO->getInputMessageQueue()->push(message); m_sampleMIMO->getInputMessageQueue()->push(message);
} }
@ -376,6 +377,15 @@ void TestMIGui::updateFrequencyShiftLimit()
ui->frequencyShift->setValueRange(false, 7, -sampleRate, sampleRate); ui->frequencyShift->setValueRange(false, 7, -sampleRate, sampleRate);
} }
void TestMIGui::updateFileRecordStatus()
{
if (((TestMI*) m_sampleMIMO)->isRecording(m_streamIndex)) {
ui->record->setStyleSheet("QToolButton { background-color : red; }");
} else {
ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
}
void TestMIGui::displaySettings() void TestMIGui::displaySettings()
{ {
blockApplySettings(true); blockApplySettings(true);

View File

@ -77,6 +77,7 @@ private:
void updateAmpCoarseLimit(); void updateAmpCoarseLimit();
void updateAmpFineLimit(); void updateAmpFineLimit();
void updateFrequencyShiftLimit(); void updateFrequencyShiftLimit();
void updateFileRecordStatus();
private slots: private slots:
void handleInputMessages(); void handleInputMessages();

View File

@ -86,22 +86,26 @@ void DeviceAPI::removeLastSinkStream()
} }
} }
void DeviceAPI::addAncillarySink(BasebandSampleSink *sink) void DeviceAPI::addAncillarySink(BasebandSampleSink *sink, unsigned int index)
{ {
if (m_deviceSourceEngine) { if (m_deviceSourceEngine) {
m_deviceSourceEngine->addSink(sink); m_deviceSourceEngine->addSink(sink);
} else if (m_deviceSinkEngine) { } else if (m_deviceSinkEngine) {
m_deviceSinkEngine->addSpectrumSink(sink); m_deviceSinkEngine->addSpectrumSink(sink);
} // TODO: MIMO } else if (m_deviceMIMOEngine) {
m_deviceMIMOEngine->addAncillarySink(sink, index);
}
} }
void DeviceAPI::removeAncillarySink(BasebandSampleSink* sink) void DeviceAPI::removeAncillarySink(BasebandSampleSink* sink, unsigned int index)
{ {
if (m_deviceSourceEngine) { if (m_deviceSourceEngine) {
m_deviceSourceEngine->removeSink(sink); m_deviceSourceEngine->removeSink(sink);
} else if (m_deviceSinkEngine) { } else if (m_deviceSinkEngine) {
m_deviceSinkEngine->removeSpectrumSink(sink); m_deviceSinkEngine->removeSpectrumSink(sink);
} // TODO: MIMO } else if (m_deviceMIMOEngine) {
m_deviceMIMOEngine->removeAncillarySink(sink, index);
}
} }
void DeviceAPI::setSpectrumSinkInput(bool sourceElseSink, unsigned int index) void DeviceAPI::setSpectrumSinkInput(bool sourceElseSink, unsigned int index)

View File

@ -72,8 +72,8 @@ public:
void addSinkStream(bool connect); void addSinkStream(bool connect);
void removeLastSinkStream(); void removeLastSinkStream();
void addAncillarySink(BasebandSampleSink* sink); //!< Adds a sink to receive full baseband and that is not a channel (e.g. spectrum) void addAncillarySink(BasebandSampleSink* sink, unsigned int index = 0); //!< Adds a sink to receive full baseband and that is not a channel (e.g. spectrum)
void removeAncillarySink(BasebandSampleSink* sink); //!< Removes it void removeAncillarySink(BasebandSampleSink* sink, unsigned int index = 0); //!< Removes it
void setSpectrumSinkInput(bool sourceElseSink = true, unsigned int index = 0); //!< Used in the MIMO case to select which stream is used as input to main spectrum void setSpectrumSinkInput(bool sourceElseSink = true, unsigned int index = 0); //!< Used in the MIMO case to select which stream is used as input to main spectrum
void addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0); //!< Add a channel sink (Rx) void addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0); //!< Add a channel sink (Rx)

View File

@ -64,9 +64,13 @@ void FileRecord::setFileName(const QString& filename)
} }
} }
void FileRecord::genUniqueFileName(uint deviceUID) void FileRecord::genUniqueFileName(uint deviceUID, int istream)
{ {
setFileName(QString("rec%1_%2.sdriq").arg(deviceUID).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz"))); if (istream < 0) {
setFileName(QString("rec%1_%2.sdriq").arg(deviceUID).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz")));
} else {
setFileName(QString("rec%1_%2_%3.sdriq").arg(deviceUID).arg(istream).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz")));
}
} }
void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly)

View File

@ -50,7 +50,7 @@ public:
quint64 getByteCount() const { return m_byteCount; } quint64 getByteCount() const { return m_byteCount; }
void setFileName(const QString& filename); void setFileName(const QString& filename);
void genUniqueFileName(uint deviceUID); void genUniqueFileName(uint deviceUID, int istream = -1);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start(); virtual void start();
@ -58,6 +58,7 @@ public:
virtual bool handleMessage(const Message& message); virtual bool handleMessage(const Message& message);
void startRecording(); void startRecording();
void stopRecording(); void stopRecording();
bool isRecording() const { return m_recordOn; }
static bool readHeader(std::ifstream& samplefile, Header& header); //!< returns true if CRC checksum is correct else false static bool readHeader(std::ifstream& samplefile, Header& header); //!< returns true if CRC checksum is correct else false
static void writeHeader(std::ofstream& samplefile, Header& header); static void writeHeader(std::ofstream& samplefile, Header& header);