mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-21 23:55:13 -05:00
Compare commits
7 Commits
73533231a5
...
0a94970a70
Author | SHA1 | Date | |
---|---|---|---|
|
0a94970a70 | ||
|
875f16f12a | ||
|
c4733a3645 | ||
|
585841e787 | ||
|
bba9d0b421 | ||
|
600e338bab | ||
|
f03499a9a3 |
@ -105,8 +105,8 @@ ADSBDemod::~ADSBDemod()
|
|||||||
delete m_networkManager;
|
delete m_networkManager;
|
||||||
m_deviceAPI->removeChannelSinkAPI(this);
|
m_deviceAPI->removeChannelSinkAPI(this);
|
||||||
m_deviceAPI->removeChannelSink(this);
|
m_deviceAPI->removeChannelSink(this);
|
||||||
|
delete m_basebandSink; // This results in a call to ADSBDemod::stop(), so need to delete before worker and thread
|
||||||
delete m_worker;
|
delete m_worker;
|
||||||
delete m_basebandSink;
|
|
||||||
delete m_thread;
|
delete m_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5113,6 +5113,7 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb
|
|||||||
|
|
||||||
ADSBDemodGUI::~ADSBDemodGUI()
|
ADSBDemodGUI::~ADSBDemodGUI()
|
||||||
{
|
{
|
||||||
|
m_adsbDemod->setMessageQueueToGUI(nullptr);
|
||||||
disconnect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &ADSBDemodGUI::preferenceChanged);
|
disconnect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &ADSBDemodGUI::preferenceChanged);
|
||||||
if (m_templateServer)
|
if (m_templateServer)
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,7 @@ void DemodAnalyzer::start()
|
|||||||
DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker *msg
|
DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker *msg
|
||||||
= DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker::create(m_settings, QList<QString>(), true);
|
= DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker::create(m_settings, QList<QString>(), true);
|
||||||
m_worker->getInputMessageQueue()->push(msg);
|
m_worker->getInputMessageQueue()->push(msg);
|
||||||
|
m_worker->applySampleRate(m_sampleRate);
|
||||||
|
|
||||||
if (m_dataPipe)
|
if (m_dataPipe)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,7 @@ MESSAGE_CLASS_DEFINITION(DemodAnalyzerWorker::MsgConnectFifo, Message)
|
|||||||
|
|
||||||
DemodAnalyzerWorker::DemodAnalyzerWorker() :
|
DemodAnalyzerWorker::DemodAnalyzerWorker() :
|
||||||
m_dataFifo(nullptr),
|
m_dataFifo(nullptr),
|
||||||
|
m_sinkSampleRate(0),
|
||||||
m_msgQueueToFeature(nullptr),
|
m_msgQueueToFeature(nullptr),
|
||||||
m_sampleBufferSize(0),
|
m_sampleBufferSize(0),
|
||||||
m_wavFileRecord(nullptr),
|
m_wavFileRecord(nullptr),
|
||||||
|
@ -67,6 +67,9 @@ if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64))
|
|||||||
add_custom_command(TARGET ${TARGET_NAME}
|
add_custom_command(TARGET ${TARGET_NAME}
|
||||||
POST_BUILD COMMAND
|
POST_BUILD COMMAND
|
||||||
${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api.so.3.15 /usr/local/lib/libsdrplay_api.so.3.15 $<TARGET_FILE:${TARGET_NAME}>)
|
${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api.so.3.15 /usr/local/lib/libsdrplay_api.so.3.15 $<TARGET_FILE:${TARGET_NAME}>)
|
||||||
|
add_custom_command(TARGET ${TARGET_NAME}
|
||||||
|
POST_BUILD COMMAND
|
||||||
|
${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api.so.3 /usr/local/lib/libsdrplay_api.so.3 $<TARGET_FILE:${TARGET_NAME}>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||||
|
@ -204,6 +204,126 @@ bool WavFileRecord::startRecording()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addString(QByteArray& buffer, const QString& type, const QString text)
|
||||||
|
{
|
||||||
|
buffer.append(type.toUtf8(), 4);
|
||||||
|
|
||||||
|
QByteArray s = text.toUtf8();
|
||||||
|
s.append('\0'); // Strings should be null terminated
|
||||||
|
if (s.size() & 1) {
|
||||||
|
s.append('\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 textSize = s.size();
|
||||||
|
buffer.append(textSize & 0xff);
|
||||||
|
buffer.append((textSize >> 8) & 0xff);
|
||||||
|
buffer.append((textSize >> 16) & 0xff);
|
||||||
|
buffer.append((textSize >> 24) & 0xff);
|
||||||
|
|
||||||
|
buffer.append(s, textSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTag(QByteArray& buffer, const QString& id, const QString text)
|
||||||
|
{
|
||||||
|
buffer.append(id.toUtf8(), 4);
|
||||||
|
QByteArray s = text.toUtf8();
|
||||||
|
int size = s.size() + 1;
|
||||||
|
buffer.append((size >> 24) & 0xff); // MSB first
|
||||||
|
buffer.append((size >> 16) & 0xff);
|
||||||
|
buffer.append((size >> 8) & 0xff);
|
||||||
|
buffer.append(size & 0xff);
|
||||||
|
|
||||||
|
buffer.append((char)0); // flags
|
||||||
|
buffer.append((char)0); // flags
|
||||||
|
|
||||||
|
buffer.append((char)0); // text encoding (0 ISO-8859-1, 1 Unicode)
|
||||||
|
buffer.append(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WavFileRecord::setMetaData(const QString& trackTitle, const QString& album, const QString& artist)
|
||||||
|
{
|
||||||
|
m_trackTitle = trackTitle;
|
||||||
|
m_album = album;
|
||||||
|
m_artist = artist;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WavFileRecord::hasMetaData() const
|
||||||
|
{
|
||||||
|
return !m_trackTitle.isEmpty() || !m_album.isEmpty() || !m_artist.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WavFileRecord::writeInfoList()
|
||||||
|
{
|
||||||
|
QByteArray meta;
|
||||||
|
|
||||||
|
meta.append("INFO", 4);
|
||||||
|
|
||||||
|
if (!m_trackTitle.isEmpty()) {
|
||||||
|
addString(meta, "INAM", m_trackTitle);
|
||||||
|
}
|
||||||
|
if (!m_album.isEmpty()) {
|
||||||
|
addString(meta, "IPRD", m_album);
|
||||||
|
}
|
||||||
|
if (!m_artist.isEmpty()) {
|
||||||
|
addString(meta, "IART", m_artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Chunk list;
|
||||||
|
list.m_id[0] = 'L';
|
||||||
|
list.m_id[1] = 'I';
|
||||||
|
list.m_id[2] = 'S';
|
||||||
|
list.m_id[3] = 'T';
|
||||||
|
list.m_size = meta.size();
|
||||||
|
|
||||||
|
m_sampleFile.write((char*)&list, sizeof(Chunk));
|
||||||
|
m_sampleFile.write((char*)meta.data(), meta.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID3 v2.3
|
||||||
|
// https://mutagen-specs.readthedocs.io/en/latest/id3/id3v2.3.0.html
|
||||||
|
void WavFileRecord::writeID3()
|
||||||
|
{
|
||||||
|
QByteArray meta;
|
||||||
|
|
||||||
|
QByteArray textInfo;
|
||||||
|
if (!m_artist.isEmpty()) {
|
||||||
|
addTag(textInfo, "TPE1", m_artist);
|
||||||
|
}
|
||||||
|
if (!m_trackTitle.isEmpty()) {
|
||||||
|
addTag(textInfo, "TIT2", m_trackTitle);
|
||||||
|
}
|
||||||
|
if (!m_album.isEmpty()) {
|
||||||
|
addTag(textInfo, "TALB", m_album);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.append("ID3", 3);
|
||||||
|
meta.append((char)3); // .3 version
|
||||||
|
meta.append((char)0); // revision
|
||||||
|
meta.append((char)0); // flags
|
||||||
|
|
||||||
|
int textInfoSize = textInfo.size();
|
||||||
|
meta.append((textInfoSize >> 24) & 0xff); // MSB first
|
||||||
|
meta.append((textInfoSize >> 16) & 0xff);
|
||||||
|
meta.append((textInfoSize >> 8) & 0xff);
|
||||||
|
meta.append(textInfoSize & 0xff);
|
||||||
|
|
||||||
|
meta.append(textInfo);
|
||||||
|
|
||||||
|
if (meta.size() & 1) {
|
||||||
|
meta.append((char)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Chunk id3;
|
||||||
|
id3.m_id[0] = 'i';
|
||||||
|
id3.m_id[1] = 'd';
|
||||||
|
id3.m_id[2] = '3';
|
||||||
|
id3.m_id[3] = ' ';
|
||||||
|
id3.m_size = meta.size();
|
||||||
|
|
||||||
|
m_sampleFile.write((char*)&id3, sizeof(Chunk));
|
||||||
|
m_sampleFile.write((char*)meta.data(), meta.size());
|
||||||
|
}
|
||||||
|
|
||||||
bool WavFileRecord::stopRecording()
|
bool WavFileRecord::stopRecording()
|
||||||
{
|
{
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
@ -213,6 +333,20 @@ bool WavFileRecord::stopRecording()
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
qDebug() << "WavFileRecord::stopRecording";
|
qDebug() << "WavFileRecord::stopRecording";
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
long dataSize = (long)m_sampleFile.size();
|
||||||
|
#else
|
||||||
|
long dataSize = m_sampleFile.tellp();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Write meta data
|
||||||
|
if (hasMetaData())
|
||||||
|
{
|
||||||
|
writeInfoList();
|
||||||
|
writeID3();
|
||||||
|
}
|
||||||
|
|
||||||
// Fix up chunk sizes
|
// Fix up chunk sizes
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
long fileSize = (long)m_sampleFile.size();
|
long fileSize = (long)m_sampleFile.size();
|
||||||
@ -228,7 +362,7 @@ bool WavFileRecord::stopRecording()
|
|||||||
#else
|
#else
|
||||||
m_sampleFile.seekp(offsetof(Header, m_dataHeader.m_size));
|
m_sampleFile.seekp(offsetof(Header, m_dataHeader.m_size));
|
||||||
#endif
|
#endif
|
||||||
size = fileSize - sizeof(Header);
|
size = dataSize - sizeof(Header);
|
||||||
m_sampleFile.write((char *)&size, 4);
|
m_sampleFile.write((char *)&size, 4);
|
||||||
m_sampleFile.close();
|
m_sampleFile.close();
|
||||||
m_recordOn = false;
|
m_recordOn = false;
|
||||||
|
@ -114,6 +114,9 @@ public:
|
|||||||
virtual bool stopRecording() override;
|
virtual bool stopRecording() override;
|
||||||
virtual bool isRecording() const override { return m_recordOn; }
|
virtual bool isRecording() const override { return m_recordOn; }
|
||||||
|
|
||||||
|
void setMetaData(const QString& trackTitle="", const QString& album="", const QString& artist="");
|
||||||
|
bool hasMetaData() const;
|
||||||
|
|
||||||
static bool readHeader(std::ifstream& samplefile, Header& header, bool check=true);
|
static bool readHeader(std::ifstream& samplefile, Header& header, bool check=true);
|
||||||
static bool readHeader(QFile& samplefile, Header& header);
|
static bool readHeader(QFile& samplefile, Header& header);
|
||||||
static void writeHeader(std::ofstream& samplefile, Header& header);
|
static void writeHeader(std::ofstream& samplefile, Header& header);
|
||||||
@ -140,7 +143,13 @@ private:
|
|||||||
qint64 m_msShift;
|
qint64 m_msShift;
|
||||||
int m_nbChannels;
|
int m_nbChannels;
|
||||||
|
|
||||||
|
QString m_trackTitle;
|
||||||
|
QString m_album;
|
||||||
|
QString m_artist;
|
||||||
|
|
||||||
void writeHeader();
|
void writeHeader();
|
||||||
|
void writeInfoList();
|
||||||
|
void writeID3();
|
||||||
|
|
||||||
static bool checkHeader(Header& header);
|
static bool checkHeader(Header& header);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user