diff options
author | Joerg Mueller <nexyon@gmail.com> | 2011-06-22 00:24:40 +0400 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2011-06-22 00:24:40 +0400 |
commit | c89b4e4b665757e0a164e98985d2f5d1c6843fa0 (patch) | |
tree | 01a30699fae68e5639dfeb61467ef1ba113d5125 | |
parent | 044887b5a4b1df57fce408f29f59bce1d7fa0085 (diff) |
3D Audio GSoC:
- Implemented a nice rechanneling solution with unofficial speaker arrangement standards similar to what OpenAL soft has
- Renamend AUD_Channel in the C API to AUD_Handle
- Removed the unlogical 7.2 speaker configuration, that's a hardware only config
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.cpp | 84 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.h | 58 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_ChannelMapperFactory.cpp | 67 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_ChannelMapperFactory.h | 19 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_ChannelMapperReader.cpp | 289 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_ChannelMapperReader.h | 38 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_DefaultMixer.cpp | 22 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_Space.h | 21 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sound.c | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_SoundActuator.h | 6 |
10 files changed, 390 insertions, 216 deletions
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index fc693be12d5..62888da14c3 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -90,7 +90,7 @@ extern "C" { typedef AUD_Reference<AUD_IFactory> AUD_Sound; typedef AUD_Reference<AUD_ReadDevice> AUD_Device; -typedef AUD_Reference<AUD_IHandle> AUD_Channel; +typedef AUD_Reference<AUD_IHandle> AUD_Handle; typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry; #define AUD_CAPI_IMPLEMENTATION @@ -374,7 +374,7 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound) } } -int AUD_setLoop(AUD_Channel* handle, int loops) +int AUD_setLoop(AUD_Handle* handle, int loops) { assert(handle); @@ -409,14 +409,14 @@ void AUD_unload(AUD_Sound* sound) delete sound; } -AUD_Channel* AUD_play(AUD_Sound* sound, int keep) +AUD_Handle* AUD_play(AUD_Sound* sound, int keep) { assert(sound); try { - AUD_Channel channel = AUD_device->play(*sound, keep); - if(!channel.isNull()) - return new AUD_Channel(channel); + AUD_Handle handle = AUD_device->play(*sound, keep); + if(!handle.isNull()) + return new AUD_Handle(handle); } catch(AUD_Exception&) { @@ -424,19 +424,19 @@ AUD_Channel* AUD_play(AUD_Sound* sound, int keep) return NULL; } -int AUD_pause(AUD_Channel* handle) +int AUD_pause(AUD_Handle* handle) { assert(handle); return (*handle)->pause(); } -int AUD_resume(AUD_Channel* handle) +int AUD_resume(AUD_Handle* handle) { assert(handle); return (*handle)->resume(); } -int AUD_stop(AUD_Channel* handle) +int AUD_stop(AUD_Handle* handle) { assert(handle); int result = (*handle)->stop(); @@ -444,25 +444,25 @@ int AUD_stop(AUD_Channel* handle) return result; } -int AUD_setKeep(AUD_Channel* handle, int keep) +int AUD_setKeep(AUD_Handle* handle, int keep) { assert(handle); return (*handle)->setKeep(keep); } -int AUD_seek(AUD_Channel* handle, float seekTo) +int AUD_seek(AUD_Handle* handle, float seekTo) { assert(handle); return (*handle)->seek(seekTo); } -float AUD_getPosition(AUD_Channel* handle) +float AUD_getPosition(AUD_Handle* handle) { assert(handle); return (*handle)->getPosition(); } -AUD_Status AUD_getStatus(AUD_Channel* handle) +AUD_Status AUD_getStatus(AUD_Handle* handle) { assert(handle); return (*handle)->getStatus(); @@ -537,7 +537,7 @@ int AUD_setDistanceModel(AUD_DistanceModel model) return false; } -int AUD_setSourceLocation(AUD_Channel* handle, const float* location) +int AUD_setSourceLocation(AUD_Handle* handle, const float* location) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -551,7 +551,7 @@ int AUD_setSourceLocation(AUD_Channel* handle, const float* location) return false; } -int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity) +int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -565,7 +565,7 @@ int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity) return false; } -int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation) +int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -579,7 +579,7 @@ int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation) return false; } -int AUD_setRelative(AUD_Channel* handle, int relative) +int AUD_setRelative(AUD_Handle* handle, int relative) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -592,7 +592,7 @@ int AUD_setRelative(AUD_Channel* handle, int relative) return false; } -int AUD_setVolumeMaximum(AUD_Channel* handle, float volume) +int AUD_setVolumeMaximum(AUD_Handle* handle, float volume) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -605,7 +605,7 @@ int AUD_setVolumeMaximum(AUD_Channel* handle, float volume) return false; } -int AUD_setVolumeMinimum(AUD_Channel* handle, float volume) +int AUD_setVolumeMinimum(AUD_Handle* handle, float volume) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -618,7 +618,7 @@ int AUD_setVolumeMinimum(AUD_Channel* handle, float volume) return false; } -int AUD_setDistanceMaximum(AUD_Channel* handle, float distance) +int AUD_setDistanceMaximum(AUD_Handle* handle, float distance) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -631,7 +631,7 @@ int AUD_setDistanceMaximum(AUD_Channel* handle, float distance) return false; } -int AUD_setDistanceReference(AUD_Channel* handle, float distance) +int AUD_setDistanceReference(AUD_Handle* handle, float distance) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -644,7 +644,7 @@ int AUD_setDistanceReference(AUD_Channel* handle, float distance) return false; } -int AUD_setAttenuation(AUD_Channel* handle, float factor) +int AUD_setAttenuation(AUD_Handle* handle, float factor) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -657,7 +657,7 @@ int AUD_setAttenuation(AUD_Channel* handle, float factor) return false; } -int AUD_setConeAngleOuter(AUD_Channel* handle, float angle) +int AUD_setConeAngleOuter(AUD_Handle* handle, float angle) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -670,7 +670,7 @@ int AUD_setConeAngleOuter(AUD_Channel* handle, float angle) return false; } -int AUD_setConeAngleInner(AUD_Channel* handle, float angle) +int AUD_setConeAngleInner(AUD_Handle* handle, float angle) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -683,7 +683,7 @@ int AUD_setConeAngleInner(AUD_Channel* handle, float angle) return false; } -int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume) +int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume) { assert(handle); AUD_Reference<AUD_I3DHandle> h(*handle); @@ -696,7 +696,7 @@ int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume) return false; } -int AUD_setSoundVolume(AUD_Channel* handle, float volume) +int AUD_setSoundVolume(AUD_Handle* handle, float volume) { assert(handle); try @@ -707,7 +707,7 @@ int AUD_setSoundVolume(AUD_Channel* handle, float volume) return false; } -int AUD_setSoundPitch(AUD_Channel* handle, float pitch) +int AUD_setSoundPitch(AUD_Handle* handle, float pitch) { assert(handle); try @@ -730,18 +730,18 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs) } } -AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek) +AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek) { assert(device); assert(sound); try { - AUD_Channel channel = (*device)->play(*sound); - if(!channel.isNull()) + AUD_Handle handle = (*device)->play(*sound); + if(!handle.isNull()) { - channel->seek(seek); - return new AUD_Channel(channel); + handle->seek(seek); + return new AUD_Handle(handle); } } catch(AUD_Exception&) @@ -848,13 +848,13 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high, return result; } -static void pauseSound(AUD_Channel* handle) +static void pauseSound(AUD_Handle* handle) { assert(handle); (*handle)->pause(); } -AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds) +AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds) { AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory; AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds); @@ -863,12 +863,12 @@ AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds) try { - AUD_Channel channel = AUD_device->play(limiter); - if(!channel.isNull()) + AUD_Handle handle2 = AUD_device->play(limiter); + if(!handle2.isNull()) { - channel->setStopCallback((stopCallback)pauseSound, handle); + handle2->setStopCallback((stopCallback)pauseSound, handle); AUD_device->unlock(); - return new AUD_Channel(channel); + return new AUD_Handle(handle2); } } catch(AUD_Exception&) @@ -996,7 +996,7 @@ void AUD_stopPlayback() #endif } -void AUD_seekSequencer(AUD_Channel* handle, float time) +void AUD_seekSequencer(AUD_Handle* handle, float time) { #ifdef WITH_JACK AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); @@ -1010,7 +1010,7 @@ void AUD_seekSequencer(AUD_Channel* handle, float time) } } -float AUD_getSequencerPosition(AUD_Channel* handle) +float AUD_getSequencerPosition(AUD_Handle* handle) { #ifdef WITH_JACK AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get()); @@ -1048,7 +1048,7 @@ AUD_Sound* AUD_copy(AUD_Sound* sound) return new AUD_Reference<AUD_IFactory>(*sound); } -void AUD_freeChannel(AUD_Channel* channel) +void AUD_freeHandle(AUD_Handle* handle) { - delete channel; + delete handle; } diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 945faa50070..fad54cdb721 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -57,7 +57,7 @@ typedef struct #ifndef AUD_CAPI_IMPLEMENTATION typedef void AUD_Sound; - typedef void AUD_Channel; + typedef void AUD_Handle; typedef void AUD_Device; typedef void AUD_SEntry; typedef float (*AUD_volumeFunction)(void*, void*, float); @@ -159,7 +159,7 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound); * \param loops The count of remaining loops, -1 for infinity. * \return Whether the handle is valid. */ -extern int AUD_setLoop(AUD_Channel* handle, int loops); +extern int AUD_setLoop(AUD_Handle* handle, int loops); /** * Rectifies a sound. @@ -181,28 +181,28 @@ extern void AUD_unload(AUD_Sound* sound); * paused when its end has been reached. * \return A handle to the played back sound. */ -extern AUD_Channel* AUD_play(AUD_Sound* sound, int keep); +extern AUD_Handle* AUD_play(AUD_Sound* sound, int keep); /** * Pauses a played back sound. * \param handle The handle to the sound. * \return Whether the handle has been playing or not. */ -extern int AUD_pause(AUD_Channel* handle); +extern int AUD_pause(AUD_Handle* handle); /** * Resumes a paused sound. * \param handle The handle to the sound. * \return Whether the handle has been paused or not. */ -extern int AUD_resume(AUD_Channel* handle); +extern int AUD_resume(AUD_Handle* handle); /** * Stops a playing or paused sound. * \param handle The handle to the sound. * \return Whether the handle has been valid or not. */ -extern int AUD_stop(AUD_Channel* handle); +extern int AUD_stop(AUD_Handle* handle); /** * Sets the end behaviour of a playing or paused sound. @@ -211,7 +211,7 @@ extern int AUD_stop(AUD_Channel* handle); * paused when its end has been reached. * \return Whether the handle has been valid or not. */ -extern int AUD_setKeep(AUD_Channel* handle, int keep); +extern int AUD_setKeep(AUD_Handle* handle, int keep); /** * Seeks a playing or paused sound. @@ -219,7 +219,7 @@ extern int AUD_setKeep(AUD_Channel* handle, int keep); * \param seekTo From where the sound file should be played back in seconds. * \return Whether the handle has been valid or not. */ -extern int AUD_seek(AUD_Channel* handle, float seekTo); +extern int AUD_seek(AUD_Handle* handle, float seekTo); /** * Retrieves the playback position of a handle. @@ -227,14 +227,14 @@ extern int AUD_seek(AUD_Channel* handle, float seekTo); * \return The current playback position in seconds or 0.0 if the handle is * invalid. */ -extern float AUD_getPosition(AUD_Channel* handle); +extern float AUD_getPosition(AUD_Handle* handle); /** * Returns the status of a playing, paused or stopped sound. * \param handle The handle to the sound. * \return The status of the sound behind the handle. */ -extern AUD_Status AUD_getStatus(AUD_Channel* handle); +extern AUD_Status AUD_getStatus(AUD_Handle* handle); /** * Sets the listener location. @@ -281,7 +281,7 @@ extern int AUD_setDistanceModel(AUD_DistanceModel model); * \param location The new location. * \return Whether the action succeeded. */ -extern int AUD_setSourceLocation(AUD_Channel* handle, const float* location); +extern int AUD_setSourceLocation(AUD_Handle* handle, const float* location); /** * Sets the velocity of a source. @@ -289,7 +289,7 @@ extern int AUD_setSourceLocation(AUD_Channel* handle, const float* location); * \param velocity The new velocity. * \return Whether the action succeeded. */ -extern int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity); +extern int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity); /** * Sets the orientation of a source. @@ -297,7 +297,7 @@ extern int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity); * \param orientation The new orientation as quaternion. * \return Whether the action succeeded. */ -extern int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation); +extern int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation); /** * Sets whether the source location, velocity and orientation are relative @@ -306,7 +306,7 @@ extern int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientatio * \param relative Whether the source is relative. * \return Whether the action succeeded. */ -extern int AUD_setRelative(AUD_Channel* handle, int relative); +extern int AUD_setRelative(AUD_Handle* handle, int relative); /** * Sets the maximum volume of a source. @@ -314,7 +314,7 @@ extern int AUD_setRelative(AUD_Channel* handle, int relative); * \param volume The new maximum volume. * \return Whether the action succeeded. */ -extern int AUD_setVolumeMaximum(AUD_Channel* handle, float volume); +extern int AUD_setVolumeMaximum(AUD_Handle* handle, float volume); /** * Sets the minimum volume of a source. @@ -322,7 +322,7 @@ extern int AUD_setVolumeMaximum(AUD_Channel* handle, float volume); * \param volume The new minimum volume. * \return Whether the action succeeded. */ -extern int AUD_setVolumeMinimum(AUD_Channel* handle, float volume); +extern int AUD_setVolumeMinimum(AUD_Handle* handle, float volume); /** * Sets the maximum distance of a source. @@ -332,7 +332,7 @@ extern int AUD_setVolumeMinimum(AUD_Channel* handle, float volume); * \param distance The new maximum distance. * \return Whether the action succeeded. */ -extern int AUD_setDistanceMaximum(AUD_Channel* handle, float distance); +extern int AUD_setDistanceMaximum(AUD_Handle* handle, float distance); /** * Sets the reference distance of a source. @@ -340,7 +340,7 @@ extern int AUD_setDistanceMaximum(AUD_Channel* handle, float distance); * \param distance The new reference distance. * \return Whether the action succeeded. */ -extern int AUD_setDistanceReference(AUD_Channel* handle, float distance); +extern int AUD_setDistanceReference(AUD_Handle* handle, float distance); /** * Sets the attenuation of a source. @@ -349,7 +349,7 @@ extern int AUD_setDistanceReference(AUD_Channel* handle, float distance); * \param factor The new attenuation. * \return Whether the action succeeded. */ -extern int AUD_setAttenuation(AUD_Channel* handle, float factor); +extern int AUD_setAttenuation(AUD_Handle* handle, float factor); /** * Sets the outer angle of the cone of a source. @@ -357,7 +357,7 @@ extern int AUD_setAttenuation(AUD_Channel* handle, float factor); * \param angle The new outer angle of the cone. * \return Whether the action succeeded. */ -extern int AUD_setConeAngleOuter(AUD_Channel* handle, float angle); +extern int AUD_setConeAngleOuter(AUD_Handle* handle, float angle); /** * Sets the inner angle of the cone of a source. @@ -365,7 +365,7 @@ extern int AUD_setConeAngleOuter(AUD_Channel* handle, float angle); * \param angle The new inner angle of the cone. * \return Whether the action succeeded. */ -extern int AUD_setConeAngleInner(AUD_Channel* handle, float angle); +extern int AUD_setConeAngleInner(AUD_Handle* handle, float angle); /** * Sets the outer volume of the cone of a source. @@ -375,7 +375,7 @@ extern int AUD_setConeAngleInner(AUD_Channel* handle, float angle); * \param volume The new outer volume of the cone. * \return Whether the action succeeded. */ -extern int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume); +extern int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume); /** * Sets the volume of a played back sound. @@ -383,7 +383,7 @@ extern int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume); * \param volume The new volume, must be between 0.0 and 1.0. * \return Whether the action succeeded. */ -extern int AUD_setSoundVolume(AUD_Channel* handle, float volume); +extern int AUD_setSoundVolume(AUD_Handle* handle, float volume); /** * Sets the pitch of a played back sound. @@ -391,7 +391,7 @@ extern int AUD_setSoundVolume(AUD_Channel* handle, float volume); * \param pitch The new pitch. * \return Whether the action succeeded. */ -extern int AUD_setSoundPitch(AUD_Channel* handle, float pitch); +extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch); /** * Opens a read device, with which audio data can be read. @@ -415,7 +415,7 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume); * \param seek The position where the sound should be seeked to. * \return A handle to the played back sound. */ -extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek); +extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek); /** * Reads the next samples into the supplied buffer. @@ -450,7 +450,7 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high, * \param time The time in seconds. * \return The silence handle. */ -extern AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds); +extern AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds); extern AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume); @@ -475,9 +475,9 @@ extern void AUD_startPlayback(void); extern void AUD_stopPlayback(void); -extern void AUD_seekSequencer(AUD_Channel* handle, float time); +extern void AUD_seekSequencer(AUD_Handle* handle, float time); -extern float AUD_getSequencerPosition(AUD_Channel* handle); +extern float AUD_getSequencerPosition(AUD_Handle* handle); #ifdef WITH_JACK extern void AUD_setSyncCallback(AUD_syncFunction function, void* data); @@ -487,7 +487,7 @@ extern int AUD_doesPlayback(void); extern AUD_Sound* AUD_copy(AUD_Sound* sound); -extern void AUD_freeChannel(AUD_Channel* channel); +extern void AUD_freeHandle(AUD_Handle* channel); #ifdef WITH_PYTHON extern PyObject* AUD_getPythonFactory(AUD_Sound* sound); diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp index d8ed1153dae..ea6c738cb58 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp +++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp @@ -38,75 +38,10 @@ AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> f AUD_DeviceSpecs specs) : AUD_MixerFactory(factory, specs) { - memset(m_mapping, 0, sizeof(m_mapping)); -} - -AUD_ChannelMapperFactory::~AUD_ChannelMapperFactory() -{ - for(int i = 1; i < 10; i++) - deleteMapping(i); -} - -float** AUD_ChannelMapperFactory::getMapping(int ic) -{ - ic--; - if(ic > 8 || ic < 0) - return 0; - - if(m_mapping[ic]) - { - int channels = -1; - while(m_mapping[ic][++channels] != 0); - if(channels != m_specs.channels) - deleteMapping(ic+1); - } - - if(!m_mapping[ic]) - { - int channels = m_specs.channels; - - m_mapping[ic] = new float*[channels+1]; - m_mapping[ic][channels] = 0; - - for(int i = 0; i < channels; i++) - { - m_mapping[ic][i] = new float[ic+1]; - for(int j = 0; j <= ic; j++) - m_mapping[ic][i][j] = ((i == j) || (channels == 1) || - (ic == 0)) ? 1.0f : 0.0f; - } - } - - return m_mapping[ic]; -} - -void AUD_ChannelMapperFactory::deleteMapping(int ic) -{ - ic--; - if(ic > 8 || ic < 0) - return; - - if(m_mapping[ic]) - { - for(int i = 0; 1; i++) - { - if(m_mapping[ic][i] != 0) - { - delete[] m_mapping[ic][i]; - } - else - break; - } - delete[] m_mapping[ic]; - m_mapping[ic] = 0; - } } AUD_Reference<AUD_IReader> AUD_ChannelMapperFactory::createReader() { AUD_Reference<AUD_IReader> reader = getReader(); - int ic = reader->getSpecs().channels; - - return new AUD_ChannelMapperReader(reader, - const_cast<AUD_ChannelMapperFactory*>(this)->getMapping(ic)); + return new AUD_ChannelMapperReader(reader, m_specs.channels); } diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h index 7c48aa791a6..ce43c6462de 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h +++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h @@ -41,11 +41,6 @@ class AUD_ChannelMapperFactory : public AUD_MixerFactory { private: - /** - * The mapping specification. - */ - float **m_mapping[9]; - // hide copy constructor and operator= AUD_ChannelMapperFactory(const AUD_ChannelMapperFactory&); AUD_ChannelMapperFactory& operator=(const AUD_ChannelMapperFactory&); @@ -53,20 +48,6 @@ private: public: AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs); - virtual ~AUD_ChannelMapperFactory(); - - /** - * Returns the mapping array for editing. - * \param ic The count of input channels the array should have. - * \note The count of output channels is read of the desired output specs. - */ - float** getMapping(int ic); - - /** - * Deletes the current channel mapping. - */ - void deleteMapping(int ic); - virtual AUD_Reference<AUD_IReader> createReader(); }; diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp index 5c135153d0e..ab7b5317be1 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp @@ -28,57 +28,124 @@ * \ingroup audaspaceintern */ +#include <cmath> #include "AUD_ChannelMapperReader.h" AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, - float **mapping) : - AUD_EffectReader(reader) + AUD_Channels channels) : + AUD_EffectReader(reader), m_target_channels(channels), + m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0) { - m_specs = reader->getSpecs(); +} - int channels = -1; - m_rch = m_specs.channels; - while(mapping[++channels] != 0); +AUD_ChannelMapperReader::~AUD_ChannelMapperReader() +{ + delete[] m_mapping; +} - m_mapping = new float*[channels]; - m_specs.channels = (AUD_Channels)channels; +float AUD_ChannelMapperReader::angleDistance(float alpha, float beta) +{ + alpha = fabs(alpha - beta); - float sum; - int i; + if(alpha > M_PI) + alpha = fabs(alpha - 2 * M_PI); - while(channels--) - { - m_mapping[channels] = new float[m_rch]; - sum = 0.0f; - for(i=0; i < m_rch; i++) - sum += mapping[channels][i]; - for(i=0; i < m_rch; i++) - m_mapping[channels][i] = sum > 0.0f ? - mapping[channels][i]/sum : 0.0f; - } + return alpha; } -AUD_ChannelMapperReader::~AUD_ChannelMapperReader() +void AUD_ChannelMapperReader::calculateMapping() { - int channels = m_specs.channels; + delete[] m_mapping; + m_mapping = new float[m_source_channels * m_target_channels]; - while(channels--) + const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1]; + const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1]; + + int lfe = -1; + + for(int i = 0; i < m_target_channels; i++) { - delete[] m_mapping[channels]; + if(target_channels[i] == AUD_CHANNEL_LFE) + { + lfe = i; + break; + } } - delete[] m_mapping; + const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1]; + const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1]; + + int channel_min1, channel_min2; + float angle_min1, angle_min2, angle; + + for(int i = 0; i < m_source_channels; i++) + { + if(source_channels[i] == AUD_CHANNEL_LFE) + { + if(lfe != -1) + m_mapping[lfe * m_source_channels + i] = 1; + + continue; + } + + channel_min1 = channel_min2 = -1; + angle_min1 = angle_min2 = 2 * M_PI; + + for(int j = 0; j < m_target_channels; j++) + { + angle = angleDistance(source_angles[i], target_angles[j]); + if(angle < angle_min1) + { + channel_min2 = channel_min1; + angle_min2 = angle_min1; + + channel_min1 = j; + angle_min1 = angle; + } + else if(angle < angle_min2) + { + channel_min2 = j; + angle_min2 = angle; + } + } + + if(channel_min2 == -1) + { + m_mapping[channel_min1 * m_source_channels + i] = 1; + } + else + { + angle = angle_min1 + angle_min2; + m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle); + m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle); + } + } } AUD_Specs AUD_ChannelMapperReader::getSpecs() const { - return m_specs; + AUD_Specs specs = m_reader->getSpecs(); + specs.channels = m_target_channels; + return specs; } void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer) { - m_buffer.assureSize(length * m_rch * sizeof(sample_t)); + AUD_Channels channels = m_reader->getSpecs().channels; + if(channels != m_source_channels) + { + m_source_channels = channels; + calculateMapping(); + } + + if(m_source_channels == m_target_channels) + { + m_reader->read(length, eos, buffer); + return; + } + + m_buffer.assureSize(length * channels * sizeof(sample_t)); sample_t* in = m_buffer.getBuffer(); @@ -88,12 +155,172 @@ void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer) for(int i = 0; i < length; i++) { - for(int j = 0; j < m_specs.channels; j++) + for(int j = 0; j < m_target_channels; j++) { sum = 0; - for(int k = 0; k < m_rch; k++) - sum += m_mapping[j][k] * in[i * m_rch + k]; - buffer[i * m_specs.channels + j] = sum; + for(int k = 0; k < m_source_channels; k++) + sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k]; + buffer[i * m_target_channels + j] = sum; } } } + +const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] = +{ + AUD_CHANNEL_FRONT_CENTER +}; + +const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT +}; + +const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_LFE +}; + +const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT +}; + +const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_FRONT_CENTER, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT +}; + +const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_FRONT_CENTER, + AUD_CHANNEL_LFE, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT +}; + +const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_FRONT_CENTER, + AUD_CHANNEL_LFE, + AUD_CHANNEL_REAR_CENTER, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT +}; + +const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] = +{ + AUD_CHANNEL_FRONT_LEFT, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_FRONT_CENTER, + AUD_CHANNEL_LFE, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT, + AUD_CHANNEL_SIDE_LEFT, + AUD_CHANNEL_SIDE_RIGHT +}; + +const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] = +{ + AUD_ChannelMapperReader::MONO_MAP, + AUD_ChannelMapperReader::STEREO_MAP, + AUD_ChannelMapperReader::STEREO_LFE_MAP, + AUD_ChannelMapperReader::SURROUND4_MAP, + AUD_ChannelMapperReader::SURROUND5_MAP, + AUD_ChannelMapperReader::SURROUND51_MAP, + AUD_ChannelMapperReader::SURROUND61_MAP, + AUD_ChannelMapperReader::SURROUND71_MAP +}; + +const float AUD_ChannelMapperReader::MONO_ANGLES[] = +{ + 0.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::STEREO_ANGLES[] = +{ + -90.0f * M_PI / 180.0f, + 90.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] = +{ + -90.0f * M_PI / 180.0f, + 90.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] = +{ + -45.0f * M_PI / 180.0f, + 45.0f * M_PI / 180.0f, + -135.0f * M_PI / 180.0f, + 135.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] = +{ + -30.0f * M_PI / 180.0f, + 30.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + -110.0f * M_PI / 180.0f, + 110.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] = +{ + -30.0f * M_PI / 180.0f, + 30.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + -110.0f * M_PI / 180.0f, + 110.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] = +{ + -30.0f * M_PI / 180.0f, + 30.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + 180.0f * M_PI / 180.0f, + -110.0f * M_PI / 180.0f, + 110.0f * M_PI / 180.0f +}; + +const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] = +{ + -30.0f * M_PI / 180.0f, + 30.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + 0.0f * M_PI / 180.0f, + -110.0f * M_PI / 180.0f, + 110.0f * M_PI / 180.0f + -150.0f * M_PI / 180.0f, + 150.0f * M_PI / 180.0f +}; + +const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] = +{ + AUD_ChannelMapperReader::MONO_ANGLES, + AUD_ChannelMapperReader::STEREO_ANGLES, + AUD_ChannelMapperReader::STEREO_LFE_ANGLES, + AUD_ChannelMapperReader::SURROUND4_ANGLES, + AUD_ChannelMapperReader::SURROUND5_ANGLES, + AUD_ChannelMapperReader::SURROUND51_ANGLES, + AUD_ChannelMapperReader::SURROUND61_ANGLES, + AUD_ChannelMapperReader::SURROUND71_ANGLES +}; diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h index b1246c08f75..949bb4427e2 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.h +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h @@ -50,29 +50,59 @@ private: /** * The output specification. */ - AUD_Specs m_specs; + AUD_Channels m_target_channels; /** * The channel count of the reader. */ - int m_rch; + AUD_Channels m_source_channels; /** * The mapping specification. */ - float **m_mapping; + float* m_mapping; + + static const AUD_Channel MONO_MAP[]; + static const AUD_Channel STEREO_MAP[]; + static const AUD_Channel STEREO_LFE_MAP[]; + static const AUD_Channel SURROUND4_MAP[]; + static const AUD_Channel SURROUND5_MAP[]; + static const AUD_Channel SURROUND51_MAP[]; + static const AUD_Channel SURROUND61_MAP[]; + static const AUD_Channel SURROUND71_MAP[]; + static const AUD_Channel* CHANNEL_MAPS[]; + + static const float MONO_ANGLES[]; + static const float STEREO_ANGLES[]; + static const float STEREO_LFE_ANGLES[]; + static const float SURROUND4_ANGLES[]; + static const float SURROUND5_ANGLES[]; + static const float SURROUND51_ANGLES[]; + static const float SURROUND61_ANGLES[]; + static const float SURROUND71_ANGLES[]; + static const float* CHANNEL_ANGLES[]; // hide copy constructor and operator= AUD_ChannelMapperReader(const AUD_ChannelMapperReader&); AUD_ChannelMapperReader& operator=(const AUD_ChannelMapperReader&); + /** + * Calculates the mapping matrix. + */ + void calculateMapping(); + + /** + * Calculates the distance between two angles. + */ + float angleDistance(float alpha, float beta); + public: /** * Creates a channel mapper reader. * \param reader The reader to map. * \param mapping The mapping specification as two dimensional float array. */ - AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, float **mapping); + AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, AUD_Channels channels); /** * Destroys the reader. diff --git a/intern/audaspace/intern/AUD_DefaultMixer.cpp b/intern/audaspace/intern/AUD_DefaultMixer.cpp index 24fea6527ba..62992b0201d 100644 --- a/intern/audaspace/intern/AUD_DefaultMixer.cpp +++ b/intern/audaspace/intern/AUD_DefaultMixer.cpp @@ -47,31 +47,15 @@ AUD_DefaultMixer::AUD_DefaultMixer(AUD_DeviceSpecs specs) : AUD_Reference<AUD_IReader> AUD_DefaultMixer::prepare(AUD_Reference<AUD_IReader> reader) { - // hacky for now, until a better channel mapper reader is available - AUD_ChannelMapperFactory cmf(NULL, m_specs); - - AUD_Specs specs = reader->getSpecs(); - - // if channel count is lower in output, rechannel before resampling - if(specs.channels < m_specs.channels) - { - reader = new AUD_ChannelMapperReader(reader, - cmf.getMapping(specs.channels)); - specs.channels = m_specs.channels; - } - // resample - if(specs.rate != m_specs.rate) #ifdef WITH_SAMPLERATE - reader = new AUD_SRCResampleReader(reader, m_specs.specs); + reader = new AUD_SRCResampleReader(reader, m_specs.specs); #else - reader = new AUD_LinearResampleReader(reader, m_specs.specs); + reader = new AUD_LinearResampleReader(reader, m_specs.specs); #endif // rechannel - if(specs.channels != m_specs.channels) - reader = new AUD_ChannelMapperReader(reader, - cmf.getMapping(specs.channels)); + reader = new AUD_ChannelMapperReader(reader, m_specs.channels); return reader; } diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h index ee28a05b80d..00bc22b97c6 100644 --- a/intern/audaspace/intern/AUD_Space.h +++ b/intern/audaspace/intern/AUD_Space.h @@ -41,6 +41,9 @@ /// Throws a AUD_Exception with the provided error code. #define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; } +/// Returns the bit for a channel mask. +#define AUD_CHANNEL_BIT(channel) (0x01 << channel) + /// Returns the smaller of the two values. #define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b)) /// Returns the bigger of the two values. @@ -79,10 +82,24 @@ typedef enum AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound. AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound. AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound. - AUD_CHANNELS_SURROUND71 = 8, /// 7.1 surround sound. - AUD_CHANNELS_SURROUND72 = 9 /// 7.2 surround sound. + AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound. } AUD_Channels; +/// The channel names. +typedef enum +{ + AUD_CHANNEL_FRONT_LEFT = 0, + AUD_CHANNEL_FRONT_RIGHT, + AUD_CHANNEL_FRONT_CENTER, + AUD_CHANNEL_LFE, + AUD_CHANNEL_REAR_LEFT, + AUD_CHANNEL_REAR_RIGHT, + AUD_CHANNEL_REAR_CENTER, + AUD_CHANNEL_SIDE_LEFT, + AUD_CHANNEL_SIDE_RIGHT, + AUD_CHANNEL_MAX +} AUD_Channel; + /** * The sample rate tells how many samples are played back within one second. * Some exotic formats may use other sample rates than provided here. diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 18eab716924..60a24c2eace 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -346,7 +346,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, AUD_setDeviceVolume(mixdown, volume); - AUD_freeChannel(AUD_playDevice(mixdown, scene->sound_scene, start / FPS)); + AUD_freeHandle(AUD_playDevice(mixdown, scene->sound_scene, start / FPS)); return mixdown; } diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index dc90d7d24de..9f145a71546 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -53,14 +53,14 @@ typedef struct KX_3DSoundSettings class KX_SoundActuator : public SCA_IActuator { - Py_Header; - bool m_isplaying; + Py_Header; + bool m_isplaying; AUD_Sound* m_sound; float m_volume; float m_pitch; bool m_is3d; KX_3DSoundSettings m_3d; - AUD_Channel* m_handle; + AUD_Handle* m_handle; void play(); |