-
Notifications
You must be signed in to change notification settings - Fork 0
/
output.cpp
84 lines (79 loc) · 2.2 KB
/
output.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
#include "output.h"
#include "logger.h"
Output::Output()
: _active(false),
_type(INVALID),
_encoder(0)
{
connect(this, SIGNAL(message(QString)), Logger::getInstance(), SLOT(message(QString)));
connect(this, SIGNAL(warn(QString)), Logger::getInstance(), SLOT(warn(QString)));
connect(this, SIGNAL(error(QString)), Logger::getInstance(), SLOT(error(QString)));
_inbuffer.init(OUTPUT_RINGSIZE);
}
Output::~Output()
{
disconnect(this, SIGNAL(message(QString)), Logger::getInstance(), SLOT(message(QString)));
disconnect(this, SIGNAL(warn(QString)), Logger::getInstance(), SLOT(warn(QString)));
disconnect(this, SIGNAL(error(QString)), Logger::getInstance(), SLOT(error(QString)));
if (_active)
disable();
delete _encoder;
}
void Output::disable()
{
if (_active) {
_active = false;
_workCondition.wakeAll();
wait();
}
}
void Output::run()
{
_active = true;
uint32_t read;
sample_t buffer[OUTPUT_RINGSIZE];
if (_encoder) {
_encoder->setup();
output(_encoder->getBuffer(), _encoder->getBufferValid());
}
while (_active) {
_work.lock();
while (_inbuffer.getFillLevel() == 0) {
_workCondition.wait(&_work);
if (!_active) {
_work.unlock();
return;
}
}
read = _inbuffer.read(buffer, OUTPUT_RINGSIZE);
assert(read != 0);
_work.unlock();
if (_encoder) {
_encoder->encode(buffer, read);
output(_encoder->getBuffer(), _encoder->getBufferValid());
}
}
if (_encoder) {
_encoder->finalize();
output(_encoder->getBuffer(), _encoder->getBufferValid());
}
}
void Output::feed(const sample_t* buffer, uint32_t samples)
{
if (!_active)
return;
// FIXME waittime should be based on the current samplerate
if (_work.tryLock(5)) {
_inbuffer.write(buffer, samples);
if (_inbuffer.getFillLevel() != 0) {
_work.unlock();
_workCondition.wakeOne();
}
else
_work.unlock();
}
else {
// do something about it?
emit message("Dropout in output occurred");
}
}