-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathDigitalRenderer_audioqueue.i
80 lines (64 loc) · 2.21 KB
/
DigitalRenderer_audioqueue.i
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
/*
Frodo, Commodore 64 emulator for the iPhone
Copyright (C) 2007-2010 Stuart Carnie
See gpl.txt for license information.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
void DigitalRenderer::init_sound() {
sid_filters = ThePrefs.SIDFilters;
_audioQueue = new CAudioQueueManager(SAMPLE_FREQ, FRAGMENT_SIZE, MonoSound);
_audioQueue->start();
if (!ThePrefs.SIDOn)
Pause();
ready = true;
}
DigitalRenderer::~DigitalRenderer() {
if (_audioQueue) {
// default is to auto-delete
_audioQueue->stop();
}
}
void DigitalRenderer::VBlank() {
// Convert latency preferences from milliseconds to frags.
int lead_hiwater = ThePrefs.LatencyMax;
int lead_lowater = ThePrefs.LatencyMin;
long remainingMilliseconds = _audioQueue->remainingMilliseconds();
if (remainingMilliseconds > lead_hiwater)
return;
// Calculate one frag.
short* buffer = _audioQueue->getNextBuffer();
if (!buffer)
return;
calc_buffer(buffer, FRAGMENT_SIZE);
_audioQueue->queueBuffer(buffer);
int neededMilliseconds = lead_lowater - _audioQueue->remainingMilliseconds();
// If we're getting too far behind the audio add an extra frag.
if (neededMilliseconds > 0) {
const int millisecondsPerFragment = (float)FRAGMENT_SIZE / (float)SAMPLE_FREQ * 1000.0;
int neededFragments = neededMilliseconds / millisecondsPerFragment;
while (neededFragments--) {
short* buffer = _audioQueue->getNextBuffer();
if (buffer) {
calc_buffer(buffer, FRAGMENT_SIZE);
_audioQueue->queueBuffer(buffer);
} else
break;
}
}
}
void DigitalRenderer::Pause() {
_audioQueue->pause();
}
void DigitalRenderer::Resume() {
if (ThePrefs.SIDOn)
_audioQueue->resume();
}