Skip to content

Commit

Permalink
Issue 3289 update sound from stringbuffer (defold#5675)
Browse files Browse the repository at this point in the history
* Update sound resource from buffer - ref defold#3289

* 'Published' sound resource property in sound component.
  Now accessible from lua resource.get()

* Support for sound-data resource update from lua string

* Test case for stringbuffer sound update - ref defold#3289
  • Loading branch information
otsakir committed Mar 30, 2021
1 parent dc69d18 commit f7a1bb5
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 5 deletions.
16 changes: 11 additions & 5 deletions engine/gamesys/src/gamesys/components/comp_sound.cpp
Expand Up @@ -25,6 +25,8 @@
#include "../gamesys.h"
#include "../gamesys_private.h"
#include "../resources/res_sound.h"
#include "comp_private.h"


namespace dmGameSystem
{
Expand Down Expand Up @@ -61,6 +63,7 @@ namespace dmGameSystem
static const dmhash_t SOUND_PROP_GAIN = dmHashString64("gain");
static const dmhash_t SOUND_PROP_PAN = dmHashString64("pan");
static const dmhash_t SOUND_PROP_SPEED = dmHashString64("speed");
static const dmhash_t SOUND_PROP_SOUND = dmHashString64("sound");

dmGameObject::CreateResult CompSoundNewWorld(const dmGameObject::ComponentNewWorldParams& params)
{
Expand Down Expand Up @@ -466,12 +469,15 @@ namespace dmGameSystem
uint32_t index = *params.m_UserData;
SoundComponent* component = &world->m_Components.Get(index);

dmSound::Parameter parameter = GetSoundParameterType(params.m_PropertyId);
if (parameter == dmSound::PARAMETER_MAX) {
return dmGameObject::PROPERTY_RESULT_NOT_FOUND;
if (params.m_PropertyId == SOUND_PROP_SOUND) {
return GetResourceProperty(dmGameObject::GetFactory(params.m_Instance), component->m_Resource->m_SoundData, out_value);
} else {
dmSound::Parameter parameter = GetSoundParameterType(params.m_PropertyId);
if (parameter == dmSound::PARAMETER_MAX) {
return dmGameObject::PROPERTY_RESULT_NOT_FOUND;
}
return SoundGetParameter(world, params.m_Instance, component, parameter, out_value);
}

return SoundGetParameter(world, params.m_Instance, component, parameter, out_value);
}

dmGameObject::PropertyResult CompSoundSetProperty(const dmGameObject::ComponentSetPropertyParams& params)
Expand Down
29 changes: 29 additions & 0 deletions engine/gamesys/src/gamesys/scripts/script_resource.cpp
Expand Up @@ -474,6 +474,34 @@ static int SetTexture(lua_State* L)
return 0;
}

/*# Update internal sound resource
* Update internal sound resource (wavc/oggc) with new data
*
* @name resource.set_sound
*
* @param path [type:hash|string] The path to the resource
* @param buffer [type:string] A lua string containing the binary sound data
*/
static int SetSound(lua_State* L) {
DM_LUA_STACK_CHECK(L, 0);

// get resource path as hash
const dmhash_t path_hash = dmScript::CheckHashOrString(L, 1);
// get the sound buffer
luaL_checktype(L, 2, LUA_TSTRING);
size_t buffer_size;
const char* buffer = lua_tolstring(L, 2, &buffer_size);

dmResource::Result r = dmResource::SetResource(g_ResourceModule.m_Factory, path_hash, (void*) buffer, buffer_size);

if( r != dmResource::RESULT_OK ) {
return ReportPathError(L, r, path_hash);
}

return 0;
}


/*# get resource buffer
* gets the buffer from a resource
*
Expand Down Expand Up @@ -672,6 +700,7 @@ static const luaL_reg Module_methods[] =
{"set", Set},
{"load", Load},
{"set_texture", SetTexture},
{"set_sound", SetSound},
{"get_buffer", GetBuffer},
{"set_buffer", SetBuffer},

Expand Down
17 changes: 17 additions & 0 deletions engine/gamesys/src/gamesys/test/sound/set_sound.script
@@ -0,0 +1,17 @@
function init(self)
self.updated = false
end

function update(self, dt)
-- update sound only once
if not self.updated then
local f = io.open("src/gamesys/test/sound_ext/replacement.wav")
local c = f:read("*all")
f:close()

local path = go.get("/go#dynamic-sound", "sound")
resource.set_sound(path, c);

self.updated = true;
end
end
8 changes: 8 additions & 0 deletions engine/gamesys/src/gamesys/test/sound/updated_sound.go
@@ -0,0 +1,8 @@
components {
id: "dynamic-sound"
component: "/sound/valid.sound"
}
components {
id: "set-sound-script"
component: "/sound/set_sound.script"
}
Binary file not shown.
40 changes: 40 additions & 0 deletions engine/gamesys/src/gamesys/test/test_gamesys.cpp
Expand Up @@ -428,6 +428,46 @@ static dmGameObject::PropertyResult SetResourceProperty(dmGameObject::HInstance
return dmGameObject::SetProperty(instance, comp_name, prop_name, prop_var);
}

TEST_F(SoundTest, UpdateSoundResource)
{
// import 'resource' lua api among others
dmGameSystem::ScriptLibContext scriptlibcontext;
scriptlibcontext.m_Factory = m_Factory;
scriptlibcontext.m_Register = m_Register;
scriptlibcontext.m_LuaState = dmScript::GetLuaState(m_ScriptContext);
dmGameSystem::InitializeScriptLibs(scriptlibcontext);

const char* go_path = "/sound/updated_sound.goc";

// Create gameobject
dmGameObject::HInstance go = Spawn(m_Factory, m_Collection, go_path, dmHashString64("/go"));
ASSERT_NE((void*)0, go);

// Update sound component with custom buffer from lua. See set_sound.script:update()
ASSERT_TRUE(dmGameObject::Update(m_Collection, &m_UpdateContext));
ASSERT_TRUE(dmGameObject::PostUpdate(m_Collection));

// Check the size of the updated resource

dmhash_t comp_name = dmHashString64("dynamic-sound"); // id of soundc component
dmhash_t prop_name = dmHashString64("sound"); // property of sound data resource within a sound component
// Get hash of the sounddata resource
dmhash_t soundata_hash = 0;
GetResourceProperty(go, comp_name, prop_name, &soundata_hash);
dmResource::SResourceDescriptor* descp = dmResource::FindByHash(m_Factory, soundata_hash);
dmLogInfo("size: %i", descp->m_ResourceSize);
ASSERT_EQ(98510+16, descp->m_ResourceSize); // size returned is always +16 from size of wav: sound_data->m_Size + sizeof(SoundData) from sound_null.cpp;

ASSERT_TRUE(dmGameObject::Final(m_Collection));

// release GO
DeleteInstance(m_Collection, go);

// release lua api deps
dmGameSystem::FinalizeScriptLibs(scriptlibcontext);
}


TEST_P(ResourcePropTest, ResourceRefCounting)
{
const char* go_path = "/resource/res_getset_prop.goc";
Expand Down
6 changes: 6 additions & 0 deletions engine/gamesys/src/gamesys/test/test_gamesys.h
Expand Up @@ -236,6 +236,12 @@ class CursorTest : public GamesysTest<CursorTestParams>
virtual ~CursorTest() {}
};

class SoundTest : public GamesysTest<const char*>
{
public:
virtual ~SoundTest() {}
};

bool CopyResource(const char* src, const char* dst);
bool UnlinkResource(const char* name);

Expand Down

0 comments on commit f7a1bb5

Please sign in to comment.