Unverified Commit e751294b authored by Jake Stine's avatar Jake Stine Committed by GitHub
Browse files

audio: temporary workaround for audio crashing (#172)

* audio: temporary workaround for audio crashing - nullify samples on unexpected __gc

* audio: Fixed compile error

* sound: don't cleanup sndta, only sources in mixer need cleanup on __gc for now.
parent 4d332d8e
......@@ -8,6 +8,7 @@
#include <file/file_path.h>
#include <audio/conversion/float_to_s16.h>
#include <math.h>
#include <assert.h>
/* TODO/FIXME - no sound on big-endian */
......@@ -23,6 +24,29 @@ static int16_t saturate(mixer_presaturate_t in) {
return cvt_presaturate_to_int16(in);
}
int audio_sources_nullify_refs(const audio_Source* source)
{
int counted = 0;
if (!source) return 0;
// rather than crash, let's nullify any known references here,
// even if they're currently playing (they'll be cut to silence)
for(int i=0; i<num_sources; ++i)
{
if (sources[i] == source)
{
if (sources[i]->state != AUDIO_STOPPED)
++counted;
// do not free - the pointers in sources are lua user data
sources[i] = NULL;
}
}
return counted;
}
void mixer_render(int16_t *buffer)
{
static mixer_presaturate_t presaturateBuffer[AUDIO_FRAMES * CHANNELS];
......@@ -32,6 +56,9 @@ void mixer_render(int16_t *buffer)
// Loop over audio sources
for (int i = 0; i < num_sources; i++)
{
if (!sources[i])
continue;
if (sources[i]->state == AUDIO_STOPPED)
continue;
......@@ -154,7 +181,7 @@ void lutro_audio_deinit()
{
for (unsigned i = 0; i < num_sources; i++)
{
if (sources[i]->oggData)
if (sources[i] && sources[i]->oggData)
{
ov_clear(&sources[i]->oggData->vf);
free(sources[i]->oggData);
......@@ -167,6 +194,19 @@ void lutro_audio_deinit()
}
}
static int assign_to_existing_source_slot(audio_Source* self)
{
for(int i=0; i<num_sources; ++i)
{
if (!sources[i])
{
sources[i] = self;
return 1;
}
}
return 0;
}
int audio_newSource(lua_State *L)
{
int n = lua_gettop(L);
......@@ -178,6 +218,11 @@ int audio_newSource(lua_State *L)
self->oggData = NULL;
self->sndta.fp = NULL;
//if (lua_isstring(L,1)) // (lua_type(L, 1) == LUA_TSTRING)
//{
//
//}
void *p = lua_touserdata(L, 1);
if (p == NULL)
{
......@@ -227,9 +272,13 @@ int audio_newSource(lua_State *L)
self->bps = self->sndta.head.NumChannels * self->sndta.head.BitsPerSample / 8;
fseek(self->sndta.fp, 0, SEEK_END);
}
if (!assign_to_existing_source_slot(self))
{
num_sources++;
sources = (audio_Source**)realloc(sources, num_sources * sizeof(audio_Source));
sources[num_sources-1] = self;
}
if (luaL_newmetatable(L, "Source") != 0)
{
......@@ -418,6 +467,18 @@ int source_getPitch(lua_State *L)
int source_gc(lua_State *L)
{
audio_Source* self = (audio_Source*)luaL_checkudata(L, 1, "Source");
// todo - add some info to help identify the offending leaker.
// (don't get carried away tho - this message is only really useful to lutro core devs since
// it indiciates a failure of our internal Lua/C glue)
int leaks = audio_sources_nullify_refs(self);
if (leaks)
{
fprintf(stderr, "source_gc: playing audio references were nullified.\n");
//assert(false);
}
(void)self;
return 0;
}
......
......@@ -77,4 +77,5 @@ int source_setPitch(lua_State *L);
int source_gc(lua_State *L);
#endif // AUDIO_H
#include "sound.h"
#include "lutro.h"
#include "audio.h"
#include "compat/strl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int lutro_sound_preload(lua_State *L)
{
......@@ -25,6 +27,11 @@ void lutro_sound_init()
{
}
void newSoundData_internal(lua_State *L, const char* path)
{
snd_SoundData* self = (snd_SoundData*)lua_newuserdata(L, sizeof(snd_SoundData));
}
int snd_newSoundData(lua_State *L)
{
int n = lua_gettop(L);
......@@ -72,7 +79,7 @@ int snd_newSoundData(lua_State *L)
int sndta_type(lua_State *L)
{
wavhead_t* self = (wavhead_t*)luaL_checkudata(L, 1, "SoundData");
snd_SoundData* self = (snd_SoundData*)luaL_checkudata(L, 1, "SoundData");
(void) self;
lua_pushstring(L, "SoundData");
return 1;
......@@ -80,7 +87,10 @@ int sndta_type(lua_State *L)
int sndta_gc(lua_State *L)
{
wavhead_t* self = (wavhead_t*)luaL_checkudata(L, 1, "SoundData");
snd_SoundData* self = (snd_SoundData*)luaL_checkudata(L, 1, "SoundData");
//audio makes deep copies of this object when it preps it as a mixer source, so no cleanup needed here.
(void)self;
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment