1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-07 08:24:43 -04:00

Support FileInput plugin on Android, by using QFile rather istream

This commit is contained in:
Jon Beniston
2023-01-02 15:42:34 +00:00
parent 5be2b1674e
commit d574e74908
10 changed files with 771 additions and 543 deletions
+55 -3
View File
@@ -100,7 +100,17 @@ void FileInput::openFileStream()
{
//stopInput();
if (m_ifstream.is_open()) {
#ifdef ANDROID
if (m_inputFile.isOpen()) {
m_inputFile.close();
}
m_inputFile.setFileName(m_settings.m_fileName);
m_inputFile.open(QIODevice::ReadOnly | QIODevice::ExistingOnly);
quint64 fileSize = (quint64) m_inputFile.size();
#else
if (m_ifstream.is_open()) {
m_ifstream.close();
}
@@ -110,12 +120,18 @@ void FileInput::openFileStream()
m_ifstream.open(m_settings.m_fileName.toStdString().c_str(), std::ios::binary | std::ios::ate);
#endif
quint64 fileSize = m_ifstream.tellg();
#endif
if (m_settings.m_fileName.endsWith(".wav"))
{
WavFileRecord::Header header;
#ifdef ANDROID
m_inputFile.seek(0);
bool headerOK = WavFileRecord::readHeader(m_inputFile, header);
#else
m_ifstream.seekg(0, std::ios_base::beg);
bool headerOK = WavFileRecord::readHeader(m_ifstream, header);
#endif
m_sampleRate = header.m_sampleRate;
if (header.m_auxiHeader.m_size > 0)
{
@@ -136,7 +152,12 @@ void FileInput::openFileStream()
if (headerOK && (m_sampleRate > 0) && (m_sampleSize > 0))
{
m_recordLengthMuSec = ((fileSize - m_ifstream.tellg()) * 1000000UL) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate);
#ifdef ANDROID
qint64 pos = m_inputFile.pos();
#else
qint64 pos = m_ifstream.tellg();
#endif
m_recordLengthMuSec = ((fileSize - pos) * 1000000UL) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate);
}
else
{
@@ -153,8 +174,13 @@ void FileInput::openFileStream()
else if (fileSize > sizeof(FileRecord::Header))
{
FileRecord::Header header;
#ifdef ANDROID
m_inputFile.seek(0);
bool crcOK = FileRecord::readHeader(m_inputFile, header);
#else
m_ifstream.seekg(0,std::ios_base::beg);
bool crcOK = FileRecord::readHeader(m_ifstream, header);
#endif
m_sampleRate = header.sampleRate;
m_centerFrequency = header.centerFrequency;
m_startingTimeStamp = header.startTimeStamp;
@@ -208,7 +234,11 @@ void FileInput::openFileStream()
}
if (m_recordLengthMuSec == 0) {
#ifdef ANDROID
m_inputFile.close();
#else
m_ifstream.close();
#endif
}
}
@@ -216,14 +246,24 @@ void FileInput::seekFileStream(int seekMillis)
{
QMutexLocker mutexLocker(&m_mutex);
if ((m_ifstream.is_open()) && m_fileInputWorker && !m_fileInputWorker->isRunning())
if (
#ifdef ANDROID
m_inputFile.isOpen()
#else
m_ifstream.is_open()
#endif
&& m_fileInputWorker && !m_fileInputWorker->isRunning())
{
quint64 seekPoint = ((m_recordLengthMuSec * seekMillis) / 1000) * m_sampleRate;
seekPoint /= 1000000UL;
m_fileInputWorker->setSamplesCount(seekPoint);
seekPoint *= (m_sampleSize == 24 ? 8 : 4); // + sizeof(FileRecord::Header)
#ifdef ANDROID
m_inputFile.seek(seekPoint + sizeof(FileRecord::Header));
#else
m_ifstream.clear();
m_ifstream.seekg(seekPoint + sizeof(FileRecord::Header), std::ios::beg);
#endif
}
}
@@ -235,7 +275,11 @@ void FileInput::init()
bool FileInput::start()
{
#ifdef ANDROID
if (!m_inputFile.isOpen())
#else
if (!m_ifstream.is_open())
#endif
{
qWarning("FileInput::start: file not open. not starting");
return false;
@@ -244,11 +288,15 @@ bool FileInput::start()
QMutexLocker mutexLocker(&m_mutex);
qDebug() << "FileInput::start";
#ifdef ANDROID
m_inputFile.seek(0);
#else
if (m_ifstream.tellg() != (std::streampos)0)
{
m_ifstream.clear();
m_ifstream.seekg(sizeof(FileRecord::Header), std::ios::beg);
}
#endif
if (!m_sampleFifo.setSize(m_settings.m_accelerationFactor * m_sampleRate * sizeof(Sample)))
{
@@ -256,7 +304,11 @@ bool FileInput::start()
return false;
}
#ifdef ANDROID
m_fileInputWorker = new FileInputWorker(&m_inputFile, &m_sampleFifo, m_masterTimer, &m_inputMessageQueue);
#else
m_fileInputWorker = new FileInputWorker(&m_ifstream, &m_sampleFifo, m_masterTimer, &m_inputMessageQueue);
#endif
m_fileInputWorker->moveToThread(&m_fileInputWorkerThread);
m_fileInputWorker->setSampleRateAndSize(m_settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed
startWorker();
@@ -28,6 +28,7 @@
#include <QThread>
#include <QMutex>
#include <QNetworkRequest>
#include <QFile>
#include "dsp/devicesamplesource.h"
#include "fileinputsettings.h"
@@ -334,7 +335,11 @@ public:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
FileInputSettings m_settings;
#ifdef ANDROID
QFile m_inputFile;
#else
std::ifstream m_ifstream;
#endif
FileInputWorker* m_fileInputWorker;
QThread m_fileInputWorkerThread;
QString m_deviceDescription;
@@ -28,6 +28,7 @@
#include "gui/colormapper.h"
#include "gui/glspectrum.h"
#include "gui/basicdevicesettingsdialog.h"
#include "gui/dialogpositioner.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
@@ -313,7 +314,8 @@ void FileInputGUI::on_showFileDialog_clicked(bool checked)
{
(void) checked;
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq *.wav)"), 0, QFileDialog::DontUseNativeDialog);
tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq *.wav)"), 0);
if (fileName != "")
{
@@ -450,6 +452,7 @@ void FileInputGUI::openDeviceSettingsDialog(const QPoint& p)
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
dialog.move(p);
new DialogPositioner(&dialog, false);
dialog.exec();
m_settings.m_useReverseAPI = dialog.useReverseAPI();
@@ -26,7 +26,12 @@
MESSAGE_CLASS_DEFINITION(FileInputWorker::MsgReportEOF, Message)
FileInputWorker::FileInputWorker(std::ifstream *samplesStream,
FileInputWorker::FileInputWorker(
#ifdef ANDROID
QFile *samplesStream,
#else
std::ifstream *samplesStream,
#endif
SampleSinkFifo* sampleFifo,
const QTimer& timer,
MessageQueue *fileInputMessageQueue,
@@ -69,7 +74,11 @@ void FileInputWorker::startWork()
{
qDebug() << "FileInputThread::startWork: ";
#ifdef ANDROID
if (m_ifstream->isOpen())
#else
if (m_ifstream->is_open())
#endif
{
qDebug() << "FileInputThread::startWork: file stream open, starting...";
m_elapsedTimer.start();
@@ -172,6 +181,23 @@ void FileInputWorker::tick()
setBuffers(m_chunksize);
}
#ifdef ANDROID
// read samples directly feeding the SampleFifo (no callback)
qint64 bytesRead = m_ifstream->read(reinterpret_cast<char*>(m_fileBuf), m_chunksize);
if (m_ifstream->atEnd())
{
writeToSampleFifo(m_fileBuf, (qint32) bytesRead);
MsgReportEOF *message = MsgReportEOF::create();
m_fileInputMessageQueue->push(message);
}
else
{
writeToSampleFifo(m_fileBuf, (qint32) m_chunksize);
m_samplesCount += m_chunksize / (2 * m_samplebytes);
}
#else
// read samples directly feeding the SampleFifo (no callback)
m_ifstream->read(reinterpret_cast<char*>(m_fileBuf), m_chunksize);
@@ -186,6 +212,7 @@ void FileInputWorker::tick()
writeToSampleFifo(m_fileBuf, (qint32) m_chunksize);
m_samplesCount += m_chunksize / (2 * m_samplebytes);
}
#endif
}
}
@@ -50,7 +50,12 @@ public:
{ }
};
FileInputWorker(std::ifstream *samplesStream,
FileInputWorker(
#ifdef ANDROID
QFile *samplesStream,
#else
std::ifstream *samplesStream,
#endif
SampleSinkFifo* sampleFifo,
const QTimer& timer,
MessageQueue *fileInputMessageQueue,
@@ -68,7 +73,11 @@ public:
private:
volatile bool m_running;
#ifdef ANDROID
QFile *m_ifstream;
#else
std::ifstream* m_ifstream;
#endif
quint8 *m_fileBuf;
quint8 *m_convertBuf;
std::size_t m_bufsize;