diff --git a/core/audio/AudioEngine.cpp b/core/audio/AudioEngine.cpp index 5fa61d8177af..1e380dc2ce6a 100644 --- a/core/audio/AudioEngine.cpp +++ b/core/audio/AudioEngine.cpp @@ -216,6 +216,21 @@ void AudioEngine::setVolume(AUDIO_ID audioID, float volume) } } +void AudioEngine::setPitch(AUDIO_ID audioID, float pitch) +{ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end()) + { + pitch = std::clamp(pitch, 0.5f, 2.0f); + + if (it->second.pitch != pitch) + { + _audioEngineImpl->setPitch(audioID, pitch); + it->second.pitch = pitch; + } + } +} + void AudioEngine::pause(AUDIO_ID audioID) { auto it = _audioIDInfoMap.find(audioID); diff --git a/core/audio/AudioEngine.h b/core/audio/AudioEngine.h index b1a83c62626a..0faf6c69acd0 100644 --- a/core/audio/AudioEngine.h +++ b/core/audio/AudioEngine.h @@ -189,6 +189,22 @@ class AX_DLL AudioEngine */ static float getVolume(AUDIO_ID audioID); + /** + * Sets pitch for an audio instance. + * + * @param audioID An audioID returned by the play2d function. + * @param pitch Volume value (range from 0.5 to 2.0). + */ + static void setPitch(AUDIO_ID audioID, float pitch); + + /** + * Gets the volume value of an audio instance. + * + * @param audioID An audioID returned by the play2d function. + * @return pitch value (range from 0.5 to 2.0). + */ + static float getPitch(AUDIO_ID audioID); + /** * Pause an audio instance. * @@ -354,6 +370,7 @@ class AX_DLL AudioEngine ProfileHelper* profileHelper; float volume; + float pitch; bool loop; float duration; AudioState state; diff --git a/core/audio/AudioEngineImpl.cpp b/core/audio/AudioEngineImpl.cpp index dfc5ba2099e0..068651229464 100644 --- a/core/audio/AudioEngineImpl.cpp +++ b/core/audio/AudioEngineImpl.cpp @@ -551,6 +551,7 @@ AUDIO_ID AudioEngineImpl::play2d(std::string_view filePath, bool loop, float vol player->_alSource = alSource; player->_loop = loop; player->_volume = volume; + player->_pitch = 1.0f; if (time > 0.0f) { player->_currTime = time; @@ -644,6 +645,30 @@ void AudioEngineImpl::setVolume(AUDIO_ID audioID, float volume) } } +void AudioEngineImpl::setPitch(AUDIO_ID audioID, float pitch) +{ + std::unique_lock lck(_threadMutex); + auto iter = _audioPlayers.find(audioID); + if (iter == _audioPlayers.end()) + return; + + auto player = iter->second; + lck.unlock(); + + player->_pitch = pitch; + + if (player->_ready) + { + alSourcef(player->_alSource, AL_PITCH, pitch); + + auto error = alGetError(); + if (error != AL_NO_ERROR) + { + AXLOGE("{}: audio id = {}, error = {:#x}", __FUNCTION__, audioID, error); + } + } +} + void AudioEngineImpl::setLoop(AUDIO_ID audioID, bool loop) { std::unique_lock lck(_threadMutex); diff --git a/core/audio/AudioEngineImpl.h b/core/audio/AudioEngineImpl.h index eabc2a9e29e8..3da8ed90e0f5 100644 --- a/core/audio/AudioEngineImpl.h +++ b/core/audio/AudioEngineImpl.h @@ -51,6 +51,7 @@ class AX_DLL AudioEngineImpl : public ax::Object bool init(); AUDIO_ID play2d(std::string_view fileFullPath, bool loop, float volume, float time); void setVolume(AUDIO_ID audioID, float volume); + void setPitch(AUDIO_ID audioID, float pitch); void setLoop(AUDIO_ID audioID, bool loop); bool pause(AUDIO_ID audioID); bool resume(AUDIO_ID audioID); diff --git a/core/audio/AudioPlayer.h b/core/audio/AudioPlayer.h index b1393927b62d..f152e7b9193b 100644 --- a/core/audio/AudioPlayer.h +++ b/core/audio/AudioPlayer.h @@ -71,6 +71,7 @@ class AX_DLL AudioPlayer AudioCache* _audioCache; float _volume; + float _pitch; bool _loop; std::function _finishCallbak;