Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-06-22 00:24:40 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-06-22 00:24:40 +0400
commitc89b4e4b665757e0a164e98985d2f5d1c6843fa0 (patch)
tree01a30699fae68e5639dfeb61467ef1ba113d5125 /intern/audaspace
parent044887b5a4b1df57fce408f29f59bce1d7fa0085 (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
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp84
-rw-r--r--intern/audaspace/intern/AUD_C-API.h58
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp67
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h19
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp289
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h38
-rw-r--r--intern/audaspace/intern/AUD_DefaultMixer.cpp22
-rw-r--r--intern/audaspace/intern/AUD_Space.h21
8 files changed, 386 insertions, 212 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.