-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaudioplaythread.cpp
122 lines (90 loc) · 2.81 KB
/
audioplaythread.cpp
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "audioplaythread.h"
#include <QDebug>
#include <QSemaphore>
const int BufferSize = 44100 * 10000;
int iCurrentRead = 0;
int iCurrentWrite = 0;
char buffer[BufferSize];
QSemaphore freeBytes(BufferSize);
QSemaphore usedBytes;
AudioPlayThread::AudioPlayThread(QObject *parent):
QThread (parent),
m_audioOutput(nullptr),
m_audioOutDevice(nullptr),
m_buf(nullptr),
m_index(0)
{
initializeAudio(QAudioDeviceInfo::defaultOutputDevice());
}
void AudioPlayThread::updateAudioData(QByteArray audio)
{
int out_buffer_size = audio.size();
if(freeBytes.tryAcquire(out_buffer_size)){
memcpy(buffer + iCurrentWrite, audio.constData(), out_buffer_size);
iCurrentWrite += out_buffer_size;
iCurrentWrite = iCurrentWrite % BufferSize;
usedBytes.release(out_buffer_size);
}
}
void AudioPlayThread::run()
{
while (1) {
#if 0
QByteArray buffer(32768, 0);
int chunks = m_audioOutput->bytesFree() / m_audioOutput->periodSize();
while (chunks) {
const qint64 len = m_generator->read(buffer.data(), m_audioOutput->periodSize());
if (len)
io->write(buffer.data(), len);
if (len != m_audioOutput->periodSize())
break;
--chunks;
}
#endif
int chunks = m_audioOutput->bytesFree() / m_audioOutput->periodSize();
while (chunks) {
int len = m_audioOutput->periodSize();
if(usedBytes.tryAcquire(len)){
m_audioOutDevice->write(buffer + iCurrentRead, len);
iCurrentRead += len;
iCurrentRead = iCurrentRead % BufferSize;
freeBytes.release();
}
--chunks;
}
}
}
void AudioPlayThread::initializeAudio(const QAudioDeviceInfo &deviceInfo)
{
if(m_audioOutput){
m_audioOutput->stop();
delete m_audioOutput;
m_audioOutput = nullptr;
}
if(m_audioOutDevice){
m_audioOutDevice->close();
delete m_audioOutDevice;
m_audioOutDevice = nullptr;
}
QAudioFormat format;
format.setSampleRate(44100);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
if (!deviceInfo.isFormatSupported(format)) {
qWarning() << "Default format not supported - trying to use nearest";
format = deviceInfo.nearestFormat(format);
}
m_audioOutput = new QAudioOutput(deviceInfo, format);
m_audioOutDevice = m_audioOutput->start();
// m_pcmStream = new PcmStream();
// m_pcmStream->start();
int bf = m_audioOutput->bytesFree();
if(!m_buf){
m_buf = new char[bf * 2000];
}
memset(m_buf, 0, bf * 2000);
m_index = 0;
}