alsa: set period size before buffer size. make it match SAMPLE_COUNT

simplify WriteSample
This commit is contained in:
Flyinghead 2021-03-23 16:27:57 +01:00
parent a4120ef075
commit 73a969b1a4
4 changed files with 36 additions and 43 deletions

View File

@ -111,6 +111,16 @@ static void alsa_init()
return;
}
// Period size (512)
period_size = std::min(SAMPLE_COUNT, (u32)config::AudioBufferSize / 4);
rc = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, nullptr);
if (rc < 0)
{
WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_periods_near %s", snd_strerror(rc));
return;
}
INFO_LOG(AUDIO, "ALSA: period size set to %zd", (size_t)period_size);
// Sample buffer size
buffer_size = config::AudioBufferSize;
rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
@ -121,16 +131,6 @@ static void alsa_init()
}
INFO_LOG(AUDIO, "ALSA: buffer size set to %ld", buffer_size);
// Period size (1024)
period_size = 1024;
rc = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, nullptr);
if (rc < 0)
{
WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_periods_near %s", snd_strerror(rc));
return;
}
INFO_LOG(AUDIO, "ALSA: period size set to %zd", (size_t)period_size);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0)
@ -241,16 +241,19 @@ static u32 alsa_push(const void* frame, u32 samples, bool wait)
}
int rc = snd_pcm_writei(handle, frame, samples);
if (rc == -EPIPE)
if (rc < 0)
{
/* EPIPE means underrun */
snd_pcm_prepare(handle);
// Write some silence then our samples
const size_t silence_size = buffer_size - period_size;
void *silence = alloca(silence_size * 4);
memset(silence, 0, silence_size * 4);
snd_pcm_writei(handle, silence, silence_size);
snd_pcm_writei(handle, frame, samples);
snd_pcm_recover(handle, rc, 1);
if (rc == -EPIPE)
{
// EPIPE means underrun
// Write some silence then our samples
const size_t silence_size = buffer_size - samples;
void *silence = alloca(silence_size * 4);
memset(silence, 0, silence_size * 4);
snd_pcm_writei(handle, silence, silence_size);
snd_pcm_writei(handle, frame, samples);
}
}
return 1;
}

View File

@ -1,14 +1,10 @@
#include "audiostream.h"
#include <algorithm>
#include <memory>
struct SoundFrame { s16 l;s16 r; };
constexpr u32 SAMPLE_COUNT = 512;
struct SoundFrame { s16 l; s16 r; };
static SoundFrame RingBuffer[SAMPLE_COUNT];
static u32 WritePtr; //last WRITTEN sample
static SoundFrame Buffer[SAMPLE_COUNT];
static u32 writePtr; // next sample index
static audiobackend_t *audiobackend_current = nullptr;
static std::unique_ptr<std::vector<audiobackend_t *>> audiobackends; // Using a pointer to avoid out of order init
@ -81,23 +77,17 @@ audiobackend_t* GetAudioBackend(const std::string& slug)
return nullptr;
}
static u32 PushAudio(void* frame, u32 amt, bool wait)
{
if (audiobackend_current != nullptr)
return audiobackend_current->push(frame, amt, wait);
return 0;
}
void WriteSample(s16 r, s16 l)
{
const u32 ptr=(WritePtr+1)%SAMPLE_COUNT;
RingBuffer[ptr].r=r;
RingBuffer[ptr].l=l;
WritePtr=ptr;
Buffer[writePtr].r = r;
Buffer[writePtr].l = l;
if (WritePtr == SAMPLE_COUNT - 1)
PushAudio(RingBuffer,SAMPLE_COUNT, config::LimitFPS);
if (++writePtr == SAMPLE_COUNT)
{
if (audiobackend_current != nullptr)
audiobackend_current->push(Buffer, SAMPLE_COUNT, config::LimitFPS);
writePtr = 0;
}
}
void InitAudio()

View File

@ -26,7 +26,7 @@ typedef struct {
typedef audio_option_t* (*audio_options_func_t)(int* option_count);
typedef void (*audio_backend_init_func_t)();
typedef u32 (*audio_backend_push_func_t)(const void*, u32, bool);
typedef u32 (*audio_backend_push_func_t)(const void *data, u32 frames, bool wait);
typedef void (*audio_backend_term_func_t)();
typedef struct {
std::string slug;
@ -51,3 +51,5 @@ void StopAudioRecording();
u32 GetAudioBackendCount();
audiobackend_t* GetAudioBackend(int num);
audiobackend_t* GetAudioBackend(const std::string& slug);
constexpr u32 SAMPLE_COUNT = 512; // push() is always called with that many frames

View File

@ -291,7 +291,6 @@ jmethodID startRecordingMid;
jmethodID stopRecordingMid;
//stuff for audio
#define SAMPLE_COUNT 512
jshortArray jsamples;
jmethodID writeBufferMid;
jmethodID audioInitMid;
@ -468,7 +467,6 @@ JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsContentBrows
// Audio Stuff
static u32 androidaudio_push(const void* frame, u32 amt, bool wait)
{
verify(amt==SAMPLE_COUNT);
jvm_attacher.getEnv()->SetShortArrayRegion(jsamples, 0, amt * 2, (jshort *)frame);
return jvm_attacher.getEnv()->CallIntMethod(g_audioBackend, writeBufferMid, jsamples, wait);
}