mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
fix: stream stops and dies on underflow
This commit is contained in:
parent
ab7bf9c709
commit
cf561e78a8
6 changed files with 60 additions and 27 deletions
|
|
@ -164,9 +164,10 @@ std::unique_ptr<Speaker> ALStream::createSpeaker(bool loop, int channel) {
|
|||
for (uint i = 0; i < ALStream::STREAM_BUFFERS; i++) {
|
||||
uint free_buffer = al->getFreeBuffer();
|
||||
if (!preloadBuffer(free_buffer, loop)) {
|
||||
break;
|
||||
unusedBuffers.push(free_buffer);
|
||||
} else {
|
||||
AL_CHECK(alSourceQueueBuffers(free_source, 1, &free_buffer));
|
||||
}
|
||||
AL_CHECK(alSourceQueueBuffers(free_source, 1, &free_buffer));
|
||||
}
|
||||
return std::make_unique<ALSpeaker>(al, free_source, PRIORITY_HIGH, channel);
|
||||
}
|
||||
|
|
@ -213,11 +214,11 @@ void ALStream::unqueueBuffers(uint alsource) {
|
|||
uint ALStream::enqueueBuffers(uint alsource) {
|
||||
uint preloaded = 0;
|
||||
if (!unusedBuffers.empty()) {
|
||||
uint first_buffer = unusedBuffers.front();
|
||||
if (preloadBuffer(first_buffer, loop)) {
|
||||
uint firstBuffer = unusedBuffers.front();
|
||||
if (preloadBuffer(firstBuffer, loop)) {
|
||||
preloaded++;
|
||||
unusedBuffers.pop();
|
||||
AL_CHECK(alSourceQueueBuffers(alsource, 1, &first_buffer));
|
||||
AL_CHECK(alSourceQueueBuffers(alsource, 1, &firstBuffer));
|
||||
}
|
||||
}
|
||||
return preloaded;
|
||||
|
|
@ -227,14 +228,14 @@ void ALStream::update(double delta) {
|
|||
if (this->speaker == 0) {
|
||||
return;
|
||||
}
|
||||
auto p_speaker = audio::get_speaker(this->speaker);
|
||||
if (p_speaker == nullptr) {
|
||||
auto speaker = audio::get_speaker(this->speaker);
|
||||
if (speaker == nullptr) {
|
||||
this->speaker = 0;
|
||||
return;
|
||||
}
|
||||
ALSpeaker* alspeaker = dynamic_cast<ALSpeaker*>(p_speaker);
|
||||
ALSpeaker* alspeaker = dynamic_cast<ALSpeaker*>(speaker);
|
||||
assert(alspeaker != nullptr);
|
||||
if (alspeaker->stopped) {
|
||||
if (alspeaker->manuallyStopped) {
|
||||
this->speaker = 0;
|
||||
return;
|
||||
}
|
||||
|
|
@ -245,11 +246,11 @@ void ALStream::update(double delta) {
|
|||
uint preloaded = enqueueBuffers(alsource);
|
||||
|
||||
// alspeaker->stopped is assigned to false at ALSpeaker::play(...)
|
||||
if (p_speaker->isStopped() && !alspeaker->stopped) { //TODO: -V560 false-positive?
|
||||
if (preloaded || dynamic_cast<MemoryPCMStream*>(source.get())) {
|
||||
p_speaker->play();
|
||||
} else {
|
||||
p_speaker->stop();
|
||||
if (speaker->isStopped() && !alspeaker->manuallyStopped) { //TODO: -V560 false-positive?
|
||||
if (preloaded) {
|
||||
speaker->play();
|
||||
} else if (isStopOnEnd()){
|
||||
speaker->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -290,6 +291,14 @@ void ALStream::setTime(duration_t time) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ALStream::isStopOnEnd() const {
|
||||
return stopOnEnd;
|
||||
}
|
||||
|
||||
void ALStream::setStopOnEnd(bool flag) {
|
||||
stopOnEnd = flag;
|
||||
}
|
||||
|
||||
ALSpeaker::ALSpeaker(ALAudio* al, uint source, int priority, int channel)
|
||||
: al(al), priority(priority), channel(channel), source(source) {
|
||||
}
|
||||
|
|
@ -356,7 +365,7 @@ void ALSpeaker::setLoop(bool loop) {
|
|||
|
||||
void ALSpeaker::play() {
|
||||
paused = false;
|
||||
stopped = false;
|
||||
manuallyStopped = false;
|
||||
auto p_channel = get_channel(this->channel);
|
||||
AL_CHECK(alSourcef(
|
||||
source,
|
||||
|
|
@ -372,7 +381,7 @@ void ALSpeaker::pause() {
|
|||
}
|
||||
|
||||
void ALSpeaker::stop() {
|
||||
stopped = true;
|
||||
manuallyStopped = true;
|
||||
if (source) {
|
||||
AL_CHECK(alSourceStop(source));
|
||||
|
||||
|
|
@ -436,6 +445,11 @@ int ALSpeaker::getPriority() const {
|
|||
return priority;
|
||||
}
|
||||
|
||||
|
||||
bool ALSpeaker::isManuallyStopped() const {
|
||||
return manuallyStopped;
|
||||
}
|
||||
|
||||
static bool alc_enumeration_ext = false;
|
||||
|
||||
ALAudio::ALAudio(ALCdevice* device, ALCcontext* context)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue