Added support for all OpenAL Audio Effects. Access can be gotten through the main audio manager using the AudioEffects interface. IEffect provides access to effect parameters and allows for binding to cAudio sources. IFilter provides access to filters that can be attached to sources and effects.
Added conversion functions from our audio format enum to OpenAL's in preparation for supporting more formats. Reorganized cAudio defines, made it easier to access some compile time parameters. Fixed a bug where a source could not be played again after it reached the end of its audio stream. Added better checking for sources. IsValid() should provide a more useful indication of whether a source is usable. Added error checking and logging to cAudioCapture. Prevented initializing of cAudioManager until shutdown() has been called. Added a tutorial for Audio Effects. Added a footsteps sound for showing off Audio Effects. Moved the default compile location for the main library to lib/. The msvc project will copy the cAudio.dll to bin/win32-visual/
This commit is contained in:
parent
2132eea8bf
commit
30e5b4a99e
|
@ -58,7 +58,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
//Include our version of Sleep to free CPU usage
|
||||
#include "../../include/cAudioSleep.h"
|
||||
|
||||
#include "../../include/ILogger.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const unsigned int CAPTURE_FREQUENCY = 22050;
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="Tutorial5_AudioEffects"
|
||||
ProjectGUID="{EA03D1BB-6D71-4960-958A-670480A8259A}"
|
||||
RootNamespace="Tutorial5_AudioEffects"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../bin/win32-visual"
|
||||
IntermediateDirectory="obj/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../bin/win32-visual"
|
||||
IntermediateDirectory="obj/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,361 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
//Include IAudioManager so we can easily work with cAudio
|
||||
#include "../../include/IAudioManager.h"
|
||||
//Include IAudio so we can create cAudio objects
|
||||
#include "../../include/IAudio.h"
|
||||
//Include our version of Sleep to free CPU usage
|
||||
#include "../../include/cAudioSleep.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
//Some fancy text
|
||||
cout << "cAudio 1.7.1 Tutorial 5: Audio Effects \n \n";
|
||||
|
||||
//Create an uninitialized Audio Manager
|
||||
cAudio::IAudioManager* manager = cAudio::createAudioManager(false);
|
||||
|
||||
if(manager)
|
||||
{
|
||||
//Allow the user to choose a playback device
|
||||
cout << "Available Playback Devices: \n";
|
||||
unsigned int deviceCount = manager->getAvailableDeviceCount();
|
||||
std::string defaultDeviceName = manager->getDefaultDeviceName();
|
||||
for(unsigned int i=0; i<deviceCount; ++i)
|
||||
{
|
||||
std::string deviceName = manager->getAvailableDeviceName(i);
|
||||
if(deviceName.compare(defaultDeviceName) == 0)
|
||||
cout << i << "): " << deviceName << " [DEFAULT] \n";
|
||||
else
|
||||
cout << i << "): " << deviceName << " \n";
|
||||
}
|
||||
cout << std::endl;
|
||||
cout << "Choose a device by number: ";
|
||||
unsigned int deviceSelection = 0;
|
||||
cin >> deviceSelection;
|
||||
cout << std::endl;
|
||||
|
||||
//Initialize the manager with the user settings
|
||||
manager->initialize(manager->getAvailableDeviceName(deviceSelection));
|
||||
|
||||
cAudio::IAudioEffects* effects = manager->getEffects();
|
||||
if(effects)
|
||||
{
|
||||
cAudio::IEffect* effect = effects->createEffect();
|
||||
cAudio::IFilter* filter = effects->createFilter();
|
||||
|
||||
if(effect && effect->isValid() && filter && filter->isValid())
|
||||
{
|
||||
filter->setHighFrequencyVolume(0.1f);
|
||||
filter->setLowFrequencyVolume(0.1f);
|
||||
|
||||
//Create a IAudio object and load a sound from a file
|
||||
cAudio::IAudio* mysound = manager->createFromFile("bling","../../media/Footsteps.wav",false);
|
||||
|
||||
if(mysound)
|
||||
{
|
||||
mysound->setVolume(1.0f);
|
||||
mysound->attachFilter(filter);
|
||||
mysound->attachEffect(0, effect);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Simultaneous Effects Supported: " << effects->getMaxEffectsSupported() << ". \n";
|
||||
std::cout << std::endl;
|
||||
|
||||
{
|
||||
std::cout << "Playing sound with no effect or filter. \n";
|
||||
filter->setType(cAudio::EFT_NULL);
|
||||
effect->setType(cAudio::EET_NULL);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
|
||||
if(effects->isFilterSupported(cAudio::EFT_LOWPASS))
|
||||
{
|
||||
std::cout << "Playing sound with lowpass filter. \n";
|
||||
filter->setType(cAudio::EFT_LOWPASS);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Lowpass filter not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isFilterSupported(cAudio::EFT_HIGHPASS))
|
||||
{
|
||||
std::cout << "Playing sound with highpass filter. \n";
|
||||
filter->setType(cAudio::EFT_HIGHPASS);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Highpass filter not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isFilterSupported(cAudio::EFT_BANDPASS))
|
||||
{
|
||||
std::cout << "Playing sound with bandpass filter. \n";
|
||||
filter->setType(cAudio::EFT_BANDPASS);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Bandpass filter not supported by this OpenAL device. \n";
|
||||
}
|
||||
|
||||
filter->setType(cAudio::EFT_NULL);
|
||||
|
||||
if(effects->isEffectSupported(cAudio::EET_EAX_REVERB))
|
||||
{
|
||||
std::cout << "Playing sound with EAX Reverb effect. \n";
|
||||
|
||||
//Set the effect to a setting that distinctly shows off the effect (EAX_BATHROOM)
|
||||
effect->setType(cAudio::EET_EAX_REVERB);
|
||||
cAudio::sEAXReverbParameters param;
|
||||
param.Gain = 0.316f;
|
||||
param.GainHF = 0.251f;
|
||||
param.GainLF = 1.0f;
|
||||
param.Density = 0.17f;
|
||||
param.DecayHFRatio = 0.54f;
|
||||
param.ReflectionsGain = 0.653f;
|
||||
param.ReflectionsDelay = 0.01f;
|
||||
param.LateReverbDelay = 0.01f;
|
||||
param.LateReverbGain = 3.273f;
|
||||
|
||||
effect->setEAXReverbParameters(param);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "EAX Reverb effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_REVERB))
|
||||
{
|
||||
std::cout << "Playing sound with Reverb effect. \n";
|
||||
|
||||
//Set the effect to a setting that distinctly shows off the effect (EAX_BATHROOM)
|
||||
effect->setType(cAudio::EET_REVERB);
|
||||
cAudio::sReverbParameters param;
|
||||
param.Gain = 0.316f;
|
||||
param.GainHF = 0.251f;
|
||||
param.Density = 0.17f;
|
||||
param.DecayHFRatio = 0.54f;
|
||||
param.ReflectionsGain = 0.653f;
|
||||
param.ReflectionsDelay = 0.01f;
|
||||
param.LateReverbDelay = 0.01f;
|
||||
param.LateReverbGain = 3.273f;
|
||||
|
||||
effect->setReverbParameters(param);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Reverb effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_CHORUS))
|
||||
{
|
||||
std::cout << "Playing sound with Chorus effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_CHORUS);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Chorus effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_DISTORTION))
|
||||
{
|
||||
std::cout << "Playing sound with Distortion effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_DISTORTION);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Distortion effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_ECHO))
|
||||
{
|
||||
std::cout << "Playing sound with Echo effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_ECHO);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Echo effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_FLANGER))
|
||||
{
|
||||
std::cout << "Playing sound with Flanger effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_FLANGER);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Flanger effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_FREQUENCY_SHIFTER))
|
||||
{
|
||||
std::cout << "Playing sound with Frequency Shifter effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_FREQUENCY_SHIFTER);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Frequency Shifter effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_VOCAL_MORPHER))
|
||||
{
|
||||
std::cout << "Playing sound with Vocal Morpher effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_VOCAL_MORPHER);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Vocal Morpher effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_PITCH_SHIFTER))
|
||||
{
|
||||
std::cout << "Playing sound with Pitch Shifter effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_PITCH_SHIFTER);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Pitch Shifter effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_RING_MODULATOR))
|
||||
{
|
||||
std::cout << "Playing sound with Ring Modulator effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_RING_MODULATOR);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Ring Modulator effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_AUTOWAH))
|
||||
{
|
||||
std::cout << "Playing sound with Autowah effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_AUTOWAH);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Autowah effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_COMPRESSOR))
|
||||
{
|
||||
std::cout << "Playing sound with Compressor effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_COMPRESSOR);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Compressor effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
if(effects->isEffectSupported(cAudio::EET_EQUALIZER))
|
||||
{
|
||||
std::cout << "Playing sound with Equalizer effect. \n";
|
||||
|
||||
//Default settings
|
||||
effect->setType(cAudio::EET_EQUALIZER);
|
||||
mysound->play2d(false);
|
||||
|
||||
while(mysound->isPlaying())
|
||||
cAudio::cAudioSleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Equalizer effect not supported by this OpenAL device. \n";
|
||||
}
|
||||
}
|
||||
filter->drop();
|
||||
effect->drop();
|
||||
}
|
||||
}
|
||||
|
||||
//Delete all IAudio sounds
|
||||
manager->release();
|
||||
//Shutdown cAudio
|
||||
manager->shutDown();
|
||||
|
||||
cAudio::destroyAudioManager(manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to create audio playback manager. \n";
|
||||
}
|
||||
|
||||
std::cout << "Press any key to quit \n";
|
||||
std::cin.get();
|
||||
std::cin.get();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -9,18 +9,18 @@
|
|||
#include "../Include/cVector3.h"
|
||||
#include "../Headers/cMutex.h"
|
||||
#include "../include/ILogger.h"
|
||||
|
||||
//! Size of each internal buffer for sound (total amount buffered is BUFFER_SIZE * NUM_BUFFERS)
|
||||
#define BUFFER_SIZE ( 1024 * 64 )
|
||||
//! Number of internal buffers to cycle through (Note: using only 1 leads to choppy sound or premature ending of sources)
|
||||
#define NUM_BUFFERS 3
|
||||
#include "../Headers/cEFXFunctions.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class cAudio : public IAudio
|
||||
{
|
||||
public:
|
||||
cAudio(IAudioDecoder* decoder);
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
cAudio(IAudioDecoder* decoder, ALCcontext* context, cEFXFunctions* oALFunctions);
|
||||
#else
|
||||
cAudio(IAudioDecoder* decoder, ALCcontext* context);
|
||||
#endif
|
||||
~cAudio();
|
||||
|
||||
//! Plays the source with the default or last set values
|
||||
|
@ -38,7 +38,8 @@ namespace cAudio
|
|||
virtual void loop(const bool& toLoop);
|
||||
//! Seeks through the audio stream to a specific spot
|
||||
/** Note: May not be supported by all codecs
|
||||
\param seconds: Number of seconds from the start of the audio stream to seek to
|
||||
\param seconds: Number of seconds to seek
|
||||
\param relative: Whether to seek from the current position or the start of the stream
|
||||
\return True on success, False if the codec does not support seeking. */
|
||||
virtual bool seek(const float& seconds, bool relative = false);
|
||||
|
||||
|
@ -153,6 +154,22 @@ namespace cAudio
|
|||
//!Returns the override for the doppler velocity vector
|
||||
virtual const cVector3 getDopplerVelocity() const;
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//! Returns the number of effects at one time this source can support
|
||||
virtual unsigned int getNumEffectSlotsAvailable() const;
|
||||
//! Attaches an EFX audio effect to this sound source to a specific slot
|
||||
//! Range (slot): 0 to getNumEffectSlotsAvailable()
|
||||
virtual bool attachEffect(unsigned int slot, IEffect* effect);
|
||||
//! Removes an EFX audio effect from this sound source
|
||||
//! Range (slot): 0 to getNumEffectSlotsAvailable()
|
||||
virtual void removeEffect(unsigned int slot);
|
||||
|
||||
//! Attaches an audio filter to this sound source that will operate on the direct feed, seperate from any effects
|
||||
virtual bool attachFilter(IFilter* filter);
|
||||
//! Removes the previously attached filter
|
||||
virtual void removeFilter();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
private:
|
||||
//Mutex for thread syncronization
|
||||
|
@ -161,11 +178,16 @@ namespace cAudio
|
|||
void empty();
|
||||
//Checks for OpenAL errors and reports them
|
||||
bool checkError();
|
||||
//Steams audio data from the decoder into a buffer
|
||||
//Streams audio data from the decoder into a buffer
|
||||
bool stream(ALuint buffer);
|
||||
//Converts our audio format enum to OpenAL's
|
||||
ALenum convertAudioFormatEnum(AudioFormats format);
|
||||
|
||||
//The context that owns this source
|
||||
ALCcontext* Context;
|
||||
|
||||
//Internal audio buffers
|
||||
ALuint Buffers[NUM_BUFFERS];
|
||||
ALuint Buffers[CAUDIO_SOURCE_NUM_BUFFERS];
|
||||
//OpenAL source
|
||||
ALuint Source;
|
||||
//cAudio decoder being used to stream data
|
||||
|
@ -175,6 +197,26 @@ namespace cAudio
|
|||
bool Loop;
|
||||
//Stores whether the source is ready to be used
|
||||
bool Valid;
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//Holds pointers to all the EFX related functions
|
||||
cEFXFunctions* EFX;
|
||||
//Updates the attached filter
|
||||
void updateFilter(bool remove = false);
|
||||
//Updates the effect attached to a specific slot
|
||||
void updateEffect(unsigned int slot, bool remove = false);
|
||||
|
||||
//Stores the effects attached to this source
|
||||
IEffect* Effects[CAUDIO_SOURCE_MAX_EFFECT_SLOTS];
|
||||
unsigned int LastEffectTimeStamp[CAUDIO_SOURCE_MAX_EFFECT_SLOTS];
|
||||
|
||||
//Stores the attached direct feed filter
|
||||
IFilter* Filter;
|
||||
unsigned int LastFilterTimeStamp;
|
||||
|
||||
//Number of effects supported by the OpenAL Context
|
||||
unsigned int EffectSlotsAvailable;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
};
|
||||
#endif //! CAUDIO_H_INCLUDED
|
||||
|
|
|
@ -109,6 +109,11 @@ namespace cAudio
|
|||
|
||||
std::string DeviceName;
|
||||
ALCdevice* CaptureDevice;
|
||||
|
||||
//! Check for OpenAL errors
|
||||
bool checkError();
|
||||
//Converts our audio format enum to OpenAL's
|
||||
ALenum convertAudioFormatEnum(AudioFormats format);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef CAUDIOEFFECTS_H
|
||||
#define CAUDIOEFFECTS_H
|
||||
|
||||
#include "../include/IAudioEffects.h"
|
||||
#include "../Headers/cMutex.h"
|
||||
#include "../Headers/cEFXFunctions.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class cAudioEffects : public IAudioEffects
|
||||
{
|
||||
public:
|
||||
cAudioEffects();
|
||||
virtual ~cAudioEffects();
|
||||
|
||||
virtual IEffect* createEffect();
|
||||
virtual IFilter* createFilter();
|
||||
|
||||
virtual unsigned int getMaxEffectsSupported() const;
|
||||
virtual bool isEffectSupported(const EffectTypes& type) const;
|
||||
virtual bool isFilterSupported(const FilterTypes& type) const;
|
||||
|
||||
cEFXFunctions* getEFXInterface();
|
||||
void checkEFXSupportDetails();
|
||||
|
||||
private:
|
||||
cAudioMutex Mutex;
|
||||
cEFXFunctions EFXInterface;
|
||||
unsigned int MaxEffectsSupported;
|
||||
bool SupportedEffects[EET_COUNT];
|
||||
bool SupportedFilters[EFT_COUNT];
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! CAUDIOEFFECTS_H
|
|
@ -10,6 +10,7 @@
|
|||
#include "cListener.h"
|
||||
#include "../include/IAudioManager.h"
|
||||
#include "../Headers/cMutex.h"
|
||||
#include "../Headers/cAudioEffects.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
@ -65,6 +66,7 @@ namespace cAudio
|
|||
void getAvailableDevices();
|
||||
|
||||
virtual IListener* getListener() { return &initlistener; }
|
||||
virtual IAudioEffects* getEffects() { return &initEffects; }
|
||||
|
||||
private:
|
||||
//Mutex for thread syncronization
|
||||
|
@ -89,8 +91,10 @@ namespace cAudio
|
|||
std::map<std::string, IAudioDecoderFactory*> decodermap;
|
||||
//! The listener object
|
||||
cListener initlistener;
|
||||
//! Interface for audio effects
|
||||
cAudioEffects initEffects;
|
||||
//! Check for OpenAL errors
|
||||
void checkError();
|
||||
bool checkError();
|
||||
|
||||
std::vector<std::string> AvailableDevices;
|
||||
std::string DefaultDevice;
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
#ifndef CEFXFUNCTIONS_H
|
||||
#define CEFXFUNCTIONS_H
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/efx.h>
|
||||
#include <AL/efx-creative.h>
|
||||
|
||||
#include "../Headers/cMutex.h"
|
||||
|
||||
// EFX Extension function pointer variables
|
||||
namespace cAudio
|
||||
{
|
||||
struct cEFXFunctions
|
||||
{
|
||||
cEFXFunctions::cEFXFunctions()
|
||||
{
|
||||
alGenEffects = NULL;
|
||||
alDeleteEffects = NULL;
|
||||
alIsEffect = NULL;
|
||||
alEffecti = NULL;
|
||||
alEffectiv = NULL;
|
||||
alEffectf = NULL;
|
||||
alEffectfv = NULL;
|
||||
alGetEffecti = NULL;
|
||||
alGetEffectiv = NULL;
|
||||
alGetEffectf = NULL;
|
||||
alGetEffectfv = NULL;
|
||||
|
||||
alGenFilters = NULL;
|
||||
alDeleteFilters = NULL;
|
||||
alIsFilter = NULL;
|
||||
alFilteri = NULL;
|
||||
alFilteriv = NULL;
|
||||
alFilterf = NULL;
|
||||
alFilterfv = NULL;
|
||||
alGetFilteri = NULL;
|
||||
alGetFilteriv = NULL;
|
||||
alGetFilterf = NULL;
|
||||
alGetFilterfv = NULL;
|
||||
|
||||
alGenAuxiliaryEffectSlots = NULL;
|
||||
alDeleteAuxiliaryEffectSlots = NULL;
|
||||
alIsAuxiliaryEffectSlot = NULL;
|
||||
alAuxiliaryEffectSloti = NULL;
|
||||
alAuxiliaryEffectSlotiv = NULL;
|
||||
alAuxiliaryEffectSlotf = NULL;
|
||||
alAuxiliaryEffectSlotfv = NULL;
|
||||
alGetAuxiliaryEffectSloti = NULL;
|
||||
alGetAuxiliaryEffectSlotiv = NULL;
|
||||
alGetAuxiliaryEffectSlotf = NULL;
|
||||
alGetAuxiliaryEffectSlotfv = NULL;
|
||||
|
||||
Supported = false;
|
||||
}
|
||||
|
||||
// Effect objects
|
||||
LPALGENEFFECTS alGenEffects;
|
||||
LPALDELETEEFFECTS alDeleteEffects;
|
||||
LPALISEFFECT alIsEffect;
|
||||
LPALEFFECTI alEffecti;
|
||||
LPALEFFECTIV alEffectiv;
|
||||
LPALEFFECTF alEffectf;
|
||||
LPALEFFECTFV alEffectfv;
|
||||
LPALGETEFFECTI alGetEffecti;
|
||||
LPALGETEFFECTIV alGetEffectiv;
|
||||
LPALGETEFFECTF alGetEffectf;
|
||||
LPALGETEFFECTFV alGetEffectfv;
|
||||
|
||||
// Filter objects
|
||||
LPALGENFILTERS alGenFilters;
|
||||
LPALDELETEFILTERS alDeleteFilters;
|
||||
LPALISFILTER alIsFilter;
|
||||
LPALFILTERI alFilteri;
|
||||
LPALFILTERIV alFilteriv;
|
||||
LPALFILTERF alFilterf;
|
||||
LPALFILTERFV alFilterfv;
|
||||
LPALGETFILTERI alGetFilteri;
|
||||
LPALGETFILTERIV alGetFilteriv;
|
||||
LPALGETFILTERF alGetFilterf;
|
||||
LPALGETFILTERFV alGetFilterfv;
|
||||
|
||||
// Auxiliary slot object
|
||||
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
||||
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
||||
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
|
||||
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
||||
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
|
||||
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
|
||||
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
|
||||
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
|
||||
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
|
||||
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
||||
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
||||
|
||||
cAudioMutex Mutex;
|
||||
|
||||
bool Supported;
|
||||
|
||||
bool CheckEFXSupport(ALCdevice* device)
|
||||
{
|
||||
Supported = false;
|
||||
if (alcIsExtensionPresent(device, "ALC_EXT_EFX"))
|
||||
{
|
||||
// Get function pointers
|
||||
alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects");
|
||||
alDeleteEffects = (LPALDELETEEFFECTS )alGetProcAddress("alDeleteEffects");
|
||||
alIsEffect = (LPALISEFFECT )alGetProcAddress("alIsEffect");
|
||||
alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti");
|
||||
alEffectiv = (LPALEFFECTIV)alGetProcAddress("alEffectiv");
|
||||
alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf");
|
||||
alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv");
|
||||
alGetEffecti = (LPALGETEFFECTI)alGetProcAddress("alGetEffecti");
|
||||
alGetEffectiv = (LPALGETEFFECTIV)alGetProcAddress("alGetEffectiv");
|
||||
alGetEffectf = (LPALGETEFFECTF)alGetProcAddress("alGetEffectf");
|
||||
alGetEffectfv = (LPALGETEFFECTFV)alGetProcAddress("alGetEffectfv");
|
||||
alGenFilters = (LPALGENFILTERS)alGetProcAddress("alGenFilters");
|
||||
alDeleteFilters = (LPALDELETEFILTERS)alGetProcAddress("alDeleteFilters");
|
||||
alIsFilter = (LPALISFILTER)alGetProcAddress("alIsFilter");
|
||||
alFilteri = (LPALFILTERI)alGetProcAddress("alFilteri");
|
||||
alFilteriv = (LPALFILTERIV)alGetProcAddress("alFilteriv");
|
||||
alFilterf = (LPALFILTERF)alGetProcAddress("alFilterf");
|
||||
alFilterfv = (LPALFILTERFV)alGetProcAddress("alFilterfv");
|
||||
alGetFilteri = (LPALGETFILTERI )alGetProcAddress("alGetFilteri");
|
||||
alGetFilteriv= (LPALGETFILTERIV )alGetProcAddress("alGetFilteriv");
|
||||
alGetFilterf = (LPALGETFILTERF )alGetProcAddress("alGetFilterf");
|
||||
alGetFilterfv= (LPALGETFILTERFV )alGetProcAddress("alGetFilterfv");
|
||||
alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots");
|
||||
alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots");
|
||||
alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)alGetProcAddress("alIsAuxiliaryEffectSlot");
|
||||
alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti");
|
||||
alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)alGetProcAddress("alAuxiliaryEffectSlotiv");
|
||||
alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)alGetProcAddress("alAuxiliaryEffectSlotf");
|
||||
alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)alGetProcAddress("alAuxiliaryEffectSlotfv");
|
||||
alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)alGetProcAddress("alGetAuxiliaryEffectSloti");
|
||||
alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)alGetProcAddress("alGetAuxiliaryEffectSlotiv");
|
||||
alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)alGetProcAddress("alGetAuxiliaryEffectSlotf");
|
||||
alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)alGetProcAddress("alGetAuxiliaryEffectSlotfv");
|
||||
|
||||
if (alGenEffects && alDeleteEffects && alIsEffect && alEffecti && alEffectiv && alEffectf &&
|
||||
alEffectfv && alGetEffecti && alGetEffectiv && alGetEffectf && alGetEffectfv && alGenFilters &&
|
||||
alDeleteFilters && alIsFilter && alFilteri && alFilteriv && alFilterf && alFilterfv &&
|
||||
alGetFilteri && alGetFilteriv && alGetFilterf && alGetFilterfv && alGenAuxiliaryEffectSlots &&
|
||||
alDeleteAuxiliaryEffectSlots && alIsAuxiliaryEffectSlot && alAuxiliaryEffectSloti &&
|
||||
alAuxiliaryEffectSlotiv && alAuxiliaryEffectSlotf && alAuxiliaryEffectSlotfv &&
|
||||
alGetAuxiliaryEffectSloti && alGetAuxiliaryEffectSlotiv && alGetAuxiliaryEffectSlotf &&
|
||||
alGetAuxiliaryEffectSlotfv)
|
||||
Supported = true;
|
||||
}
|
||||
|
||||
return Supported;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! CEFXFUNCTIONS_H
|
|
@ -0,0 +1,117 @@
|
|||
#ifndef CEFFECT_H
|
||||
#define CEFFECT_H
|
||||
|
||||
#include "../include/IEffect.h"
|
||||
#include "../Headers/cMutex.h"
|
||||
#include "../Headers/cEFXFunctions.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class cEffect : public IEffect
|
||||
{
|
||||
public:
|
||||
cEffect(cEFXFunctions* oALFunctions);
|
||||
virtual ~cEffect();
|
||||
|
||||
virtual const EffectTypes& getType() const;
|
||||
virtual void setType(const EffectTypes& type);
|
||||
|
||||
virtual const sEAXReverbParameters& getEAXReverbParameters() const;
|
||||
virtual void setEAXReverbParameters(const sEAXReverbParameters& param);
|
||||
|
||||
virtual const sReverbParameters& getReverbParameters() const;
|
||||
virtual void setReverbParameters(const sReverbParameters& param);
|
||||
|
||||
virtual const sChorusParameters& getChorusParameters() const;
|
||||
virtual void setChorusParameters(const sChorusParameters& param);
|
||||
|
||||
virtual const sDistortionParameters& getDistortionParameters() const;
|
||||
virtual void setDistortionParameters(const sDistortionParameters& param);
|
||||
|
||||
virtual const sEchoParameters& getEchoParameters() const;
|
||||
virtual void setEchoParameters(const sEchoParameters& param);
|
||||
|
||||
virtual const sFlangerParameters& getFlangerParameters() const;
|
||||
virtual void setFlangerParameters(const sFlangerParameters& param);
|
||||
|
||||
virtual const sFrequencyShiftParameters& getFrequencyShiftParameters() const;
|
||||
virtual void setFrequencyShiftParameters(const sFrequencyShiftParameters& param);
|
||||
|
||||
virtual const sVocalMorpherParameters& getVocalMorpherParameters() const;
|
||||
virtual void setVocalMorpherParameters(const sVocalMorpherParameters& param);
|
||||
|
||||
virtual const sPitchShifterParameters& getPitchShifterParameters() const;
|
||||
virtual void setPitchShifterParameters(const sPitchShifterParameters& param);
|
||||
|
||||
virtual const sRingModulatorParameters& getRingModulatorParameters() const;
|
||||
virtual void setRingModulatorParameters(const sRingModulatorParameters& param);
|
||||
|
||||
virtual const sAutowahParameters& getAutowahParameters() const;
|
||||
virtual void setAutowahParameters(const sAutowahParameters& param);
|
||||
|
||||
virtual const sCompressorParameters& getCompressorParameters() const;
|
||||
virtual void setCompressorParameters(const sCompressorParameters& param);
|
||||
|
||||
virtual const sEqualizerParameters& getEqualizerParameters() const;
|
||||
virtual void setEqualizerParameters(const sEqualizerParameters& param);
|
||||
|
||||
virtual float getMasterVolume() const;
|
||||
virtual void setMasterVolume(const float& volume);
|
||||
|
||||
virtual bool isIgnoringAttenuation() const;
|
||||
virtual void ignoreAttenuation(const bool& ignore);
|
||||
|
||||
virtual IFilter* getFilter() const;
|
||||
virtual void attachFilter(IFilter* filter);
|
||||
virtual void removeFilter();
|
||||
|
||||
virtual unsigned int getLastUpdated() const;
|
||||
virtual bool isValid() const;
|
||||
|
||||
ALuint getOpenALEffect() const;
|
||||
ALuint getOpenALEffectSlot() const;
|
||||
|
||||
private:
|
||||
cEFXFunctions* EFX;
|
||||
//Mutex for thread syncronization
|
||||
cAudioMutex Mutex;
|
||||
|
||||
EffectTypes Type;
|
||||
float Volume;
|
||||
bool IgnoreAttenuation;
|
||||
unsigned int LastUpdated;
|
||||
|
||||
bool Valid;
|
||||
|
||||
IFilter* Filter;
|
||||
|
||||
ALuint Effect;
|
||||
ALuint EffectSlot;
|
||||
|
||||
bool UpdateEffect();
|
||||
bool CheckError();
|
||||
ALenum ConvertEffectEnum(EffectTypes type);
|
||||
ALenum ConvertFrequencyShiftEnum(sFrequencyShiftParameters::ShiftDirection shift);
|
||||
ALenum ConvertVocalMorphPhonemeEnum(sVocalMorpherParameters::MorpherPhoneme phoneme);
|
||||
|
||||
//Storage for all the possible settings for effects
|
||||
sEAXReverbParameters EAXReverbParam;
|
||||
sReverbParameters ReverbParam;
|
||||
sChorusParameters ChorusParam;
|
||||
sDistortionParameters DistortionParam;
|
||||
sEchoParameters EchoParam;
|
||||
sFlangerParameters FlangerParam;
|
||||
sFrequencyShiftParameters FrequencyShiftParam;
|
||||
sVocalMorpherParameters VocalMorpherParam;
|
||||
sPitchShifterParameters PitchShifterParam;
|
||||
sRingModulatorParameters RingModulatorParam;
|
||||
sAutowahParameters AutowahParam;
|
||||
sCompressorParameters CompressorParam;
|
||||
sEqualizerParameters EqualizerParam;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! CEFFECT_H
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef CFILTER_H
|
||||
#define CFILTER_H
|
||||
|
||||
#include "../include/IFilter.h"
|
||||
#include "../Headers/cMutex.h"
|
||||
#include "../Headers/cEFXFunctions.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class cFilter : public IFilter
|
||||
{
|
||||
public:
|
||||
cFilter(cEFXFunctions* oALFunctions);
|
||||
~cFilter();
|
||||
|
||||
virtual const FilterTypes& getType() const;
|
||||
virtual void setType(const FilterTypes& type);
|
||||
|
||||
virtual float getVolume() const;
|
||||
virtual void setVolume(const float& volume);
|
||||
|
||||
virtual float getLowFrequencyVolume() const;
|
||||
virtual void setLowFrequencyVolume(const float& volumeLF);
|
||||
|
||||
virtual float getHighFrequencyVolume() const;
|
||||
virtual void setHighFrequencyVolume(const float& volumeHF);
|
||||
|
||||
virtual unsigned int getLastUpdated() const;
|
||||
virtual bool isValid() const;
|
||||
|
||||
ALuint getOpenALFilter() const;
|
||||
|
||||
protected:
|
||||
cEFXFunctions* EFX;
|
||||
|
||||
//Mutex for thread syncronization
|
||||
cAudioMutex Mutex;
|
||||
|
||||
FilterTypes Type;
|
||||
float Volume;
|
||||
float LowFreqVolume;
|
||||
float HighFreqVolume;
|
||||
unsigned int LastUpdated;
|
||||
|
||||
bool Valid;
|
||||
|
||||
ALuint Filter;
|
||||
|
||||
bool UpdateFilter();
|
||||
bool CheckError();
|
||||
ALenum ConvertFilterEnum(FilterTypes type);
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! CFILTER_H
|
|
@ -41,6 +41,14 @@ namespace cAudio
|
|||
virtual cVector3 getVelocity(void) const { return Velocity; }
|
||||
//!Returns the global volume modifier for all sources
|
||||
virtual float getMasterVolume(void) const { return MasterGain; }
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//!Sets the meters per user world unit for use with sound effects
|
||||
virtual void setMetersPerUnit(const float& meters);
|
||||
//!Returns the meters per user world unit for use with sound effects
|
||||
virtual float getMetersPerUnit(void) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
cAudioMutex Mutex;
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ namespace cAudio
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CAUDIO_MAKE_THREAD_SAFE
|
||||
class cAudioMutexBasicLock
|
||||
{
|
||||
public:
|
||||
|
@ -63,7 +62,6 @@ namespace cAudio
|
|||
protected:
|
||||
cAudioMutex* Mutex;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //! CAUDIOMUTEX_H
|
|
@ -1,39 +1,91 @@
|
|||
#include "../Headers/cAudio.h"
|
||||
#include "../Headers/cLogger.h"
|
||||
#include "../Headers/cFilter.h"
|
||||
#include "../Headers/cEffect.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
cAudio::cAudio(IAudioDecoder* decoder) : Decoder(decoder), Loop(false), Valid(false)
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
cAudio::cAudio(IAudioDecoder* decoder, ALCcontext* context, cEFXFunctions* oALFunctions)
|
||||
: Context(context), Source(0), Decoder(decoder), Loop(false), Valid(false),
|
||||
EFX(oALFunctions), Filter(NULL), EffectSlotsAvailable(0), LastFilterTimeStamp(0)
|
||||
#else
|
||||
cAudio::cAudio(IAudioDecoder* decoder, ALCcontext* context)
|
||||
: Context(context), Source(0), Decoder(decoder), Loop(false), Valid(false)
|
||||
#endif
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
|
||||
for(int i=0; i<CAUDIO_SOURCE_NUM_BUFFERS; ++i)
|
||||
Buffers[i] = 0;
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
|
||||
Effects[i] = NULL;
|
||||
|
||||
for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
|
||||
LastEffectTimeStamp[i] = 0;
|
||||
#endif
|
||||
|
||||
if(Decoder)
|
||||
Decoder->grab();
|
||||
|
||||
//Generates 3 buffers for the ogg file
|
||||
alGenBuffers(NUM_BUFFERS, Buffers);
|
||||
//Creates one source to be stored.
|
||||
alGenSources(1, &Source);
|
||||
alGenBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
|
||||
bool state = !checkError();
|
||||
Valid = state && (Decoder != NULL);
|
||||
Mutex.unlock();
|
||||
if(state)
|
||||
{
|
||||
//Creates one source to be stored.
|
||||
alGenSources(1, &Source);
|
||||
state = !checkError();
|
||||
}
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
Valid = state && (Decoder != NULL) && (Context != NULL) && (EFX != NULL);
|
||||
#else
|
||||
Valid = state && (Decoder != NULL) && (Context != NULL);
|
||||
#endif
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
int numSlots = 0;
|
||||
ALCdevice* device = alcGetContextsDevice(Context);
|
||||
alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &numSlots);
|
||||
|
||||
EffectSlotsAvailable = (numSlots <= CAUDIO_SOURCE_MAX_EFFECT_SLOTS) ? numSlots : CAUDIO_SOURCE_MAX_EFFECT_SLOTS;
|
||||
#endif
|
||||
}
|
||||
|
||||
cAudio::~cAudio()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Decoder)
|
||||
Decoder->drop();
|
||||
Mutex.unlock();
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
|
||||
{
|
||||
if(Effects[i])
|
||||
Effects[i]->drop();
|
||||
Effects[i] = NULL;
|
||||
}
|
||||
|
||||
if(Filter)
|
||||
Filter->drop();
|
||||
Filter = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool cAudio::play()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if (!isPaused())
|
||||
{
|
||||
int queueSize = 0;
|
||||
for(int u = 0; u < NUM_BUFFERS; u++)
|
||||
int queueSize = 0;
|
||||
//Resets the audio to the beginning
|
||||
Decoder->setPosition(0, false);
|
||||
//Purges all buffers from the source
|
||||
alSourcei(Source, AL_BUFFER, 0);
|
||||
checkError();
|
||||
for(int u = 0; u < CAUDIO_SOURCE_NUM_BUFFERS; u++)
|
||||
{
|
||||
int val = stream(Buffers[u]);
|
||||
|
||||
|
@ -48,76 +100,75 @@ namespace cAudio
|
|||
alSourceQueueBuffers(Source, queueSize, Buffers);
|
||||
checkError();
|
||||
}
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
updateFilter();
|
||||
for(unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
|
||||
updateEffect(i);
|
||||
#endif
|
||||
alSourcePlay(Source);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
getLogger()->logDebug("Audio Source", "Source playing.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cAudio::play2d(const bool& toLoop)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcei(Source, AL_SOURCE_RELATIVE, true);
|
||||
loop(toLoop);
|
||||
bool state = play();
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
}
|
||||
|
||||
bool cAudio::play3d(const cVector3& position, const float& soundstr, const bool& toLoop)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcei(Source, AL_SOURCE_RELATIVE, false);
|
||||
setPosition(position);
|
||||
setStrength(soundstr);
|
||||
loop(toLoop);
|
||||
bool state = play();
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
}
|
||||
|
||||
void cAudio::pause()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcePause(Source);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
getLogger()->logDebug("Audio Source", "Source paused.");
|
||||
}
|
||||
|
||||
void cAudio::stop()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourceStop(Source);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
getLogger()->logDebug("Audio Source", "Source stopped.");
|
||||
}
|
||||
|
||||
void cAudio::loop(const bool& loop)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Loop = loop;
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
bool cAudio::seek(const float& seconds, bool relative)
|
||||
{
|
||||
bool state = false;
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Decoder->isSeekingSupported())
|
||||
{
|
||||
state = Decoder->seek(seconds, relative);
|
||||
}
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
}
|
||||
|
||||
bool cAudio::update()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(!isValid() || !isPlaying())
|
||||
{
|
||||
return false;
|
||||
|
@ -125,7 +176,12 @@ namespace cAudio
|
|||
int processed = 0;
|
||||
bool active = true;
|
||||
|
||||
Mutex.lock();
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
updateFilter();
|
||||
for(unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
|
||||
updateEffect(i);
|
||||
#endif
|
||||
|
||||
//gets the sound source processed buffers
|
||||
alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed);
|
||||
//while there is more data refill buffers with audio data.
|
||||
|
@ -141,22 +197,20 @@ namespace cAudio
|
|||
|
||||
checkError();
|
||||
}
|
||||
Mutex.unlock();
|
||||
return active;
|
||||
}
|
||||
|
||||
void cAudio::release()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
//Stops the audio Source
|
||||
alSourceStop(Source);
|
||||
empty();
|
||||
//Deletes the source
|
||||
alDeleteSources(1, &Source);
|
||||
//deletes the last filled buffer
|
||||
alDeleteBuffers(NUM_BUFFERS, Buffers);
|
||||
alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
getLogger()->logDebug("Audio Source", "Audio source released.");
|
||||
}
|
||||
|
||||
|
@ -193,34 +247,30 @@ namespace cAudio
|
|||
|
||||
void cAudio::setPosition(const cVector3& position)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setVelocity(const cVector3& velocity)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setDirection(const cVector3& direction)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSource3f(Source, AL_DIRECTION, direction.x, direction.y, direction.z);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setRolloffFactor(const float& rolloff)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_ROLLOFF_FACTOR, rolloff);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setStrength(const float& soundstrength)
|
||||
|
@ -229,110 +279,97 @@ namespace cAudio
|
|||
if(soundstrength > 0.0f)
|
||||
inverseStrength = 1.0f / soundstrength;
|
||||
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_ROLLOFF_FACTOR, inverseStrength);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setMinDistance(const float& minDistance)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_REFERENCE_DISTANCE, minDistance);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setMaxDistance(const float& maxDistance)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_MAX_DISTANCE, maxDistance);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setPitch(const float& pitch)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef (Source, AL_PITCH, pitch);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setVolume(const float& volume)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_GAIN, volume);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setMinVolume(const float& minVolume)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_MIN_GAIN, minVolume);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setMaxVolume(const float& maxVolume)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_MAX_GAIN, maxVolume);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setInnerConeAngle(const float& innerAngle)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_CONE_INNER_ANGLE, innerAngle);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setOuterConeAngle(const float& outerAngle)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_CONE_OUTER_ANGLE, outerAngle);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setOuterConeVolume(const float& outerVolume)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_CONE_OUTER_GAIN, outerVolume);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setDopplerStrength(const float& dstrength)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSourcef(Source, AL_DOPPLER_FACTOR, dstrength);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::setDopplerVelocity(const cVector3& dvelocity)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alSource3f(Source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudio::move(const cVector3& position)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
cVector3 oldPos = getPosition();
|
||||
cVector3 velocity = position - oldPos;
|
||||
|
||||
alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
|
||||
alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
|
||||
checkError();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
const cVector3 cAudio::getPosition() const
|
||||
|
@ -452,6 +489,65 @@ namespace cAudio
|
|||
return velocity;
|
||||
}
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
unsigned int cAudio::getNumEffectSlotsAvailable() const
|
||||
{
|
||||
return EffectSlotsAvailable;
|
||||
}
|
||||
|
||||
bool cAudio::attachEffect(unsigned int slot, IEffect* effect)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(slot < EffectSlotsAvailable)
|
||||
{
|
||||
Effects[slot] = effect;
|
||||
|
||||
if(Effects[slot])
|
||||
Effects[slot]->grab();
|
||||
|
||||
updateEffect(slot);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cAudio::removeEffect(unsigned int slot)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(slot < EffectSlotsAvailable)
|
||||
{
|
||||
if(Effects[slot])
|
||||
Effects[slot]->drop();
|
||||
|
||||
Effects[slot] = NULL;
|
||||
LastEffectTimeStamp[slot] = 0;
|
||||
updateEffect(slot, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool cAudio::attachFilter(IFilter* filter)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Filter = filter;
|
||||
|
||||
if(Filter)
|
||||
Filter->grab();
|
||||
|
||||
updateFilter();
|
||||
return true;
|
||||
}
|
||||
|
||||
void cAudio::removeFilter()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Filter)
|
||||
Filter->drop();
|
||||
Filter = NULL;
|
||||
LastFilterTimeStamp = 0;
|
||||
updateFilter(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void cAudio::empty()
|
||||
{
|
||||
int queued = 0;
|
||||
|
@ -489,11 +585,11 @@ namespace cAudio
|
|||
//stores the caculated data into buffer that is passed to output.
|
||||
size_t totalread = 0;
|
||||
unsigned int errorcount = 0;
|
||||
char tempbuffer[BUFFER_SIZE];
|
||||
while( totalread < BUFFER_SIZE )
|
||||
char tempbuffer[CAUDIO_SOURCE_BUFFER_SIZE];
|
||||
while( totalread < CAUDIO_SOURCE_BUFFER_SIZE )
|
||||
{
|
||||
char tempbuffer2[BUFFER_SIZE];
|
||||
int actualread = Decoder->readAudioData(tempbuffer2, BUFFER_SIZE-totalread);
|
||||
char tempbuffer2[CAUDIO_SOURCE_BUFFER_SIZE];
|
||||
int actualread = Decoder->readAudioData(tempbuffer2, CAUDIO_SOURCE_BUFFER_SIZE-totalread);
|
||||
if(actualread > 0)
|
||||
{
|
||||
memcpy(tempbuffer+totalread,tempbuffer2,actualread);
|
||||
|
@ -525,10 +621,86 @@ namespace cAudio
|
|||
return false;
|
||||
}
|
||||
getLogger()->logDebug("Audio Source", "Buffered %i bytes of data into buffer %i at %i hz.", totalread, buffer, Decoder->getFrequency());
|
||||
alBufferData(buffer, Decoder->getFormat(), tempbuffer, totalread, Decoder->getFrequency());
|
||||
alBufferData(buffer, convertAudioFormatEnum(Decoder->getFormat()), tempbuffer, totalread, Decoder->getFrequency());
|
||||
checkError();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum cAudio::convertAudioFormatEnum(AudioFormats format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case EAF_8BIT_MONO:
|
||||
return AL_FORMAT_MONO8;
|
||||
case EAF_16BIT_MONO:
|
||||
return AL_FORMAT_MONO16;
|
||||
case EAF_8BIT_STEREO:
|
||||
return AL_FORMAT_STEREO8;
|
||||
case EAF_16BIT_STEREO:
|
||||
return AL_FORMAT_STEREO16;
|
||||
default:
|
||||
return AL_FORMAT_MONO8;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
void cAudio::updateFilter(bool remove)
|
||||
{
|
||||
if(!remove)
|
||||
{
|
||||
if(Filter && Filter->isValid())
|
||||
{
|
||||
if(LastFilterTimeStamp != Filter->getLastUpdated())
|
||||
{
|
||||
LastFilterTimeStamp = Filter->getLastUpdated();
|
||||
cFilter* theFilter = static_cast<cFilter*>(Filter);
|
||||
if(theFilter)
|
||||
{
|
||||
alSourcei(Source, AL_DIRECT_FILTER, theFilter->getOpenALFilter());
|
||||
checkError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||
checkError();
|
||||
}
|
||||
|
||||
void cAudio::updateEffect(unsigned int slot, bool remove)
|
||||
{
|
||||
if(slot < EffectSlotsAvailable)
|
||||
{
|
||||
if(!remove)
|
||||
{
|
||||
if(Effects[slot] && Effects[slot]->isValid())
|
||||
{
|
||||
if(LastEffectTimeStamp[slot] != Effects[slot]->getLastUpdated())
|
||||
{
|
||||
LastEffectTimeStamp[slot] = Effects[slot]->getLastUpdated();
|
||||
cEffect* theEffect = static_cast<cEffect*>(Effects[slot]);
|
||||
if(theEffect)
|
||||
{
|
||||
ALuint filterID = AL_FILTER_NULL;
|
||||
cFilter* theFilter = static_cast<cFilter*>(theEffect->getFilter());
|
||||
if(theFilter)
|
||||
{
|
||||
filterID = theFilter->getOpenALFilter();
|
||||
}
|
||||
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, theEffect->getOpenALEffectSlot(), slot, filterID);
|
||||
checkError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot, AL_FILTER_NULL);
|
||||
checkError();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../Headers/cUtils.h"
|
||||
#include "../Headers/cThread.h"
|
||||
#include "../include/cAudioSleep.h"
|
||||
#include "../Headers/cLogger.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <set>
|
||||
|
@ -46,39 +47,39 @@ namespace cAudio
|
|||
|
||||
bool cAudioCapture::checkCaptureExtension()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
// Check for Capture Extension support
|
||||
Supported = ( alcIsExtensionPresent(NULL, "ALC_EXT_CAPTURE") == AL_TRUE );
|
||||
Mutex.unlock();
|
||||
return Supported;
|
||||
}
|
||||
|
||||
bool cAudioCapture::initOpenALDevice()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Supported)
|
||||
{
|
||||
if(CaptureDevice)
|
||||
shutdownOpenALDevice();
|
||||
if(DeviceName.empty())
|
||||
CaptureDevice = alcCaptureOpenDevice(NULL, Frequency, Format, InternalBufferSize / SampleSize);
|
||||
CaptureDevice = alcCaptureOpenDevice(NULL, Frequency, convertAudioFormatEnum(Format), InternalBufferSize / SampleSize);
|
||||
else
|
||||
CaptureDevice = alcCaptureOpenDevice(DeviceName.c_str(), Frequency, Format, InternalBufferSize / SampleSize);
|
||||
CaptureDevice = alcCaptureOpenDevice(DeviceName.c_str(), Frequency, convertAudioFormatEnum(Format), InternalBufferSize / SampleSize);
|
||||
if(CaptureDevice)
|
||||
{
|
||||
DeviceName = alcGetString(CaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER);
|
||||
Ready = true;
|
||||
Mutex.unlock();
|
||||
checkError();
|
||||
getLogger()->logDebug("AudioCapture", "OpenAL Capture Device Opened.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
checkError();
|
||||
return false;
|
||||
}
|
||||
|
||||
void cAudioCapture::shutdownOpenALDevice()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Supported)
|
||||
{
|
||||
if(Capturing)
|
||||
|
@ -89,23 +90,23 @@ namespace cAudio
|
|||
alcCaptureCloseDevice(CaptureDevice);
|
||||
CaptureDevice = NULL;
|
||||
Ready = false;
|
||||
getLogger()->logDebug("AudioCapture", "OpenAL Capture Device Closed.");
|
||||
}
|
||||
checkError();
|
||||
CaptureBuffer.clear();
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudioCapture::shutdown()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
shutdownOpenALDevice();
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void cAudioCapture::getAvailableDevices()
|
||||
{
|
||||
// Get list of available Capture Devices
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if( alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE )
|
||||
{
|
||||
const char* deviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
|
||||
|
@ -122,43 +123,36 @@ namespace cAudio
|
|||
// Get the name of the 'default' capture device
|
||||
DefaultDevice = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
const char* cAudioCapture::getAvailableDeviceName(unsigned int index)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(!AvailableDevices.empty())
|
||||
{
|
||||
//Bounds check
|
||||
if( index > (AvailableDevices.size()-1) ) index = (AvailableDevices.size()-1);
|
||||
const char* deviceName = AvailableDevices[index].c_str();
|
||||
Mutex.unlock();
|
||||
return deviceName;
|
||||
}
|
||||
Mutex.unlock();
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned int cAudioCapture::getAvailableDeviceCount()
|
||||
{
|
||||
Mutex.lock();
|
||||
unsigned int size = AvailableDevices.size();
|
||||
Mutex.unlock();
|
||||
return size;
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
return AvailableDevices.size();
|
||||
}
|
||||
|
||||
const char* cAudioCapture::getDefaultDeviceName()
|
||||
{
|
||||
Mutex.lock();
|
||||
const char* deviceName = DefaultDevice.empty() ? "" : DefaultDevice.c_str();
|
||||
Mutex.unlock();
|
||||
return deviceName;
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
return DefaultDevice.empty() ? "" : DefaultDevice.c_str();
|
||||
}
|
||||
|
||||
void cAudioCapture::updateCaptureBuffer(bool force)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Capturing && CaptureDevice && Ready)
|
||||
{
|
||||
int AvailableSamples = 0;
|
||||
|
@ -174,15 +168,16 @@ namespace cAudio
|
|||
const unsigned int oldBufferSize = CaptureBuffer.size();
|
||||
CaptureBuffer.resize(oldBufferSize + availbuffersize, 0);
|
||||
alcCaptureSamples(CaptureDevice, &CaptureBuffer[oldBufferSize], AvailableSamples);
|
||||
checkError();
|
||||
getLogger()->logDebug("AudioCapture", "Captured %i bytes of audio data.", availbuffersize);
|
||||
}
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
bool cAudioCapture::beginCapture()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(!Capturing)
|
||||
{
|
||||
CaptureBuffer.clear();
|
||||
|
@ -190,32 +185,31 @@ namespace cAudio
|
|||
{
|
||||
alcCaptureStart(CaptureDevice);
|
||||
Capturing = true;
|
||||
getLogger()->logDebug("AudioCapture", "OpenAL Capture Started.");
|
||||
}
|
||||
Mutex.unlock();
|
||||
checkError();
|
||||
return Capturing;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
checkError();
|
||||
return false;
|
||||
}
|
||||
|
||||
void cAudioCapture::stopCapture()
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(CaptureDevice && Ready)
|
||||
{
|
||||
alcCaptureStop(CaptureDevice);
|
||||
updateCaptureBuffer(true);
|
||||
checkError();
|
||||
getLogger()->logDebug("AudioCapture", "OpenAL Capture Stopped.");
|
||||
}
|
||||
Capturing = false;
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
unsigned int cAudioCapture::getCapturedAudio(void* outputBuffer, unsigned int outputBufferSize)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
unsigned int internalBufferSize = CaptureBuffer.size();
|
||||
if(outputBuffer && outputBufferSize > 0 && internalBufferSize > 0)
|
||||
{
|
||||
|
@ -223,34 +217,30 @@ namespace cAudio
|
|||
memcpy(outputBuffer, &CaptureBuffer[0], sizeToCopy);
|
||||
CaptureBuffer.erase(CaptureBuffer.begin(), CaptureBuffer.begin()+sizeToCopy);
|
||||
|
||||
Mutex.unlock();
|
||||
getLogger()->logDebug("AudioCapture", "Copied out %i bytes of data out of %i bytes in the buffer at user request.", sizeToCopy, internalBufferSize);
|
||||
|
||||
return sizeToCopy;
|
||||
}
|
||||
Mutex.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int cAudioCapture::getCurrentCapturedAudioSize()
|
||||
{
|
||||
Mutex.lock();
|
||||
unsigned int size = CaptureBuffer.size();
|
||||
Mutex.unlock();
|
||||
return size;
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
return CaptureBuffer.size();
|
||||
}
|
||||
|
||||
bool cAudioCapture::setFrequency(unsigned int frequency)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Frequency = frequency;
|
||||
shutdownOpenALDevice();
|
||||
bool state = initOpenALDevice();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
return initOpenALDevice();
|
||||
}
|
||||
|
||||
bool cAudioCapture::setFormat(AudioFormats format)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Format = format;
|
||||
if(Format == EAF_8BIT_MONO)
|
||||
SampleSize = 1;
|
||||
|
@ -262,36 +252,30 @@ namespace cAudio
|
|||
SampleSize = 4;
|
||||
|
||||
shutdownOpenALDevice();
|
||||
bool state = initOpenALDevice();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
return initOpenALDevice();
|
||||
}
|
||||
|
||||
bool cAudioCapture::setInternalBufferSize(unsigned int internalBufferSize)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
InternalBufferSize = internalBufferSize;
|
||||
|
||||
shutdownOpenALDevice();
|
||||
bool state = initOpenALDevice();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
return initOpenALDevice();
|
||||
}
|
||||
|
||||
bool cAudioCapture::setDevice(const char* deviceName)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
DeviceName = safeCStr(deviceName);
|
||||
|
||||
shutdownOpenALDevice();
|
||||
bool state = initOpenALDevice();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
return initOpenALDevice();
|
||||
}
|
||||
|
||||
bool cAudioCapture::initialize(const char* deviceName, unsigned int frequency, AudioFormats format, unsigned int internalBufferSize)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
DeviceName = safeCStr(deviceName);
|
||||
Frequency = frequency;
|
||||
InternalBufferSize = internalBufferSize;
|
||||
|
@ -307,9 +291,39 @@ namespace cAudio
|
|||
SampleSize = 4;
|
||||
|
||||
shutdownOpenALDevice();
|
||||
bool state = initOpenALDevice();
|
||||
Mutex.unlock();
|
||||
return state;
|
||||
return initOpenALDevice();
|
||||
}
|
||||
|
||||
bool cAudioCapture::checkError()
|
||||
{
|
||||
if(CaptureDevice)
|
||||
{
|
||||
int error = alcGetError(CaptureDevice);
|
||||
if (error != AL_NO_ERROR)
|
||||
{
|
||||
const char* errorString = alGetString(error);
|
||||
getLogger()->logError("AudioCapture", "OpenAL Error: %s.", errorString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum cAudioCapture::convertAudioFormatEnum(AudioFormats format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case EAF_8BIT_MONO:
|
||||
return AL_FORMAT_MONO8;
|
||||
case EAF_16BIT_MONO:
|
||||
return AL_FORMAT_MONO16;
|
||||
case EAF_8BIT_STEREO:
|
||||
return AL_FORMAT_STEREO8;
|
||||
case EAF_16BIT_STEREO:
|
||||
return AL_FORMAT_STEREO16;
|
||||
default:
|
||||
return AL_FORMAT_MONO8;
|
||||
};
|
||||
}
|
||||
|
||||
CAUDIO_API IAudioCapture* createAudioCapture(bool initializeDefault)
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
#include "../Headers/cAudioEffects.h"
|
||||
#include "../Headers/cFilter.h"
|
||||
#include "../Headers/cEffect.h"
|
||||
|
||||
//Number of effect slots to try to create
|
||||
#define EFFECT_SLOTS_TO_TEST 256
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
|
||||
cAudioEffects::cAudioEffects() : MaxEffectsSupported(0)
|
||||
{
|
||||
for(int i=0; i<EET_COUNT; ++i)
|
||||
SupportedEffects[i] = false;
|
||||
|
||||
for(int i=0; i<EFT_COUNT; ++i)
|
||||
SupportedFilters[i] = false;
|
||||
}
|
||||
|
||||
cAudioEffects::~cAudioEffects()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IEffect* cAudioEffects::createEffect()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
IEffect* effect = new cEffect(&EFXInterface);
|
||||
|
||||
if(effect && effect->isValid())
|
||||
return effect;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IFilter* cAudioEffects::createFilter()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
IFilter* filter = new cFilter(&EFXInterface);
|
||||
|
||||
if(filter && filter->isValid())
|
||||
return filter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int cAudioEffects::getMaxEffectsSupported() const
|
||||
{
|
||||
return MaxEffectsSupported;
|
||||
}
|
||||
|
||||
bool cAudioEffects::isEffectSupported(const EffectTypes& type) const
|
||||
{
|
||||
return SupportedEffects[type];
|
||||
}
|
||||
|
||||
bool cAudioEffects::isFilterSupported(const FilterTypes& type) const
|
||||
{
|
||||
return SupportedFilters[type];
|
||||
}
|
||||
|
||||
cEFXFunctions* cAudioEffects::getEFXInterface()
|
||||
{
|
||||
return &EFXInterface;
|
||||
}
|
||||
|
||||
void cAudioEffects::checkEFXSupportDetails()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(EFXInterface.Supported)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFXInterface.Mutex);
|
||||
|
||||
//Count the number of effect slots this device supports (limits the max number of effects available)
|
||||
unsigned int count = 0;
|
||||
ALuint effectSlots[EFFECT_SLOTS_TO_TEST];
|
||||
for(count=0; count<EFFECT_SLOTS_TO_TEST; ++count)
|
||||
{
|
||||
EFXInterface.alGenAuxiliaryEffectSlots(1, &effectSlots[count]);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
MaxEffectsSupported = count;
|
||||
|
||||
//Check what effects are supported
|
||||
ALuint Effect;
|
||||
EFXInterface.alGenEffects(1, &Effect);
|
||||
if (alGetError() == AL_NO_ERROR)
|
||||
{
|
||||
SupportedEffects[EET_NULL] = true;
|
||||
|
||||
// Try setting Effect Type to known Effects
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
SupportedEffects[EET_REVERB] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
SupportedEffects[EET_EAX_REVERB] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS);
|
||||
SupportedEffects[EET_CHORUS] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION);
|
||||
SupportedEffects[EET_DISTORTION] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO);
|
||||
SupportedEffects[EET_ECHO] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER);
|
||||
SupportedEffects[EET_FLANGER] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER);
|
||||
SupportedEffects[EET_FREQUENCY_SHIFTER] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER);
|
||||
SupportedEffects[EET_VOCAL_MORPHER] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
|
||||
SupportedEffects[EET_PITCH_SHIFTER] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR);
|
||||
SupportedEffects[EET_RING_MODULATOR] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH);
|
||||
SupportedEffects[EET_AUTOWAH] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR);
|
||||
SupportedEffects[EET_COMPRESSOR] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alEffecti(Effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
|
||||
SupportedEffects[EET_EQUALIZER] = (alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Delete Effect
|
||||
EFXInterface.alDeleteEffects(1, &Effect);
|
||||
|
||||
// Generate a Filter to use to determine what Filter Types are supported
|
||||
ALuint Filter;
|
||||
EFXInterface.alGenFilters(1, &Filter);
|
||||
if (alGetError() == AL_NO_ERROR)
|
||||
{
|
||||
SupportedFilters[EFT_NULL] = true;
|
||||
|
||||
// Try setting the Filter type to known Filters
|
||||
EFXInterface.alFilteri(Filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||
SupportedFilters[EFT_LOWPASS] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alFilteri(Filter, AL_FILTER_TYPE, AL_FILTER_HIGHPASS);
|
||||
SupportedFilters[EFT_HIGHPASS] = (alGetError() == AL_NO_ERROR);
|
||||
|
||||
EFXInterface.alFilteri(Filter, AL_FILTER_TYPE, AL_FILTER_BANDPASS);
|
||||
SupportedFilters[EFT_BANDPASS] = (alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
// Delete Filter
|
||||
EFXInterface.alDeleteFilters(1, &Filter);
|
||||
|
||||
//Cleanup the slots we created
|
||||
while(count > 0)
|
||||
{
|
||||
EFXInterface.alDeleteAuxiliaryEffectSlots(1, &effectSlots[--count]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
|
@ -11,10 +11,6 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
#include <AL/efx.h>
|
||||
#include <AL/efx-creative.h>
|
||||
#include <AL/xram.h>
|
||||
|
||||
#define LOAD_AL_FUNC(x) (x = (typeof(x))alGetProcAddress(#x))
|
||||
|
||||
namespace cAudio
|
||||
|
@ -59,7 +55,7 @@ namespace cAudio
|
|||
cAudioMutexBasicLock lock(Mutex);
|
||||
|
||||
if(Initialized)
|
||||
shutDown();
|
||||
return false;
|
||||
|
||||
//Stores the context attributes (MAX of 4, with 2 zeros to terminate)
|
||||
ALint attribs[6] = { 0 };
|
||||
|
@ -86,10 +82,6 @@ namespace cAudio
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef CAUDIO_EAX_ENABLED
|
||||
EFXSupported = (alcIsExtensionPresent(Device, "ALC_EXT_EFX") == AL_TRUE);
|
||||
#endif
|
||||
|
||||
Context = alcCreateContext(Device, attribs);
|
||||
if (Context == NULL)
|
||||
{
|
||||
|
@ -111,10 +103,17 @@ namespace cAudio
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
initEffects.getEFXInterface()->Mutex.lock();
|
||||
EFXSupported = initEffects.getEFXInterface()->CheckEFXSupport(Device);
|
||||
initEffects.getEFXInterface()->Mutex.unlock();
|
||||
initEffects.checkEFXSupportDetails();
|
||||
#endif
|
||||
|
||||
getLogger()->logInfo("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION));
|
||||
getLogger()->logInfo("AudioManager", "Vendor: %s", alGetString(AL_VENDOR));
|
||||
getLogger()->logInfo("AudioManager", "Renderer: %s", alGetString(AL_RENDERER));
|
||||
#ifdef CAUDIO_EAX_ENABLED
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
if(EFXSupported)
|
||||
{
|
||||
int EFXMajorVersion = 0;
|
||||
|
@ -170,7 +169,7 @@ namespace cAudio
|
|||
{
|
||||
if(decoder->isValid())
|
||||
{
|
||||
IAudio* audio = new cAudio(decoder);
|
||||
IAudio* audio = new cAudio(decoder, Context, initEffects.getEFXInterface());
|
||||
decoder->drop();
|
||||
|
||||
if(audio)
|
||||
|
@ -262,7 +261,7 @@ namespace cAudio
|
|||
{
|
||||
if(decoder->isValid())
|
||||
{
|
||||
IAudio* audio = new cAudio(decoder);
|
||||
IAudio* audio = new cAudio(decoder, Context, initEffects.getEFXInterface());
|
||||
decoder->drop();
|
||||
|
||||
if(audio)
|
||||
|
@ -322,7 +321,7 @@ namespace cAudio
|
|||
{
|
||||
if(decoder->isValid())
|
||||
{
|
||||
IAudio* audio = new cAudio(decoder);
|
||||
IAudio* audio = new cAudio(decoder, Context, initEffects.getEFXInterface());
|
||||
decoder->drop();
|
||||
|
||||
if(audio)
|
||||
|
@ -469,7 +468,7 @@ namespace cAudio
|
|||
}
|
||||
}
|
||||
|
||||
void cAudioManager::checkError()
|
||||
bool cAudioManager::checkError()
|
||||
{
|
||||
int error = alGetError();
|
||||
const char* errorString;
|
||||
|
@ -478,6 +477,7 @@ namespace cAudio
|
|||
{
|
||||
errorString = alGetString(error);
|
||||
getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Device)
|
||||
|
@ -487,8 +487,10 @@ namespace cAudio
|
|||
{
|
||||
errorString = alGetString(error);
|
||||
getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cAudioManager::getAvailableDevices()
|
||||
|
|
|
@ -0,0 +1,697 @@
|
|||
#include "../Headers/cEffect.h"
|
||||
#include "../Headers/cLogger.h"
|
||||
#include "../Headers/cUtils.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
cEffect::cEffect(cEFXFunctions* oALFunctions) : EFX(oALFunctions), Type(EET_NULL),
|
||||
Volume(1.0f), IgnoreAttenuation(false), LastUpdated(0), Valid(false), Filter(NULL),
|
||||
Effect(0), EffectSlot(0)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(EFX)
|
||||
{
|
||||
if(EFX->Supported)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
|
||||
//Create Effect Slot
|
||||
EFX->alGenAuxiliaryEffectSlots(1, &EffectSlot);
|
||||
bool error = CheckError();
|
||||
if(error)
|
||||
{
|
||||
EffectSlot = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//Create the effect object
|
||||
EFX->alGenEffects(1, &Effect);
|
||||
error = CheckError();
|
||||
if(error)
|
||||
{
|
||||
EFX->alDeleteAuxiliaryEffectSlots(1, &EffectSlot);
|
||||
EffectSlot = 0;
|
||||
Effect = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//Bind the effect to the effect slot
|
||||
EFX->alAuxiliaryEffectSloti(EffectSlot, AL_EFFECTSLOT_EFFECT, Effect);
|
||||
error = CheckError();
|
||||
if(error)
|
||||
{
|
||||
EFX->alDeleteEffects(1, &Effect);
|
||||
EFX->alDeleteAuxiliaryEffectSlots(1, &EffectSlot);
|
||||
EffectSlot = 0;
|
||||
Effect = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//Everything worked, effect is ready to use
|
||||
Valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cEffect::~cEffect()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(EFX && EFX->Supported)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
EFX->alAuxiliaryEffectSloti(EffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
|
||||
|
||||
if(Effect)
|
||||
{
|
||||
EFX->alDeleteEffects(1, &Effect);
|
||||
}
|
||||
|
||||
if(EffectSlot)
|
||||
{
|
||||
EFX->alDeleteAuxiliaryEffectSlots(1, &EffectSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EffectTypes& cEffect::getType() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
void cEffect::setType(const EffectTypes& type)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Type = type;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sEAXReverbParameters& cEffect::getEAXReverbParameters() const
|
||||
{
|
||||
return EAXReverbParam;
|
||||
}
|
||||
|
||||
void cEffect::setEAXReverbParameters(const sEAXReverbParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
EAXReverbParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sReverbParameters& cEffect::getReverbParameters() const
|
||||
{
|
||||
return ReverbParam;
|
||||
}
|
||||
|
||||
void cEffect::setReverbParameters(const sReverbParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
ReverbParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sChorusParameters& cEffect::getChorusParameters() const
|
||||
{
|
||||
return ChorusParam;
|
||||
}
|
||||
|
||||
void cEffect::setChorusParameters(const sChorusParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
ChorusParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sDistortionParameters& cEffect::getDistortionParameters() const
|
||||
{
|
||||
return DistortionParam;
|
||||
}
|
||||
|
||||
void cEffect::setDistortionParameters(const sDistortionParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
DistortionParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sEchoParameters& cEffect::getEchoParameters() const
|
||||
{
|
||||
return EchoParam;
|
||||
}
|
||||
|
||||
void cEffect::setEchoParameters(const sEchoParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
EchoParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sFlangerParameters& cEffect::getFlangerParameters() const
|
||||
{
|
||||
return FlangerParam;
|
||||
}
|
||||
|
||||
void cEffect::setFlangerParameters(const sFlangerParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
FlangerParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sFrequencyShiftParameters& cEffect::getFrequencyShiftParameters() const
|
||||
{
|
||||
return FrequencyShiftParam;
|
||||
}
|
||||
|
||||
void cEffect::setFrequencyShiftParameters(const sFrequencyShiftParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
FrequencyShiftParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sVocalMorpherParameters& cEffect::getVocalMorpherParameters() const
|
||||
{
|
||||
return VocalMorpherParam;
|
||||
}
|
||||
|
||||
void cEffect::setVocalMorpherParameters(const sVocalMorpherParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
VocalMorpherParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sPitchShifterParameters& cEffect::getPitchShifterParameters() const
|
||||
{
|
||||
return PitchShifterParam;
|
||||
}
|
||||
|
||||
void cEffect::setPitchShifterParameters(const sPitchShifterParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
PitchShifterParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sRingModulatorParameters& cEffect::getRingModulatorParameters() const
|
||||
{
|
||||
return RingModulatorParam;
|
||||
}
|
||||
|
||||
void cEffect::setRingModulatorParameters(const sRingModulatorParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
RingModulatorParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sAutowahParameters& cEffect::getAutowahParameters() const
|
||||
{
|
||||
return AutowahParam;
|
||||
}
|
||||
|
||||
void cEffect::setAutowahParameters(const sAutowahParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
AutowahParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sCompressorParameters& cEffect::getCompressorParameters() const
|
||||
{
|
||||
return CompressorParam;
|
||||
}
|
||||
|
||||
void cEffect::setCompressorParameters(const sCompressorParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
CompressorParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
const sEqualizerParameters& cEffect::getEqualizerParameters() const
|
||||
{
|
||||
return EqualizerParam;
|
||||
}
|
||||
|
||||
void cEffect::setEqualizerParameters(const sEqualizerParameters& param)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
EqualizerParam = param;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
float cEffect::getMasterVolume() const
|
||||
{
|
||||
return Volume;
|
||||
}
|
||||
|
||||
void cEffect::setMasterVolume(const float& volume)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Volume = volume;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
bool cEffect::isIgnoringAttenuation() const
|
||||
{
|
||||
return IgnoreAttenuation;
|
||||
}
|
||||
|
||||
void cEffect::ignoreAttenuation(const bool& ignore)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
IgnoreAttenuation = ignore;
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
IFilter* cEffect::getFilter() const
|
||||
{
|
||||
return Filter;
|
||||
}
|
||||
|
||||
void cEffect::attachFilter(IFilter* filter)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Filter = filter;
|
||||
|
||||
if(Filter)
|
||||
Filter->grab();
|
||||
UpdateEffect();
|
||||
}
|
||||
|
||||
void cEffect::removeFilter()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Filter)
|
||||
Filter->drop();
|
||||
Filter = NULL;
|
||||
}
|
||||
|
||||
unsigned int cEffect::getLastUpdated() const
|
||||
{
|
||||
return LastUpdated;
|
||||
}
|
||||
|
||||
bool cEffect::isValid() const
|
||||
{
|
||||
return Valid;
|
||||
}
|
||||
|
||||
ALuint cEffect::getOpenALEffect() const
|
||||
{
|
||||
return Effect;
|
||||
}
|
||||
|
||||
ALuint cEffect::getOpenALEffectSlot() const
|
||||
{
|
||||
return EffectSlot;
|
||||
}
|
||||
|
||||
bool cEffect::UpdateEffect()
|
||||
{
|
||||
++LastUpdated;
|
||||
|
||||
ALenum alEffectType = ConvertEffectEnum(Type);
|
||||
|
||||
if(EFX && EFX->Supported && EffectSlot && Effect)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
EFX->alEffecti(Effect, AL_EFFECT_TYPE, alEffectType);
|
||||
Valid = !CheckError();
|
||||
if(!Valid)
|
||||
return false;
|
||||
|
||||
EFX->alAuxiliaryEffectSlotf(EffectSlot, AL_EFFECTSLOT_GAIN, Volume);
|
||||
Valid = !CheckError();
|
||||
if(!Valid)
|
||||
return false;
|
||||
|
||||
EFX->alAuxiliaryEffectSloti(EffectSlot, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, IgnoreAttenuation ? AL_TRUE : AL_FALSE);
|
||||
Valid = !CheckError();
|
||||
if(!Valid)
|
||||
return false;
|
||||
|
||||
if(Type == EET_EAX_REVERB)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_DENSITY, EAXReverbParam.Density);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_DIFFUSION, EAXReverbParam.Diffusion);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_GAIN, EAXReverbParam.Gain);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_GAINHF, EAXReverbParam.GainHF);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_GAINLF, EAXReverbParam.GainLF);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_DECAY_TIME, EAXReverbParam.DecayTime);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_DECAY_HFRATIO, EAXReverbParam.DecayHFRatio);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_DECAY_LFRATIO, EAXReverbParam.DecayLFRatio);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_REFLECTIONS_GAIN, EAXReverbParam.ReflectionsGain);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_REFLECTIONS_DELAY, EAXReverbParam.ReflectionsDelay);
|
||||
EFX->alEffectfv(Effect, AL_EAXREVERB_REFLECTIONS_PAN, &EAXReverbParam.ReflectionsPan.x);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_LATE_REVERB_GAIN, EAXReverbParam.LateReverbGain);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_LATE_REVERB_DELAY, EAXReverbParam.LateReverbDelay);
|
||||
EFX->alEffectfv(Effect, AL_EAXREVERB_LATE_REVERB_PAN, &EAXReverbParam.LateReverbPan.x);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_ECHO_TIME, EAXReverbParam.EchoTime);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_ECHO_DEPTH, EAXReverbParam.EchoDepth);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_MODULATION_TIME, EAXReverbParam.ModulationTime);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_MODULATION_DEPTH, EAXReverbParam.ModulationDepth);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_HFREFERENCE, EAXReverbParam.HFReference);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_LFREFERENCE, EAXReverbParam.LFReference);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, EAXReverbParam.RoomRolloffFactor);
|
||||
EFX->alEffectf(Effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, EAXReverbParam.AirAbsorptionGainHF);
|
||||
EFX->alEffecti(Effect, AL_EAXREVERB_DECAY_HFLIMIT, EAXReverbParam.DecayHFLimit ? AL_TRUE : AL_FALSE);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_REVERB)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_REVERB_DENSITY, ReverbParam.Density);
|
||||
EFX->alEffectf(Effect, AL_REVERB_DIFFUSION, ReverbParam.Diffusion);
|
||||
EFX->alEffectf(Effect, AL_REVERB_GAIN, ReverbParam.Gain);
|
||||
EFX->alEffectf(Effect, AL_REVERB_GAINHF, ReverbParam.GainHF);
|
||||
EFX->alEffectf(Effect, AL_REVERB_DECAY_TIME, ReverbParam.DecayTime);
|
||||
EFX->alEffectf(Effect, AL_REVERB_DECAY_HFRATIO, ReverbParam.DecayHFRatio);
|
||||
EFX->alEffectf(Effect, AL_REVERB_REFLECTIONS_GAIN, ReverbParam.ReflectionsGain);
|
||||
EFX->alEffectf(Effect, AL_REVERB_REFLECTIONS_DELAY, ReverbParam.ReflectionsDelay);
|
||||
EFX->alEffectf(Effect, AL_REVERB_LATE_REVERB_GAIN, ReverbParam.LateReverbGain);
|
||||
EFX->alEffectf(Effect, AL_REVERB_LATE_REVERB_DELAY, ReverbParam.LateReverbDelay);
|
||||
EFX->alEffectf(Effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, ReverbParam.RoomRolloffFactor);
|
||||
EFX->alEffectf(Effect, AL_REVERB_AIR_ABSORPTION_GAINHF, ReverbParam.AirAbsorptionGainHF);
|
||||
EFX->alEffecti(Effect, AL_REVERB_DECAY_HFLIMIT, ReverbParam.DecayHFLimit ? AL_TRUE : AL_FALSE);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_CHORUS)
|
||||
{
|
||||
ALenum waveform = AL_CHORUS_DEFAULT_WAVEFORM;
|
||||
switch(ChorusParam.Waveform)
|
||||
{
|
||||
case sChorusParameters::ECW_SINUSOID:
|
||||
waveform = AL_CHORUS_WAVEFORM_SINUSOID;
|
||||
break;
|
||||
case sChorusParameters::ECW_TRIANGLE:
|
||||
waveform = AL_CHORUS_WAVEFORM_TRIANGLE;
|
||||
break;
|
||||
default:
|
||||
waveform = AL_CHORUS_DEFAULT_WAVEFORM;
|
||||
break;
|
||||
};
|
||||
EFX->alEffecti(Effect, AL_CHORUS_WAVEFORM, waveform);
|
||||
EFX->alEffecti(Effect, AL_CHORUS_PHASE, ChorusParam.Phase);
|
||||
EFX->alEffectf(Effect, AL_CHORUS_RATE, ChorusParam.Rate);
|
||||
EFX->alEffectf(Effect, AL_CHORUS_DEPTH, ChorusParam.Depth);
|
||||
EFX->alEffectf(Effect, AL_CHORUS_FEEDBACK, ChorusParam.Feedback);
|
||||
EFX->alEffectf(Effect, AL_CHORUS_DELAY, ChorusParam.Delay);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_DISTORTION)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_DISTORTION_EDGE, DistortionParam.Edge);
|
||||
EFX->alEffectf(Effect, AL_DISTORTION_GAIN, DistortionParam.Gain);
|
||||
EFX->alEffectf(Effect, AL_DISTORTION_LOWPASS_CUTOFF, DistortionParam.LowpassCutoff);
|
||||
EFX->alEffectf(Effect, AL_DISTORTION_EQCENTER, DistortionParam.EqCenter);
|
||||
EFX->alEffectf(Effect, AL_DISTORTION_EQBANDWIDTH, DistortionParam.EqBandwidth);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_ECHO)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_ECHO_DELAY, EchoParam.Delay);
|
||||
EFX->alEffectf(Effect, AL_ECHO_LRDELAY, EchoParam.LRDelay);
|
||||
EFX->alEffectf(Effect, AL_ECHO_DAMPING, EchoParam.Damping);
|
||||
EFX->alEffectf(Effect, AL_ECHO_FEEDBACK, EchoParam.Feedback);
|
||||
EFX->alEffectf(Effect, AL_ECHO_SPREAD, EchoParam.Spread);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_FLANGER)
|
||||
{
|
||||
ALenum waveform = AL_FLANGER_DEFAULT_WAVEFORM;
|
||||
switch(FlangerParam.Waveform)
|
||||
{
|
||||
case sFlangerParameters::EFW_SINUSOID:
|
||||
waveform = AL_FLANGER_WAVEFORM_SINUSOID;
|
||||
break;
|
||||
case sFlangerParameters::EFW_TRIANGLE:
|
||||
waveform = AL_FLANGER_WAVEFORM_SINUSOID;
|
||||
break;
|
||||
default:
|
||||
waveform = AL_FLANGER_DEFAULT_WAVEFORM;
|
||||
break;
|
||||
};
|
||||
EFX->alEffecti(Effect, AL_FLANGER_WAVEFORM, waveform);
|
||||
EFX->alEffecti(Effect, AL_FLANGER_PHASE, FlangerParam.Phase);
|
||||
EFX->alEffectf(Effect, AL_FLANGER_RATE, FlangerParam.Rate);
|
||||
EFX->alEffectf(Effect, AL_FLANGER_DEPTH, FlangerParam.Depth);
|
||||
EFX->alEffectf(Effect, AL_FLANGER_FEEDBACK, FlangerParam.Feedback);
|
||||
EFX->alEffectf(Effect, AL_FLANGER_DELAY, FlangerParam.Delay);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_FREQUENCY_SHIFTER)
|
||||
{
|
||||
ALenum shiftleft = ConvertFrequencyShiftEnum(FrequencyShiftParam.Left);
|
||||
ALenum shiftright = ConvertFrequencyShiftEnum(FrequencyShiftParam.Right);
|
||||
EFX->alEffectf(Effect, AL_FREQUENCY_SHIFTER_FREQUENCY, FrequencyShiftParam.Frequency);
|
||||
EFX->alEffecti(Effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, shiftleft);
|
||||
EFX->alEffecti(Effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, shiftright);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_VOCAL_MORPHER)
|
||||
{
|
||||
ALenum pA = ConvertVocalMorphPhonemeEnum(VocalMorpherParam.PhonemeA);
|
||||
ALenum pB = ConvertVocalMorphPhonemeEnum(VocalMorpherParam.PhonemeB);
|
||||
|
||||
ALenum waveform = AL_VOCAL_MORPHER_DEFAULT_WAVEFORM;
|
||||
switch(VocalMorpherParam.Waveform)
|
||||
{
|
||||
case sVocalMorpherParameters::EMW_SINUSOID:
|
||||
waveform = AL_VOCAL_MORPHER_WAVEFORM_SINUSOID;
|
||||
break;
|
||||
case sVocalMorpherParameters::EMW_TRIANGLE:
|
||||
waveform = AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE;
|
||||
break;
|
||||
case sVocalMorpherParameters::EMW_SAW:
|
||||
waveform = AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH;
|
||||
break;
|
||||
default:
|
||||
waveform = AL_VOCAL_MORPHER_DEFAULT_WAVEFORM;
|
||||
break;
|
||||
};
|
||||
|
||||
EFX->alEffecti(Effect, AL_VOCAL_MORPHER_PHONEMEA, pA);
|
||||
EFX->alEffecti(Effect, AL_VOCAL_MORPHER_PHONEMEB, pB);
|
||||
EFX->alEffecti(Effect, AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING, VocalMorpherParam.PhonemeACoarseTune);
|
||||
EFX->alEffecti(Effect, AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING, VocalMorpherParam.PhonemeBCoarseTune);
|
||||
EFX->alEffecti(Effect, AL_VOCAL_MORPHER_WAVEFORM, waveform);
|
||||
EFX->alEffectf(Effect, AL_VOCAL_MORPHER_RATE, VocalMorpherParam.Rate);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_PITCH_SHIFTER)
|
||||
{
|
||||
EFX->alEffecti(Effect, AL_PITCH_SHIFTER_COARSE_TUNE, PitchShifterParam.CoarseTune);
|
||||
EFX->alEffecti(Effect, AL_PITCH_SHIFTER_FINE_TUNE, PitchShifterParam.FineTune);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_RING_MODULATOR)
|
||||
{
|
||||
ALenum waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM;
|
||||
switch(RingModulatorParam.Waveform)
|
||||
{
|
||||
case sRingModulatorParameters::EMW_SINUSOID:
|
||||
waveform = AL_RING_MODULATOR_SINUSOID;
|
||||
break;
|
||||
case sRingModulatorParameters::EMW_SAW:
|
||||
waveform = AL_RING_MODULATOR_SAWTOOTH;
|
||||
break;
|
||||
case sRingModulatorParameters::EMW_SQUARE:
|
||||
waveform = AL_RING_MODULATOR_SQUARE;
|
||||
break;
|
||||
default:
|
||||
waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM;
|
||||
break;
|
||||
};
|
||||
|
||||
EFX->alEffectf(Effect, AL_RING_MODULATOR_FREQUENCY, RingModulatorParam.Frequency);
|
||||
EFX->alEffectf(Effect, AL_RING_MODULATOR_HIGHPASS_CUTOFF, RingModulatorParam.HighPassCutoff);
|
||||
EFX->alEffecti(Effect, AL_RING_MODULATOR_WAVEFORM, waveform);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_AUTOWAH)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_AUTOWAH_ATTACK_TIME, AutowahParam.AttackTime);
|
||||
EFX->alEffectf(Effect, AL_AUTOWAH_RELEASE_TIME, AutowahParam.ReleaseTime);
|
||||
EFX->alEffectf(Effect, AL_AUTOWAH_RESONANCE, AutowahParam.Resonance);
|
||||
EFX->alEffectf(Effect, AL_AUTOWAH_PEAK_GAIN, AutowahParam.PeakGain);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_COMPRESSOR)
|
||||
{
|
||||
EFX->alEffecti(Effect, AL_COMPRESSOR_ONOFF, CompressorParam.Active ? AL_TRUE : AL_FALSE);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EET_EQUALIZER)
|
||||
{
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_LOW_GAIN, EqualizerParam.LowGain);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_LOW_CUTOFF, EqualizerParam.LowCutoff);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID1_GAIN, EqualizerParam.Mid1Gain);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID1_CENTER, EqualizerParam.Mid1Center);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID1_WIDTH, EqualizerParam.Mid1Width);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID2_GAIN, EqualizerParam.Mid2Gain);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID2_CENTER, EqualizerParam.Mid2Center);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_MID2_WIDTH, EqualizerParam.Mid2Width);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_HIGH_GAIN, EqualizerParam.HighGain);
|
||||
EFX->alEffectf(Effect, AL_EQUALIZER_HIGH_CUTOFF, EqualizerParam.HighCutoff);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cEffect::CheckError()
|
||||
{
|
||||
int error = alGetError();
|
||||
const char* errorString;
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
{
|
||||
errorString = alGetString(error);
|
||||
if(error == AL_OUT_OF_MEMORY)
|
||||
getLogger()->logCritical("Audio Effect", "OpenAL Error: %s.", errorString);
|
||||
else
|
||||
getLogger()->logError("Audio Effect", "OpenAL Error: %s.", errorString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum cEffect::ConvertEffectEnum(EffectTypes type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case EET_NULL:
|
||||
return AL_EFFECT_NULL;
|
||||
case EET_EAX_REVERB:
|
||||
return AL_EFFECT_EAXREVERB;
|
||||
case EET_REVERB:
|
||||
return AL_EFFECT_REVERB;
|
||||
case EET_CHORUS:
|
||||
return AL_EFFECT_CHORUS;
|
||||
case EET_DISTORTION:
|
||||
return AL_EFFECT_DISTORTION;
|
||||
case EET_ECHO:
|
||||
return AL_EFFECT_ECHO;
|
||||
case EET_FLANGER:
|
||||
return AL_EFFECT_FLANGER;
|
||||
case EET_FREQUENCY_SHIFTER:
|
||||
return AL_EFFECT_FREQUENCY_SHIFTER;
|
||||
case EET_VOCAL_MORPHER:
|
||||
return AL_EFFECT_VOCAL_MORPHER;
|
||||
case EET_PITCH_SHIFTER:
|
||||
return AL_EFFECT_PITCH_SHIFTER;
|
||||
case EET_RING_MODULATOR:
|
||||
return AL_EFFECT_RING_MODULATOR;
|
||||
case EET_AUTOWAH:
|
||||
return AL_EFFECT_AUTOWAH;
|
||||
case EET_COMPRESSOR:
|
||||
return AL_EFFECT_COMPRESSOR;
|
||||
case EET_EQUALIZER:
|
||||
return AL_EFFECT_EQUALIZER;
|
||||
default:
|
||||
return AL_EFFECT_NULL;
|
||||
};
|
||||
}
|
||||
|
||||
ALenum cEffect::ConvertFrequencyShiftEnum(sFrequencyShiftParameters::ShiftDirection shift)
|
||||
{
|
||||
switch(shift)
|
||||
{
|
||||
case sFrequencyShiftParameters::ESD_DOWN:
|
||||
return AL_FREQUENCY_SHIFTER_DIRECTION_DOWN;
|
||||
case sFrequencyShiftParameters::ESD_UP:
|
||||
return AL_FREQUENCY_SHIFTER_DIRECTION_UP;
|
||||
case sFrequencyShiftParameters::ESD_OFF:
|
||||
return AL_FREQUENCY_SHIFTER_DIRECTION_OFF;
|
||||
default:
|
||||
return AL_FREQUENCY_SHIFTER_DIRECTION_DOWN;
|
||||
};
|
||||
}
|
||||
|
||||
ALenum cEffect::ConvertVocalMorphPhonemeEnum(sVocalMorpherParameters::MorpherPhoneme phoneme)
|
||||
{
|
||||
switch(phoneme)
|
||||
{
|
||||
case sVocalMorpherParameters::EMP_A:
|
||||
return AL_VOCAL_MORPHER_PHONEME_A;
|
||||
case sVocalMorpherParameters::EMP_E:
|
||||
return AL_VOCAL_MORPHER_PHONEME_E;
|
||||
case sVocalMorpherParameters::EMP_I:
|
||||
return AL_VOCAL_MORPHER_PHONEME_I;
|
||||
case sVocalMorpherParameters::EMP_O:
|
||||
return AL_VOCAL_MORPHER_PHONEME_O;
|
||||
case sVocalMorpherParameters::EMP_U:
|
||||
return AL_VOCAL_MORPHER_PHONEME_U;
|
||||
case sVocalMorpherParameters::EMP_AA:
|
||||
return AL_VOCAL_MORPHER_PHONEME_AA;
|
||||
case sVocalMorpherParameters::EMP_AE:
|
||||
return AL_VOCAL_MORPHER_PHONEME_AE;
|
||||
case sVocalMorpherParameters::EMP_AH:
|
||||
return AL_VOCAL_MORPHER_PHONEME_AH;
|
||||
case sVocalMorpherParameters::EMP_AO:
|
||||
return AL_VOCAL_MORPHER_PHONEME_AO;
|
||||
case sVocalMorpherParameters::EMP_EH:
|
||||
return AL_VOCAL_MORPHER_PHONEME_EH;
|
||||
case sVocalMorpherParameters::EMP_ER:
|
||||
return AL_VOCAL_MORPHER_PHONEME_ER;
|
||||
case sVocalMorpherParameters::EMP_IH:
|
||||
return AL_VOCAL_MORPHER_PHONEME_IH;
|
||||
case sVocalMorpherParameters::EMP_IY:
|
||||
return AL_VOCAL_MORPHER_PHONEME_IY;
|
||||
case sVocalMorpherParameters::EMP_UH:
|
||||
return AL_VOCAL_MORPHER_PHONEME_UH;
|
||||
case sVocalMorpherParameters::EMP_UW:
|
||||
return AL_VOCAL_MORPHER_PHONEME_UW;
|
||||
case sVocalMorpherParameters::EMP_B:
|
||||
return AL_VOCAL_MORPHER_PHONEME_B;
|
||||
case sVocalMorpherParameters::EMP_D:
|
||||
return AL_VOCAL_MORPHER_PHONEME_D;
|
||||
case sVocalMorpherParameters::EMP_F:
|
||||
return AL_VOCAL_MORPHER_PHONEME_F;
|
||||
case sVocalMorpherParameters::EMP_G:
|
||||
return AL_VOCAL_MORPHER_PHONEME_G;
|
||||
case sVocalMorpherParameters::EMP_J:
|
||||
return AL_VOCAL_MORPHER_PHONEME_J;
|
||||
case sVocalMorpherParameters::EMP_K:
|
||||
return AL_VOCAL_MORPHER_PHONEME_K;
|
||||
case sVocalMorpherParameters::EMP_L:
|
||||
return AL_VOCAL_MORPHER_PHONEME_L;
|
||||
case sVocalMorpherParameters::EMP_M:
|
||||
return AL_VOCAL_MORPHER_PHONEME_M;
|
||||
case sVocalMorpherParameters::EMP_N:
|
||||
return AL_VOCAL_MORPHER_PHONEME_N;
|
||||
case sVocalMorpherParameters::EMP_P:
|
||||
return AL_VOCAL_MORPHER_PHONEME_P;
|
||||
case sVocalMorpherParameters::EMP_R:
|
||||
return AL_VOCAL_MORPHER_PHONEME_R;
|
||||
case sVocalMorpherParameters::EMP_S:
|
||||
return AL_VOCAL_MORPHER_PHONEME_S;
|
||||
case sVocalMorpherParameters::EMP_T:
|
||||
return AL_VOCAL_MORPHER_PHONEME_T;
|
||||
case sVocalMorpherParameters::EMP_V:
|
||||
return AL_VOCAL_MORPHER_PHONEME_V;
|
||||
case sVocalMorpherParameters::EMP_Z:
|
||||
return AL_VOCAL_MORPHER_PHONEME_Z;
|
||||
default:
|
||||
return AL_VOCAL_MORPHER_DEFAULT_PHONEMEA;
|
||||
};
|
||||
}
|
||||
};
|
|
@ -0,0 +1,175 @@
|
|||
#include "../Headers/cFilter.h"
|
||||
#include "../Headers/cLogger.h"
|
||||
#include "../Headers/cUtils.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
cFilter::cFilter(cEFXFunctions* oALFunctions) : EFX(oALFunctions), Type(EFT_NULL),
|
||||
Volume(1.0f), LowFreqVolume(1.0f), HighFreqVolume(1.0f), LastUpdated(0),
|
||||
Valid(false), Filter(0)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(EFX)
|
||||
Valid = EFX->Supported;
|
||||
|
||||
if(Valid)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
EFX->alGenFilters(1, &Filter);
|
||||
Valid = !CheckError();
|
||||
if(!Valid)
|
||||
Filter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cFilter::~cFilter()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
if(Filter && EFX && EFX->Supported)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
EFX->alDeleteFilters(1, &Filter);
|
||||
}
|
||||
}
|
||||
|
||||
const FilterTypes& cFilter::getType() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
void cFilter::setType(const FilterTypes& type)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Type = type;
|
||||
UpdateFilter();
|
||||
}
|
||||
|
||||
float cFilter::getVolume() const
|
||||
{
|
||||
return Volume;
|
||||
}
|
||||
|
||||
void cFilter::setVolume(const float& volume)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Volume = volume;
|
||||
UpdateFilter();
|
||||
}
|
||||
|
||||
float cFilter::getLowFrequencyVolume() const
|
||||
{
|
||||
return LowFreqVolume;
|
||||
}
|
||||
|
||||
void cFilter::setLowFrequencyVolume(const float& volumeLF)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
LowFreqVolume = volumeLF;
|
||||
UpdateFilter();
|
||||
}
|
||||
|
||||
float cFilter::getHighFrequencyVolume() const
|
||||
{
|
||||
return HighFreqVolume;
|
||||
}
|
||||
|
||||
void cFilter::setHighFrequencyVolume(const float& volumeHF)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
HighFreqVolume = volumeHF;
|
||||
UpdateFilter();
|
||||
}
|
||||
|
||||
unsigned int cFilter::getLastUpdated() const
|
||||
{
|
||||
return LastUpdated;
|
||||
}
|
||||
|
||||
bool cFilter::isValid() const
|
||||
{
|
||||
return Valid;
|
||||
}
|
||||
|
||||
ALuint cFilter::getOpenALFilter() const
|
||||
{
|
||||
return Filter;
|
||||
}
|
||||
|
||||
bool cFilter::UpdateFilter()
|
||||
{
|
||||
++LastUpdated;
|
||||
|
||||
ALenum alFilterType = ConvertFilterEnum(Type);
|
||||
|
||||
if(Filter && EFX && EFX->Supported)
|
||||
{
|
||||
cAudioMutexBasicLock lock(EFX->Mutex);
|
||||
EFX->alFilteri(Filter, AL_FILTER_TYPE, alFilterType);
|
||||
Valid = !CheckError();
|
||||
if(!Valid)
|
||||
return false;
|
||||
|
||||
if(Type == EFT_LOWPASS)
|
||||
{
|
||||
EFX->alFilterf(Filter, AL_LOWPASS_GAIN, Volume);
|
||||
EFX->alFilterf(Filter, AL_LOWPASS_GAINHF, HighFreqVolume);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EFT_HIGHPASS)
|
||||
{
|
||||
EFX->alFilterf(Filter, AL_HIGHPASS_GAIN, Volume);
|
||||
EFX->alFilterf(Filter, AL_HIGHPASS_GAINLF, LowFreqVolume);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else if(Type == EFT_BANDPASS)
|
||||
{
|
||||
EFX->alFilterf(Filter, AL_BANDPASS_GAIN, Volume);
|
||||
EFX->alFilterf(Filter, AL_BANDPASS_GAINLF, LowFreqVolume);
|
||||
EFX->alFilterf(Filter, AL_BANDPASS_GAINHF, HighFreqVolume);
|
||||
Valid = !CheckError();
|
||||
return Valid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cFilter::CheckError()
|
||||
{
|
||||
int error = alGetError();
|
||||
const char* errorString;
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
{
|
||||
errorString = alGetString(error);
|
||||
if(error == AL_OUT_OF_MEMORY)
|
||||
getLogger()->logCritical("Audio Filter", "OpenAL Error: %s.", errorString);
|
||||
else
|
||||
getLogger()->logError("Audio Filter", "OpenAL Error: %s.", errorString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum cFilter::ConvertFilterEnum(FilterTypes type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case EFT_NULL:
|
||||
return AL_FILTER_NULL;
|
||||
case EFT_LOWPASS:
|
||||
return AL_FILTER_LOWPASS;
|
||||
case EFT_HIGHPASS:
|
||||
return AL_FILTER_HIGHPASS;
|
||||
case EFT_BANDPASS:
|
||||
return AL_FILTER_BANDPASS;
|
||||
default:
|
||||
return AL_FILTER_NULL;
|
||||
};
|
||||
}
|
||||
};
|
|
@ -1,53 +1,64 @@
|
|||
#include "../Headers/cListener.h"
|
||||
#include <AL/al.h>
|
||||
#include "../Headers/cEFXFunctions.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
void cListener::setPosition(const cVector3 pos)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Position = pos;
|
||||
alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
|
||||
Mutex.unlock();
|
||||
}
|
||||
void cListener::setDirection(const cVector3 dir)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Direction = dir;
|
||||
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
|
||||
alListenerfv(AL_ORIENTATION, orient);
|
||||
Mutex.unlock();
|
||||
}
|
||||
void cListener::setUpVector(const cVector3 up)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
UpVector = up;
|
||||
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
|
||||
alListenerfv(AL_ORIENTATION, orient);
|
||||
Mutex.unlock();
|
||||
}
|
||||
void cListener::setVelocity(const cVector3 vel)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Velocity = vel;
|
||||
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
|
||||
Mutex.unlock();
|
||||
}
|
||||
void cListener::setMasterVolume(const float volume)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
MasterGain = volume;
|
||||
alListenerf(AL_GAIN, MasterGain);
|
||||
Mutex.unlock();
|
||||
}
|
||||
void cListener::move(const cVector3 pos)
|
||||
{
|
||||
Mutex.lock();
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
Velocity = pos - Position;
|
||||
Position = pos;
|
||||
|
||||
alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
|
||||
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
|
||||
Mutex.unlock();
|
||||
}
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//!Sets the meters per user world unit for use with sound effects
|
||||
void cListener::setMetersPerUnit(const float& meters)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
alListenerf(AL_METERS_PER_UNIT, meters);
|
||||
}
|
||||
|
||||
//!Returns the meters per user world unit for use with sound effects
|
||||
float cListener::getMetersPerUnit(void) const
|
||||
{
|
||||
float value = 1.0f;
|
||||
alGetListenerf(AL_METERS_PER_UNIT, &value);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
};
|
16
cAudio.sln
16
cAudio.sln
|
@ -24,8 +24,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tutorial4_AudioCapture", "E
|
|||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stress_Test", "tests\Stress_Test\Stress_Test.vcproj", "{0E491D8E-6B9E-4107-B50B-EC48CBA3203D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{ACD6C202-85D4-44F5-83BF-6577A074F655} = {ACD6C202-85D4-44F5-83BF-6577A074F655}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3Decoder", "plugins\mp3Decoder\mp3Decoder.vcproj", "{F1741962-FBBB-4BA2-AC74-A97E2DDF6B2E}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tutorial5_AudioEffects", "Examples\Tutorial5_AudioEffects\Tutorial5_AudioEffects.vcproj", "{EA03D1BB-6D71-4960-958A-670480A8259A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{ACD6C202-85D4-44F5-83BF-6577A074F655} = {ACD6C202-85D4-44F5-83BF-6577A074F655}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -57,10 +63,10 @@ Global
|
|||
{0E491D8E-6B9E-4107-B50B-EC48CBA3203D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0E491D8E-6B9E-4107-B50B-EC48CBA3203D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0E491D8E-6B9E-4107-B50B-EC48CBA3203D}.Release|Win32.Build.0 = Release|Win32
|
||||
{F1741962-FBBB-4BA2-AC74-A97E2DDF6B2E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F1741962-FBBB-4BA2-AC74-A97E2DDF6B2E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F1741962-FBBB-4BA2-AC74-A97E2DDF6B2E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F1741962-FBBB-4BA2-AC74-A97E2DDF6B2E}.Release|Win32.Build.0 = Release|Win32
|
||||
{EA03D1BB-6D71-4960-958A-670480A8259A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EA03D1BB-6D71-4960-958A-670480A8259A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EA03D1BB-6D71-4960-958A-670480A8259A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EA03D1BB-6D71-4960-958A-670480A8259A}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="bin/win32-visual"
|
||||
OutputDirectory="lib/win32-visual"
|
||||
IntermediateDirectory="obj/$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
|
@ -90,11 +90,12 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy "$(TargetPath)" "$(SolutionDir)\bin\win32-visual\" /y"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="bin/win32-visual"
|
||||
OutputDirectory="lib/win32-visual"
|
||||
IntermediateDirectory="obj/$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
|
@ -166,6 +167,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy "$(TargetPath)" "$(SolutionDir)\bin\win32-visual\" /y"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
|
@ -185,6 +187,10 @@
|
|||
RelativePath=".\Headers\cAudioCapture.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cAudioEffects.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cAudioManager.h"
|
||||
>
|
||||
|
@ -193,10 +199,22 @@
|
|||
RelativePath=".\Headers\cConsoleLogReceiver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cEffect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cEFXFunctions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cFileSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cFilter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cListener.h"
|
||||
>
|
||||
|
@ -265,6 +283,10 @@
|
|||
RelativePath=".\Source\cAudioCapture.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cAudioEffects.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cAudioManager.cpp"
|
||||
>
|
||||
|
@ -277,10 +299,18 @@
|
|||
RelativePath=".\Source\cConsoleLogReceiver.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cEffect.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cFileSource.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cFilter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cListener.cpp"
|
||||
>
|
||||
|
@ -357,6 +387,10 @@
|
|||
RelativePath=".\include\IAudioDecoderFactory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IAudioEffects.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IAudioManager.h"
|
||||
>
|
||||
|
@ -365,6 +399,18 @@
|
|||
RelativePath=".\include\IDataSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IEffect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IEffectParameters.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IFilter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\IListener.h"
|
||||
>
|
||||
|
|
|
@ -6,10 +6,10 @@ namespace cAudio
|
|||
|
||||
enum AudioFormats
|
||||
{
|
||||
EAF_8BIT_MONO = 0x1100,
|
||||
EAF_8BIT_STEREO = 0x1102,
|
||||
EAF_16BIT_MONO = 0x1101,
|
||||
EAF_16BIT_STEREO = 0x1103
|
||||
EAF_8BIT_MONO,
|
||||
EAF_8BIT_STEREO,
|
||||
EAF_16BIT_MONO,
|
||||
EAF_16BIT_STEREO
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#ifndef IAUDIO_H
|
||||
#define IAUDIO_H
|
||||
|
||||
#include "cAudioDefines.h"
|
||||
#include "IRefCounted.h"
|
||||
#include "IAudioDecoder.h"
|
||||
#include "cVector3.h"
|
||||
#include "IEffect.h"
|
||||
#include "IFilter.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
|
@ -28,7 +31,8 @@ namespace cAudio
|
|||
virtual void loop(const bool& toLoop) = 0;
|
||||
//! Seeks through the audio stream to a specific spot
|
||||
/** Note: May not be supported by all codecs
|
||||
\param seconds: Number of seconds from the start of the audio stream to seek to
|
||||
\param seconds: Number of seconds to seek
|
||||
\param relative: Whether to seek from the current position or the start of the stream
|
||||
\return True on success, False if the codec does not support seeking. */
|
||||
virtual bool seek(const float& seconds, bool relative = false) = 0;
|
||||
|
||||
|
@ -143,6 +147,22 @@ namespace cAudio
|
|||
//! Returns the override for the doppler velocity vector
|
||||
virtual const cVector3 getDopplerVelocity() const = 0;
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//! Returns the number of effects at one time this source can support
|
||||
virtual unsigned int getNumEffectSlotsAvailable() const = 0;
|
||||
//! Attaches an EFX audio effect to this sound source to a specific slot
|
||||
//! Range (slot): 0 to getNumEffectSlotsAvailable()
|
||||
virtual bool attachEffect(unsigned int slot, IEffect* effect) = 0;
|
||||
//! Removes an EFX audio effect from this sound source
|
||||
//! Range (slot): 0 to getNumEffectSlotsAvailable()
|
||||
virtual void removeEffect(unsigned int slot) = 0;
|
||||
|
||||
//! Attaches an audio filter to this sound source that will operate on the direct feed, seperate from any effects
|
||||
virtual bool attachFilter(IFilter* filter) = 0;
|
||||
//! Removes the previously attached filter
|
||||
virtual void removeFilter() = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef IAUDIOEFFECTS_H
|
||||
#define IAUDIOEFFECTS_H
|
||||
|
||||
#include "IEffect.h"
|
||||
#include "IFilter.h"
|
||||
#include "cAudioDefines.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class IAudioEffects
|
||||
{
|
||||
public:
|
||||
IAudioEffects() {}
|
||||
virtual ~IAudioEffects() {}
|
||||
|
||||
virtual IEffect* createEffect() = 0;
|
||||
virtual IFilter* createFilter() = 0;
|
||||
|
||||
virtual unsigned int getMaxEffectsSupported() const = 0;
|
||||
virtual bool isEffectSupported(const EffectTypes& type) const = 0;
|
||||
virtual bool isFilterSupported(const FilterTypes& type) const = 0;
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! IAUDIOEFFECTS_H
|
|
@ -4,6 +4,7 @@
|
|||
#include "IListener.h"
|
||||
#include "cAudioDefines.h"
|
||||
#include "eAudioFormats.h"
|
||||
#include "IAudioEffects.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
|
@ -55,6 +56,7 @@ namespace cAudio
|
|||
|
||||
//!Returns an interface for the listener
|
||||
virtual IListener* getListener() = 0;
|
||||
virtual IAudioEffects* getEffects() = 0;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef IEFFECT_H
|
||||
#define IEFFECT_H
|
||||
|
||||
#include "IRefCounted.h"
|
||||
#include "IFilter.h"
|
||||
#include "IEffectParameters.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
enum EffectTypes
|
||||
{
|
||||
EET_NULL,
|
||||
EET_EAX_REVERB,
|
||||
EET_REVERB,
|
||||
EET_CHORUS,
|
||||
EET_DISTORTION,
|
||||
EET_ECHO,
|
||||
EET_FLANGER,
|
||||
EET_FREQUENCY_SHIFTER,
|
||||
EET_VOCAL_MORPHER,
|
||||
EET_PITCH_SHIFTER,
|
||||
EET_RING_MODULATOR,
|
||||
EET_AUTOWAH,
|
||||
EET_COMPRESSOR,
|
||||
EET_EQUALIZER,
|
||||
EET_COUNT
|
||||
};
|
||||
|
||||
class IEffect : public IRefCounted
|
||||
{
|
||||
public:
|
||||
IEffect() { }
|
||||
virtual ~IEffect() { }
|
||||
|
||||
virtual const EffectTypes& getType() const = 0;
|
||||
virtual void setType(const EffectTypes& type) = 0;
|
||||
|
||||
virtual const sEAXReverbParameters& getEAXReverbParameters() const = 0;
|
||||
virtual void setEAXReverbParameters(const sEAXReverbParameters& param) = 0;
|
||||
|
||||
virtual const sReverbParameters& getReverbParameters() const = 0;
|
||||
virtual void setReverbParameters(const sReverbParameters& param) = 0;
|
||||
|
||||
virtual const sChorusParameters& getChorusParameters() const = 0;
|
||||
virtual void setChorusParameters(const sChorusParameters& param) = 0;
|
||||
|
||||
virtual const sDistortionParameters& getDistortionParameters() const = 0;
|
||||
virtual void setDistortionParameters(const sDistortionParameters& param) = 0;
|
||||
|
||||
virtual const sEchoParameters& getEchoParameters() const = 0;
|
||||
virtual void setEchoParameters(const sEchoParameters& param) = 0;
|
||||
|
||||
virtual const sFlangerParameters& getFlangerParameters() const = 0;
|
||||
virtual void setFlangerParameters(const sFlangerParameters& param) = 0;
|
||||
|
||||
virtual const sFrequencyShiftParameters& getFrequencyShiftParameters() const = 0;
|
||||
virtual void setFrequencyShiftParameters(const sFrequencyShiftParameters& param) = 0;
|
||||
|
||||
virtual const sVocalMorpherParameters& getVocalMorpherParameters() const = 0;
|
||||
virtual void setVocalMorpherParameters(const sVocalMorpherParameters& param) = 0;
|
||||
|
||||
virtual const sPitchShifterParameters& getPitchShifterParameters() const = 0;
|
||||
virtual void setPitchShifterParameters(const sPitchShifterParameters& param) = 0;
|
||||
|
||||
virtual const sRingModulatorParameters& getRingModulatorParameters() const = 0;
|
||||
virtual void setRingModulatorParameters(const sRingModulatorParameters& param) = 0;
|
||||
|
||||
virtual const sAutowahParameters& getAutowahParameters() const = 0;
|
||||
virtual void setAutowahParameters(const sAutowahParameters& param) = 0;
|
||||
|
||||
virtual const sCompressorParameters& getCompressorParameters() const = 0;
|
||||
virtual void setCompressorParameters(const sCompressorParameters& param) = 0;
|
||||
|
||||
virtual const sEqualizerParameters& getEqualizerParameters() const = 0;
|
||||
virtual void setEqualizerParameters(const sEqualizerParameters& param) = 0;
|
||||
|
||||
virtual float getMasterVolume() const = 0;
|
||||
virtual void setMasterVolume(const float& volume) = 0;
|
||||
|
||||
virtual bool isIgnoringAttenuation() const = 0;
|
||||
virtual void ignoreAttenuation(const bool& ignore) = 0;
|
||||
|
||||
virtual IFilter* getFilter() const = 0;
|
||||
virtual void attachFilter(IFilter* filter) = 0;
|
||||
virtual void removeFilter() = 0;
|
||||
|
||||
virtual unsigned int getLastUpdated() const = 0;
|
||||
virtual bool isValid() const = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! IEFFECT_H
|
|
@ -0,0 +1,364 @@
|
|||
#ifndef IEFFECTPARAMETERS_H
|
||||
#define IEFFECTPARAMETERS_H
|
||||
|
||||
#include "cVector3.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
struct sEAXReverbParameters
|
||||
{
|
||||
sEAXReverbParameters(
|
||||
float density = 1.0f,
|
||||
float diffusion = 1.0f,
|
||||
float gain = 0.32f,
|
||||
float gainHF = 0.89f,
|
||||
float gainLF = 0.0f,
|
||||
float decayTime = 1.49f,
|
||||
float decayHFRatio = 0.83f,
|
||||
float decayLFRatio = 1.0f,
|
||||
float reflectionsGain = 0.05f,
|
||||
float reflectionsDelay = 0.007f,
|
||||
cVector3 reflectionsPan = cVector3(0.0f, 0.0f, 0.0f),
|
||||
float lateReverbGain = 1.26f,
|
||||
float lateReverbDelay = 0.011f,
|
||||
cVector3 lateReverbPan = cVector3(0.0f, 0.0f, 0.0f),
|
||||
float echoTime = 0.25f,
|
||||
float echoDepth = 0.0f,
|
||||
float modulationTime = 0.25f,
|
||||
float modulationDepth = 0.0f,
|
||||
float airAbsorptionGainHF = 0.994f,
|
||||
float hFReference = 5000.0f,
|
||||
float lFReference = 250.0f,
|
||||
float roomRolloffFactor = 0.0f,
|
||||
bool decayHFLimit = true) :
|
||||
Density(density), Diffusion(diffusion), Gain(gain), GainHF(gainHF), GainLF(gainLF),
|
||||
DecayTime(decayTime), DecayHFRatio(decayHFRatio), DecayLFRatio(decayLFRatio),
|
||||
ReflectionsGain(reflectionsGain), ReflectionsDelay(reflectionsDelay),
|
||||
ReflectionsPan(reflectionsPan), LateReverbGain(lateReverbGain),
|
||||
LateReverbDelay(lateReverbDelay), LateReverbPan(lateReverbPan),
|
||||
EchoTime(echoTime), EchoDepth(echoDepth),ModulationTime(modulationTime),
|
||||
ModulationDepth(modulationDepth), AirAbsorptionGainHF(airAbsorptionGainHF),
|
||||
HFReference(hFReference), LFReference(lFReference),
|
||||
RoomRolloffFactor(roomRolloffFactor), DecayHFLimit(decayHFLimit) { }
|
||||
|
||||
float Density;
|
||||
float Diffusion;
|
||||
float Gain;
|
||||
float GainHF;
|
||||
float GainLF;
|
||||
float DecayTime;
|
||||
float DecayHFRatio;
|
||||
float DecayLFRatio;
|
||||
float ReflectionsGain;
|
||||
float ReflectionsDelay;
|
||||
cVector3 ReflectionsPan;
|
||||
float LateReverbGain;
|
||||
float LateReverbDelay;
|
||||
cVector3 LateReverbPan;
|
||||
float EchoTime;
|
||||
float EchoDepth;
|
||||
float ModulationTime;
|
||||
float ModulationDepth;
|
||||
float AirAbsorptionGainHF;
|
||||
float HFReference;
|
||||
float LFReference;
|
||||
float RoomRolloffFactor;
|
||||
bool DecayHFLimit;
|
||||
};
|
||||
|
||||
struct sReverbParameters
|
||||
{
|
||||
sReverbParameters(
|
||||
float density = 1.0f,
|
||||
float diffusion = 1.0f,
|
||||
float gain = 0.32f,
|
||||
float gainHF = 0.89f,
|
||||
float decayTime = 1.49f,
|
||||
float decayHFRatio = 0.83f,
|
||||
float reflectionsGain = 0.05f,
|
||||
float reflectionsDelay = 0.007f,
|
||||
float lateReverbGain = 1.26f,
|
||||
float lateReverbDelay = 0.011f,
|
||||
float airAbsorptionGainHF = 0.994f,
|
||||
float roomRolloffFactor = 0.0f,
|
||||
bool decayHFLimit = true) :
|
||||
Density(density), Diffusion(diffusion), Gain(gain), GainHF(gainHF),
|
||||
DecayTime(decayTime), DecayHFRatio(decayHFRatio),
|
||||
ReflectionsGain(reflectionsGain), ReflectionsDelay(reflectionsDelay),
|
||||
LateReverbGain(lateReverbGain), LateReverbDelay(lateReverbDelay),
|
||||
AirAbsorptionGainHF(airAbsorptionGainHF), RoomRolloffFactor(roomRolloffFactor),
|
||||
DecayHFLimit(decayHFLimit) { }
|
||||
|
||||
float Density;
|
||||
float Diffusion;
|
||||
float Gain;
|
||||
float GainHF;
|
||||
float DecayTime;
|
||||
float DecayHFRatio;
|
||||
float ReflectionsGain;
|
||||
float ReflectionsDelay;
|
||||
float LateReverbGain;
|
||||
float LateReverbDelay;
|
||||
float AirAbsorptionGainHF;
|
||||
float RoomRolloffFactor;
|
||||
bool DecayHFLimit;
|
||||
};
|
||||
|
||||
struct sChorusParameters
|
||||
{
|
||||
enum ChorusWaveform
|
||||
{
|
||||
ECW_SINUSOID,
|
||||
ECW_TRIANGLE,
|
||||
ECW_COUNT
|
||||
};
|
||||
sChorusParameters(
|
||||
ChorusWaveform waveform = ECW_TRIANGLE,
|
||||
int phase = 90,
|
||||
float rate = 1.1f,
|
||||
float depth = 0.1f,
|
||||
float feedback = 0.25f,
|
||||
float delay = 0.016f) :
|
||||
Waveform(waveform), Phase(phase), Rate(rate), Depth(depth), Feedback(feedback),
|
||||
Delay(delay) { }
|
||||
|
||||
ChorusWaveform Waveform;
|
||||
int Phase;
|
||||
float Rate;
|
||||
float Depth;
|
||||
float Feedback;
|
||||
float Delay;
|
||||
};
|
||||
|
||||
struct sDistortionParameters
|
||||
{
|
||||
sDistortionParameters(
|
||||
float edge = 0.2f,
|
||||
float gain = 0.05f,
|
||||
float lowpassCutoff = 8000.0f,
|
||||
float eqCenter = 3600.0f,
|
||||
float eqBandwidth = 3600.0f) :
|
||||
Edge(edge), Gain(gain), LowpassCutoff(lowpassCutoff), EqCenter(eqCenter),
|
||||
EqBandwidth(eqBandwidth) { }
|
||||
|
||||
float Edge;
|
||||
float Gain;
|
||||
float LowpassCutoff;
|
||||
float EqCenter;
|
||||
float EqBandwidth;
|
||||
};
|
||||
|
||||
struct sEchoParameters
|
||||
{
|
||||
sEchoParameters(
|
||||
float delay = 0.1f,
|
||||
float lRDelay = 0.1f,
|
||||
float damping = 0.5f,
|
||||
float feedback = 0.5f,
|
||||
float spread = -1.0f) :
|
||||
Delay(delay), LRDelay(lRDelay), Damping(damping), Feedback(feedback),
|
||||
Spread(spread) { }
|
||||
|
||||
float Delay;
|
||||
float LRDelay;
|
||||
float Damping;
|
||||
float Feedback;
|
||||
float Spread;
|
||||
};
|
||||
|
||||
struct sFlangerParameters
|
||||
{
|
||||
enum FlangerWaveform
|
||||
{
|
||||
EFW_SINUSOID,
|
||||
EFW_TRIANGLE,
|
||||
EFW_COUNT
|
||||
};
|
||||
sFlangerParameters(
|
||||
FlangerWaveform waveform = EFW_TRIANGLE,
|
||||
int phase = 0,
|
||||
float rate = 0.27f,
|
||||
float depth = 1.0f,
|
||||
float feedback = -0.5f,
|
||||
float delay = 0.002f) :
|
||||
Waveform(waveform), Phase(phase), Rate(rate), Depth(depth), Feedback(feedback),
|
||||
Delay(delay) { }
|
||||
|
||||
FlangerWaveform Waveform;
|
||||
int Phase;
|
||||
float Rate;
|
||||
float Depth;
|
||||
float Feedback;
|
||||
float Delay;
|
||||
};
|
||||
|
||||
struct sFrequencyShiftParameters
|
||||
{
|
||||
enum ShiftDirection
|
||||
{
|
||||
ESD_DOWN,
|
||||
ESD_UP,
|
||||
ESD_OFF,
|
||||
ESD_COUNT
|
||||
};
|
||||
sFrequencyShiftParameters(
|
||||
float frequency = 0.0f,
|
||||
ShiftDirection left = ESD_DOWN,
|
||||
ShiftDirection right = ESD_DOWN) :
|
||||
Frequency(frequency), Left(left), Right(right) { }
|
||||
|
||||
float Frequency;
|
||||
ShiftDirection Left;
|
||||
ShiftDirection Right;
|
||||
};
|
||||
|
||||
struct sVocalMorpherParameters
|
||||
{
|
||||
enum MorpherPhoneme
|
||||
{
|
||||
EMP_A,
|
||||
EMP_E,
|
||||
EMP_I,
|
||||
EMP_O,
|
||||
EMP_U,
|
||||
EMP_AA,
|
||||
EMP_AE,
|
||||
EMP_AH,
|
||||
EMP_AO,
|
||||
EMP_EH,
|
||||
EMP_ER,
|
||||
EMP_IH,
|
||||
EMP_IY,
|
||||
EMP_UH,
|
||||
EMP_UW,
|
||||
EMP_B,
|
||||
EMP_D,
|
||||
EMP_F,
|
||||
EMP_G,
|
||||
EMP_J,
|
||||
EMP_K,
|
||||
EMP_L,
|
||||
EMP_M,
|
||||
EMP_N,
|
||||
EMP_P,
|
||||
EMP_R,
|
||||
EMP_S,
|
||||
EMP_T,
|
||||
EMP_V,
|
||||
EMP_Z,
|
||||
ESD_COUNT
|
||||
};
|
||||
|
||||
enum MorpherWaveform
|
||||
{
|
||||
EMW_SINUSOID,
|
||||
EMW_TRIANGLE,
|
||||
EMW_SAW,
|
||||
EMW_COUNT
|
||||
};
|
||||
sVocalMorpherParameters(
|
||||
MorpherPhoneme phonemeA = EMP_A,
|
||||
MorpherPhoneme phonemeB = EMP_ER,
|
||||
int phonemeACoarseTune = 0,
|
||||
int phonemeBCoarseTune = 0,
|
||||
MorpherWaveform waveform = EMW_SINUSOID,
|
||||
float rate = 1.41f) :
|
||||
PhonemeA(phonemeA), PhonemeB(phonemeB), PhonemeACoarseTune(phonemeACoarseTune),
|
||||
PhonemeBCoarseTune(phonemeBCoarseTune), Waveform(waveform), Rate(rate) { }
|
||||
|
||||
MorpherPhoneme PhonemeA;
|
||||
MorpherPhoneme PhonemeB;
|
||||
int PhonemeACoarseTune;
|
||||
int PhonemeBCoarseTune;
|
||||
MorpherWaveform Waveform;
|
||||
float Rate;
|
||||
};
|
||||
|
||||
struct sPitchShifterParameters
|
||||
{
|
||||
sPitchShifterParameters(
|
||||
int coarseTune = 12,
|
||||
int fineTune = 0) :
|
||||
CoarseTune(coarseTune), FineTune(fineTune) { }
|
||||
|
||||
int CoarseTune;
|
||||
int FineTune;
|
||||
};
|
||||
|
||||
struct sRingModulatorParameters
|
||||
{
|
||||
enum ModulatorWaveform
|
||||
{
|
||||
EMW_SINUSOID,
|
||||
EMW_SAW,
|
||||
EMW_SQUARE,
|
||||
EMW_COUNT
|
||||
};
|
||||
sRingModulatorParameters(
|
||||
float frequency = 440.0f,
|
||||
float highPassCutoff = 800.0f,
|
||||
ModulatorWaveform waveform = EMW_SINUSOID) :
|
||||
Frequency(frequency), HighPassCutoff(highPassCutoff), Waveform(waveform) { }
|
||||
|
||||
float Frequency;
|
||||
float HighPassCutoff;
|
||||
ModulatorWaveform Waveform;
|
||||
};
|
||||
|
||||
struct sAutowahParameters
|
||||
{
|
||||
sAutowahParameters(
|
||||
float attackTime = 0.06f,
|
||||
float releaseTime = 0.06f,
|
||||
float resonance = 1000.0f,
|
||||
float peakGain = 11.22f) :
|
||||
AttackTime(attackTime), ReleaseTime(releaseTime), Resonance(resonance),
|
||||
PeakGain(peakGain) { }
|
||||
|
||||
float AttackTime;
|
||||
float ReleaseTime;
|
||||
float Resonance;
|
||||
float PeakGain;
|
||||
};
|
||||
|
||||
struct sCompressorParameters
|
||||
{
|
||||
sCompressorParameters(
|
||||
bool active = true) :
|
||||
Active(active) { }
|
||||
|
||||
bool Active;
|
||||
};
|
||||
|
||||
struct sEqualizerParameters
|
||||
{
|
||||
sEqualizerParameters(
|
||||
float lowGain = 1.0f,
|
||||
float lowCutoff = 200.0f,
|
||||
float mid1Gain = 1.0f,
|
||||
float mid1Center = 500.0f,
|
||||
float mid1Width = 1.0f,
|
||||
float mid2Gain = 1.0f,
|
||||
float mid2Center = 3000.0f,
|
||||
float mid2Width = 1.0f,
|
||||
float highGain = 1.0f,
|
||||
float highCutoff = 6000.0f) :
|
||||
LowGain(lowGain), LowCutoff(lowCutoff), Mid1Gain(mid1Gain),
|
||||
Mid1Center(mid1Center), Mid1Width(mid1Width), Mid2Gain(mid2Gain),
|
||||
Mid2Center(mid2Center), Mid2Width(mid2Width), HighGain(highGain),
|
||||
HighCutoff(highCutoff) { }
|
||||
|
||||
float LowGain;
|
||||
float LowCutoff;
|
||||
float Mid1Gain;
|
||||
float Mid1Center;
|
||||
float Mid1Width;
|
||||
float Mid2Gain;
|
||||
float Mid2Center;
|
||||
float Mid2Width;
|
||||
float HighGain;
|
||||
float HighCutoff;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! IEFFECTPARAMETERS_H
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef IFILTER_H
|
||||
#define IFILTER_H
|
||||
|
||||
#include "IRefCounted.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
enum FilterTypes
|
||||
{
|
||||
EFT_NULL,
|
||||
EFT_LOWPASS,
|
||||
EFT_HIGHPASS,
|
||||
EFT_BANDPASS,
|
||||
EFT_COUNT
|
||||
};
|
||||
|
||||
class IFilter : public IRefCounted
|
||||
{
|
||||
public:
|
||||
IFilter() { }
|
||||
virtual ~IFilter() { }
|
||||
|
||||
virtual const FilterTypes& getType() const = 0;
|
||||
virtual void setType(const FilterTypes& type) = 0;
|
||||
|
||||
virtual float getVolume() const = 0;
|
||||
virtual void setVolume(const float& volume) = 0;
|
||||
|
||||
virtual float getLowFrequencyVolume() const = 0;
|
||||
virtual void setLowFrequencyVolume(const float& volumeLF) = 0;
|
||||
|
||||
virtual float getHighFrequencyVolume() const = 0;
|
||||
virtual void setHighFrequencyVolume(const float& volumeHF) = 0;
|
||||
|
||||
virtual unsigned int getLastUpdated() const = 0;
|
||||
virtual bool isValid() const = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //! IFILTER_H
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#ifndef ILISTENER_H
|
||||
#define ILISTENER_H
|
||||
|
||||
#include "cVector3.h"
|
||||
#include "cAudioDefines.h"
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
|
@ -40,6 +40,13 @@ namespace cAudio
|
|||
//!Returns the global volume modifier for all sources
|
||||
virtual float getMasterVolume(void) const = 0;
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//!Sets the meters per user world unit for use with sound effects
|
||||
virtual void setMetersPerUnit(const float& meters) = 0;
|
||||
//!Returns the meters per user world unit for use with sound effects
|
||||
virtual float getMetersPerUnit(void) const = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -5,27 +5,27 @@
|
|||
#ifndef CAUDIO_STATIC_LIB
|
||||
|
||||
#ifdef CAUDIO_EXPORTS
|
||||
#define CAUDIO_API __declspec(dllexport)
|
||||
#define CAUDIO_API __declspec(dllexport)
|
||||
#else
|
||||
#define CAUDIO_API//! __declspec(dllimport)
|
||||
#define CAUDIO_API//! __declspec(dllimport)
|
||||
#endif // CAUDIO_EXPORTS
|
||||
|
||||
#else
|
||||
#define CAUDIO_API
|
||||
#define CAUDIO_API
|
||||
#endif // CAUDIO_STATIC_LIB
|
||||
|
||||
//////////////////////////
|
||||
//Global Library Settings
|
||||
//////////////////////////
|
||||
|
||||
//Define for making the entire library Thread Safe, comment out to disable
|
||||
//Will also disable internal threading by the library
|
||||
#define CAUDIO_MAKE_THREAD_SAFE
|
||||
|
||||
//Define for compiling with EAX
|
||||
#define CAUDIO_EAX_ENABLED
|
||||
|
||||
#ifdef CAUDIO_MAKE_THREAD_SAFE
|
||||
//Define enables threading for the main update loop. Disable to run the internal update loop yourself
|
||||
//NOTE: Internal threading should NOT be used if the library is not thread safe!
|
||||
#define CAUDIO_USE_INTERNAL_THREAD
|
||||
|
||||
//Define enables threading for the main update loop. Disable to run the internal update loop yourself
|
||||
//NOTE: Internal threading should NOT be used if the library is not thread safe!
|
||||
#define CAUDIO_USE_INTERNAL_THREAD
|
||||
#endif
|
||||
|
||||
//These defines control which of the default audio codecs are compiled into the library
|
||||
|
@ -33,4 +33,25 @@
|
|||
#define CAUDIO_COMPILE_WITH_WAV_DECODER
|
||||
#define CAUDIO_COMPILE_WITH_RAW_DECODER
|
||||
|
||||
////////////////////////
|
||||
//Audio Source Settings
|
||||
////////////////////////
|
||||
|
||||
//Size of the internal buffer per source for audio data (total amount buffered is CAUDIO_SOURCE_BUFFER_SIZE * CAUDIO_SOURCE_NUM_BUFFERS)
|
||||
#define CAUDIO_SOURCE_BUFFER_SIZE ( 1024 * 64 )
|
||||
//Number of internal buffers to cycle through per source (Note: using only 1 leads to choppy sound or premature ending of sources)
|
||||
#define CAUDIO_SOURCE_NUM_BUFFERS 3
|
||||
|
||||
/////////////////////////
|
||||
//Audio Effects Settings
|
||||
/////////////////////////
|
||||
|
||||
//Comment out to remove all EFX support from the library
|
||||
#define CAUDIO_EFX_ENABLED
|
||||
|
||||
#ifdef CAUDIO_EFX_ENABLED
|
||||
//Max number of effects that can be attached to a single sound source
|
||||
#define CAUDIO_SOURCE_MAX_EFFECT_SLOTS 4
|
||||
#endif
|
||||
|
||||
#endif //! CAUDIODEFINES_H
|
Binary file not shown.
|
@ -58,7 +58,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="cAudio.lib"
|
||||
AdditionalLibraryDirectories=""..\..\bin\win32-visual""
|
||||
AdditionalLibraryDirectories=""..\..\lib\win32-visual""
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
|
|
Loading…
Reference in New Issue