From 8113ed23b9d9d54ebd347f16412af72d1be6f665 Mon Sep 17 00:00:00 2001 From: Miron Alexandru Date: Sun, 22 Sep 2024 02:26:25 +0300 Subject: [PATCH] Implement new audio functions --- include/CSFML/Audio/EffectProcessor.h | 106 ++++++++++ include/CSFML/Audio/Listener.h | 56 +++++ include/CSFML/Audio/Music.h | 267 ++++++++++++++++++++++++ include/CSFML/Audio/Sound.h | 254 ++++++++++++++++++++++ include/CSFML/Audio/SoundBuffer.h | 14 ++ include/CSFML/Audio/SoundRecorder.h | 15 ++ include/CSFML/Audio/SoundSourceCone.h | 43 ++++ include/CSFML/Audio/SoundStream.h | 266 +++++++++++++++++++++++ src/CSFML/Audio/CMakeLists.txt | 4 + src/CSFML/Audio/ConvertCone.hpp | 50 +++++ src/CSFML/Audio/Listener.cpp | 46 ++++ src/CSFML/Audio/Music.cpp | 208 +++++++++++++++++- src/CSFML/Audio/MusicStruct.hpp | 8 +- src/CSFML/Audio/Sound.cpp | 183 ++++++++++++++++ src/CSFML/Audio/SoundBuffer.cpp | 26 ++- src/CSFML/Audio/SoundBufferStruct.hpp | 5 +- src/CSFML/Audio/SoundRecorder.cpp | 19 +- src/CSFML/Audio/SoundRecorderStruct.hpp | 5 +- src/CSFML/Audio/SoundStream.cpp | 203 +++++++++++++++++- src/CSFML/Audio/SoundStreamStruct.hpp | 3 +- 20 files changed, 1766 insertions(+), 15 deletions(-) create mode 100644 include/CSFML/Audio/EffectProcessor.h create mode 100644 include/CSFML/Audio/SoundSourceCone.h create mode 100644 src/CSFML/Audio/ConvertCone.hpp diff --git a/include/CSFML/Audio/EffectProcessor.h b/include/CSFML/Audio/EffectProcessor.h new file mode 100644 index 0000000..17ee499 --- /dev/null +++ b/include/CSFML/Audio/EffectProcessor.h @@ -0,0 +1,106 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +/// \brief Callable that is provided with sound data for processing +/// +/// When the audio engine sources sound data from sound +/// sources it will pass the data through an effects +/// processor if one is set. The sound data will already be +/// converted to the internal floating point format. +/// +/// Sound data that is processed this way is provided in +/// frames. Each frame contains 1 floating point sample per +/// channel. If e.g. the data source provides stereo data, +/// each frame will contain 2 floats. +/// +/// The effects processor function takes 4 parameters: +/// - The input data frames, channels interleaved +/// - The number of input data frames available +/// - The buffer to write output data frames to, channels interleaved +/// - The number of output data frames that the output buffer can hold +/// - The channel count +/// +/// The input and output frame counts are in/out parameters. +/// +/// When this function is called, the input count will +/// contain the number of frames available in the input +/// buffer. The output count will contain the size of the +/// output buffer i.e. the maximum number of frames that +/// can be written to the output buffer. +/// +/// Attempting to read more frames than the input frame +/// count or write more frames than the output frame count +/// will result in undefined behaviour. +/// +/// It is important to note that the channel count of the +/// audio engine currently sourcing data from this sound +/// will always be provided in `frameChannelCount`. This can +/// be different from the channel count of the sound source +/// so make sure to size necessary processing buffers +/// according to the engine channel count and not the sound +/// source channel count. +/// +/// When done processing the frames, the input and output +/// frame counts must be updated to reflect the actual +/// number of frames that were read from the input and +/// written to the output. +/// +/// The processing function should always try to process as +/// much sound data as possible i.e. always try to fill the +/// output buffer to the maximum. In certain situations for +/// specific effects it can be possible that the input frame +/// count and output frame count aren't equal. As long as +/// the frame counts are updated accordingly this is +/// perfectly valid. +/// +/// If the audio engine determines that no audio data is +/// available from the data source, the input data frames +/// pointer is set to `NULL` and the input frame count is +/// set to 0. In this case it is up to the function to +/// decide how to handle the situation. For specific effects +/// e.g. Echo/Delay buffered data might still be able to be +/// written to the output buffer even if there is no longer +/// any input data. +/// +/// An important thing to remember is that this function is +/// directly called by the audio engine. Because the audio +/// engine runs on an internal thread of its own, make sure +/// access to shared data is synchronized appropriately. +/// +/// Because this function is stored by the `SoundSource` +/// object it will be able to be called as long as the +/// `SoundSource` object hasn't yet been destroyed. Make sure +/// that any data this function references outlives the +/// SoundSource object otherwise use-after-free errors will +/// occur. +/// +//////////////////////////////////////////////////////////// +typedef void (*sfEffectProcessor)(const float* inputFrames, + unsigned int* inputFrameCount, + float* outputFrames, + unsigned int* outputFrameCount, + unsigned int frameChannelCount); diff --git a/include/CSFML/Audio/Listener.h b/include/CSFML/Audio/Listener.h index 1d5c7f2..e85f632 100644 --- a/include/CSFML/Audio/Listener.h +++ b/include/CSFML/Audio/Listener.h @@ -32,6 +32,25 @@ #include +//////////////////////////////////////////////////////////// +/// \brief Structure defining the properties of a directional cone +/// +/// Sounds will play at gain 1 when they are positioned +/// within the inner angle of the cone. Sounds will play +/// at `outerGain` when they are positioned outside the +/// outer angle of the cone. The gain declines linearly +/// from 1 to `outerGain` as the sound moves from the inner +/// angle to the outer angle. +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + float innerAngle; //!< Inner angle, in degrees + float outerAngle; //!< Outer angle, in degrees + float outerGain; //!< Outer gain +} sfListenerCone; + + //////////////////////////////////////////////////////////// /// \brief Change the global volume of all the sounds and musics /// @@ -93,6 +112,43 @@ CSFML_AUDIO_API void sfListener_setDirection(sfVector3f direction); //////////////////////////////////////////////////////////// CSFML_AUDIO_API sfVector3f sfListener_getDirection(void); +//////////////////////////////////////////////////////////// +/// \brief Set the velocity of the listener in the scene +/// +/// The default listener's velocity is (0, 0, -1). +/// +/// \param velocity New listener's velocity +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfListener_setVelocity(sfVector3f velocity); + +//////////////////////////////////////////////////////////// +/// \brief Get the current forward vector of the listener in the scene +/// +/// \return Listener's velocity +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfListener_getVelocity(void); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the listener in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param cone Cone properties of the listener in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfListener_setCone(sfListenerCone cone); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the listener in the audio scene +/// +/// \return Cone properties of the listener +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfListenerCone sfListener_getCone(void); + //////////////////////////////////////////////////////////// /// \brief Set the upward vector of the listener in the scene /// diff --git a/include/CSFML/Audio/Music.h b/include/CSFML/Audio/Music.h index d6a2736..5a90142 100644 --- a/include/CSFML/Audio/Music.h +++ b/include/CSFML/Audio/Music.h @@ -29,6 +29,9 @@ //////////////////////////////////////////////////////////// #include +#include +#include +#include #include #include #include @@ -130,6 +133,18 @@ CSFML_AUDIO_API void sfMusic_setLooping(sfMusic* music, bool loop); //////////////////////////////////////////////////////////// CSFML_AUDIO_API bool sfMusic_isLooping(const sfMusic* music); +//////////////////////////////////////////////////////////// +/// \brief Set the effect processor to be applied to the sound +/// +/// The effect processor is a callable that will be called +/// with sound data to be processed. +/// +/// \param music Music object +/// \param effectProcessor The effect processor to attach to this sound, attach a null processor to disable processing +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setEffectProcessor(sfMusic* music, sfEffectProcessor effectProcessor); + //////////////////////////////////////////////////////////// /// \brief Get the total duration of a music /// @@ -244,6 +259,20 @@ CSFML_AUDIO_API unsigned int sfMusic_getChannelCount(const sfMusic* music); //////////////////////////////////////////////////////////// CSFML_AUDIO_API unsigned int sfMusic_getSampleRate(const sfMusic* music); +//////////////////////////////////////////////////////////// +/// \brief Get the map of position in sample frame to sound channel +/// +/// This is used to map a sample in the sample stream to a +/// position during spatialization. +/// +/// \param music Music object +/// \param count Pointer to a variable that will be filled with the number of channels in the map +/// +/// \return Map of position in sample frame to sound channel +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API const sfSoundChannel* sfMusic_getChannelMap(const sfMusic* music, size_t* count); + //////////////////////////////////////////////////////////// /// \brief Get the current status of a music (stopped, paused, playing) /// @@ -279,6 +308,20 @@ CSFML_AUDIO_API sfTime sfMusic_getPlayingOffset(const sfMusic* music); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfMusic_setPitch(sfMusic* music, float pitch); +//////////////////////////////////////////////////////////// +/// \brief Set the pan of the sound +/// +/// Using panning, a mono sound can be panned between +/// stereo channels. When the pan is set to -1, the sound +/// is played only on the left channel, when the pan is set +/// to +1, the sound is played only on the right channel. +/// +/// \param music Music object +/// \param pan New pan to apply to the sound [-1, +1] +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setPan(sfMusic* music, float pan); + //////////////////////////////////////////////////////////// /// \brief Set the volume of a music /// @@ -291,6 +334,20 @@ CSFML_AUDIO_API void sfMusic_setPitch(sfMusic* music, float pitch); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfMusic_setVolume(sfMusic* music, float volume); +//////////////////////////////////////////////////////////// +/// \brief Set whether spatialization of the sound is enabled +/// +/// Spatialization is the application of various effects to +/// simulate a sound being emitted at a virtual position in +/// 3D space and exhibiting various physical phenomena such as +/// directional attenuation and doppler shift. +/// +/// \param music Music object +/// \param enabled `true` to enable spatialization, `false` to disable +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setSpatializationEnabled(sfMusic* music, bool enabled); + //////////////////////////////////////////////////////////// /// \brief Set the 3D position of a music in the audio scene /// @@ -304,6 +361,74 @@ CSFML_AUDIO_API void sfMusic_setVolume(sfMusic* music, float volume); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfMusic_setPosition(sfMusic* music, sfVector3f position); +//////////////////////////////////////////////////////////// +/// \brief Set the 3D direction of the sound in the audio scene +/// +/// The direction defines where the sound source is facing +/// in 3D space. It will affect how the sound is attenuated +/// if facing away from the listener. +/// The default direction of a sound is (0, 0, -1). +/// +/// \param music Music object +/// \param direction Direction of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setDirection(sfMusic* music, sfVector3f direction); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the sound in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param music Music object +/// \param cone Cone properties of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setCone(sfMusic* music, sfSoundSourceCone cone); + +//////////////////////////////////////////////////////////// +/// \brief Set the 3D velocity of the sound in the audio scene +/// +/// The velocity is used to determine how to doppler shift +/// the sound. Sounds moving towards the listener will be +/// perceived to have a higher pitch and sounds moving away +/// from the listener will be perceived to have a lower pitch. +/// +/// \param music Music object +/// \param velocity Velocity of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setVelocity(sfMusic* music, sfVector3f velocity); + +//////////////////////////////////////////////////////////// +/// \brief Set the doppler factor of the sound +/// +/// The doppler factor determines how strong the doppler +/// shift will be. +/// +/// \param music Music object +/// \param factor New doppler factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setDopplerFactor(sfMusic* music, float factor); + +//////////////////////////////////////////////////////////// +/// \brief Set the directional attenuation factor of the sound +/// +/// Depending on the virtual position of an output channel +/// relative to the listener (such as in surround sound +/// setups), sounds will be attenuated when emitting them +/// from certain channels. This factor determines how strong +/// the attenuation based on output channel position +/// relative to the listener is. +/// +/// \param music Music object +/// \param factor New directional attenuation factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setDirectionalAttenuationFactor(sfMusic* music, float factor); + //////////////////////////////////////////////////////////// /// \brief Make a musics's position relative to the listener or absolute /// @@ -335,6 +460,48 @@ CSFML_AUDIO_API void sfMusic_setRelativeToListener(sfMusic* music, bool relative //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfMusic_setMinDistance(sfMusic* music, float distance); +//////////////////////////////////////////////////////////// +/// \brief Set the maximum distance of the sound +/// +/// The "maximum distance" of a sound is the minimum +/// distance at which it is heard at its minimum volume. Closer +/// than the maximum distance, it will start to fade in according +/// to its attenuation factor. +/// The default value of the maximum distance is the maximum +/// value a float can represent. +/// +/// \param music Music object +/// \param distance New maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setMaxDistance(sfMusic* music, float distance); + +//////////////////////////////////////////////////////////// +/// \brief Set the minimum gain of the sound +/// +/// When the sound is further away from the listener than +/// the "maximum distance" the attenuated gain is clamped +/// so it cannot go below the minimum gain value. +/// +/// \param music Music object +/// \param gain New minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setMinGain(sfMusic* music, float gain); + +//////////////////////////////////////////////////////////// +/// \brief Set the maximum gain of the sound +/// +/// When the sound is closer from the listener than +/// the "minimum distance" the attenuated gain is clamped +/// so it cannot go above the maximum gain value. +/// +/// \param music Music object +/// \param gain New maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setMaxGain(sfMusic* music, float gain); + //////////////////////////////////////////////////////////// /// \brief Set the attenuation factor of a music /// @@ -375,6 +542,26 @@ CSFML_AUDIO_API void sfMusic_setPlayingOffset(sfMusic* music, sfTime timeOffset) //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfMusic_getPitch(const sfMusic* music); +//////////////////////////////////////////////////////////// +/// \brief Get the pan of the sound +/// +/// \param music Music object +/// +/// \return Pan of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getPan(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Tell whether spatialization of the sound is enabled +/// +/// \param music Music object +/// +/// \return `true` if spatialization is enabled, `false` if it's disabled +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API bool sfMusic_isSpatializationEnabled(const sfMusic* music); + //////////////////////////////////////////////////////////// /// \brief Get the volume of a music /// @@ -395,6 +582,56 @@ CSFML_AUDIO_API float sfMusic_getVolume(const sfMusic* music); //////////////////////////////////////////////////////////// CSFML_AUDIO_API sfVector3f sfMusic_getPosition(const sfMusic* music); +//////////////////////////////////////////////////////////// +/// \brief Get the 3D direction of the sound in the audio scene +/// +/// \param music Music object +/// +/// \return Direction of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfMusic_getDirection(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the sound in the audio scene +/// +/// \param music Music object +/// +/// \return Cone properties of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundSourceCone sfMusic_getCone(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the 3D velocity of the sound in the audio scene +/// +/// \param music Music object +/// +/// \return Velocity of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfMusic_getVelocity(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the doppler factor of the sound +/// +/// \param music Music object +/// +/// \return Doppler factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getDopplerFactor(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the directional attenuation factor of the sound +/// +/// \param music Music object +/// +/// \return Directional attenuation factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getDirectionalAttenuationFactor(const sfMusic* music); + //////////////////////////////////////////////////////////// /// \brief Tell whether a music's position is relative to the /// listener or is absolute @@ -416,6 +653,36 @@ CSFML_AUDIO_API bool sfMusic_isRelativeToListener(const sfMusic* music); //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfMusic_getMinDistance(const sfMusic* music); +//////////////////////////////////////////////////////////// +/// \brief Get the maximum distance of the sound +/// +/// \param music Music object +/// +/// \return Maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getMaxDistance(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the minimum gain of the sound +/// +/// \param music Music object +/// +/// \return Minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getMinGain(const sfMusic* music); + +//////////////////////////////////////////////////////////// +/// \brief Get the maximum gain of the sound +/// +/// \param music Music object +/// +/// \return Maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfMusic_getMaxGain(const sfMusic* music); + //////////////////////////////////////////////////////////// /// \brief Get the attenuation factor of a music /// diff --git a/include/CSFML/Audio/Sound.h b/include/CSFML/Audio/Sound.h index b7a2f26..ccc0bbd 100644 --- a/include/CSFML/Audio/Sound.h +++ b/include/CSFML/Audio/Sound.h @@ -29,6 +29,8 @@ //////////////////////////////////////////////////////////// #include +#include +#include #include #include #include @@ -172,6 +174,21 @@ CSFML_AUDIO_API sfSoundStatus sfSound_getStatus(const sfSound* sound); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSound_setPitch(sfSound* sound, float pitch); +//////////////////////////////////////////////////////////// +/// \brief Set the pan of the sound +/// +/// Using panning, a mono sound can be panned between +/// stereo channels. When the pan is set to -1, the sound +/// is played only on the left channel, when the pan is set +/// to +1, the sound is played only on the right channel. +/// +/// \param sound Sound object +/// \param pan New pan to apply to the sound [-1, +1] +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setPan(sfSound* sound, float pan); + + //////////////////////////////////////////////////////////// /// \brief Set the volume of a sound /// @@ -184,6 +201,20 @@ CSFML_AUDIO_API void sfSound_setPitch(sfSound* sound, float pitch); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSound_setVolume(sfSound* sound, float volume); +//////////////////////////////////////////////////////////// +/// \brief Set whether spatialization of the sound is enabled +/// +/// Spatialization is the application of various effects to +/// simulate a sound being emitted at a virtual position in +/// 3D space and exhibiting various physical phenomena such as +/// directional attenuation and doppler shift. +/// +/// \param sound Sound object +/// \param enabled `true` to enable spatialization, `false` to disable +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setSpatializationEnabled(sfSound* sound, bool enabled); + //////////////////////////////////////////////////////////// /// \brief Set the 3D position of a sound in the audio scene /// @@ -197,6 +228,74 @@ CSFML_AUDIO_API void sfSound_setVolume(sfSound* sound, float volume); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSound_setPosition(sfSound* sound, sfVector3f position); +//////////////////////////////////////////////////////////// +/// \brief Set the 3D direction of the sound in the audio scene +/// +/// The direction defines where the sound source is facing +/// in 3D space. It will affect how the sound is attenuated +/// if facing away from the listener. +/// The default direction of a sound is (0, 0, -1). +/// +/// \param sound Sound object +/// \param direction Direction of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setDirection(sfSound* sound, sfVector3f direction); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the sound in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param sound Sound object +/// \param cone Cone properties of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setCone(sfSound* sound, sfSoundSourceCone cone); + +//////////////////////////////////////////////////////////// +/// \brief Set the 3D velocity of the sound in the audio scene +/// +/// The velocity is used to determine how to doppler shift +/// the sound. Sounds moving towards the listener will be +/// perceived to have a higher pitch and sounds moving away +/// from the listener will be perceived to have a lower pitch. +/// +/// \param sound Sound object +/// \param velocity Velocity of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setVelocity(sfSound* sound, sfVector3f velocity); + +//////////////////////////////////////////////////////////// +/// \brief Set the doppler factor of the sound +/// +/// The doppler factor determines how strong the doppler +/// shift will be. +/// +/// \param sound Sound object +/// \param factor New doppler factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setDopplerFactor(sfSound* sound, float factor); + +//////////////////////////////////////////////////////////// +/// \brief Set the directional attenuation factor of the sound +/// +/// Depending on the virtual position of an output channel +/// relative to the listener (such as in surround sound +/// setups), sounds will be attenuated when emitting them +/// from certain channels. This factor determines how strong +/// the attenuation based on output channel position +/// relative to the listener is. +/// +/// \param sound Sound object +/// \param factor New directional attenuation factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setDirectionalAttenuationFactor(sfSound* sound, float factor); + //////////////////////////////////////////////////////////// /// \brief Make the sound's position relative to the listener or absolute /// @@ -228,6 +327,49 @@ CSFML_AUDIO_API void sfSound_setRelativeToListener(sfSound* sound, bool relative //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSound_setMinDistance(sfSound* sound, float distance); +//////////////////////////////////////////////////////////// +/// \brief Set the maximum distance of the sound +/// +/// The "maximum distance" of a sound is the minimum +/// distance at which it is heard at its minimum volume. Closer +/// than the maximum distance, it will start to fade in according +/// to its attenuation factor. +/// The default value of the maximum distance is the maximum +/// value a float can represent. +/// +/// \param sound Sound object +/// \param distance New maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setMaxDistance(sfSound* sound, float distance); + +//////////////////////////////////////////////////////////// +/// \brief Set the minimum gain of the sound +/// +/// When the sound is further away from the listener than +/// the "maximum distance" the attenuated gain is clamped +/// so it cannot go below the minimum gain value. +/// +/// \param sound Sound object +/// \param gain New minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setMinGain(sfSound* sound, float gain); + +//////////////////////////////////////////////////////////// +/// \brief Set the maximum gain of the sound +/// +/// When the sound is closer from the listener than +/// the "minimum distance" the attenuated gain is clamped +/// so it cannot go above the maximum gain value. +/// +/// +/// \param sound Sound object +/// \param gain New maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setMaxGain(sfSound* sound, float gain); + //////////////////////////////////////////////////////////// /// \brief Set the attenuation factor of a sound /// @@ -258,6 +400,18 @@ CSFML_AUDIO_API void sfSound_setAttenuation(sfSound* sound, float attenuation); //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSound_setPlayingOffset(sfSound* sound, sfTime timeOffset); +//////////////////////////////////////////////////////////// +/// \brief Set the effect processor to be applied to the sound +/// +/// The effect processor is a callable that will be called +/// with sound data to be processed. +/// +/// \param sound Sound object +/// \param effectProcessor The effect processor to attach to this sound, attach an empty processor to disable processing +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSound_setEffectProcessor(sfSound* sound, sfEffectProcessor effectProcessor); + //////////////////////////////////////////////////////////// /// \brief Get the pitch of a sound /// @@ -268,6 +422,16 @@ CSFML_AUDIO_API void sfSound_setPlayingOffset(sfSound* sound, sfTime timeOffset) //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSound_getPitch(const sfSound* sound); +//////////////////////////////////////////////////////////// +/// \brief Get the pan of the sound +/// +/// \param sound Sound object +/// +/// \return Pan of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getPan(const sfSound* sound); + //////////////////////////////////////////////////////////// /// \brief Get the volume of a sound /// @@ -278,6 +442,16 @@ CSFML_AUDIO_API float sfSound_getPitch(const sfSound* sound); //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSound_getVolume(const sfSound* sound); +//////////////////////////////////////////////////////////// +/// \brief Tell whether spatialization of the sound is enabled +/// +/// \param sound Sound object +/// +/// \return `true` if spatialization is enabled, `false` if it's disabled +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API bool sfSound_isSpatializationEnabled(const sfSound* sound); + //////////////////////////////////////////////////////////// /// \brief Get the 3D position of a sound in the audio scene /// @@ -288,6 +462,56 @@ CSFML_AUDIO_API float sfSound_getVolume(const sfSound* sound); //////////////////////////////////////////////////////////// CSFML_AUDIO_API sfVector3f sfSound_getPosition(const sfSound* sound); +//////////////////////////////////////////////////////////// +/// \brief Get the 3D direction of the sound in the audio scene +/// +/// \param sound Sound object +/// +/// \return Direction of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfSound_getDirection(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the sound in the audio scene +/// +/// \param sound Sound object +/// +/// \return Cone properties of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundSourceCone sfSound_getCone(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the 3D velocity of the sound in the audio scene +/// +/// \param sound Sound object +/// +/// \return Velocity of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfSound_getVelocity(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the doppler factor of the sound +/// +/// \param sound Sound object +/// +/// \return Doppler factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getDopplerFactor(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the directional attenuation factor of the sound +/// +/// \param sound Sound object +/// +/// \return Directional attenuation factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getDirectionalAttenuationFactor(const sfSound* sound); + //////////////////////////////////////////////////////////// /// \brief Tell whether a sound's position is relative to the /// listener or is absolute @@ -309,6 +533,36 @@ CSFML_AUDIO_API bool sfSound_isRelativeToListener(const sfSound* sound); //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSound_getMinDistance(const sfSound* sound); +//////////////////////////////////////////////////////////// +/// \brief Get the maximum distance of the sound +/// +/// \param sound Sound object +/// +/// \return Maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getMaxDistance(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the minimum gain of the sound +/// +/// \param sound Sound object +/// +/// \return Minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getMinGain(const sfSound* sound); + +//////////////////////////////////////////////////////////// +/// \brief Get the maximum gain of the sound +/// +/// \param sound Sound object +/// +/// \return Maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSound_getMaxGain(const sfSound* sound); + //////////////////////////////////////////////////////////// /// \brief Get the attenuation factor of a sound /// diff --git a/include/CSFML/Audio/SoundBuffer.h b/include/CSFML/Audio/SoundBuffer.h index f07241d..cb7ab80 100644 --- a/include/CSFML/Audio/SoundBuffer.h +++ b/include/CSFML/Audio/SoundBuffer.h @@ -191,6 +191,20 @@ CSFML_AUDIO_API unsigned int sfSoundBuffer_getSampleRate(const sfSoundBuffer* so //////////////////////////////////////////////////////////// CSFML_AUDIO_API unsigned int sfSoundBuffer_getChannelCount(const sfSoundBuffer* soundBuffer); +//////////////////////////////////////////////////////////// +/// \brief Get the map of position in sample frame to sound channel +/// +/// This is used to map a sample in the sample stream to a +/// position during spatialization. +/// +/// \param soundBuffer Sound buffer object +/// \param count Pointer to a variable that will be filled with the number of channels in the map +/// +/// \return Map of position in sample frame to sound channel +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundChannel* sfSoundBuffer_getChannelMap(const sfSoundBuffer* soundBuffer, size_t* count); + //////////////////////////////////////////////////////////// /// \brief Get the total duration of a sound buffer /// diff --git a/include/CSFML/Audio/SoundRecorder.h b/include/CSFML/Audio/SoundRecorder.h index 700d62c..9c70462 100644 --- a/include/CSFML/Audio/SoundRecorder.h +++ b/include/CSFML/Audio/SoundRecorder.h @@ -29,6 +29,7 @@ //////////////////////////////////////////////////////////// #include +#include #include #include @@ -195,3 +196,17 @@ CSFML_AUDIO_API void sfSoundRecorder_setChannelCount(sfSoundRecorder* soundRecor /// //////////////////////////////////////////////////////////// CSFML_AUDIO_API unsigned int sfSoundRecorder_getChannelCount(const sfSoundRecorder* soundRecorder); + +//////////////////////////////////////////////////////////// +/// \brief Get the map of position in sample frame to sound channel +/// +/// This is used to map a sample in the sample stream to a +/// position during spatialization. +/// +/// \param soundRecorder Sound recorder object +/// \param count Pointer to a variable that will be filled with the number of channels in the map +/// +/// \return Map of position in sample frame to sound channel +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundChannel* sfSoundRecorder_getChannelMap(const sfSoundRecorder* soundRecorder, size_t* count); diff --git a/include/CSFML/Audio/SoundSourceCone.h b/include/CSFML/Audio/SoundSourceCone.h new file mode 100644 index 0000000..0226d95 --- /dev/null +++ b/include/CSFML/Audio/SoundSourceCone.h @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +/// \brief Structure defining the properties of a directional cone +/// +/// Sounds will play at gain 1 when the listener +/// is positioned within the inner angle of the cone. +/// Sounds will play at `outerGain` when the listener is +/// positioned outside the outer angle of the cone. +/// The gain declines linearly from 1 to `outerGain` as the +/// listener moves from the inner angle to the outer angle. +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + float innerAngle; //!< Inner angle, in degrees + float outerAngle; //!< Outer angle, in degrees + float outerGain; //!< Outer gain +} sfSoundSourceCone; diff --git a/include/CSFML/Audio/SoundStream.h b/include/CSFML/Audio/SoundStream.h index 0a68a78..b927f82 100644 --- a/include/CSFML/Audio/SoundStream.h +++ b/include/CSFML/Audio/SoundStream.h @@ -29,7 +29,9 @@ //////////////////////////////////////////////////////////// #include +#include #include +#include #include #include #include @@ -155,6 +157,20 @@ CSFML_AUDIO_API unsigned int sfSoundStream_getChannelCount(const sfSoundStream* //////////////////////////////////////////////////////////// CSFML_AUDIO_API unsigned int sfSoundStream_getSampleRate(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Get the map of position in sample frame to sound channel +/// +/// This is used to map a sample in the sample stream to a +/// position during spatialization. +/// +/// \param soundStream Sound stream object +/// \param count Pointer to a variable that will be filled with the number of channels in the map +/// +/// \return Map of position in sample frame to sound channel +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundChannel* sfSoundStream_getChannelMap(const sfSoundStream* soundStream, size_t* count); + //////////////////////////////////////////////////////////// /// \brief Set the pitch of a sound stream /// @@ -170,6 +186,20 @@ CSFML_AUDIO_API unsigned int sfSoundStream_getSampleRate(const sfSoundStream* so //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSoundStream_setPitch(sfSoundStream* soundStream, float pitch); +//////////////////////////////////////////////////////////// +/// \brief Set the pan of the sound +/// +/// Using panning, a mono sound can be panned between +/// stereo channels. When the pan is set to -1, the sound +/// is played only on the left channel, when the pan is set +/// to +1, the sound is played only on the right channel. +/// +/// \param soundStream Sound stream object +/// \param pan New pan to apply to the sound [-1, +1] +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setPan(sfSoundStream* soundStream, float pan); + //////////////////////////////////////////////////////////// /// \brief Set the volume of a sound stream /// @@ -182,6 +212,20 @@ CSFML_AUDIO_API void sfSoundStream_setPitch(sfSoundStream* soundStream, float pi //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSoundStream_setVolume(sfSoundStream* soundStream, float volume); +//////////////////////////////////////////////////////////// +/// \brief Set whether spatialization of the sound is enabled +/// +/// Spatialization is the application of various effects to +/// simulate a sound being emitted at a virtual position in +/// 3D space and exhibiting various physical phenomena such as +/// directional attenuation and doppler shift. +/// +/// \param soundStream Sound stream object +/// \param enabled `true` to enable spatialization, `false` to disable +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setSpatializationEnabled(sfSoundStream* soundStream, bool enabled); + //////////////////////////////////////////////////////////// /// \brief Set the 3D position of a sound stream in the audio scene /// @@ -195,6 +239,74 @@ CSFML_AUDIO_API void sfSoundStream_setVolume(sfSoundStream* soundStream, float v //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSoundStream_setPosition(sfSoundStream* soundStream, sfVector3f position); +//////////////////////////////////////////////////////////// +/// \brief Set the 3D direction of the sound in the audio scene +/// +/// The direction defines where the sound source is facing +/// in 3D space. It will affect how the sound is attenuated +/// if facing away from the listener. +/// The default direction of a sound is (0, 0, -1). +/// +/// \param soundStream Sound stream object +/// \param direction Direction of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setDirection(sfSoundStream* soundStream, sfVector3f direction); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the sound in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param soundStream Sound stream object +/// \param cone Cone properties of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setCone(sfSoundStream* soundStream, sfSoundSourceCone cone); + +//////////////////////////////////////////////////////////// +/// \brief Set the 3D velocity of the sound in the audio scene +/// +/// The velocity is used to determine how to doppler shift +/// the sound. Sounds moving towards the listener will be +/// perceived to have a higher pitch and sounds moving away +/// from the listener will be perceived to have a lower pitch. +/// +/// \param soundStream Sound stream object +/// \param velocity Velocity of the sound in the scene +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setVelocity(sfSoundStream* soundStream, sfVector3f velocity); + +//////////////////////////////////////////////////////////// +/// \brief Set the doppler factor of the sound +/// +/// The doppler factor determines how strong the doppler +/// shift will be. +/// +/// \param soundStream Sound stream object +/// \param factor New doppler factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setDopplerFactor(sfSoundStream* soundStream, float factor); + +//////////////////////////////////////////////////////////// +/// \brief Set the directional attenuation factor of the sound +/// +/// Depending on the virtual position of an output channel +/// relative to the listener (such as in surround sound +/// setups), sounds will be attenuated when emitting them +/// from certain channels. This factor determines how strong +/// the attenuation based on output channel position +/// relative to the listener is. +/// +/// \param soundStream Sound stream object +/// \param factor New directional attenuation factor to apply to the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setDirectionalAttenuationFactor(sfSoundStream* soundStream, float factor); + //////////////////////////////////////////////////////////// /// \brief Make a sound stream's position relative to the listener or absolute /// @@ -226,6 +338,48 @@ CSFML_AUDIO_API void sfSoundStream_setRelativeToListener(sfSoundStream* soundStr //////////////////////////////////////////////////////////// CSFML_AUDIO_API void sfSoundStream_setMinDistance(sfSoundStream* soundStream, float distance); +//////////////////////////////////////////////////////////// +/// \brief Set the maximum distance of the sound +/// +/// The "maximum distance" of a sound is the minimum +/// distance at which it is heard at its minimum volume. Closer +/// than the maximum distance, it will start to fade in according +/// to its attenuation factor. +/// The default value of the maximum distance is the maximum +/// value a float can represent. +/// +/// \param soundStream Sound stream object +/// \param distance New maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setMaxDistance(sfSoundStream* soundStream, float distance); + +//////////////////////////////////////////////////////////// +/// \brief Set the minimum gain of the sound +/// +/// When the sound is further away from the listener than +/// the "maximum distance" the attenuated gain is clamped +/// so it cannot go below the minimum gain value. +/// +/// \param soundStream Sound stream object +/// \param gain New minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setMinGain(sfSoundStream* soundStream, float gain); + +//////////////////////////////////////////////////////////// +/// \brief Set the maximum gain of the sound +/// +/// When the sound is closer from the listener than +/// the "minimum distance" the attenuated gain is clamped +/// so it cannot go above the maximum gain value. +/// +/// \param soundStream Sound stream object +/// \param gain New maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setMaxGain(sfSoundStream* soundStream, float gain); + //////////////////////////////////////////////////////////// /// \brief Set the attenuation factor of a sound stream /// @@ -280,6 +434,16 @@ CSFML_AUDIO_API void sfSoundStream_setLooping(sfSoundStream* soundStream, bool l //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSoundStream_getPitch(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Get the pan of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Pan of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getPan(const sfSoundStream* soundStream); + //////////////////////////////////////////////////////////// /// \brief Get the volume of a sound stream /// @@ -290,6 +454,16 @@ CSFML_AUDIO_API float sfSoundStream_getPitch(const sfSoundStream* soundStream); //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSoundStream_getVolume(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Tell whether spatialization of the sound is enabled +/// +/// \param soundStream Sound stream object +/// +/// \return `true` if spatialization is enabled, `false` if it's disabled +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API bool sfSoundStream_isSpatializationEnabled(const sfSoundStream* soundStream); + //////////////////////////////////////////////////////////// /// \brief Get the 3D position of a sound stream in the audio scene /// @@ -300,6 +474,56 @@ CSFML_AUDIO_API float sfSoundStream_getVolume(const sfSoundStream* soundStream); //////////////////////////////////////////////////////////// CSFML_AUDIO_API sfVector3f sfSoundStream_getPosition(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Get the 3D direction of the sound in the audio scene +/// +/// \param soundStream Sound stream object +/// +/// \return Direction of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfSoundStream_getDirection(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the sound in the audio scene +/// +/// \param soundStream Sound stream object +/// +/// \return Cone properties of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfSoundSourceCone sfSoundStream_getCone(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the 3D velocity of the sound in the audio scene +/// +/// \param soundStream Sound stream object +/// +/// \return Velocity of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API sfVector3f sfSoundStream_getVelocity(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the doppler factor of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Doppler factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getDopplerFactor(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the directional attenuation factor of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Directional attenuation factor of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getDirectionalAttenuationFactor(const sfSoundStream* soundStream); + //////////////////////////////////////////////////////////// /// \brief Tell whether a sound stream's position is relative to the /// listener or is absolute @@ -321,6 +545,36 @@ CSFML_AUDIO_API bool sfSoundStream_isRelativeToListener(const sfSoundStream* sou //////////////////////////////////////////////////////////// CSFML_AUDIO_API float sfSoundStream_getMinDistance(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Get the maximum distance of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Maximum distance of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getMaxDistance(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the minimum gain of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Minimum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getMinGain(const sfSoundStream* soundStream); + +//////////////////////////////////////////////////////////// +/// \brief Get the maximum gain of the sound +/// +/// \param soundStream Sound stream object +/// +/// \return Maximum gain of the sound +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API float sfSoundStream_getMaxGain(const sfSoundStream* soundStream); + //////////////////////////////////////////////////////////// /// \brief Get the attenuation factor of a sound stream /// @@ -341,6 +595,18 @@ CSFML_AUDIO_API float sfSoundStream_getAttenuation(const sfSoundStream* soundStr //////////////////////////////////////////////////////////// CSFML_AUDIO_API bool sfSoundStream_isLooping(const sfSoundStream* soundStream); +//////////////////////////////////////////////////////////// +/// \brief Set the effect processor to be applied to the sound +/// +/// The effect processor is a callable that will be called +/// with sound data to be processed. +/// +/// \param soundStream Sound stream object +/// \param effectProcessor The effect processor to attach to this sound, attach an empty processor to disable processing +/// +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfSoundStream_setEffectProcessor(sfSoundStream* soundStream, sfEffectProcessor effectProcessor); + //////////////////////////////////////////////////////////// /// \brief Get the current playing position of a sound stream /// diff --git a/src/CSFML/Audio/CMakeLists.txt b/src/CSFML/Audio/CMakeLists.txt index 9ca5f94..eb7e439 100644 --- a/src/CSFML/Audio/CMakeLists.txt +++ b/src/CSFML/Audio/CMakeLists.txt @@ -4,6 +4,8 @@ set(SRCROOT ${PROJECT_SOURCE_DIR}/src/CSFML/Audio) # all source files set(SRC ${INCROOT}/Export.h + ${SRCROOT}/ConvertCone.hpp + ${INCROOT}/EffectProcessor.h ${SRCROOT}/Listener.cpp ${INCROOT}/Listener.h ${SRCROOT}/Music.cpp @@ -18,9 +20,11 @@ set(SRC ${SRCROOT}/SoundBufferRecorder.cpp ${SRCROOT}/SoundBufferRecorderStruct.hpp ${INCROOT}/SoundBufferRecorder.h + ${INCROOT}/SoundChannel.h ${SRCROOT}/SoundRecorder.cpp ${SRCROOT}/SoundRecorderStruct.hpp ${INCROOT}/SoundRecorder.h + ${INCROOT}/SoundSourceCone.h ${INCROOT}/SoundStatus.h ${SRCROOT}/SoundStream.cpp ${SRCROOT}/SoundStreamStruct.hpp diff --git a/src/CSFML/Audio/ConvertCone.hpp b/src/CSFML/Audio/ConvertCone.hpp new file mode 100644 index 0000000..c21b7d5 --- /dev/null +++ b/src/CSFML/Audio/ConvertCone.hpp @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + + +//////////////////////////////////////////////////////////// +// Convert sf::SoundSource::Cone to sfSoundSourceCone +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sfSoundSourceCone convertCone(const sf::SoundSource::Cone cone) +{ + return {cone.innerAngle.asDegrees(), cone.outerAngle.asDegrees(), cone.outerGain}; +} + + +//////////////////////////////////////////////////////////// +// Convert sfSoundSourceCone to sf::SoundSource::Cone +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sf::SoundSource::Cone convertCone(const sfSoundSourceCone cone) +{ + return {sf::degrees(cone.innerAngle), sf::degrees(cone.outerAngle), cone.outerGain}; +} diff --git a/src/CSFML/Audio/Listener.cpp b/src/CSFML/Audio/Listener.cpp index e5c96bb..80cb706 100644 --- a/src/CSFML/Audio/Listener.cpp +++ b/src/CSFML/Audio/Listener.cpp @@ -31,6 +31,24 @@ #include +//////////////////////////////////////////////////////////// +// Convert sf::Listener::Cone to sfListenerCone +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sfListenerCone convertCone(const sf::Listener::Cone cone) +{ + return {cone.innerAngle.asDegrees(), cone.outerAngle.asDegrees(), cone.outerGain}; +} + + +//////////////////////////////////////////////////////////// +// Convert sfVector3f to sf::Vector3f +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sf::Listener::Cone convertCone(const sfListenerCone cone) +{ + return {sf::degrees(cone.innerAngle), sf::degrees(cone.outerAngle), cone.outerGain}; +} + + //////////////////////////////////////////////////////////// void sfListener_setGlobalVolume(float volume) { @@ -73,6 +91,34 @@ sfVector3f sfListener_getDirection() } +//////////////////////////////////////////////////////////// +void sfListener_setVelocity(sfVector3f velocity) +{ + sf::Listener::setVelocity(convertVector3(velocity)); +} + + +//////////////////////////////////////////////////////////// +sfVector3f sfListener_getVelocity() +{ + return convertVector3(sf::Listener::getVelocity()); +} + + +//////////////////////////////////////////////////////////// +void sfListener_setCone(sfListenerCone cone) +{ + sf::Listener::setCone(convertCone(cone)); +} + + +//////////////////////////////////////////////////////////// +sfListenerCone sfListener_getCone() +{ + return convertCone(sf::Listener::getCone()); +} + + //////////////////////////////////////////////////////////// void sfListener_setUpVector(sfVector3f upVector) { diff --git a/src/CSFML/Audio/Music.cpp b/src/CSFML/Audio/Music.cpp index 3c364d0..b573490 100644 --- a/src/CSFML/Audio/Music.cpp +++ b/src/CSFML/Audio/Music.cpp @@ -25,10 +25,14 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include +#include + +#include //////////////////////////////////////////////////////////// sfMusic* sfMusic_createFromFile(const char* filename) @@ -39,7 +43,7 @@ sfMusic* sfMusic_createFromFile(const char* filename) if (!music.openFromFile(filename)) return nullptr; - return new sfMusic{std::move(music), {}}; + return new sfMusic{std::move(music), {}, {}}; } @@ -50,7 +54,7 @@ sfMusic* sfMusic_createFromMemory(const void* data, size_t sizeInBytes) if (!music.openFromMemory(data, sizeInBytes)) return nullptr; - return new sfMusic{std::move(music), {}}; + return new sfMusic{std::move(music), {}, {}}; } @@ -59,7 +63,7 @@ sfMusic* sfMusic_createFromStream(sfInputStream* stream) { assert(stream); - auto music = std::make_unique(sfMusic{{}, {stream}}); + auto music = std::make_unique(sfMusic{{}, {}, {stream}}); if (!music->This.openFromStream(music->Stream)) return nullptr; @@ -90,6 +94,28 @@ bool sfMusic_isLooping(const sfMusic* music) } +//////////////////////////////////////////////////////////// +void sfMusic_setEffectProcessor(sfMusic* music, sfEffectProcessor effectProcessor) +{ + assert(music); + + if (!effectProcessor) + { + music->This.setEffectProcessor(nullptr); + } + else + { + music->This.setEffectProcessor( + [effectProcessor](const float* inputFrames, + unsigned int& inputFrameCount, + float* outputFrames, + unsigned int& outputFrameCount, + unsigned int frameChannelCount) + { effectProcessor(inputFrames, &inputFrameCount, outputFrames, &outputFrameCount, frameChannelCount); }); + } +} + + //////////////////////////////////////////////////////////// sfTime sfMusic_getDuration(const sfMusic* music) { @@ -156,6 +182,22 @@ unsigned int sfMusic_getSampleRate(const sfMusic* music) } +//////////////////////////////////////////////////////////// +const sfSoundChannel* sfMusic_getChannelMap(const sfMusic* music, size_t* count) +{ + assert(music); + assert(count); + + const auto channels = music->This.getChannelMap(); + + music->Channels.resize(channels.size()); + std::memcpy(music->Channels.data(), channels.data(), sizeof(sfSoundChannel) * channels.size()); + + *count = music->Channels.size(); + return music->Channels.data(); +} + + //////////////////////////////////////////////////////////// sfSoundStatus sfMusic_getStatus(const sfMusic* music) { @@ -180,6 +222,14 @@ void sfMusic_setPitch(sfMusic* music, float pitch) } +//////////////////////////////////////////////////////////// +void sfMusic_setPan(sfMusic* music, float pan) +{ + assert(music); + music->This.setPan(pan); +} + + //////////////////////////////////////////////////////////// void sfMusic_setVolume(sfMusic* music, float volume) { @@ -188,6 +238,14 @@ void sfMusic_setVolume(sfMusic* music, float volume) } +//////////////////////////////////////////////////////////// +void sfMusic_setSpatializationEnabled(sfMusic* music, bool enabled) +{ + assert(music); + music->This.setSpatializationEnabled(enabled); +} + + //////////////////////////////////////////////////////////// void sfMusic_setPosition(sfMusic* music, sfVector3f position) { @@ -196,6 +254,46 @@ void sfMusic_setPosition(sfMusic* music, sfVector3f position) } +//////////////////////////////////////////////////////////// +void sfMusic_setDirection(sfMusic* music, sfVector3f position) +{ + assert(music); + music->This.setDirection(convertVector3(position)); +} + + +//////////////////////////////////////////////////////////// +void sfMusic_setCone(sfMusic* music, sfSoundSourceCone cone) +{ + assert(music); + music->This.setCone(convertCone(cone)); +} + + +//////////////////////////////////////////////////////////// +void sfMusic_setVelocity(sfMusic* music, sfVector3f velocity) +{ + assert(music); + music->This.setVelocity(convertVector3(velocity)); +} + + +//////////////////////////////////////////////////////////// +void sfMusic_setDopplerFactor(sfMusic* music, float factor) +{ + assert(music); + music->This.setDopplerFactor(factor); +} + + +//////////////////////////////////////////////////////////// +CSFML_AUDIO_API void sfMusic_setDirectionalAttenuationFactor(sfMusic* music, float factor) +{ + assert(music); + music->This.setDirectionalAttenuationFactor(factor); +} + + //////////////////////////////////////////////////////////// void sfMusic_setRelativeToListener(sfMusic* music, bool relative) { @@ -212,6 +310,30 @@ void sfMusic_setMinDistance(sfMusic* music, float distance) } +//////////////////////////////////////////////////////////// +void sfMusic_setMaxDistance(sfMusic* music, float distance) +{ + assert(music); + music->This.setMaxDistance(distance); +} + + +//////////////////////////////////////////////////////////// +void sfMusic_setMinGain(sfMusic* music, float gain) +{ + assert(music); + music->This.setMinGain(gain); +} + + +//////////////////////////////////////////////////////////// +void sfMusic_setMaxGain(sfMusic* music, float gain) +{ + assert(music); + music->This.setMaxGain(gain); +} + + //////////////////////////////////////////////////////////// void sfMusic_setAttenuation(sfMusic* music, float attenuation) { @@ -236,6 +358,14 @@ float sfMusic_getPitch(const sfMusic* music) } +//////////////////////////////////////////////////////////// +float sfMusic_getPan(const sfMusic* music) +{ + assert(music); + return music->This.getPan(); +} + + //////////////////////////////////////////////////////////// float sfMusic_getVolume(const sfMusic* music) { @@ -244,6 +374,14 @@ float sfMusic_getVolume(const sfMusic* music) } +//////////////////////////////////////////////////////////// +bool sfMusic_isSpatializationEnabled(const sfMusic* music) +{ + assert(music); + return music->This.isSpatializationEnabled(); +} + + //////////////////////////////////////////////////////////// sfVector3f sfMusic_getPosition(const sfMusic* music) { @@ -252,6 +390,46 @@ sfVector3f sfMusic_getPosition(const sfMusic* music) } +//////////////////////////////////////////////////////////// +sfVector3f sfMusic_getDirection(const sfMusic* music) +{ + assert(music); + return convertVector3(music->This.getDirection()); +} + + +//////////////////////////////////////////////////////////// +sfSoundSourceCone sfMusic_getCone(const sfMusic* music) +{ + assert(music); + return convertCone(music->This.getCone()); +} + + +//////////////////////////////////////////////////////////// +sfVector3f sfMusic_getVelocity(const sfMusic* music) +{ + assert(music); + return convertVector3(music->This.getVelocity()); +} + + +//////////////////////////////////////////////////////////// +float sfMusic_getDopplerFactor(const sfMusic* music) +{ + assert(music); + return music->This.getDopplerFactor(); +} + + +//////////////////////////////////////////////////////////// +float sfMusic_getDirectionalAttenuationFactor(const sfMusic* music) +{ + assert(music); + return music->This.getDirectionalAttenuationFactor(); +} + + //////////////////////////////////////////////////////////// bool sfMusic_isRelativeToListener(const sfMusic* music) { @@ -268,6 +446,30 @@ float sfMusic_getMinDistance(const sfMusic* music) } +//////////////////////////////////////////////////////////// +float sfMusic_getMaxDistance(const sfMusic* music) +{ + assert(music); + return music->This.getMaxDistance(); +} + + +//////////////////////////////////////////////////////////// +float sfMusic_getMinGain(const sfMusic* music) +{ + assert(music); + return music->This.getMinGain(); +} + + +//////////////////////////////////////////////////////////// +float sfMusic_getMaxGain(const sfMusic* music) +{ + assert(music); + return music->This.getMinGain(); +} + + //////////////////////////////////////////////////////////// float sfMusic_getAttenuation(const sfMusic* music) { diff --git a/src/CSFML/Audio/MusicStruct.hpp b/src/CSFML/Audio/MusicStruct.hpp index 6d33849..1e97cb0 100644 --- a/src/CSFML/Audio/MusicStruct.hpp +++ b/src/CSFML/Audio/MusicStruct.hpp @@ -27,16 +27,20 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include +#include + //////////////////////////////////////////////////////////// // Internal structure of sfMusic //////////////////////////////////////////////////////////// struct sfMusic { - sf::Music This; - CallbackStream Stream; + sf::Music This; + mutable std::vector Channels; + CallbackStream Stream; }; diff --git a/src/CSFML/Audio/Sound.cpp b/src/CSFML/Audio/Sound.cpp index 03184d7..a887764 100644 --- a/src/CSFML/Audio/Sound.cpp +++ b/src/CSFML/Audio/Sound.cpp @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include @@ -129,6 +130,14 @@ void sfSound_setPitch(sfSound* sound, float pitch) } +//////////////////////////////////////////////////////////// +void sfSound_setPan(sfSound* sound, float pan) +{ + assert(sound); + sound->This.setPan(pan); +} + + //////////////////////////////////////////////////////////// void sfSound_setVolume(sfSound* sound, float volume) { @@ -137,6 +146,14 @@ void sfSound_setVolume(sfSound* sound, float volume) } +//////////////////////////////////////////////////////////// +void sfSound_setSpatializationEnabled(sfSound* sound, bool enabled) +{ + assert(sound); + sound->This.setSpatializationEnabled(enabled); +} + + //////////////////////////////////////////////////////////// void sfSound_setPosition(sfSound* sound, sfVector3f position) { @@ -145,6 +162,46 @@ void sfSound_setPosition(sfSound* sound, sfVector3f position) } +//////////////////////////////////////////////////////////// +void sfSound_setDirection(sfSound* sound, sfVector3f direction) +{ + assert(sound); + sound->This.setDirection(convertVector3(direction)); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setCone(sfSound* sound, sfSoundSourceCone cone) +{ + assert(sound); + sound->This.setCone(convertCone(cone)); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setVelocity(sfSound* sound, sfVector3f velocity) +{ + assert(sound); + sound->This.setVelocity(convertVector3(velocity)); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setDopplerFactor(sfSound* sound, float factor) +{ + assert(sound); + sound->This.setDopplerFactor(factor); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setDirectionalAttenuationFactor(sfSound* sound, float factor) +{ + assert(sound); + sound->This.setDirectionalAttenuationFactor(factor); +} + + //////////////////////////////////////////////////////////// void sfSound_setRelativeToListener(sfSound* sound, bool relative) { @@ -161,6 +218,30 @@ void sfSound_setMinDistance(sfSound* sound, float distance) } +//////////////////////////////////////////////////////////// +void sfSound_setMaxDistance(sfSound* sound, float distance) +{ + assert(sound); + sound->This.setMaxDistance(distance); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setMinGain(sfSound* sound, float gain) +{ + assert(sound); + sound->This.setMinGain(gain); +} + + +//////////////////////////////////////////////////////////// +void sfSound_setMaxGain(sfSound* sound, float gain) +{ + assert(sound); + sound->This.setMaxGain(gain); +} + + //////////////////////////////////////////////////////////// void sfSound_setAttenuation(sfSound* sound, float attenuation) { @@ -177,6 +258,28 @@ void sfSound_setPlayingOffset(sfSound* sound, sfTime timeOffset) } +//////////////////////////////////////////////////////////// +void sfSound_setEffectProcessor(sfSound* sound, sfEffectProcessor effectProcessor) +{ + assert(sound); + + if (!effectProcessor) + { + sound->This.setEffectProcessor(nullptr); + } + else + { + sound->This.setEffectProcessor( + [effectProcessor](const float* inputFrames, + unsigned int& inputFrameCount, + float* outputFrames, + unsigned int& outputFrameCount, + unsigned int frameChannelCount) + { effectProcessor(inputFrames, &inputFrameCount, outputFrames, &outputFrameCount, frameChannelCount); }); + } +} + + //////////////////////////////////////////////////////////// float sfSound_getPitch(const sfSound* sound) { @@ -185,6 +288,14 @@ float sfSound_getPitch(const sfSound* sound) } +//////////////////////////////////////////////////////////// +float sfSound_getPan(const sfSound* sound) +{ + assert(sound); + return sound->This.getPan(); +} + + //////////////////////////////////////////////////////////// float sfSound_getVolume(const sfSound* sound) { @@ -193,6 +304,14 @@ float sfSound_getVolume(const sfSound* sound) } +//////////////////////////////////////////////////////////// +bool sfSound_isSpatializationEnabled(const sfSound* sound) +{ + assert(sound); + return sound->This.isSpatializationEnabled(); +} + + //////////////////////////////////////////////////////////// sfVector3f sfSound_getPosition(const sfSound* sound) { @@ -201,6 +320,46 @@ sfVector3f sfSound_getPosition(const sfSound* sound) } +//////////////////////////////////////////////////////////// +sfVector3f sfSound_getDirection(const sfSound* sound) +{ + assert(sound); + return convertVector3(sound->This.getDirection()); +} + + +//////////////////////////////////////////////////////////// +sfSoundSourceCone sfSound_getCone(const sfSound* sound) +{ + assert(sound); + return convertCone(sound->This.getCone()); +} + + +//////////////////////////////////////////////////////////// +sfVector3f sfSound_getVelocity(const sfSound* sound) +{ + assert(sound); + return convertVector3(sound->This.getVelocity()); +} + + +//////////////////////////////////////////////////////////// +float sfSound_getDopplerFactor(const sfSound* sound) +{ + assert(sound); + return sound->This.getDopplerFactor(); +} + + +//////////////////////////////////////////////////////////// +float sfSound_getDirectionalAttenuationFactor(const sfSound* sound) +{ + assert(sound); + return sound->This.getDopplerFactor(); +} + + //////////////////////////////////////////////////////////// bool sfSound_isRelativeToListener(const sfSound* sound) { @@ -217,6 +376,30 @@ float sfSound_getMinDistance(const sfSound* sound) } +//////////////////////////////////////////////////////////// +float sfSound_getMaxDistance(const sfSound* sound) +{ + assert(sound); + return sound->This.getMaxDistance(); +} + + +//////////////////////////////////////////////////////////// +float sfSound_getMinGain(const sfSound* sound) +{ + assert(sound); + return sound->This.getMinGain(); +} + + +//////////////////////////////////////////////////////////// +float sfSound_getMaxGain(const sfSound* sound) +{ + assert(sound); + return sound->This.getMaxGain(); +} + + //////////////////////////////////////////////////////////// float sfSound_getAttenuation(const sfSound* sound) { diff --git a/src/CSFML/Audio/SoundBuffer.cpp b/src/CSFML/Audio/SoundBuffer.cpp index 81ce1d7..c97a4fe 100644 --- a/src/CSFML/Audio/SoundBuffer.cpp +++ b/src/CSFML/Audio/SoundBuffer.cpp @@ -29,6 +29,8 @@ #include #include +#include + //////////////////////////////////////////////////////////// sfSoundBuffer* sfSoundBuffer_createFromFile(const char* filename) @@ -39,7 +41,7 @@ sfSoundBuffer* sfSoundBuffer_createFromFile(const char* filename) if (!soundBuffer.loadFromFile(filename)) return nullptr; - return new sfSoundBuffer{std::move(soundBuffer)}; + return new sfSoundBuffer{std::move(soundBuffer), {}}; } @@ -50,7 +52,7 @@ sfSoundBuffer* sfSoundBuffer_createFromMemory(const void* data, size_t sizeInByt if (!soundBuffer.loadFromMemory(data, sizeInBytes)) return nullptr; - return new sfSoundBuffer{std::move(soundBuffer)}; + return new sfSoundBuffer{std::move(soundBuffer), {}}; } @@ -64,7 +66,7 @@ sfSoundBuffer* sfSoundBuffer_createFromStream(sfInputStream* stream) if (!soundBuffer.loadFromStream(sfmlStream)) return nullptr; - return new sfSoundBuffer{std::move(soundBuffer)}; + return new sfSoundBuffer{std::move(soundBuffer), {}}; } @@ -85,7 +87,7 @@ sfSoundBuffer* sfSoundBuffer_createFromSamples( if (!soundBuffer.loadFromSamples(samples, sampleCount, channelCount, sampleRate, channelMap)) return nullptr; - return new sfSoundBuffer{std::move(soundBuffer)}; + return new sfSoundBuffer{std::move(soundBuffer), {}}; } @@ -145,6 +147,22 @@ unsigned int sfSoundBuffer_getChannelCount(const sfSoundBuffer* soundBuffer) } +//////////////////////////////////////////////////////////// +sfSoundChannel* sfSoundBuffer_getChannelMap(const sfSoundBuffer* soundBuffer, size_t* count) +{ + assert(soundBuffer); + assert(count); + + const auto channels = soundBuffer->This.getChannelMap(); + + soundBuffer->Channels.resize(channels.size()); + std::memcpy(soundBuffer->Channels.data(), channels.data(), sizeof(sfSoundChannel) * channels.size()); + + *count = soundBuffer->Channels.size(); + return soundBuffer->Channels.data(); +} + + //////////////////////////////////////////////////////////// sfTime sfSoundBuffer_getDuration(const sfSoundBuffer* soundBuffer) { diff --git a/src/CSFML/Audio/SoundBufferStruct.hpp b/src/CSFML/Audio/SoundBufferStruct.hpp index 2d0d020..1fdd84c 100644 --- a/src/CSFML/Audio/SoundBufferStruct.hpp +++ b/src/CSFML/Audio/SoundBufferStruct.hpp @@ -27,6 +27,8 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include + #include @@ -35,5 +37,6 @@ //////////////////////////////////////////////////////////// struct sfSoundBuffer { - sf::SoundBuffer This; + sf::SoundBuffer This; + mutable std::vector Channels; }; diff --git a/src/CSFML/Audio/SoundRecorder.cpp b/src/CSFML/Audio/SoundRecorder.cpp index 9269627..e879607 100644 --- a/src/CSFML/Audio/SoundRecorder.cpp +++ b/src/CSFML/Audio/SoundRecorder.cpp @@ -29,6 +29,7 @@ #include #include +#include //////////////////////////////////////////////////////////// @@ -37,7 +38,7 @@ sfSoundRecorder* sfSoundRecorder_create(sfSoundRecorderStartCallback onStart, sfSoundRecorderStopCallback onStop, void* userData) { - return new sfSoundRecorder{{onStart, onProcess, onStop, userData}, {}}; + return new sfSoundRecorder{{onStart, onProcess, onStop, userData}, {}, ""}; } @@ -143,3 +144,19 @@ unsigned int sfSoundRecorder_getChannelCount(const sfSoundRecorder* soundRecorde assert(soundRecorder); return soundRecorder->This.getChannelCount(); } + + +//////////////////////////////////////////////////////////// +sfSoundChannel* sfSoundRecorder_getChannelMap(const sfSoundRecorder* soundRecorder, size_t* count) +{ + assert(soundRecorder); + assert(count); + + const auto channels = soundRecorder->This.getChannelMap(); + + soundRecorder->Channels.resize(channels.size()); + std::memcpy(soundRecorder->Channels.data(), channels.data(), sizeof(sfSoundChannel) * channels.size()); + + *count = soundRecorder->Channels.size(); + return soundRecorder->Channels.data(); +} diff --git a/src/CSFML/Audio/SoundRecorderStruct.hpp b/src/CSFML/Audio/SoundRecorderStruct.hpp index 55b8d01..5f34299 100644 --- a/src/CSFML/Audio/SoundRecorderStruct.hpp +++ b/src/CSFML/Audio/SoundRecorderStruct.hpp @@ -85,6 +85,7 @@ private: //////////////////////////////////////////////////////////// struct sfSoundRecorder { - sfSoundRecorderImpl This; - std::string DeviceName; + sfSoundRecorderImpl This; + mutable std::vector Channels; + std::string DeviceName; }; diff --git a/src/CSFML/Audio/SoundStream.cpp b/src/CSFML/Audio/SoundStream.cpp index 43f4204..3830bcd 100644 --- a/src/CSFML/Audio/SoundStream.cpp +++ b/src/CSFML/Audio/SoundStream.cpp @@ -25,10 +25,13 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include +#include + //////////////////////////////////////////////////////////// sfSoundStream* sfSoundStream_create( @@ -40,7 +43,7 @@ sfSoundStream* sfSoundStream_create( size_t channelMapSize, void* userData) { - return new sfSoundStream{{onGetData, onSeek, channelCount, sampleRate, channelMapData, channelMapSize, userData}}; + return new sfSoundStream{{onGetData, onSeek, channelCount, sampleRate, channelMapData, channelMapSize, userData}, {}}; } @@ -99,6 +102,22 @@ unsigned int sfSoundStream_getSampleRate(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +sfSoundChannel* sfSoundStream_getChannelMap(const sfSoundStream* soundStream, size_t* count) +{ + assert(soundStream); + assert(count); + + const auto channels = soundStream->This.getChannelMap(); + + soundStream->Channels.resize(channels.size()); + std::memcpy(soundStream->Channels.data(), channels.data(), sizeof(sfSoundChannel) * channels.size()); + + *count = soundStream->Channels.size(); + return soundStream->Channels.data(); +} + + //////////////////////////////////////////////////////////// void sfSoundStream_setPitch(sfSoundStream* soundStream, float pitch) { @@ -107,6 +126,14 @@ void sfSoundStream_setPitch(sfSoundStream* soundStream, float pitch) } +//////////////////////////////////////////////////////////// +void sfSoundStream_setPan(sfSoundStream* soundStream, float pan) +{ + assert(soundStream); + soundStream->This.setPan(pan); +} + + //////////////////////////////////////////////////////////// void sfSoundStream_setVolume(sfSoundStream* soundStream, float volume) { @@ -115,6 +142,14 @@ void sfSoundStream_setVolume(sfSoundStream* soundStream, float volume) } +//////////////////////////////////////////////////////////// +void sfSoundStream_setSpatializationEnabled(sfSoundStream* soundStream, bool enabled) +{ + assert(soundStream); + soundStream->This.setSpatializationEnabled(enabled); +} + + //////////////////////////////////////////////////////////// void sfSoundStream_setPosition(sfSoundStream* soundStream, sfVector3f position) { @@ -123,6 +158,46 @@ void sfSoundStream_setPosition(sfSoundStream* soundStream, sfVector3f position) } +//////////////////////////////////////////////////////////// +void sfSoundStream_setDirection(sfSoundStream* soundStream, sfVector3f position) +{ + assert(soundStream); + soundStream->This.setDirection(convertVector3(position)); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setCone(sfSoundStream* soundStream, sfSoundSourceCone cone) +{ + assert(soundStream); + soundStream->This.setCone(convertCone(cone)); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setVelocity(sfSoundStream* soundStream, sfVector3f velocity) +{ + assert(soundStream); + soundStream->This.setVelocity(convertVector3(velocity)); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setDopplerFactor(sfSoundStream* soundStream, float factor) +{ + assert(soundStream); + soundStream->This.setDopplerFactor(factor); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setDirectionalAttenuationFactor(sfSoundStream* soundStream, float factor) +{ + assert(soundStream); + soundStream->This.setDirectionalAttenuationFactor(factor); +} + + //////////////////////////////////////////////////////////// void sfSoundStream_setRelativeToListener(sfSoundStream* soundStream, bool relative) { @@ -139,6 +214,30 @@ void sfSoundStream_setMinDistance(sfSoundStream* soundStream, float distance) } +//////////////////////////////////////////////////////////// +void sfSoundStream_setMaxDistance(sfSoundStream* soundStream, float distance) +{ + assert(soundStream); + soundStream->This.setMaxDistance(distance); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setMinGain(sfSoundStream* soundStream, float gain) +{ + assert(soundStream); + soundStream->This.setMinGain(gain); +} + + +//////////////////////////////////////////////////////////// +void sfSoundStream_setMaxGain(sfSoundStream* soundStream, float gain) +{ + assert(soundStream); + soundStream->This.setMaxGain(gain); +} + + //////////////////////////////////////////////////////////// void sfSoundStream_setAttenuation(sfSoundStream* soundStream, float attenuation) { @@ -171,6 +270,14 @@ float sfSoundStream_getPitch(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +float sfSoundStream_getPan(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getPan(); +} + + //////////////////////////////////////////////////////////// float sfSoundStream_getVolume(const sfSoundStream* soundStream) { @@ -179,6 +286,14 @@ float sfSoundStream_getVolume(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +bool sfSoundStream_isSpatializationEnabled(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.isSpatializationEnabled(); +} + + //////////////////////////////////////////////////////////// sfVector3f sfSoundStream_getPosition(const sfSoundStream* soundStream) { @@ -187,6 +302,46 @@ sfVector3f sfSoundStream_getPosition(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +sfVector3f sfSoundStream_getDirection(const sfSoundStream* soundStream) +{ + assert(soundStream); + return convertVector3(soundStream->This.getDirection()); +} + + +//////////////////////////////////////////////////////////// +sfSoundSourceCone sfSoundStream_getCone(const sfSoundStream* soundStream) +{ + assert(soundStream); + return convertCone(soundStream->This.getCone()); +} + + +//////////////////////////////////////////////////////////// +sfVector3f sfSoundStream_getVelocity(const sfSoundStream* soundStream) +{ + assert(soundStream); + return convertVector3(soundStream->This.getVelocity()); +} + + +//////////////////////////////////////////////////////////// +float sfSoundStream_getDopplerFactor(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getDopplerFactor(); +} + + +//////////////////////////////////////////////////////////// +float sfSoundStream_getDirectionalAttenuationFactor(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getDirectionalAttenuationFactor(); +} + + //////////////////////////////////////////////////////////// bool sfSoundStream_isRelativeToListener(const sfSoundStream* soundStream) { @@ -203,6 +358,30 @@ float sfSoundStream_getMinDistance(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +float sfSoundStream_getMaxDistance(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getMaxDistance(); +} + + +//////////////////////////////////////////////////////////// +float sfSoundStream_getMinGain(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getMinGain(); +} + + +//////////////////////////////////////////////////////////// +float sfSoundStream_getMaxGain(const sfSoundStream* soundStream) +{ + assert(soundStream); + return soundStream->This.getMaxGain(); +} + + //////////////////////////////////////////////////////////// float sfSoundStream_getAttenuation(const sfSoundStream* soundStream) { @@ -219,6 +398,28 @@ bool sfSoundStream_isLooping(const sfSoundStream* soundStream) } +//////////////////////////////////////////////////////////// +void sfSoundStream_setEffectProcessor(sfSoundStream* soundStream, sfEffectProcessor effectProcessor) +{ + assert(soundStream); + + if (!effectProcessor) + { + soundStream->This.setEffectProcessor(nullptr); + } + else + { + soundStream->This.setEffectProcessor( + [effectProcessor](const float* inputFrames, + unsigned int& inputFrameCount, + float* outputFrames, + unsigned int& outputFrameCount, + unsigned int frameChannelCount) + { effectProcessor(inputFrames, &inputFrameCount, outputFrames, &outputFrameCount, frameChannelCount); }); + } +} + + //////////////////////////////////////////////////////////// sfTime sfSoundStream_getPlayingOffset(const sfSoundStream* soundStream) { diff --git a/src/CSFML/Audio/SoundStreamStruct.hpp b/src/CSFML/Audio/SoundStreamStruct.hpp index e944bf2..7aad2ca 100644 --- a/src/CSFML/Audio/SoundStreamStruct.hpp +++ b/src/CSFML/Audio/SoundStreamStruct.hpp @@ -88,5 +88,6 @@ private: //////////////////////////////////////////////////////////// struct sfSoundStream { - sfSoundStreamImpl This; + sfSoundStreamImpl This; + mutable std::vector Channels; };