mirror of
https://github.com/JS8Call-improved/JS8Call-improved
synced 2026-08-13 17:47:36 -04:00
QByteArray is an implicitly-shared COW class, and we never change it after we read it into cache, so memory managment can be simpler here. Removed unused decoder instance variable, and moved use of file instance variable to automatic local scope. Converted from QMap to QCache, as order of cached entries is irrelevant to us.
85 lines
2 KiB
C++
85 lines
2 KiB
C++
#include "NotificationAudio.h"
|
|
#include <QDebug>
|
|
#include "Audio/BWFFile.hpp"
|
|
#include "soundout.h"
|
|
|
|
NotificationAudio::NotificationAudio(QObject * parent)
|
|
: QObject {parent}
|
|
, m_stream {new SoundOutput}
|
|
{
|
|
connect(m_stream.data(), &SoundOutput::status, this, &NotificationAudio::status);
|
|
connect(m_stream.data(), &SoundOutput::error, this, &NotificationAudio::error);
|
|
}
|
|
|
|
NotificationAudio::~NotificationAudio()
|
|
{
|
|
stop();
|
|
}
|
|
|
|
void NotificationAudio::status(QString const message)
|
|
{
|
|
if (message == "Idle") stop();
|
|
}
|
|
|
|
void NotificationAudio::error(QString const message)
|
|
{
|
|
qDebug() << "notification error:" << message;
|
|
}
|
|
|
|
void
|
|
NotificationAudio::setDevice(QAudioDevice const & device,
|
|
unsigned const msBuffer)
|
|
{
|
|
m_device = device;
|
|
m_msBuffer = msBuffer;
|
|
m_stream->setFormat(device, 2, msBuffer);
|
|
}
|
|
|
|
void
|
|
NotificationAudio::play(QString const & filePath)
|
|
{
|
|
auto const playEntry = [this, &filePath](auto const it)
|
|
{
|
|
auto const & [format, data] = *it;
|
|
|
|
if (m_buffer.isOpen()) m_buffer.close();
|
|
|
|
m_buffer.setData(data);
|
|
|
|
if (m_buffer.open(QIODevice::ReadOnly))
|
|
{
|
|
qDebug() << "notification: playing" << filePath << "with format" << format;
|
|
|
|
m_stream->setDeviceFormat(m_device, format, m_msBuffer);
|
|
m_stream->restart(&m_buffer);
|
|
}
|
|
};
|
|
|
|
if (auto const it = m_cache.constFind(filePath);
|
|
it != m_cache.constEnd())
|
|
{
|
|
qDebug() << "notifcation: cache hit on" << filePath;
|
|
|
|
playEntry(it);
|
|
}
|
|
else
|
|
{
|
|
qDebug() << "notifcation: cache miss on" << filePath;
|
|
|
|
if (auto file = BWFFile(QAudioFormat{}, filePath);
|
|
file.open(QIODevice::ReadOnly))
|
|
{
|
|
if (auto data = file.readAll();
|
|
!data.isEmpty())
|
|
{
|
|
playEntry(m_cache.emplace(filePath, file.format(), data));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotificationAudio::stop()
|
|
{
|
|
m_stream->stop();
|
|
}
|