Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
1.6.0-bacon15
Finally solve "Audio randomly dies" issue

Various additions
FX Command Box selector (#238)
* In phrase and table views a selection box appears when editing FX commands
Expand Down
28 changes: 20 additions & 8 deletions sources/Adapters/SDL2/Audio/SDLAudioDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ void sdl_callback(void *userdata, Uint8 *stream, int len) {
};

SDLAudioDriverThread::SDLAudioDriverThread(SDLAudioDriver *driver) {
semaphore_ = SysSemaphore::Create(0, 4);
// Uncap the semaphore to prevent dropped requests during long OS stalls.
semaphore_=SysSemaphore::Create(0,1024);
driver_ = driver;
};

Expand Down Expand Up @@ -62,6 +63,9 @@ bool SDLAudioDriver::InitDriver() {
input.samples = settings_.bufferSize_;
input.userdata = this;

SDL_SetHint("APP_NAME", "LittleGPTracker");
SDL_SetHint("AUDIO_DEVICE_APP_NAME", "LittleGPTracker");
Comment thread
djdiskmachine marked this conversation as resolved.

// On my machine this wasn't working.
// SDL_AudioDeviceID deviceId =
// SDL_OpenAudioDevice(NULL,0,&input,&returned,0); The above may return 0
Expand All @@ -83,8 +87,8 @@ bool SDLAudioDriver::InitDriver() {
mainBuffer_ = (char *)((((int)unalignedMain_) + 1) & (0xFFFFFFFC));
#endif

Trace::Log("AUDIO", "%s successfully opened with %d samples", driverName,
fragSize_ / 4);
Trace::Log("AUDIO", "%s successfully opened with %d samples %d", driverName,
fragSize_ / 4, returned.freq);

// Create mini blank buffer in case of underruns

Expand Down Expand Up @@ -153,22 +157,24 @@ void SDLAudioDriver::OnChunkDone(Uint8 *stream, int len) {
while (bufferSize_ - bufferPos_ < len) {

// First move remaining bytes at the front
memcpy(mainBuffer_, mainBuffer_ + bufferPos_, bufferSize_ - bufferPos_);
memmove(mainBuffer_, mainBuffer_ + bufferPos_,
bufferSize_ - bufferPos_);

// then get next queued buffer and copy data from it

if (pool_[poolPlayPosition_].buffer_ == 0) {
SYS_MEMCPY(mainBuffer_ + bufferSize_ - bufferPos_, miniBlank_, len);
bufferSize_ = bufferSize_ - bufferPos_ + len;

// Use fragSize_ instead of len! miniBlank_ is only allocated to
// fragSize_. Using len causes a buffer over-read if SDL requests a
// larger chunk.
SYS_MEMCPY(mainBuffer_+bufferSize_-bufferPos_, miniBlank_, fragSize_);
bufferSize_=bufferSize_-bufferPos_+fragSize_ ;
bufferPos_ = 0;
} else {

memcpy(mainBuffer_ + bufferSize_ - bufferPos_,
pool_[poolPlayPosition_].buffer_,
pool_[poolPlayPosition_].size_);

MidiService::GetInstance()->Flush();
// Adapt buffer variables

bufferSize_ =
Expand All @@ -181,6 +187,12 @@ void SDLAudioDriver::OnChunkDone(Uint8 *stream, int len) {
poolPlayPosition_ = (poolPlayPosition_ + 1) % SOUND_BUFFER_COUNT;
if (thread_)
thread_->Notify();
// Tick the engine and flush MIDI ONLY when a real logical block is
// processed! This keeps the sequencer perfectly in sync with the
// audio pool consumption, and prevents runaway MIDI generation on
// underruns which fills the ALSA buffer and freezes the thread.
onAudioBufferTick();
MidiService::GetInstance()->Flush() ;
}
}
// Now dump audio to the device
Expand Down
2 changes: 1 addition & 1 deletion sources/Application/Model/Project.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#define PROJECT_NUMBER "1"
#define PROJECT_RELEASE "6"
#define BUILD_COUNT "0-bacon14"
#define BUILD_COUNT "0-bacon15"

#define MAX_TAP 3

Expand Down
Loading