96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "NotificationAudio.h"
 | |
| #include "WaveFile.h"
 | |
| 
 | |
| 
 | |
| NotificationAudio::NotificationAudio(QObject *parent):
 | |
|     QObject(parent)
 | |
| {
 | |
|     m_file = new BWFFile(QAudioFormat{}, this);
 | |
| 
 | |
|     m_stream = new SoundOutput();
 | |
| 
 | |
|     connect(m_stream, &SoundOutput::status, this, &NotificationAudio::status);
 | |
|     connect(m_stream, &SoundOutput::error, this, &NotificationAudio::error);
 | |
| }
 | |
| 
 | |
| NotificationAudio::~NotificationAudio(){
 | |
|     // stop the audio
 | |
|     stop();
 | |
| 
 | |
|     // clean cache
 | |
|     foreach(auto pair, m_cache){
 | |
|         delete pair.second;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void NotificationAudio::status(QString message){
 | |
|     if(message == "Idle"){
 | |
|         stop();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void NotificationAudio::error(QString message){
 | |
|     qDebug() << "notification error:" << message;
 | |
| }
 | |
| 
 | |
| void NotificationAudio::setDevice(const QAudioDeviceInfo &device, unsigned channels, unsigned msBuffer){
 | |
|     m_device = device;
 | |
|     m_channels = channels;
 | |
|     m_msBuffer = msBuffer;
 | |
|     m_stream->setFormat(device, channels, msBuffer);
 | |
| }
 | |
| 
 | |
| void NotificationAudio::play(const QString &filePath){
 | |
|     if(m_cache.contains(filePath)){
 | |
|         auto pair = m_cache.value(filePath);
 | |
|         auto format = pair.first;
 | |
|         auto bytes = pair.second;
 | |
| 
 | |
|         qDebug() << "notification: playing" << filePath << "with format" << format << "from cache";
 | |
|         playBytes(format, bytes);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if(m_file->isOpen()){
 | |
|         m_file->close();
 | |
|     }
 | |
|     m_file->setFileName(filePath);
 | |
|     if(m_file->open(BWFFile::ReadOnly)){
 | |
|         QAudioFormat format = m_file->format();
 | |
|         QByteArray *bytes = new QByteArray(m_file->readAll());
 | |
| 
 | |
|         qDebug() << "notification: playing" << filePath << "with format" << format << "from disk";
 | |
|         playBytes(format, bytes);
 | |
| 
 | |
|         // cache the buffer
 | |
|         m_cache.insert(filePath, {format, bytes});
 | |
|     }
 | |
| }
 | |
| 
 | |
| void NotificationAudio::playBytes(const QAudioFormat &format, QByteArray *bytes){
 | |
|     if(bytes == nullptr){
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if(m_buffer.isOpen()){
 | |
|         m_buffer.close();
 | |
|     }
 | |
| 
 | |
|     m_buffer.setBuffer(bytes);
 | |
| 
 | |
|     if(!m_buffer.open(QIODevice::ReadOnly)){
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     m_stream->setDeviceFormat(m_device, format, format.channelCount(), m_msBuffer);
 | |
|     m_stream->restart(&m_buffer);
 | |
| }
 | |
| 
 | |
| void NotificationAudio::stop(){
 | |
|     m_stream->stop();
 | |
| 
 | |
|     if(m_file->isOpen()){
 | |
|         m_file->close();
 | |
|     }
 | |
| }
 | 
