summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/AudioCommon')
-rw-r--r--Source/Core/AudioCommon/AudioCommon.vcxproj72
-rw-r--r--Source/Core/AudioCommon/AudioCommon.vcxproj.filters4
-rw-r--r--Source/Core/AudioCommon/CMakeLists.txt4
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommon.cpp40
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommon.h3
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.cpp70
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.h52
-rw-r--r--Source/Core/AudioCommon/Src/DPL2Decoder.cpp400
-rw-r--r--Source/Core/AudioCommon/Src/DPL2Decoder.h24
-rw-r--r--Source/Core/AudioCommon/Src/Mixer.h5
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.cpp225
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.h26
-rw-r--r--Source/Core/AudioCommon/Src/PulseAudioStream.cpp287
-rw-r--r--Source/Core/AudioCommon/Src/PulseAudioStream.h23
-rw-r--r--Source/Core/AudioCommon/Src/WaveFile.cpp31
-rw-r--r--Source/Core/AudioCommon/Src/WaveFile.h4
-rw-r--r--Source/Core/AudioCommon/Src/aldlist.cpp6
17 files changed, 788 insertions, 488 deletions
diff --git a/Source/Core/AudioCommon/AudioCommon.vcxproj b/Source/Core/AudioCommon/AudioCommon.vcxproj
index 0c5f256c19..abb5dbf505 100644
--- a/Source/Core/AudioCommon/AudioCommon.vcxproj
+++ b/Source/Core/AudioCommon/AudioCommon.vcxproj
@@ -109,78 +109,89 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouchD.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win32;..\..\..\Externals\SoundTouch\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouchD.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win64;..\..\..\Externals\SoundTouch\Win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouch.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win32;..\..\..\Externals\SoundTouch\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouch.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win32;..\..\..\Externals\SoundTouch\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouch.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win64;..\..\..\Externals\SoundTouch\Win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>..\Common\Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\Core\Src;..\Common\Src;..\..\..\Externals;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
- <Lib />
+ <Lib>
+ <AdditionalDependencies>SoundTouch.lib;OpenAL32.lib;dsound.lib;dxerr.lib</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\Externals\OpenAL\Win64;..\..\..\Externals\SoundTouch\Win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="Src\aldlist.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
+ <ClCompile Include="Src\aldlist.cpp" />
<ClCompile Include="Src\AOSoundStream.cpp" />
<ClCompile Include="Src\AudioCommon.cpp" />
- <ClCompile Include="Src\AudioCommonConfig.cpp" />
+ <ClCompile Include="Src\DPL2Decoder.cpp" />
<ClCompile Include="Src\DSoundStream.cpp" />
<ClCompile Include="Src\Mixer.cpp" />
<ClCompile Include="Src\NullSoundStream.cpp" />
@@ -189,17 +200,10 @@
<ClCompile Include="Src\XAudio2Stream.cpp" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="Src\aldlist.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
+ <ClInclude Include="Src\aldlist.h" />
<ClInclude Include="Src\AOSoundStream.h" />
<ClInclude Include="Src\AudioCommon.h" />
- <ClInclude Include="Src\AudioCommonConfig.h" />
+ <ClInclude Include="Src\DPL2Decoder.h" />
<ClInclude Include="Src\DSoundStream.h" />
<ClInclude Include="Src\Mixer.h" />
<ClInclude Include="Src\NullSoundStream.h" />
@@ -212,6 +216,14 @@
<None Include="CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\..\Externals\SoundTouch\SoundTouch.vcxproj">
+ <Project>{68a5dd20-7057-448b-8fe0-b6ac8d205509}</Project>
+ <Private>true</Private>
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
+ </ProjectReference>
<ProjectReference Include="..\Common\Common.vcxproj">
<Project>{c87a4178-44f6-49b2-b7aa-c79af1b8c534}</Project>
<Private>true</Private>
diff --git a/Source/Core/AudioCommon/AudioCommon.vcxproj.filters b/Source/Core/AudioCommon/AudioCommon.vcxproj.filters
index 7e098ecb85..30ff35a073 100644
--- a/Source/Core/AudioCommon/AudioCommon.vcxproj.filters
+++ b/Source/Core/AudioCommon/AudioCommon.vcxproj.filters
@@ -3,7 +3,6 @@
<ItemGroup>
<ClCompile Include="Src\aldlist.cpp" />
<ClCompile Include="Src\AudioCommon.cpp" />
- <ClCompile Include="Src\AudioCommonConfig.cpp" />
<ClCompile Include="Src\Mixer.cpp" />
<ClCompile Include="Src\WaveFile.cpp" />
<ClCompile Include="Src\AOSoundStream.cpp">
@@ -21,11 +20,11 @@
<ClCompile Include="Src\NullSoundStream.cpp">
<Filter>SoundStreams</Filter>
</ClCompile>
+ <ClCompile Include="Src\DPL2Decoder.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\aldlist.h" />
<ClInclude Include="Src\AudioCommon.h" />
- <ClInclude Include="Src\AudioCommonConfig.h" />
<ClInclude Include="Src\Mixer.h" />
<ClInclude Include="Src\SoundStream.h" />
<ClInclude Include="Src\WaveFile.h" />
@@ -44,6 +43,7 @@
<ClInclude Include="Src\XAudio2Stream.h">
<Filter>SoundStreams</Filter>
</ClInclude>
+ <ClInclude Include="Src\DPL2Decoder.h" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
diff --git a/Source/Core/AudioCommon/CMakeLists.txt b/Source/Core/AudioCommon/CMakeLists.txt
index be8c58d14a..3b6d0cea4d 100644
--- a/Source/Core/AudioCommon/CMakeLists.txt
+++ b/Source/Core/AudioCommon/CMakeLists.txt
@@ -1,5 +1,5 @@
set(SRCS Src/AudioCommon.cpp
- Src/AudioCommonConfig.cpp
+ Src/DPL2Decoder.cpp
Src/Mixer.cpp
Src/WaveFile.cpp
Src/NullSoundStream.cpp)
@@ -18,7 +18,7 @@ endif(AO_FOUND)
if(OPENAL_FOUND)
set(SRCS ${SRCS} Src/OpenALStream.cpp Src/aldlist.cpp)
- set(LIBS ${LIBS} ${OPENAL_LIBRARY})
+ set(LIBS ${LIBS} ${OPENAL_LIBRARY} SoundTouch )
endif(OPENAL_FOUND)
if(PULSEAUDIO_FOUND)
diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp
index 8a568448a3..e14b9ac45e 100644
--- a/Source/Core/AudioCommon/Src/AudioCommon.cpp
+++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp
@@ -27,6 +27,10 @@
#include "OpenALStream.h"
#include "PulseAudioStream.h"
#include "../../Core/Src/Movie.h"
+#include "../../Core/Src/ConfigManager.h"
+
+// This shouldn't be a global, at least not here.
+SoundStream *soundStream;
namespace AudioCommon
{
@@ -34,7 +38,7 @@ namespace AudioCommon
{
// TODO: possible memleak with mixer
- std::string backend = ac_Config.sBackend;
+ std::string backend = SConfig::GetInstance().sBackend;
if (backend == BACKEND_OPENAL && OpenALStream::isValid())
soundStream = new OpenALStream(mixer);
else if (backend == BACKEND_NULLSOUND && NullSound::isValid())
@@ -54,10 +58,10 @@ namespace AudioCommon
if (soundStream != NULL)
{
- ac_Config.Update();
+ UpdateSoundStream();
if (soundStream->Start())
{
- if (ac_Config.m_DumpAudio)
+ if (SConfig::GetInstance().m_DumpAudio)
{
std::string audio_file_name = File::GetUserPath(D_DUMPAUDIO_IDX) + "audiodump.wav";
File::CreateFullPath(audio_file_name);
@@ -82,7 +86,7 @@ namespace AudioCommon
if (soundStream)
{
soundStream->Stop();
- if (ac_Config.m_DumpAudio)
+ if (SConfig::GetInstance().m_DumpAudio)
soundStream->GetMixer()->StopLogAudio();
//soundStream->StopLogAudio();
delete soundStream;
@@ -96,22 +100,22 @@ namespace AudioCommon
{
std::vector<std::string> backends;
- if (NullSound::isValid())
+ if (NullSound::isValid())
backends.push_back(BACKEND_NULLSOUND);
- if (DSound::isValid())
+ if (DSound::isValid())
backends.push_back(BACKEND_DIRECTSOUND);
- if (XAudio2::isValid())
+ if (XAudio2::isValid())
backends.push_back(BACKEND_XAUDIO2);
- if (OpenALStream::isValid())
- backends.push_back(BACKEND_OPENAL);
- if (AOSound::isValid())
+ if (AOSound::isValid())
backends.push_back(BACKEND_AOSOUND);
- if (AlsaSound::isValid())
+ if (AlsaSound::isValid())
backends.push_back(BACKEND_ALSA);
- if (CoreAudioSound::isValid())
+ if (CoreAudioSound::isValid())
backends.push_back(BACKEND_COREAUDIO);
- if (PulseAudio::isValid())
+ if (PulseAudio::isValid())
backends.push_back(BACKEND_PULSEAUDIO);
+ if (OpenALStream::isValid())
+ backends.push_back(BACKEND_OPENAL);
return backends;
}
@@ -122,7 +126,7 @@ namespace AudioCommon
{
return true;
}
- return ac_Config.m_EnableJIT;
+ return SConfig::GetInstance().m_EnableJIT;
}
void PauseAndLock(bool doLock, bool unpauseOnUnlock)
@@ -143,4 +147,12 @@ namespace AudioCommon
}
}
}
+ void UpdateSoundStream()
+ {
+ if (soundStream)
+ {
+ soundStream->GetMixer()->SetThrottle(SConfig::GetInstance().m_Framelimit == 2);
+ soundStream->SetVolume(SConfig::GetInstance().m_Volume);
+ }
+ }
}
diff --git a/Source/Core/AudioCommon/Src/AudioCommon.h b/Source/Core/AudioCommon/Src/AudioCommon.h
index e7a111b0a1..b7b32e7498 100644
--- a/Source/Core/AudioCommon/Src/AudioCommon.h
+++ b/Source/Core/AudioCommon/Src/AudioCommon.h
@@ -19,14 +19,12 @@
#define _AUDIO_COMMON_H_
#include "Common.h"
-#include "AudioCommonConfig.h"
#include "SoundStream.h"
class CMixer;
extern SoundStream *soundStream;
-extern AudioCommonConfig ac_Config;
// UDSPControl
union UDSPControl
@@ -60,6 +58,7 @@ namespace AudioCommon
std::vector<std::string> GetSoundBackends();
bool UseJIT();
void PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
+ void UpdateSoundStream();
}
#endif // _AUDIO_COMMON_H_
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
deleted file mode 100644
index 08902e1c3f..0000000000
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2003 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "AudioCommon.h"
-#include "CommonPaths.h"
-#include "FileUtil.h"
-#include "../../Core/Src/ConfigManager.h"
-
-AudioCommonConfig ac_Config;
-
-// This shouldn't be a global, at least not here.
-SoundStream *soundStream;
-
-// Load from given file
-void AudioCommonConfig::Load()
-{
- IniFile file;
- file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
-
- file.Get("Config", "EnableJIT", &m_EnableJIT, true);
- file.Get("Config", "DumpAudio", &m_DumpAudio, false);
-#if defined __linux__ && HAVE_ALSA
- file.Get("Config", "Backend", &sBackend, BACKEND_ALSA);
-#elif defined __APPLE__
- file.Get("Config", "Backend", &sBackend, BACKEND_COREAUDIO);
-#elif defined _WIN32
- file.Get("Config", "Backend", &sBackend, BACKEND_DIRECTSOUND);
-#else
- file.Get("Config", "Backend", &sBackend, BACKEND_NULLSOUND);
-#endif
- file.Get("Config", "Frequency", &iFrequency, 48000);
- file.Get("Config", "Volume", &m_Volume, 100);
-}
-
-// Set the values for the file
-void AudioCommonConfig::SaveSettings()
-{
- IniFile file;
- file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
-
- file.Set("Config", "EnableJIT", m_EnableJIT);
- file.Set("Config", "DumpAudio", m_DumpAudio);
- file.Set("Config", "Backend", sBackend);
- file.Set("Config", "Frequency", iFrequency);
- file.Set("Config", "Volume", m_Volume);
-
- file.Save(File::GetUserPath(F_DSPCONFIG_IDX));
-}
-
-// Update according to the values (stream/mixer)
-void AudioCommonConfig::Update() {
- if (soundStream) {
- soundStream->GetMixer()->SetThrottle(SConfig::GetInstance().m_Framelimit == 2);
- soundStream->SetVolume(m_Volume);
- }
-}
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.h b/Source/Core/AudioCommon/Src/AudioCommonConfig.h
deleted file mode 100644
index 76c50c6408..0000000000
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2003 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#ifndef _AUDIO_COMMON_CONFIG_H_
-#define _AUDIO_COMMON_CONFIG_H_
-
-#include <string>
-#include "IniFile.h"
-
-// Backend Types
-#define BACKEND_NULLSOUND "No audio output"
-#define BACKEND_ALSA "ALSA"
-#define BACKEND_AOSOUND "AOSound"
-#define BACKEND_COREAUDIO "CoreAudio"
-#define BACKEND_DIRECTSOUND "DSound"
-#define BACKEND_OPENAL "OpenAL"
-#define BACKEND_PULSEAUDIO "Pulse"
-#define BACKEND_XAUDIO2 "XAudio2"
-
-struct AudioCommonConfig
-{
- bool m_EnableJIT;
- bool m_DumpAudio;
- int m_Volume;
- std::string sBackend;
- int iFrequency;
-
- // Load from given file
- void Load();
-
- // Self explanatory
- void SaveSettings();
-
- // Update according to the values (stream/mixer)
- void Update();
-};
-
-#endif //AUDIO_COMMON_CONFIG
diff --git a/Source/Core/AudioCommon/Src/DPL2Decoder.cpp b/Source/Core/AudioCommon/Src/DPL2Decoder.cpp
new file mode 100644
index 0000000000..a5d2720878
--- /dev/null
+++ b/Source/Core/AudioCommon/Src/DPL2Decoder.cpp
@@ -0,0 +1,400 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Dolby Pro Logic 2 decoder from ffdshow-tryout
+// * Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
+// * Copyright (c) 2004-2006 Milan Cutka
+// * based on mplayer HRTF plugin by ylai
+
+#include <functional>
+#include <vector>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "DPL2Decoder.h"
+
+#define M_PI 3.14159265358979323846
+#define M_SQRT1_2 0.70710678118654752440
+
+int olddelay = -1;
+unsigned int oldfreq = 0;
+unsigned int dlbuflen;
+int cyc_pos;
+float l_fwr, r_fwr, lpr_fwr, lmr_fwr;
+std::vector<float> fwrbuf_l, fwrbuf_r;
+float adapt_l_gain, adapt_r_gain, adapt_lpr_gain, adapt_lmr_gain;
+std::vector<float> lf, rf, lr, rr, cf, cr;
+float LFE_buf[256];
+unsigned int lfe_pos;
+float *filter_coefs_lfe;
+unsigned int len125;
+
+template<class T,class _ftype_t> static _ftype_t dotproduct(int count,const T *buf,const _ftype_t *coefficients)
+{
+ float sum0=0,sum1=0,sum2=0,sum3=0;
+ for (;count>=4;buf+=4,coefficients+=4,count-=4)
+ {
+ sum0+=buf[0]*coefficients[0];
+ sum1+=buf[1]*coefficients[1];
+ sum2+=buf[2]*coefficients[2];
+ sum3+=buf[3]*coefficients[3];
+ }
+ while (count--) sum0+= *buf++ * *coefficients++;
+ return sum0+sum1+sum2+sum3;
+}
+
+template<class T> static T firfilter(const T *buf, int pos, int len, int count, const float *coefficients)
+{
+ int count1, count2;
+
+ if (pos >= count)
+ {
+ pos -= count;
+ count1 = count; count2 = 0;
+ }
+ else
+ {
+ count2 = pos;
+ count1 = count - pos;
+ pos = len - count1;
+ }
+
+ // high part of window
+ const T *ptr = &buf[pos];
+
+ float r1=dotproduct(count1,ptr,coefficients);coefficients+=count1;
+ float r2=dotproduct(count2,buf,coefficients);
+ return T(r1+r2);
+}
+
+template<class T> inline const T& limit(const T& val, const T& min, const T& max)
+{
+ if (val < min) {
+ return min;
+ } else if (val > max) {
+ return max;
+ } else {
+ return val;
+ }
+}
+
+/*
+// Hamming
+// 2*pi*k
+// w(k) = 0.54 - 0.46*cos(------), where 0 <= k < N
+// N-1
+//
+// n window length
+// w buffer for the window parameters
+*/
+void hamming(int n, float* w)
+{
+ int i;
+ float k = float(2*M_PI/((float)(n-1))); // 2*pi/(N-1)
+
+ // Calculate window coefficients
+ for (i=0; i<n; i++)
+ *w++ = float(0.54 - 0.46*cos(k*(float)i));
+}
+
+/******************************************************************************
+* FIR filter design
+******************************************************************************/
+
+/* Design FIR filter using the Window method
+
+n filter length must be odd for HP and BS filters
+w buffer for the filter taps (must be n long)
+fc cutoff frequencies (1 for LP and HP, 2 for BP and BS)
+0 < fc < 1 where 1 <=> Fs/2
+flags window and filter type as defined in filter.h
+variables are ored together: i.e. LP|HAMMING will give a
+low pass filter designed using a hamming window
+opt beta constant used only when designing using kaiser windows
+
+returns 0 if OK, -1 if fail
+*/
+float* design_fir(unsigned int *n, float* fc, float opt)
+{
+ unsigned int o = *n & 1; // Indicator for odd filter length
+ unsigned int end = ((*n + 1) >> 1) - o; // Loop end
+ unsigned int i; // Loop index
+
+ float k1 = 2 * float(M_PI); // 2*pi*fc1
+ float k2 = 0.5f * (float)(1 - o);// Constant used if the filter has even length
+ float g = 0.0f; // Gain
+ float t1; // Temporary variables
+ float fc1; // Cutoff frequencies
+
+ // Sanity check
+ if(*n==0) return NULL;
+ fc[0]=limit(fc[0],float(0.001),float(1));
+
+ float *w=(float*)calloc(sizeof(float),*n);
+
+ // Get window coefficients
+ hamming(*n,w);
+
+ fc1=*fc;
+ // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2
+ fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25f;
+ k1 *= fc1;
+
+ // Low pass filter
+
+ // If the filter length is odd, there is one point which is exactly
+ // in the middle. The value at this point is 2*fCutoff*sin(x)/x,
+ // where x is zero. To make sure nothing strange happens, we set this
+ // value separately.
+ if (o)
+ {
+ w[end] = fc1 * w[end] * 2.0f;
+ g=w[end];
+ }
+
+ // Create filter
+ for (i=0 ; i<end ; i++)
+ {
+ t1 = (float)(i+1) - k2;
+ w[end-i-1] = w[*n-end+i] = float(w[end-i-1] * sin(k1 * t1)/(M_PI * t1)); // Sinc
+ g += 2*w[end-i-1]; // Total gain in filter
+ }
+
+
+ // Normalize gain
+ g=1/g;
+ for (i=0; i<*n; i++)
+ w[i] *= g;
+
+ return w;
+}
+
+void onSeek(void)
+{
+ l_fwr = r_fwr = lpr_fwr = lmr_fwr = 0;
+ std::fill(fwrbuf_l.begin(), fwrbuf_l.end(), 0.0f);
+ std::fill(fwrbuf_r.begin(), fwrbuf_r.end(), 0.0f);
+ adapt_l_gain = adapt_r_gain = adapt_lpr_gain = adapt_lmr_gain = 0;
+ std::fill(lf.begin(), lf.end(), 0.0f);
+ std::fill(rf.begin(), rf.end(), 0.0f);
+ std::fill(lr.begin(), lr.end(), 0.0f);
+ std::fill(rr.begin(), rr.end(), 0.0f);
+ std::fill(cf.begin(), cf.end(), 0.0f);
+ std::fill(cr.begin(), cr.end(), 0.0f);
+ lfe_pos = 0;
+ memset(LFE_buf, 0, sizeof(LFE_buf));
+}
+
+void done(void)
+{
+ onSeek();
+ if (filter_coefs_lfe)
+ {
+ free(filter_coefs_lfe);
+ }
+ filter_coefs_lfe = NULL;
+}
+
+float* calc_coefficients_125Hz_lowpass(int rate)
+{
+ len125 = 256;
+ float f = 125.0f / (rate / 2);
+ float *coeffs = design_fir(&len125, &f, 0);
+ static const float M3_01DB = 0.7071067812f;
+ for (unsigned int i = 0; i < len125; i++)
+ {
+ coeffs[i] *= M3_01DB;
+ }
+ return coeffs;
+}
+
+float passive_lock(float x)
+{
+ static const float MATAGCLOCK = 0.2f; /* AGC range (around 1) where the matrix behaves passively */
+ const float x1 = x - 1;
+ const float ax1s = fabs(x - 1) * (1.0f / MATAGCLOCK);
+ return x1 - x1 / (1 + ax1s * ax1s) + 1;
+}
+
+void matrix_decode(const float *in, const int k, const int il,
+ const int ir, bool decode_rear,
+ const int dlbuflen,
+ float l_fwr, float r_fwr,
+ float lpr_fwr, float lmr_fwr,
+ float *adapt_l_gain, float *adapt_r_gain,
+ float *adapt_lpr_gain, float *adapt_lmr_gain,
+ float *lf, float *rf, float *lr,
+ float *rr, float *cf)
+{
+ static const float M9_03DB = 0.3535533906f;
+ static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
+ static const float MATAGCDECAY = 1.0f; /* AGC baseline decay rate (1/samp.) */
+ static const float MATCOMPGAIN = 0.37f; /* Cross talk compensation gain, 0.50 - 0.55 is full cancellation. */
+
+ const int kr = (k + olddelay) % dlbuflen;
+ float l_gain = (l_fwr + r_fwr) / (1 + l_fwr + l_fwr);
+ float r_gain = (l_fwr + r_fwr) / (1 + r_fwr + r_fwr);
+ /* The 2nd axis has strong gain fluctuations, and therefore require
+ limits. The factor corresponds to the 1 / amplification of (Lt
+ - Rt) when (Lt, Rt) is strongly correlated. (e.g. during
+ dialogues). It should be bigger than -12 dB to prevent
+ distortion. */
+ float lmr_lim_fwr = lmr_fwr > M9_03DB * lpr_fwr ? lmr_fwr : M9_03DB * lpr_fwr;
+ float lpr_gain = (lpr_fwr + lmr_lim_fwr) / (1 + lpr_fwr + lpr_fwr);
+ float lmr_gain = (lpr_fwr + lmr_lim_fwr) / (1 + lmr_lim_fwr + lmr_lim_fwr);
+ float lmr_unlim_gain = (lpr_fwr + lmr_fwr) / (1 + lmr_fwr + lmr_fwr);
+ float lpr, lmr;
+ float l_agc, r_agc, lpr_agc, lmr_agc;
+ float f, d_gain, c_gain, c_agc_cfk;
+
+ /*** AXIS NO. 1: (Lt, Rt) -> (C, Ls, Rs) ***/
+ /* AGC adaption */
+ d_gain = (fabs(l_gain - *adapt_l_gain) + fabs(r_gain - *adapt_r_gain)) * 0.5f;
+ f = d_gain * (1.0f / MATAGCTRIG);
+ f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
+ *adapt_l_gain = (1 - f) * *adapt_l_gain + f * l_gain;
+ *adapt_r_gain = (1 - f) * *adapt_r_gain + f * r_gain;
+ /* Matrix */
+ l_agc = in[il] * passive_lock(*adapt_l_gain);
+ r_agc = in[ir] * passive_lock(*adapt_r_gain);
+ cf[k] = (l_agc + r_agc) * (float)M_SQRT1_2;
+ if (decode_rear)
+ {
+ lr[kr] = rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2;
+ /* Stereo rear channel is steered with the same AGC steering as
+ the decoding matrix. Note this requires a fast updating AGC
+ at the order of 20 ms (which is the case here). */
+ lr[kr] *= (l_fwr + l_fwr) / (1 + l_fwr + r_fwr);
+ rr[kr] *= (r_fwr + r_fwr) / (1 + l_fwr + r_fwr);
+ }
+
+ /*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/
+ lpr = (in[il] + in[ir]) * (float)M_SQRT1_2;
+ lmr = (in[il] - in[ir]) * (float)M_SQRT1_2;
+ /* AGC adaption */
+ d_gain = fabs(lmr_unlim_gain - *adapt_lmr_gain);
+ f = d_gain * (1.0f / MATAGCTRIG);
+ f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
+ *adapt_lpr_gain = (1 - f) * *adapt_lpr_gain + f * lpr_gain;
+ *adapt_lmr_gain = (1 - f) * *adapt_lmr_gain + f * lmr_gain;
+ /* Matrix */
+ lpr_agc = lpr * passive_lock(*adapt_lpr_gain);
+ lmr_agc = lmr * passive_lock(*adapt_lmr_gain);
+ lf[k] = (lpr_agc + lmr_agc) * (float)M_SQRT1_2;
+ rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2;
+
+ /*** CENTER FRONT CANCELLATION ***/
+ /* A heuristic approach exploits that Lt + Rt gain contains the
+ information about Lt, Rt correlation. This effectively reshapes
+ the front and rear "cones" to concentrate Lt + Rt to C and
+ introduce Lt - Rt in L, R. */
+ /* 0.67677 is the empirical lower bound for lpr_gain. */
+ c_gain = 8 * (*adapt_lpr_gain - 0.67677f);
+ c_gain = c_gain > 0 ? c_gain : 0;
+ /* c_gain should not be too high, not even reaching full
+ cancellation (~ 0.50 - 0.55 at current AGC implementation), or
+ the center will sound too narrow. */
+ c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
+ c_agc_cfk = c_gain * cf[k];
+ lf[k] -= c_agc_cfk;
+ rf[k] -= c_agc_cfk;
+ cf[k] += c_agc_cfk + c_agc_cfk;
+}
+
+void dpl2decode(float *samples, int numsamples, float *out)
+{
+ static const unsigned int FWRDURATION = 240; /* FWR average duration (samples) */
+ static const int cfg_delay = 0;
+ static const unsigned int fmt_freq = 48000;
+ static const unsigned int fmt_nchannels = 2; // input channels
+
+ int cur = 0;
+
+ if (olddelay != cfg_delay || oldfreq != fmt_freq)
+ {
+ done();
+ olddelay = cfg_delay;
+ oldfreq = fmt_freq;
+ dlbuflen = std::max(FWRDURATION, (fmt_freq * cfg_delay / 1000)); //+(len7000-1);
+ cyc_pos = dlbuflen - 1;
+ fwrbuf_l.resize(dlbuflen);
+ fwrbuf_r.resize(dlbuflen);
+ lf.resize(dlbuflen);
+ rf.resize(dlbuflen);
+ lr.resize(dlbuflen);
+ rr.resize(dlbuflen);
+ cf.resize(dlbuflen);
+ cr.resize(dlbuflen);
+ filter_coefs_lfe = calc_coefficients_125Hz_lowpass(fmt_freq);
+ lfe_pos = 0;
+ memset(LFE_buf, 0, sizeof(LFE_buf));
+ }
+
+ float *in = samples; // Input audio data
+ float *end = in + numsamples * fmt_nchannels; // Loop end
+
+ while (in < end)
+ {
+ const int k = cyc_pos;
+
+ const int fwr_pos = (k + FWRDURATION) % dlbuflen;
+ /* Update the full wave rectified total amplitude */
+ /* Input matrix decoder */
+ l_fwr += fabs(in[0]) - fabs(fwrbuf_l[fwr_pos]);
+ r_fwr += fabs(in[1]) - fabs(fwrbuf_r[fwr_pos]);
+ lpr_fwr += fabs(in[0] + in[1]) - fabs(fwrbuf_l[fwr_pos] + fwrbuf_r[fwr_pos]);
+ lmr_fwr += fabs(in[0] - in[1]) - fabs(fwrbuf_l[fwr_pos] - fwrbuf_r[fwr_pos]);
+
+ /* Matrix encoded 2 channel sources */
+ fwrbuf_l[k] = in[0];
+ fwrbuf_r[k] = in[1];
+ matrix_decode(in, k, 0, 1, true, dlbuflen,
+ l_fwr, r_fwr,
+ lpr_fwr, lmr_fwr,
+ &adapt_l_gain, &adapt_r_gain,
+ &adapt_lpr_gain, &adapt_lmr_gain,
+ &lf[0], &rf[0], &lr[0], &rr[0], &cf[0]);
+
+ out[cur + 0] = lf[k];
+ out[cur + 1] = rf[k];
+ out[cur + 2] = cf[k];
+ LFE_buf[lfe_pos] = (out[0] + out[1]) / 2;
+ out[cur + 3] = firfilter(LFE_buf, lfe_pos, len125, len125, filter_coefs_lfe);
+ lfe_pos++;
+ if (lfe_pos == len125)
+ {
+ lfe_pos = 0;
+ }
+ out[cur + 4] = lr[k];
+ out[cur + 5] = rr[k];
+ // Next sample...
+ in += 2;
+ cur += 6;
+ cyc_pos--;
+ if (cyc_pos < 0)
+ {
+ cyc_pos += dlbuflen;
+ }
+ }
+}
+
+void dpl2reset()
+{
+ olddelay = -1;
+ oldfreq = 0;
+ filter_coefs_lfe = NULL;
+}
diff --git a/Source/Core/AudioCommon/Src/DPL2Decoder.h b/Source/Core/AudioCommon/Src/DPL2Decoder.h
new file mode 100644
index 0000000000..eee8fbf15e
--- /dev/null
+++ b/Source/Core/AudioCommon/Src/DPL2Decoder.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DPL2DECODER_H_
+#define _DPL2DECODER_H_
+
+void dpl2decode(float *samples, int numsamples, float *out);
+void dpl2reset();
+
+#endif // _DPL2DECODER_H_
diff --git a/Source/Core/AudioCommon/Src/Mixer.h b/Source/Core/AudioCommon/Src/Mixer.h
index da456d5bf7..c1a387cf49 100644
--- a/Source/Core/AudioCommon/Src/Mixer.h
+++ b/Source/Core/AudioCommon/Src/Mixer.h
@@ -92,6 +92,9 @@ public:
std::mutex& MixerCritical() { return m_csMixing; }
+ volatile float GetCurrentSpeed() const { return m_speed; }
+ void UpdateSpeed(volatile float val) { m_speed = val; }
+
protected:
unsigned int m_sampleRate;
unsigned int m_aiSampleRate;
@@ -113,6 +116,8 @@ protected:
bool m_AIplaying;
std::mutex m_csMixing;
+
+ volatile float m_speed; // Current rate of the emulation (1.0 = 100% speed)
private:
};
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp
index 2abd357782..cfe6a40630 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp
@@ -15,13 +15,14 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
-#include <functional>
-
#include "aldlist.h"
#include "OpenALStream.h"
+#include "DPL2Decoder.h"
#if defined HAVE_OPENAL && HAVE_OPENAL
+soundtouch::SoundTouch soundTouch;
+
//
// AyuanX: Spec says OpenAL1.1 is thread safe already
//
@@ -35,14 +36,21 @@ bool OpenALStream::Start()
pDeviceList = new ALDeviceList();
if ((pDeviceList) && (pDeviceList->GetNumDevices()))
{
- char *defDevName = pDeviceList-> \
- GetDeviceName(pDeviceList->GetDefaultDevice());
+ char *defDevName = pDeviceList->GetDeviceName(pDeviceList->GetDefaultDevice());
+
+ WARN_LOG(AUDIO, "Found OpenAL device %s", defDevName);
+
pDevice = alcOpenDevice(defDevName);
if (pDevice)
{
pContext = alcCreateContext(pDevice, NULL);
if (pContext)
{
+ // Used to determine an appropriate period size (2x period = total buffer size)
+ //ALCint refresh;
+ //alcGetIntegerv(pDevice, ALC_REFRESH, 1, &refresh);
+ //period_size_in_millisec = 1000 / refresh;
+
alcMakeContextCurrent(pContext);
thread = std::thread(std::mem_fun(&OpenALStream::SoundLoop), this);
bReturn = true;
@@ -50,8 +58,7 @@ bool OpenALStream::Start()
else
{
alcCloseDevice(pDevice);
- PanicAlertT("OpenAL: can't create context "
- "for device %s", defDevName);
+ PanicAlertT("OpenAL: can't create context for device %s", defDevName);
}
}
else
@@ -65,6 +72,10 @@ bool OpenALStream::Start()
PanicAlertT("OpenAL: can't find sound devices");
}
+ // Initialise DPL2 parameters
+ dpl2reset();
+
+ soundTouch.clear();
return bReturn;
}
@@ -74,6 +85,8 @@ void OpenALStream::Stop()
// kick the thread if it's waiting
soundSyncEvent.Set();
+ soundTouch.clear();
+
thread.join();
alSourceStop(uiSource);
@@ -82,7 +95,7 @@ void OpenALStream::Stop()
// Clean up buffers and sources
alDeleteSources(1, &uiSource);
uiSource = 0;
- alDeleteBuffers(OAL_NUM_BUFFERS, uiBuffers);
+ alDeleteBuffers(numBuffers, uiBuffers);
ALCcontext *pContext = alcGetCurrentContext();
ALCdevice *pDevice = alcGetContextsDevice(pContext);
@@ -111,6 +124,7 @@ void OpenALStream::Clear(bool mute)
if(m_muted)
{
+ soundTouch.clear();
alSourceStop(uiSource);
}
else
@@ -124,20 +138,29 @@ void OpenALStream::SoundLoop()
Common::SetCurrentThreadName("Audio thread - openal");
u32 ulFrequency = m_mixer->GetSampleRate();
+ numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers
- memset(uiBuffers, 0, OAL_NUM_BUFFERS * sizeof(ALuint));
+ memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
uiSource = 0;
// Generate some AL Buffers for streaming
- alGenBuffers(OAL_NUM_BUFFERS, (ALuint *)uiBuffers);
+ alGenBuffers(numBuffers, (ALuint *)uiBuffers);
// Generate a Source to playback the Buffers
alGenSources(1, &uiSource);
// Short Silence
+ memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * numBuffers);
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * 4);
- for (int i = 0; i < OAL_NUM_BUFFERS; i++)
- alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, OAL_MAX_SAMPLES, ulFrequency);
- alSourceQueueBuffers(uiSource, OAL_NUM_BUFFERS, uiBuffers);
+ for (int i = 0; i < numBuffers; i++)
+ {
+#if !defined(__APPLE__)
+ if (Core::g_CoreStartupParameter.bDPL2Decoder)
+ alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
+ else
+#endif
+ alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * 2 * 2, ulFrequency);
+ }
+ alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
alSourcePlay(uiSource);
// Set the default sound volume as saved in the config file.
@@ -148,41 +171,175 @@ void OpenALStream::SoundLoop()
ALint iBuffersFilled = 0;
ALint iBuffersProcessed = 0;
- ALuint uiBufferTemp[OAL_NUM_BUFFERS] = {0};
+ ALint iState = 0;
+ ALuint uiBufferTemp[OAL_MAX_BUFFERS] = {0};
+
+ soundTouch.setChannels(2);
+ soundTouch.setSampleRate(ulFrequency);
+ soundTouch.setTempo(1.0);
+ soundTouch.setSetting(SETTING_USE_QUICKSEEK, 0);
+ soundTouch.setSetting(SETTING_USE_AA_FILTER, 0);
+ soundTouch.setSetting(SETTING_SEQUENCE_MS, 1);
+ soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
+ soundTouch.setSetting(SETTING_OVERLAP_MS, 12);
+
+ bool surround_capable = Core::g_CoreStartupParameter.bDPL2Decoder;
+#if defined(__APPLE__)
+ bool float32_capable = false;
+#else
+ bool float32_capable = true;
+#endif
while (!threadData)
{
+ // num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
+ const u32 stereo_16_bit_size = 4;
+ const u32 dma_length = 32;
+ const u64 ais_samples_per_second = 48000 * stereo_16_bit_size;
+ u64 audio_dma_period = SystemTimers::GetTicksPerSecond() / (AudioInterface::GetAIDSampleRate() * stereo_16_bit_size / dma_length);
+ u64 num_samples_to_render = (audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond();
+
+ unsigned int numSamples = (unsigned int)num_samples_to_render;
+
+ numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
+ numSamples = m_mixer->Mix(realtimeBuffer, numSamples);
+
+ // Convert the samples from short to float
+ float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS];
+ for (u32 i = 0; i < numSamples; ++i)
+ {
+ dest[i * 2 + 0] = (float)realtimeBuffer[i * 2 + 0] / (1 << 16);
+ dest[i * 2 + 1] = (float)realtimeBuffer[i * 2 + 1] / (1 << 16);
+ }
+
+ soundTouch.putSamples(dest, numSamples);
+
if (iBuffersProcessed == iBuffersFilled)
{
alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
iBuffersFilled = 0;
}
- unsigned int numSamples = m_mixer->GetNumSamples();
-
- if (iBuffersProcessed && (numSamples >= OAL_THRESHOLD))
+ if (iBuffersProcessed)
{
- numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
- // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
- if (iBuffersFilled == 0)
- alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
-
- m_mixer->Mix(realtimeBuffer, numSamples);
- alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, realtimeBuffer, numSamples * 4, ulFrequency);
- alSourceQueueBuffers(uiSource, 1, &uiBufferTemp[iBuffersFilled]);
- iBuffersFilled++;
-
- if (iBuffersFilled == OAL_NUM_BUFFERS)
- alSourcePlay(uiSource);
+ float rate = m_mixer->GetCurrentSpeed();
+ if (rate <= 0)
+ {
+ Core::RequestRefreshInfo();
+ rate = m_mixer->GetCurrentSpeed();
+ }
+
+ // Place a lower limit of 10% speed. When a game boots up, there will be
+ // many silence samples. These do not need to be timestretched.
+ if (rate > 0.10)
+ {
+ // Adjust SETTING_SEQUENCE_MS to balance between lag vs hollow audio
+ soundTouch.setSetting(SETTING_SEQUENCE_MS, (int)(1 / (rate * rate)));
+ soundTouch.setTempo(rate);
+ }
+ unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS);
+ if (nSamples > 0)
+ {
+ // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
+ if (iBuffersFilled == 0)
+ {
+ alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
+ ALenum err = alGetError();
+ if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error unqueuing buffers: %08x", err);
+ }
+ }
+#if defined(__APPLE__)
+ // OSX does not have the alext AL_FORMAT_51CHN32 yet.
+ surround_capable = false;
+#else
+ if (surround_capable)
+ {
+ float dpl2[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
+ dpl2decode(sampleBuffer, nSamples, dpl2);
+
+ alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
+ ALenum err = alGetError();
+ if (err == AL_INVALID_ENUM)
+ {
+ // 5.1 is not supported by the host, fallback to stereo
+ WARN_LOG(AUDIO, "Unable to set 5.1 surround mode. Updating OpenAL Soft might fix this issue.");
+ surround_capable = false;
+ }
+ else if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error occurred while buffering data: %08x", err);
+ }
+ }
+#endif
+ if (!surround_capable)
+ {
+#if !defined(__APPLE__)
+ if (float32_capable)
+ {
+ alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * 4 * 2, ulFrequency);
+ ALenum err = alGetError();
+ if (err == AL_INVALID_ENUM)
+ {
+ float32_capable = false;
+ }
+ else if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err);
+ }
+
+ }
+#endif
+ if (!float32_capable)
+ {
+ // Convert the samples from float to short
+ short stereo[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS];
+ for (u32 i = 0; i < nSamples; ++i)
+ {
+ stereo[i * 2 + 0] = (short)((float)sampleBuffer[i * 2 + 0] * (1 << 16));
+ stereo[i * 2 + 1] = (short)((float)sampleBuffer[i * 2 + 1] * (1 << 16));
+ }
+ alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * 2 * 2, ulFrequency);
+
+ }
+ }
+
+ alSourceQueueBuffers(uiSource, 1, &uiBufferTemp[iBuffersFilled]);
+ ALenum err = alGetError();
+ if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error queuing buffers: %08x", err);
+ }
+ iBuffersFilled++;
+
+ if (iBuffersFilled == numBuffers)
+ {
+ alSourcePlay(uiSource);
+ ALenum err = alGetError();
+ if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error occurred during playback: %08x", err);
+ }
+ }
+
+ alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
+ if (iState != AL_PLAYING)
+ {
+ // Buffer underrun occurred, resume playback
+ alSourcePlay(uiSource);
+ ALenum err = alGetError();
+ if (err != 0)
+ {
+ ERROR_LOG(AUDIO, "Error occurred resuming playback: %08x", err);
+ }
+ }
+ }
}
- else if (numSamples >= OAL_THRESHOLD)
+ else
{
- ALint state = 0;
- alGetSourcei(uiSource, AL_SOURCE_STATE, &state);
- if (state == AL_STOPPED)
- alSourcePlay(uiSource);
+ soundSyncEvent.Wait();
}
- soundSyncEvent.Wait();
}
}
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.h b/Source/Core/AudioCommon/Src/OpenALStream.h
index 2c0d75b510..a808fcefc9 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.h
+++ b/Source/Core/AudioCommon/Src/OpenALStream.h
@@ -24,21 +24,30 @@
#if defined HAVE_OPENAL && HAVE_OPENAL
#ifdef _WIN32
-#include "../../../../Externals/OpenAL/include/al.h"
-#include "../../../../Externals/OpenAL/include/alc.h"
+#include <OpenAL/include/al.h>
+#include <OpenAL/include/alc.h>
+#include <OpenAL/include/alext.h>
#elif defined __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
+#include <AL/alext.h>
#endif
+#include "Core.h"
+#include "HW/SystemTimers.h"
+#include "HW/AudioInterface.h"
+#include <soundtouch/SoundTouch.h>
+#include <soundtouch/STTypes.h>
+
// 16 bit Stereo
#define SFX_MAX_SOURCE 1
-#define OAL_NUM_BUFFERS 16
-#define OAL_MAX_SAMPLES 512 // AyuanX: Don't make it too large, as larger buffer means longer delay
-#define OAL_THRESHOLD 128 // Some games are quite sensitive to delay
+#define OAL_MAX_BUFFERS 32
+#define OAL_MAX_SAMPLES 256
+#define SURROUND_CHANNELS 6 // number of channels in surround mode
+#define SIZE_FLOAT 4 // size of a float in bytes
#endif
class OpenALStream: public SoundStream
@@ -64,11 +73,14 @@ public:
private:
std::thread thread;
Common::Event soundSyncEvent;
-
+
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
- ALuint uiBuffers[OAL_NUM_BUFFERS];
+ soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
+ ALuint uiBuffers[OAL_MAX_BUFFERS];
ALuint uiSource;
ALfloat fVolume;
+
+ u8 numBuffers;
#else
public:
OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}
diff --git a/Source/Core/AudioCommon/Src/PulseAudioStream.cpp b/Source/Core/AudioCommon/Src/PulseAudioStream.cpp
index 4851b4bd12..faa94c22e0 100644
--- a/Source/Core/AudioCommon/Src/PulseAudioStream.cpp
+++ b/Source/Core/AudioCommon/Src/PulseAudioStream.cpp
@@ -22,31 +22,31 @@
#include "PulseAudioStream.h"
-#define BUFFER_SIZE 4096
-#define BUFFER_SIZE_BYTES (BUFFER_SIZE * 4)
-
-PulseAudio::PulseAudio(CMixer *mixer)
- : SoundStream(mixer), thread_running(false), mainloop(NULL)
- , context(NULL), stream(NULL), iVolume(100)
+namespace
{
- mix_buffer = new u8[BUFFER_SIZE_BYTES];
+const size_t BUFFER_SAMPLES = 512;
+const size_t CHANNEL_COUNT = 2;
+const size_t BUFFER_SIZE = BUFFER_SAMPLES * CHANNEL_COUNT;
}
-PulseAudio::~PulseAudio()
-{
- delete [] mix_buffer;
-}
+PulseAudio::PulseAudio(CMixer *mixer)
+ : SoundStream(mixer)
+ , mix_buffer(BUFFER_SIZE)
+ , thread()
+ , run_thread()
+ , pa()
+{}
bool PulseAudio::Start()
{
- thread_running = true;
+ run_thread = true;
thread = std::thread(std::mem_fun(&PulseAudio::SoundLoop), this);
return true;
}
void PulseAudio::Stop()
{
- thread_running = false;
+ run_thread = false;
thread.join();
}
@@ -60,260 +60,53 @@ void PulseAudio::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - pulse");
- thread_running = PulseInit();
-
- while (thread_running)
- {
- int frames_to_deliver = 512;
- m_mixer->Mix((short *)mix_buffer, frames_to_deliver);
- if (!Write(mix_buffer, frames_to_deliver * 4))
- ERROR_LOG(AUDIO, "PulseAudio failure writing data");
- }
- PulseShutdown();
-}
-
-bool PulseAudio::PulseInit()
-{
- // The Sample format to use
- const pa_sample_spec ss =
- {
- PA_SAMPLE_S16LE,
- m_mixer->GetSampleRate(),
- 2
- };
-
- mainloop = pa_threaded_mainloop_new();
-
- context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "dolphin-emu");
- pa_context_set_state_callback(context, ContextStateCB, this);
-
- if (pa_context_connect(context, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
+ if (PulseInit())
{
- ERROR_LOG(AUDIO, "PulseAudio failed to connect context: %s",
- pa_strerror(pa_context_errno(context)));
- return false;
- }
-
- pa_threaded_mainloop_lock(mainloop);
- pa_threaded_mainloop_start(mainloop);
-
- for (;;)
- {
- pa_context_state_t state;
-
- state = pa_context_get_state(context);
-
- if (state == PA_CONTEXT_READY)
- break;
-
- if (!PA_CONTEXT_IS_GOOD(state))
+ while (run_thread)
{
- ERROR_LOG(AUDIO, "PulseAudio context state failure: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
+ m_mixer->Mix(&mix_buffer[0], mix_buffer.size() / CHANNEL_COUNT);
+ Write(&mix_buffer[0], mix_buffer.size() * sizeof(s16));
}
- // Wait until the context is ready
- pa_threaded_mainloop_wait(mainloop);
+ PulseShutdown();
}
-
- if (!(stream = pa_stream_new(context, "emulator", &ss, NULL)))
- {
- ERROR_LOG(AUDIO, "PulseAudio failed to create playback stream: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
-
- // Set callbacks for the playback stream
- pa_stream_set_state_callback(stream, StreamStateCB, this);
- pa_stream_set_write_callback(stream, StreamWriteCB, this);
-
- if (pa_stream_connect_playback(stream, NULL, NULL, PA_STREAM_NOFLAGS, NULL, NULL) < 0)
- {
- ERROR_LOG(AUDIO, "PulseAudio failed to connect playback stream: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
-
- for (;;)
- {
- pa_stream_state_t state;
-
- state = pa_stream_get_state(stream);
-
- if (state == PA_STREAM_READY)
- break;
-
- if (!PA_STREAM_IS_GOOD(state))
- {
- ERROR_LOG(AUDIO, "PulseAudio stream state failure: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
-
- // Wait until the stream is ready
- pa_threaded_mainloop_wait(mainloop);
- }
-
- pa_threaded_mainloop_unlock(mainloop);
-
- SetVolume(iVolume);
-
- NOTICE_LOG(AUDIO, "Pulse successfully initialized.");
- return true;
}
-void PulseAudio::PulseShutdown()
+bool PulseAudio::PulseInit()
{
- if (mainloop)
- pa_threaded_mainloop_stop(mainloop);
+ pa_sample_spec ss = {};
+ ss.format = PA_SAMPLE_S16LE;
+ ss.channels = 2;
+ ss.rate = m_mixer->GetSampleRate();
- if (stream)
- pa_stream_unref(stream);
+ int error;
+ pa = pa_simple_new(nullptr, "dolphin-emu", PA_STREAM_PLAYBACK,
+ nullptr, "audio", &ss, nullptr, nullptr, &error);
- if (context)
+ if (!pa)
{
- pa_context_disconnect(context);
- pa_context_unref(context);
- }
-
- if (mainloop)
- pa_threaded_mainloop_free(mainloop);
-}
-
-void PulseAudio::SignalMainLoop()
-{
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-void PulseAudio::ContextStateCB(pa_context *c, void *userdata)
-{
- switch (pa_context_get_state(c))
- {
- case PA_CONTEXT_READY:
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- ((PulseAudio *)userdata)->SignalMainLoop();
- break;
-
- default:
- break;
+ ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s",
+ pa_strerror(error));
+ return false;
}
-}
-
-void PulseAudio::StreamStateCB(pa_stream *s, void * userdata)
-{
- switch (pa_stream_get_state(s))
+ else
{
- case PA_STREAM_READY:
- case PA_STREAM_TERMINATED:
- case PA_STREAM_FAILED:
- ((PulseAudio *)userdata)->SignalMainLoop();
- break;
-
- default:
- break;
+ NOTICE_LOG(AUDIO, "Pulse successfully initialized.");
+ return true;
}
}
-void PulseAudio::StreamWriteCB(pa_stream *s, size_t length, void *userdata)
-{
- ((PulseAudio *)userdata)->SignalMainLoop();
-}
-
-static bool StateIsGood(pa_context *context, pa_stream *stream)
+void PulseAudio::PulseShutdown()
{
- if (!context || !PA_CONTEXT_IS_GOOD(pa_context_get_state(context)) ||
- !stream || !PA_STREAM_IS_GOOD(pa_stream_get_state(stream)))
- {
- if ((context && pa_context_get_state(context) == PA_CONTEXT_FAILED) ||
- (stream && pa_stream_get_state(stream) == PA_STREAM_FAILED))
- {
- ERROR_LOG(AUDIO, "PulseAudio state failure: %s",
- pa_strerror(pa_context_errno(context)));
- }
- else
- {
- ERROR_LOG(AUDIO, "PulseAudio state failure: %s",
- pa_strerror(PA_ERR_BADSTATE));
- }
- return false;
- }
- return true;
+ pa_simple_free(pa);
}
-bool PulseAudio::Write(const void *data, size_t length)
+void PulseAudio::Write(const void *data, size_t length)
{
- if (!data || length == 0 || !stream)
- return false;
-
- pa_threaded_mainloop_lock(mainloop);
-
- if (!StateIsGood(context, stream))
+ int error;
+ if (pa_simple_write(pa, data, length, &error) < 0)
{
- pa_threaded_mainloop_unlock(mainloop);
- return false;
+ ERROR_LOG(AUDIO, "PulseAudio failed to write data: %s",
+ pa_strerror(error));
}
-
- while (length > 0)
- {
- size_t l;
- int r;
-
- while (!(l = pa_stream_writable_size(stream)))
- {
- pa_threaded_mainloop_wait(mainloop);
- if (!StateIsGood(context, stream))
- {
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
- }
-
- if (l == (size_t)-1)
- {
- ERROR_LOG(AUDIO, "PulseAudio invalid stream: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
-
- if (l > length)
- l = length;
-
- r = pa_stream_write(stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
- if (r < 0)
- {
- ERROR_LOG(AUDIO, "PulseAudio error writing to stream: %s",
- pa_strerror(pa_context_errno(context)));
- pa_threaded_mainloop_unlock(mainloop);
- return false;
- }
-
- data = (const uint8_t*) data + l;
- length -= l;
- }
-
- pa_threaded_mainloop_unlock(mainloop);
- return true;
-}
-
-void PulseAudio::SetVolume(int volume)
-{
- iVolume = volume;
-
- if (!stream)
- return;
-
- pa_cvolume cvolume;
- const pa_channel_map *channels = pa_stream_get_channel_map(stream);
- pa_cvolume_set(&cvolume, channels->channels,
- iVolume * (PA_VOLUME_NORM - PA_VOLUME_MUTED) / 100);
-
- pa_context_set_sink_input_volume(context, pa_stream_get_index(stream),
- &cvolume, NULL, this);
}
diff --git a/Source/Core/AudioCommon/Src/PulseAudioStream.h b/Source/Core/AudioCommon/Src/PulseAudioStream.h
index f3a5a43e79..38399e2506 100644
--- a/Source/Core/AudioCommon/Src/PulseAudioStream.h
+++ b/Source/Core/AudioCommon/Src/PulseAudioStream.h
@@ -19,7 +19,8 @@
#define _PULSE_AUDIO_STREAM_H
#if defined(HAVE_PULSEAUDIO) && HAVE_PULSEAUDIO
-#include <pulse/pulseaudio.h>
+#include <pulse/simple.h>
+#include <pulse/error.h>
#endif
#include "Common.h"
@@ -27,16 +28,16 @@
#include "Thread.h"
+#include <vector>
+
class PulseAudio : public SoundStream
{
#if defined(HAVE_PULSEAUDIO) && HAVE_PULSEAUDIO
public:
PulseAudio(CMixer *mixer);
- virtual ~PulseAudio();
virtual bool Start();
virtual void Stop();
- virtual void SetVolume(int volume);
static bool isValid() {return true;}
@@ -46,22 +47,16 @@ public:
private:
virtual void SoundLoop();
+
bool PulseInit();
void PulseShutdown();
- bool Write(const void *data, size_t bytes);
- void SignalMainLoop();
- static void ContextStateCB(pa_context *c, void *userdata);
- static void StreamStateCB(pa_stream *s, void * userdata);
- static void StreamWriteCB(pa_stream *s, size_t length, void *userdata);
+ void Write(const void *data, size_t bytes);
- u8 *mix_buffer;
+ std::vector<s16> mix_buffer;
std::thread thread;
- volatile bool thread_running;
+ volatile bool run_thread;
- pa_threaded_mainloop *mainloop;
- pa_context *context;
- pa_stream *stream;
- int iVolume;
+ pa_simple* pa;
#else
public:
PulseAudio(CMixer *mixer) : SoundStream(mixer) {}
diff --git a/Source/Core/AudioCommon/Src/WaveFile.cpp b/Source/Core/AudioCommon/Src/WaveFile.cpp
index 802f3f7417..d98348b8bf 100644
--- a/Source/Core/AudioCommon/Src/WaveFile.cpp
+++ b/Source/Core/AudioCommon/Src/WaveFile.cpp
@@ -100,39 +100,52 @@ void WaveFileWriter::Write4(const char *ptr)
file.WriteBytes(ptr, 4);
}
-void WaveFileWriter::AddStereoSamples(const short *sample_data, int count)
+void WaveFileWriter::AddStereoSamples(const short *sample_data, u32 count)
{
if (!file)
PanicAlertT("WaveFileWriter - file not open.");
- if (skip_silence) {
+
+ if (skip_silence)
+ {
bool all_zero = true;
- for (int i = 0; i < count * 2; i++)
- if (sample_data[i]) all_zero = false;
- if (all_zero) return;
+
+ for (u32 i = 0; i < count * 2; i++)
+ {
+ if (sample_data[i])
+ all_zero = false;
+ }
+
+ if (all_zero)
+ return;
}
+
file.WriteBytes(sample_data, count * 4);
audio_size += count * 4;
}
-void WaveFileWriter::AddStereoSamplesBE(const short *sample_data, int count)
+void WaveFileWriter::AddStereoSamplesBE(const short *sample_data, u32 count)
{
if (!file)
PanicAlertT("WaveFileWriter - file not open.");
if (count > BUF_SIZE * 2)
- PanicAlert("WaveFileWriter - buffer too small (count = %i).", count);
+ PanicAlert("WaveFileWriter - buffer too small (count = %u).", count);
if (skip_silence)
{
bool all_zero = true;
- for (int i = 0; i < count * 2; i++)
+
+ for (u32 i = 0; i < count * 2; i++)
+ {
if (sample_data[i])
all_zero = false;
+ }
+
if (all_zero)
return;
}
- for (int i = 0; i < count * 2; i++)
+ for (u32 i = 0; i < count * 2; i++)
conv_buffer[i] = Common::swap16((u16)sample_data[i]);
file.WriteBytes(conv_buffer, count * 4);
diff --git a/Source/Core/AudioCommon/Src/WaveFile.h b/Source/Core/AudioCommon/Src/WaveFile.h
index 72a090814b..11fbb4ced5 100644
--- a/Source/Core/AudioCommon/Src/WaveFile.h
+++ b/Source/Core/AudioCommon/Src/WaveFile.h
@@ -50,8 +50,8 @@ public:
void SetSkipSilence(bool skip) { skip_silence = skip; }
- void AddStereoSamples(const short *sample_data, int count);
- void AddStereoSamplesBE(const short *sample_data, int count); // big endian
+ void AddStereoSamples(const short *sample_data, u32 count);
+ void AddStereoSamplesBE(const short *sample_data, u32 count); // big endian
u32 GetAudioSize() { return audio_size; }
};
diff --git a/Source/Core/AudioCommon/Src/aldlist.cpp b/Source/Core/AudioCommon/Src/aldlist.cpp
index 69d42148ae..fa11fe3282 100644
--- a/Source/Core/AudioCommon/Src/aldlist.cpp
+++ b/Source/Core/AudioCommon/Src/aldlist.cpp
@@ -48,7 +48,7 @@ ALDeviceList::ALDeviceList()
const char *actualDeviceName = NULL;
// DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
- vDeviceInfo.empty();
+ vDeviceInfo.clear();
vDeviceInfo.reserve(10);
defaultDeviceIndex = 0;
@@ -146,12 +146,12 @@ ALDeviceList::~ALDeviceList()
{
for (u32 i = 0; i < vDeviceInfo.size(); i++) {
if (vDeviceInfo[i].pvstrExtensions) {
- vDeviceInfo[i].pvstrExtensions->empty();
+ vDeviceInfo[i].pvstrExtensions->clear();
delete vDeviceInfo[i].pvstrExtensions;
}
}
- vDeviceInfo.empty();
+ vDeviceInfo.clear();
}
/*