Allow get sample rate in conf.lua, read back with lovr.audio.getSampleRate()

This commit is contained in:
mcc 2021-07-14 15:38:21 -04:00 committed by Bjorn
parent 2a73310198
commit 56138492f2
6 changed files with 31 additions and 10 deletions

View File

@ -202,6 +202,11 @@ static int l_lovrAudioGetSpatializer(lua_State *L) {
return 1;
}
static int l_lovrAudioGetSampleRate(lua_State *L) {
lua_pushnumber(L, lovrAudioGetSampleRate());
return 1;
}
static int l_lovrAudioGetAbsorption(lua_State* L) {
float absorption[3];
lovrAudioGetAbsorption(absorption);
@ -290,6 +295,7 @@ static const luaL_Reg lovrAudio[] = {
{ "setPose", l_lovrAudioSetPose },
{ "setGeometry", l_lovrAudioSetGeometry },
{ "getSpatializer", l_lovrAudioGetSpatializer },
{ "getSampleRate", l_lovrAudioGetSampleRate },
{ "getAbsorption", l_lovrAudioGetAbsorption },
{ "setAbsorption", l_lovrAudioSetAbsorption },
{ "newSource", l_lovrAudioNewSource },
@ -305,6 +311,7 @@ int luaopen_lovr_audio(lua_State* L) {
bool start = true;
const char *spatializer = NULL;
int sampleRate = DEFAULT_SAMPLE_RATE;
luax_pushconf(L);
lua_getfield(L, -1, "audio");
if (lua_istable(L, -1)) {
@ -312,13 +319,19 @@ int luaopen_lovr_audio(lua_State* L) {
spatializer = lua_tostring(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "sampleRate");
int userSampleRate = luaL_optnumber(L, -1, 0);
if (userSampleRate > 0)
sampleRate = userSampleRate;
lua_pop(L, 1);
lua_getfield(L, -1, "start");
start = lua_isnil(L, -1) || lua_toboolean(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 2);
if (lovrAudioInit(spatializer)) {
if (lovrAudioInit(spatializer, sampleRate)) {
luax_atexit(L, lovrAudioDestroy);
if (start) {
lovrAudioSetDevice(AUDIO_PLAYBACK, NULL, 0, NULL, AUDIO_SHARED);

View File

@ -52,6 +52,7 @@ static struct {
float leftovers[BUFFER_SIZE * 2];
float absorption[3];
ma_data_converter playbackConverter;
int sampleRate;
} state;
static const ma_format miniaudioFormats[] = {
@ -226,9 +227,11 @@ static Spatializer* spatializers[] = {
// Entry
bool lovrAudioInit(const char* spatializer) {
bool lovrAudioInit(const char* spatializer, int sampleRate) {
if (state.initialized) return false;
state.sampleRate = sampleRate;
ma_result result = ma_context_init(NULL, 0, NULL, &state.context);
lovrAssert(result == MA_SUCCESS, "Failed to initialize miniaudio");
@ -295,7 +298,7 @@ bool lovrAudioSetDevice(AudioType type, void* id, size_t size, Sound* sink, Audi
// If no sink is provided for a capture device, one is created internally
if (type == AUDIO_CAPTURE && !sink) {
sink = lovrSoundCreateStream(SAMPLE_RATE * 1., SAMPLE_F32, CHANNEL_MONO, SAMPLE_RATE);
sink = lovrSoundCreateStream(state.sampleRate * 1., SAMPLE_F32, CHANNEL_MONO, state.sampleRate);
} else {
lovrRetain(sink);
}
@ -327,7 +330,7 @@ bool lovrAudioSetDevice(AudioType type, void* id, size_t size, Sound* sink, Audi
config.playback.shareMode = shareModes[shareMode];
config.playback.format = ma_format_f32;
config.playback.channels = OUTPUT_CHANNELS;
config.sampleRate = SAMPLE_RATE;
config.sampleRate = state.sampleRate;
if (sink) {
ma_data_converter_config converterConfig = ma_data_converter_config_init_default();
converterConfig.formatIn = config.playback.format;
@ -403,6 +406,10 @@ const char* lovrAudioGetSpatializer() {
return state.spatializer->name;
}
int lovrAudioGetSampleRate() {
return state.sampleRate;
}
void lovrAudioGetAbsorption(float absorption[3]) {
memcpy(absorption, state.absorption, 3 * sizeof(float));
}
@ -434,7 +441,7 @@ Source* lovrSourceCreate(Sound* sound, uint32_t effects) {
config.channelsIn = lovrSoundGetChannelCount(sound);
config.channelsOut = lovrSourceUsesSpatializer(source) ? 1 : 2; // See onPlayback
config.sampleRateIn = lovrSoundGetSampleRate(sound);
config.sampleRateOut = SAMPLE_RATE;
config.sampleRateOut = state.sampleRate;
if (config.formatIn != config.formatOut || config.channelsIn != config.channelsOut || config.sampleRateIn != config.sampleRateOut) {
source->converter = malloc(sizeof(ma_data_converter));

View File

@ -4,7 +4,7 @@
#pragma once
#define SAMPLE_RATE 48000
#define DEFAULT_SAMPLE_RATE 48000
#define BUFFER_SIZE 256
#define MAX_SOURCES 64
@ -59,7 +59,7 @@ typedef enum {
typedef void AudioDeviceCallback(const void* id, size_t size, const char* name, bool isDefault, void* userdata);
bool lovrAudioInit(const char* spatializer);
bool lovrAudioInit(const char* spatializer, int sampleRate);
void lovrAudioDestroy(void);
void lovrAudioEnumerateDevices(AudioType type, AudioDeviceCallback* callback, void* userdata);
bool lovrAudioSetDevice(AudioType type, void* id, size_t size, struct Sound* sink, AudioShareMode shareMode);
@ -72,6 +72,7 @@ void lovrAudioGetPose(float position[4], float orientation[4]);
void lovrAudioSetPose(float position[4], float orientation[4]);
bool lovrAudioSetGeometry(float* vertices, uint32_t* indices, uint32_t vertexCount, uint32_t indexCount, AudioMaterial material);
const char* lovrAudioGetSpatializer(void);
int lovrAudioGetSampleRate();
void lovrAudioGetAbsorption(float absorption[3]);
void lovrAudioSetAbsorption(float absorption[3]);

View File

@ -106,7 +106,7 @@ static bool oculus_init(void) {
config.acc_Size = sizeof(config);
config.acc_MaxNumSources = MAX_SOURCES;
config.acc_SampleRate = SAMPLE_RATE;
config.acc_SampleRate = lovrAudioGetSampleRate();
config.acc_BufferLength = BUFFER_SIZE; // Stereo
if (ovrAudio_CreateContext(&state.context, &config) != ovrSuccess) {

View File

@ -146,7 +146,7 @@ bool phonon_init() {
status = phonon_iplCreateEnvironment(state.context, NULL, simulationSettings, NULL, NULL, &state.environment);
if (status != IPL_STATUS_SUCCESS) return phonon_destroy(), false;
state.renderingSettings.samplingRate = SAMPLE_RATE;
state.renderingSettings.samplingRate = lovrAudioGetSampleRate();
state.renderingSettings.frameSize = BUFFER_SIZE;
state.renderingSettings.convolutionType = IPL_CONVOLUTIONTYPE_PHONON;

View File

@ -60,7 +60,7 @@ uint32_t simple_apply(Source* source, const float* input, float* output, uint32_
float* gain = state.gain[index];
float lerpDuration = .05f;
float lerpFrames = SAMPLE_RATE * lerpDuration;
float lerpFrames = lovrAudioGetSampleRate() * lerpDuration;
float lerpRate = 1.f / lerpFrames;
for (uint32_t c = 0; c < 2; c++) {