File: NotificationAudio.cpp

package info (click to toggle)
js8call 2.2.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 22,416 kB
  • sloc: cpp: 563,285; f90: 9,265; ansic: 937; python: 132; sh: 93; makefile: 6
file content (95 lines) | stat: -rw-r--r-- 2,335 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#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();
    }
}