From ff73c7a5da6ab8ac0bb678ebf25b83e805397029 Mon Sep 17 00:00:00 2001 From: Rui Date: Sun, 11 Jun 2017 20:58:26 +0900 Subject: [PATCH] Sound: Add pitch option (#5960) * Sound: Add pitch option --- doc/lua_api.txt | 3 +++ src/itemdef.cpp | 4 ++++ src/network/clientpackethandler.cpp | 11 +++++---- src/nodedef.cpp | 2 ++ src/script/common/c_content.cpp | 4 ++++ src/script/lua_api/l_client.cpp | 8 ++++--- src/server.cpp | 2 +- src/server.h | 36 +++++++++++------------------ src/sound.h | 28 ++++++++++++---------- src/sound_openal.cpp | 24 ++++++++++--------- 10 files changed, 68 insertions(+), 54 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2bbf18310..28067eef1 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -622,12 +622,14 @@ Examples of sound parameter tables: { gain = 1.0, -- default fade = 0.0, -- default, change to a value > 0 to fade the sound in + pitch = 1.0, -- default } -- Play locationless to one player { to_player = name, gain = 1.0, -- default fade = 0.0, -- default, change to a value > 0 to fade the sound in + pitch = 1.0, -- default } -- Play locationless to one player, looped { @@ -658,6 +660,7 @@ one player using `to_player = name,` * e.g. `{}` * e.g. `{name = "default_place_node"}` * e.g. `{name = "default_place_node", gain = 1.0}` +* e.g. `{name = "default_place_node", gain = 1.0, pitch = 1.0}` Registered definitions of stuff ------------------------------- diff --git a/src/itemdef.cpp b/src/itemdef.cpp index f1cc03c4b..ca6020e14 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -156,6 +156,8 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const writeF1000(os, sound_place_failed.gain); os << serializeString(palette_image); writeU32(os, color.color); + writeF1000(os, sound_place.pitch); + writeF1000(os, sound_place_failed.pitch); } void ItemDefinition::deSerialize(std::istream &is) @@ -214,6 +216,8 @@ void ItemDefinition::deSerialize(std::istream &is) sound_place_failed.gain = readF1000(is); palette_image = deSerializeString(is); color.set(readU32(is)); + sound_place.pitch = readF1000(is); + sound_place_failed.pitch = readF1000(is); } catch(SerializationError &e) {}; } diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 9eb6d8dca..caaf24d80 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -764,6 +764,7 @@ void Client::handleCommand_PlaySound(NetworkPacket* pkt) [23 + len] u16 object_id [25 + len] bool loop [26 + len] f32 fade + [30 + len] f32 pitch */ s32 server_id; @@ -774,29 +775,31 @@ void Client::handleCommand_PlaySound(NetworkPacket* pkt) v3f pos; u16 object_id; bool loop; - float fade = 0; + float fade = 0.0f; + float pitch = 1.0f; *pkt >> server_id >> name >> gain >> type >> pos >> object_id >> loop; try { *pkt >> fade; + *pkt >> pitch; } catch (PacketError &e) {}; // Start playing int client_id = -1; switch(type) { case 0: // local - client_id = m_sound->playSound(name, loop, gain, fade); + client_id = m_sound->playSound(name, loop, gain, fade, pitch); break; case 1: // positional - client_id = m_sound->playSoundAt(name, loop, gain, pos); + client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch); break; case 2: { // object ClientActiveObject *cao = m_env.getActiveObject(object_id); if (cao) pos = cao->getPosition(); - client_id = m_sound->playSoundAt(name, loop, gain, pos); + client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch); // TODO: Set up sound to move with object break; } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 6b2718636..02e967384 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -252,11 +252,13 @@ static void serializeSimpleSoundSpec(const SimpleSoundSpec &ss, { os<playSoundAt( - spec.name, looped, gain * spec.gain, pos); + spec.name, looped, gain * spec.gain, pos, pitch); lua_pushinteger(L, handle); return 1; } } - handle = sound->playSound(spec.name, looped, gain * spec.gain); + handle = sound->playSound(spec.name, looped, gain * spec.gain, 0.0f, pitch); lua_pushinteger(L, handle); return 1; diff --git a/src/server.cpp b/src/server.cpp index 4d7947919..5911bbaf1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2098,7 +2098,7 @@ s32 Server::playSound(const SimpleSoundSpec &spec, NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0); pkt << id << spec.name << gain << (u8) params.type << pos << params.object - << params.loop << params.fade; + << params.loop << params.fade << params.pitch; // Backwards compability bool play_sound = gain > 0; diff --git a/src/server.h b/src/server.h index 0ad5dd97a..3086e8762 100644 --- a/src/server.h +++ b/src/server.h @@ -104,29 +104,19 @@ struct MediaInfo struct ServerSoundParams { - float gain; - std::string to_player; - enum Type{ - SSP_LOCAL=0, - SSP_POSITIONAL=1, - SSP_OBJECT=2 - } type; - v3f pos; - u16 object; - float max_hear_distance; - bool loop; - float fade; - - ServerSoundParams(): - gain(1.0), - to_player(""), - type(SSP_LOCAL), - pos(0,0,0), - object(0), - max_hear_distance(32*BS), - loop(false), - fade(0) - {} + enum Type { + SSP_LOCAL, + SSP_POSITIONAL, + SSP_OBJECT + } type = SSP_LOCAL; + float gain = 1.0f; + float fade = 0.0f; + float pitch = 1.0f; + bool loop = false; + float max_hear_distance = 32*BS; + v3f pos = v3f(0, 0, 0); + u16 object = 0; + std::string to_player = ""; v3f getPos(ServerEnvironment *env, bool *pos_exists) const; }; diff --git a/src/sound.h b/src/sound.h index 76c0d1be4..9447b77ef 100644 --- a/src/sound.h +++ b/src/sound.h @@ -34,16 +34,18 @@ public: struct SimpleSoundSpec { - SimpleSoundSpec(const std::string &name = "", float gain = 1.0, float fade = 0.0) - : name(name), gain(gain), fade(fade) + SimpleSoundSpec(const std::string &name = "", float gain = 1.0f, + float fade = 0.0f, float pitch = 1.0f) + : name(name), gain(gain), fade(fade), pitch(pitch) { } bool exists() const { return name != ""; } - std::string name; - float gain; - float fade; + std::string name = ""; + float gain = 1.0f; + float fade = 0.0f; + float pitch = 1.0f; }; class ISoundManager @@ -64,9 +66,9 @@ public: // playSound functions return -1 on failure, otherwise a handle to the // sound. If name=="", call should be ignored without error. virtual int playSound(const std::string &name, bool loop, float volume, - float fade = 0) = 0; - virtual int playSoundAt( - const std::string &name, bool loop, float volume, v3f pos) = 0; + float fade = 0.0f, float pitch = 1.0f) = 0; + virtual int playSoundAt(const std::string &name, bool loop, float volume, v3f pos, + float pitch = 1.0f) = 0; virtual void stopSound(int sound) = 0; virtual bool soundExists(int sound) = 0; virtual void updateSoundPosition(int sound, v3f pos) = 0; @@ -77,11 +79,11 @@ public: int playSound(const SimpleSoundSpec &spec, bool loop) { - return playSound(spec.name, loop, spec.gain, spec.fade); + return playSound(spec.name, loop, spec.gain, spec.fade, spec.pitch); } int playSoundAt(const SimpleSoundSpec &spec, bool loop, v3f pos) { - return playSoundAt(spec.name, loop, spec.gain, pos); + return playSoundAt(spec.name, loop, spec.gain, pos, spec.pitch); } }; @@ -98,11 +100,13 @@ public: } void updateListener(v3f pos, v3f vel, v3f at, v3f up) {} void setListenerGain(float gain) {} - int playSound(const std::string &name, bool loop, float volume, float fade) + int playSound(const std::string &name, bool loop, float volume, float fade, + float pitch) { return 0; } - int playSoundAt(const std::string &name, bool loop, float volume, v3f pos) + int playSoundAt(const std::string &name, bool loop, float volume, v3f pos, + float pitch) { return 0; } diff --git a/src/sound_openal.cpp b/src/sound_openal.cpp index d1a5279b3..0b53572c4 100644 --- a/src/sound_openal.cpp +++ b/src/sound_openal.cpp @@ -394,7 +394,7 @@ public: } PlayingSound* createPlayingSound(SoundBuffer *buf, bool loop, - float volume) + float volume, float pitch) { infostream<<"OpenALSoundManager: Creating playing sound"<source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); volume = MYMAX(0.0, volume); alSourcef(sound->source_id, AL_GAIN, volume); + alSourcef(sound->source_id, AL_PITCH, pitch); alSourcePlay(sound->source_id); warn_if_error(alGetError(), "createPlayingSound"); return sound; } PlayingSound* createPlayingSoundAt(SoundBuffer *buf, bool loop, - float volume, v3f pos) + float volume, v3f pos, float pitch) { infostream<<"OpenALSoundManager: Creating positional playing sound" <source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); volume = MYMAX(0.0, volume); alSourcef(sound->source_id, AL_GAIN, volume); + alSourcef(sound->source_id, AL_PITCH, pitch); alSourcePlay(sound->source_id); warn_if_error(alGetError(), "createPlayingSoundAt"); return sound; } - int playSoundRaw(SoundBuffer *buf, bool loop, float volume) + int playSoundRaw(SoundBuffer *buf, bool loop, float volume, float pitch) { assert(buf); - PlayingSound *sound = createPlayingSound(buf, loop, volume); + PlayingSound *sound = createPlayingSound(buf, loop, volume, pitch); if(!sound) return -1; int id = m_next_id++; @@ -448,10 +450,10 @@ public: return id; } - int playSoundRawAt(SoundBuffer *buf, bool loop, float volume, v3f pos) + int playSoundRawAt(SoundBuffer *buf, bool loop, float volume, v3f pos, float pitch) { assert(buf); - PlayingSound *sound = createPlayingSoundAt(buf, loop, volume, pos); + PlayingSound *sound = createPlayingSoundAt(buf, loop, volume, pos, pitch); if(!sound) return -1; int id = m_next_id++; @@ -561,7 +563,7 @@ public: alListenerf(AL_GAIN, gain); } - int playSound(const std::string &name, bool loop, float volume, float fade) + int playSound(const std::string &name, bool loop, float volume, float fade, float pitch) { maintain(); if(name == "") @@ -574,15 +576,15 @@ public: } int handle = -1; if (fade > 0) { - handle = playSoundRaw(buf, loop, 0); + handle = playSoundRaw(buf, loop, 0.0f, 0.0f); fadeSound(handle, fade, volume); } else { - handle = playSoundRaw(buf, loop, volume); + handle = playSoundRaw(buf, loop, volume, pitch); } return handle; } - int playSoundAt(const std::string &name, bool loop, float volume, v3f pos) + int playSoundAt(const std::string &name, bool loop, float volume, v3f pos, float pitch) { maintain(); if(name == "") @@ -593,7 +595,7 @@ public: <