mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Reformat all the things. Have fun with merge conflicts.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
namespace ButtonManager
|
namespace ButtonManager
|
||||||
{
|
{
|
||||||
enum ButtonType
|
enum ButtonType
|
||||||
{
|
{
|
||||||
// GC
|
// GC
|
||||||
BUTTON_A = 0,
|
BUTTON_A = 0,
|
||||||
BUTTON_B = 1,
|
BUTTON_B = 1,
|
||||||
@@ -70,7 +70,7 @@ namespace ButtonManager
|
|||||||
WIIMOTE_SHAKE_X = 132,
|
WIIMOTE_SHAKE_X = 132,
|
||||||
WIIMOTE_SHAKE_Y = 133,
|
WIIMOTE_SHAKE_Y = 133,
|
||||||
WIIMOTE_SHAKE_Z = 134,
|
WIIMOTE_SHAKE_Z = 134,
|
||||||
//Nunchuk
|
// Nunchuk
|
||||||
NUNCHUK_BUTTON_C = 200,
|
NUNCHUK_BUTTON_C = 200,
|
||||||
NUNCHUK_BUTTON_Z = 201,
|
NUNCHUK_BUTTON_Z = 201,
|
||||||
NUNCHUK_STICK = 202, // To Be Used on Java Side
|
NUNCHUK_STICK = 202, // To Be Used on Java Side
|
||||||
@@ -94,7 +94,7 @@ namespace ButtonManager
|
|||||||
NUNCHUK_SHAKE_X = 220,
|
NUNCHUK_SHAKE_X = 220,
|
||||||
NUNCHUK_SHAKE_Y = 221,
|
NUNCHUK_SHAKE_Y = 221,
|
||||||
NUNCHUK_SHAKE_Z = 222,
|
NUNCHUK_SHAKE_Z = 222,
|
||||||
//Classic
|
// Classic
|
||||||
CLASSIC_BUTTON_A = 300,
|
CLASSIC_BUTTON_A = 300,
|
||||||
CLASSIC_BUTTON_B = 301,
|
CLASSIC_BUTTON_B = 301,
|
||||||
CLASSIC_BUTTON_X = 302,
|
CLASSIC_BUTTON_X = 302,
|
||||||
@@ -120,7 +120,7 @@ namespace ButtonManager
|
|||||||
CLASSIC_STICK_RIGHT_RIGHT = 322,
|
CLASSIC_STICK_RIGHT_RIGHT = 322,
|
||||||
CLASSIC_TRIGGER_L = 323,
|
CLASSIC_TRIGGER_L = 323,
|
||||||
CLASSIC_TRIGGER_R = 324,
|
CLASSIC_TRIGGER_R = 324,
|
||||||
//Guitar
|
// Guitar
|
||||||
GUITAR_BUTTON_MINUS = 400,
|
GUITAR_BUTTON_MINUS = 400,
|
||||||
GUITAR_BUTTON_PLUS = 401,
|
GUITAR_BUTTON_PLUS = 401,
|
||||||
GUITAR_FRET_GREEN = 402,
|
GUITAR_FRET_GREEN = 402,
|
||||||
@@ -136,7 +136,7 @@ namespace ButtonManager
|
|||||||
GUITAR_STICK_LEFT = 412,
|
GUITAR_STICK_LEFT = 412,
|
||||||
GUITAR_STICK_RIGHT = 413,
|
GUITAR_STICK_RIGHT = 413,
|
||||||
GUITAR_WHAMMY_BAR = 414,
|
GUITAR_WHAMMY_BAR = 414,
|
||||||
//Drums
|
// Drums
|
||||||
DRUMS_BUTTON_MINUS = 500,
|
DRUMS_BUTTON_MINUS = 500,
|
||||||
DRUMS_BUTTON_PLUS = 501,
|
DRUMS_BUTTON_PLUS = 501,
|
||||||
DRUMS_PAD_RED = 502,
|
DRUMS_PAD_RED = 502,
|
||||||
@@ -150,7 +150,7 @@ namespace ButtonManager
|
|||||||
DRUMS_STICK_DOWN = 510,
|
DRUMS_STICK_DOWN = 510,
|
||||||
DRUMS_STICK_LEFT = 511,
|
DRUMS_STICK_LEFT = 511,
|
||||||
DRUMS_STICK_RIGHT = 512,
|
DRUMS_STICK_RIGHT = 512,
|
||||||
//Turntable
|
// Turntable
|
||||||
TURNTABLE_BUTTON_GREEN_LEFT = 600,
|
TURNTABLE_BUTTON_GREEN_LEFT = 600,
|
||||||
TURNTABLE_BUTTON_RED_LEFT = 601,
|
TURNTABLE_BUTTON_RED_LEFT = 601,
|
||||||
TURNTABLE_BUTTON_BLUE_LEFT = 602,
|
TURNTABLE_BUTTON_BLUE_LEFT = 602,
|
||||||
@@ -176,42 +176,42 @@ namespace ButtonManager
|
|||||||
TURNTABLE_CROSSFADE = 622, // To Be Used on Java Side
|
TURNTABLE_CROSSFADE = 622, // To Be Used on Java Side
|
||||||
TURNTABLE_CROSSFADE_LEFT = 623,
|
TURNTABLE_CROSSFADE_LEFT = 623,
|
||||||
TURNTABLE_CROSSFADE_RIGHT = 624,
|
TURNTABLE_CROSSFADE_RIGHT = 624,
|
||||||
};
|
};
|
||||||
enum ButtonState
|
enum ButtonState
|
||||||
{
|
{
|
||||||
BUTTON_RELEASED = 0,
|
BUTTON_RELEASED = 0,
|
||||||
BUTTON_PRESSED = 1
|
BUTTON_PRESSED = 1
|
||||||
};
|
};
|
||||||
enum BindType
|
enum BindType
|
||||||
{
|
{
|
||||||
BIND_BUTTON = 0,
|
BIND_BUTTON = 0,
|
||||||
BIND_AXIS
|
BIND_AXIS
|
||||||
};
|
};
|
||||||
class Button
|
class Button
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ButtonState m_state;
|
ButtonState m_state;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
Button() : m_state(BUTTON_RELEASED) {}
|
Button() : m_state(BUTTON_RELEASED) {}
|
||||||
void SetState(ButtonState state) { m_state = state; }
|
void SetState(ButtonState state) { m_state = state; }
|
||||||
bool Pressed() { return m_state == BUTTON_PRESSED; }
|
bool Pressed() { return m_state == BUTTON_PRESSED; }
|
||||||
|
|
||||||
~Button() {}
|
~Button() {}
|
||||||
};
|
};
|
||||||
class Axis
|
class Axis
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
float m_value;
|
float m_value;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
Axis() : m_value(0.0f) {}
|
Axis() : m_value(0.0f) {}
|
||||||
void SetValue(float value) { m_value = value; }
|
void SetValue(float value) { m_value = value; }
|
||||||
float AxisValue() { return m_value; }
|
float AxisValue() { return m_value; }
|
||||||
|
|
||||||
~Axis() {}
|
~Axis() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sBind
|
struct sBind
|
||||||
{
|
{
|
||||||
const int _padID;
|
const int _padID;
|
||||||
const ButtonType _buttontype;
|
const ButtonType _buttontype;
|
||||||
const BindType _bindtype;
|
const BindType _bindtype;
|
||||||
@@ -219,22 +219,22 @@ namespace ButtonManager
|
|||||||
const float _neg;
|
const float _neg;
|
||||||
sBind(int padID, ButtonType buttontype, BindType bindtype, int bind, float neg)
|
sBind(int padID, ButtonType buttontype, BindType bindtype, int bind, float neg)
|
||||||
: _padID(padID), _buttontype(buttontype), _bindtype(bindtype), _bind(bind), _neg(neg)
|
: _padID(padID), _buttontype(buttontype), _bindtype(bindtype), _bind(bind), _neg(neg)
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class InputDevice
|
|
||||||
{
|
{
|
||||||
private:
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputDevice
|
||||||
|
{
|
||||||
|
private:
|
||||||
const std::string _dev;
|
const std::string _dev;
|
||||||
std::map<ButtonType, bool> _buttons;
|
std::map<ButtonType, bool> _buttons;
|
||||||
std::map<ButtonType, float> _axises;
|
std::map<ButtonType, float> _axises;
|
||||||
|
|
||||||
// Key is padID and ButtonType
|
// Key is padID and ButtonType
|
||||||
std::map<std::pair<int, ButtonType>, sBind*> _inputbinds;
|
std::map<std::pair<int, ButtonType>, sBind*> _inputbinds;
|
||||||
public:
|
|
||||||
InputDevice(std::string dev)
|
public:
|
||||||
: _dev(dev) {}
|
InputDevice(std::string dev) : _dev(dev) {}
|
||||||
~InputDevice()
|
~InputDevice()
|
||||||
{
|
{
|
||||||
for (const auto& bind : _inputbinds)
|
for (const auto& bind : _inputbinds)
|
||||||
@@ -246,12 +246,12 @@ namespace ButtonManager
|
|||||||
void AxisEvent(int axis, float value);
|
void AxisEvent(int axis, float value);
|
||||||
bool ButtonValue(int padID, ButtonType button);
|
bool ButtonValue(int padID, ButtonType button);
|
||||||
float AxisValue(int padID, ButtonType axis);
|
float AxisValue(int padID, ButtonType axis);
|
||||||
};
|
};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
bool GetButtonPressed(int padID, ButtonType button);
|
bool GetButtonPressed(int padID, ButtonType button);
|
||||||
float GetAxisValue(int padID, ButtonType axis);
|
float GetAxisValue(int padID, ButtonType axis);
|
||||||
bool GamepadEvent(const std::string& dev, int button, int action);
|
bool GamepadEvent(const std::string& dev, int button, int action);
|
||||||
void GamepadAxisEvent(const std::string& dev, int axis, float value);
|
void GamepadAxisEvent(const std::string& dev, int axis, float value);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
}
|
}
|
||||||
|
|||||||
+215
-103
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
#include "AudioCommon/AOSoundStream.h"
|
#include "AudioCommon/AOSoundStream.h"
|
||||||
#include "AudioCommon/Mixer.h"
|
#include "AudioCommon/Mixer.h"
|
||||||
#include "Common/MsgHandler.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/MsgHandler.h"
|
||||||
|
|
||||||
#if defined(HAVE_AO) && HAVE_AO
|
#if defined(HAVE_AO) && HAVE_AO
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ void AOSound::SoundLoop()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_size = format.bits/8 * format.channels * format.rate;
|
buf_size = format.bits / 8 * format.channels * format.rate;
|
||||||
|
|
||||||
while (m_run_thread.load())
|
while (m_run_thread.load())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class AOSound final : public SoundStream
|
|||||||
|
|
||||||
int buf_size;
|
int buf_size;
|
||||||
|
|
||||||
ao_device *device;
|
ao_device* device;
|
||||||
ao_sample_format format;
|
ao_sample_format format;
|
||||||
int default_driver;
|
int default_driver;
|
||||||
|
|
||||||
@@ -38,10 +38,6 @@ public:
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
static bool isValid()
|
static bool isValid() { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,13 +6,12 @@
|
|||||||
|
|
||||||
#include "AudioCommon/AlsaSoundStream.h"
|
#include "AudioCommon/AlsaSoundStream.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Thread.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/Thread.h"
|
||||||
|
|
||||||
AlsaSound::AlsaSound()
|
AlsaSound::AlsaSound()
|
||||||
: m_thread_status(ALSAThreadStatus::STOPPED)
|
: m_thread_status(ALSAThreadStatus::STOPPED), handle(nullptr),
|
||||||
, handle(nullptr)
|
frames_to_deliver(FRAME_COUNT_MIN)
|
||||||
, frames_to_deliver(FRAME_COUNT_MIN)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +32,8 @@ void AlsaSound::Stop()
|
|||||||
{
|
{
|
||||||
m_thread_status.store(ALSAThreadStatus::STOPPING);
|
m_thread_status.store(ALSAThreadStatus::STOPPING);
|
||||||
|
|
||||||
//Give the opportunity to the audio thread
|
// Give the opportunity to the audio thread
|
||||||
//to realize we are stopping the emulation
|
// to realize we are stopping the emulation
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
@@ -70,7 +69,7 @@ void AlsaSound::SoundLoop()
|
|||||||
|
|
||||||
// Block until thread status changes.
|
// Block until thread status changes.
|
||||||
std::unique_lock<std::mutex> lock(cv_m);
|
std::unique_lock<std::mutex> lock(cv_m);
|
||||||
cv.wait(lock, [this]{ return m_thread_status.load() != ALSAThreadStatus::PAUSED; });
|
cv.wait(lock, [this] { return m_thread_status.load() != ALSAThreadStatus::PAUSED; });
|
||||||
|
|
||||||
snd_pcm_prepare(handle); // resume sound output
|
snd_pcm_prepare(handle); // resume sound output
|
||||||
}
|
}
|
||||||
@@ -79,7 +78,6 @@ void AlsaSound::SoundLoop()
|
|||||||
m_thread_status.store(ALSAThreadStatus::STOPPED);
|
m_thread_status.store(ALSAThreadStatus::STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AlsaSound::Clear(bool muted)
|
void AlsaSound::Clear(bool muted)
|
||||||
{
|
{
|
||||||
m_muted = muted;
|
m_muted = muted;
|
||||||
@@ -92,9 +90,9 @@ bool AlsaSound::AlsaInit()
|
|||||||
unsigned int sample_rate = m_mixer->GetSampleRate();
|
unsigned int sample_rate = m_mixer->GetSampleRate();
|
||||||
int err;
|
int err;
|
||||||
int dir;
|
int dir;
|
||||||
snd_pcm_sw_params_t *swparams;
|
snd_pcm_sw_params_t* swparams;
|
||||||
snd_pcm_hw_params_t *hwparams;
|
snd_pcm_hw_params_t* hwparams;
|
||||||
snd_pcm_uframes_t buffer_size,buffer_size_max;
|
snd_pcm_uframes_t buffer_size, buffer_size_max;
|
||||||
unsigned int periods;
|
unsigned int periods;
|
||||||
|
|
||||||
err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
||||||
@@ -179,16 +177,18 @@ bool AlsaSound::AlsaInit()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//periods is the number of fragments alsa can wait for during one
|
// periods is the number of fragments alsa can wait for during one
|
||||||
//buffer_size
|
// buffer_size
|
||||||
frames_to_deliver = buffer_size / periods;
|
frames_to_deliver = buffer_size / periods;
|
||||||
//limit the minimum size. pulseaudio advertises a minimum of 32 samples.
|
// limit the minimum size. pulseaudio advertises a minimum of 32 samples.
|
||||||
if (frames_to_deliver < FRAME_COUNT_MIN)
|
if (frames_to_deliver < FRAME_COUNT_MIN)
|
||||||
frames_to_deliver = FRAME_COUNT_MIN;
|
frames_to_deliver = FRAME_COUNT_MIN;
|
||||||
//it is probably a bad idea to try to send more than one buffer of data
|
// it is probably a bad idea to try to send more than one buffer of data
|
||||||
if ((unsigned int)frames_to_deliver > buffer_size)
|
if ((unsigned int)frames_to_deliver > buffer_size)
|
||||||
frames_to_deliver = buffer_size;
|
frames_to_deliver = buffer_size;
|
||||||
NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d samples per fragments.\n", buffer_size, periods, frames_to_deliver);
|
NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d "
|
||||||
|
"samples per fragments.\n",
|
||||||
|
buffer_size, periods, frames_to_deliver);
|
||||||
|
|
||||||
snd_pcm_sw_params_alloca(&swparams);
|
snd_pcm_sw_params_alloca(&swparams);
|
||||||
|
|
||||||
@@ -232,4 +232,3 @@ void AlsaSound::AlsaShutdown()
|
|||||||
handle = nullptr;
|
handle = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,7 @@ public:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
void Clear(bool) override;
|
void Clear(bool) override;
|
||||||
|
|
||||||
static bool isValid()
|
static bool isValid() { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// maximum number of frames the buffer can hold
|
// maximum number of frames the buffer can hold
|
||||||
static constexpr size_t BUFFER_SIZE_MAX = 8192;
|
static constexpr size_t BUFFER_SIZE_MAX = 8192;
|
||||||
@@ -60,7 +56,7 @@ private:
|
|||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
std::mutex cv_m;
|
std::mutex cv_m;
|
||||||
|
|
||||||
snd_pcm_t *handle;
|
snd_pcm_t* handle;
|
||||||
unsigned int frames_to_deliver;
|
unsigned int frames_to_deliver;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,22 +2,21 @@
|
|||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
|
||||||
#include "AudioCommon/AlsaSoundStream.h"
|
|
||||||
#include "AudioCommon/AOSoundStream.h"
|
|
||||||
#include "AudioCommon/AudioCommon.h"
|
#include "AudioCommon/AudioCommon.h"
|
||||||
|
#include "AudioCommon/AOSoundStream.h"
|
||||||
|
#include "AudioCommon/AlsaSoundStream.h"
|
||||||
#include "AudioCommon/CoreAudioSoundStream.h"
|
#include "AudioCommon/CoreAudioSoundStream.h"
|
||||||
#include "AudioCommon/Mixer.h"
|
#include "AudioCommon/Mixer.h"
|
||||||
#include "AudioCommon/NullSoundStream.h"
|
#include "AudioCommon/NullSoundStream.h"
|
||||||
#include "AudioCommon/OpenALStream.h"
|
#include "AudioCommon/OpenALStream.h"
|
||||||
#include "AudioCommon/OpenSLESStream.h"
|
#include "AudioCommon/OpenSLESStream.h"
|
||||||
#include "AudioCommon/PulseAudioStream.h"
|
#include "AudioCommon/PulseAudioStream.h"
|
||||||
#include "AudioCommon/XAudio2_7Stream.h"
|
|
||||||
#include "AudioCommon/XAudio2Stream.h"
|
#include "AudioCommon/XAudio2Stream.h"
|
||||||
|
#include "AudioCommon/XAudio2_7Stream.h"
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/MsgHandler.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/MsgHandler.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
|
||||||
@@ -28,11 +27,11 @@ static bool s_audio_dump_start = false;
|
|||||||
|
|
||||||
namespace AudioCommon
|
namespace AudioCommon
|
||||||
{
|
{
|
||||||
static const int AUDIO_VOLUME_MIN = 0;
|
static const int AUDIO_VOLUME_MIN = 0;
|
||||||
static const int AUDIO_VOLUME_MAX = 100;
|
static const int AUDIO_VOLUME_MAX = 100;
|
||||||
|
|
||||||
SoundStream* InitSoundStream()
|
SoundStream* InitSoundStream()
|
||||||
{
|
{
|
||||||
std::string backend = SConfig::GetInstance().sBackend;
|
std::string backend = SConfig::GetInstance().sBackend;
|
||||||
if (backend == BACKEND_OPENAL && OpenALStream::isValid())
|
if (backend == BACKEND_OPENAL && OpenALStream::isValid())
|
||||||
g_sound_stream = new OpenALStream();
|
g_sound_stream = new OpenALStream();
|
||||||
@@ -58,8 +57,8 @@ namespace AudioCommon
|
|||||||
|
|
||||||
if (!g_sound_stream && NullSound::isValid())
|
if (!g_sound_stream && NullSound::isValid())
|
||||||
{
|
{
|
||||||
WARN_LOG(AUDIO, "Could not initialize backend %s, using %s instead.",
|
WARN_LOG(AUDIO, "Could not initialize backend %s, using %s instead.", backend.c_str(),
|
||||||
backend.c_str(), BACKEND_NULLSOUND);
|
BACKEND_NULLSOUND);
|
||||||
g_sound_stream = new NullSound();
|
g_sound_stream = new NullSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +67,8 @@ namespace AudioCommon
|
|||||||
UpdateSoundStream();
|
UpdateSoundStream();
|
||||||
if (!g_sound_stream->Start())
|
if (!g_sound_stream->Start())
|
||||||
{
|
{
|
||||||
ERROR_LOG(AUDIO, "Could not start backend %s, using %s instead",
|
ERROR_LOG(AUDIO, "Could not start backend %s, using %s instead", backend.c_str(),
|
||||||
backend.c_str(), BACKEND_NULLSOUND);
|
BACKEND_NULLSOUND);
|
||||||
delete g_sound_stream;
|
delete g_sound_stream;
|
||||||
g_sound_stream = new NullSound();
|
g_sound_stream = new NullSound();
|
||||||
g_sound_stream->Start();
|
g_sound_stream->Start();
|
||||||
@@ -86,10 +85,10 @@ namespace AudioCommon
|
|||||||
delete g_sound_stream;
|
delete g_sound_stream;
|
||||||
g_sound_stream = nullptr;
|
g_sound_stream = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownSoundStream()
|
void ShutdownSoundStream()
|
||||||
{
|
{
|
||||||
INFO_LOG(AUDIO, "Shutting down sound stream");
|
INFO_LOG(AUDIO, "Shutting down sound stream");
|
||||||
|
|
||||||
if (g_sound_stream)
|
if (g_sound_stream)
|
||||||
@@ -102,10 +101,10 @@ namespace AudioCommon
|
|||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(AUDIO, "Done shutting down sound stream");
|
INFO_LOG(AUDIO, "Done shutting down sound stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetSoundBackends()
|
std::vector<std::string> GetSoundBackends()
|
||||||
{
|
{
|
||||||
std::vector<std::string> backends;
|
std::vector<std::string> backends;
|
||||||
|
|
||||||
if (NullSound::isValid())
|
if (NullSound::isValid())
|
||||||
@@ -125,25 +124,25 @@ namespace AudioCommon
|
|||||||
if (OpenSLESStream::isValid())
|
if (OpenSLESStream::isValid())
|
||||||
backends.push_back(BACKEND_OPENSLES);
|
backends.push_back(BACKEND_OPENSLES);
|
||||||
return backends;
|
return backends;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateSoundStream()
|
void UpdateSoundStream()
|
||||||
{
|
{
|
||||||
if (g_sound_stream)
|
if (g_sound_stream)
|
||||||
{
|
{
|
||||||
int volume = SConfig::GetInstance().m_IsMuted ? 0 : SConfig::GetInstance().m_Volume;
|
int volume = SConfig::GetInstance().m_IsMuted ? 0 : SConfig::GetInstance().m_Volume;
|
||||||
g_sound_stream->SetVolume(volume);
|
g_sound_stream->SetVolume(volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearAudioBuffer(bool mute)
|
void ClearAudioBuffer(bool mute)
|
||||||
{
|
{
|
||||||
if (g_sound_stream)
|
if (g_sound_stream)
|
||||||
g_sound_stream->Clear(mute);
|
g_sound_stream->Clear(mute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendAIBuffer(short *samples, unsigned int num_samples)
|
void SendAIBuffer(short* samples, unsigned int num_samples)
|
||||||
{
|
{
|
||||||
if (!g_sound_stream)
|
if (!g_sound_stream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -160,10 +159,10 @@ namespace AudioCommon
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_sound_stream->Update();
|
g_sound_stream->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartAudioDump()
|
void StartAudioDump()
|
||||||
{
|
{
|
||||||
std::string audio_file_name_dtk = File::GetUserPath(D_DUMPAUDIO_IDX) + "dtkdump.wav";
|
std::string audio_file_name_dtk = File::GetUserPath(D_DUMPAUDIO_IDX) + "dtkdump.wav";
|
||||||
std::string audio_file_name_dsp = File::GetUserPath(D_DUMPAUDIO_IDX) + "dspdump.wav";
|
std::string audio_file_name_dsp = File::GetUserPath(D_DUMPAUDIO_IDX) + "dspdump.wav";
|
||||||
File::CreateFullPath(audio_file_name_dtk);
|
File::CreateFullPath(audio_file_name_dtk);
|
||||||
@@ -171,39 +170,39 @@ namespace AudioCommon
|
|||||||
g_sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk);
|
g_sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk);
|
||||||
g_sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp);
|
g_sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp);
|
||||||
s_audio_dump_start = true;
|
s_audio_dump_start = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopAudioDump()
|
void StopAudioDump()
|
||||||
{
|
{
|
||||||
g_sound_stream->GetMixer()->StopLogDTKAudio();
|
g_sound_stream->GetMixer()->StopLogDTKAudio();
|
||||||
g_sound_stream->GetMixer()->StopLogDSPAudio();
|
g_sound_stream->GetMixer()->StopLogDSPAudio();
|
||||||
s_audio_dump_start = false;
|
s_audio_dump_start = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncreaseVolume(unsigned short offset)
|
void IncreaseVolume(unsigned short offset)
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_IsMuted = false;
|
SConfig::GetInstance().m_IsMuted = false;
|
||||||
int& currentVolume = SConfig::GetInstance().m_Volume;
|
int& currentVolume = SConfig::GetInstance().m_Volume;
|
||||||
currentVolume += offset;
|
currentVolume += offset;
|
||||||
if (currentVolume > AUDIO_VOLUME_MAX)
|
if (currentVolume > AUDIO_VOLUME_MAX)
|
||||||
currentVolume = AUDIO_VOLUME_MAX;
|
currentVolume = AUDIO_VOLUME_MAX;
|
||||||
UpdateSoundStream();
|
UpdateSoundStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecreaseVolume(unsigned short offset)
|
void DecreaseVolume(unsigned short offset)
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_IsMuted = false;
|
SConfig::GetInstance().m_IsMuted = false;
|
||||||
int& currentVolume = SConfig::GetInstance().m_Volume;
|
int& currentVolume = SConfig::GetInstance().m_Volume;
|
||||||
currentVolume -= offset;
|
currentVolume -= offset;
|
||||||
if (currentVolume < AUDIO_VOLUME_MIN)
|
if (currentVolume < AUDIO_VOLUME_MIN)
|
||||||
currentVolume = AUDIO_VOLUME_MIN;
|
currentVolume = AUDIO_VOLUME_MIN;
|
||||||
UpdateSoundStream();
|
UpdateSoundStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleMuteVolume()
|
void ToggleMuteVolume()
|
||||||
{
|
{
|
||||||
bool& isMuted = SConfig::GetInstance().m_IsMuted;
|
bool& isMuted = SConfig::GetInstance().m_IsMuted;
|
||||||
isMuted = !isMuted;
|
isMuted = !isMuted;
|
||||||
UpdateSoundStream();
|
UpdateSoundStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,21 @@
|
|||||||
#include "AudioCommon/SoundStream.h"
|
#include "AudioCommon/SoundStream.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
|
||||||
class CMixer;
|
class CMixer;
|
||||||
|
|
||||||
extern SoundStream *g_sound_stream;
|
extern SoundStream* g_sound_stream;
|
||||||
|
|
||||||
namespace AudioCommon
|
namespace AudioCommon
|
||||||
{
|
{
|
||||||
SoundStream* InitSoundStream();
|
SoundStream* InitSoundStream();
|
||||||
void ShutdownSoundStream();
|
void ShutdownSoundStream();
|
||||||
std::vector<std::string> GetSoundBackends();
|
std::vector<std::string> GetSoundBackends();
|
||||||
void UpdateSoundStream();
|
void UpdateSoundStream();
|
||||||
void ClearAudioBuffer(bool mute);
|
void ClearAudioBuffer(bool mute);
|
||||||
void SendAIBuffer(short* samples, unsigned int num_samples);
|
void SendAIBuffer(short* samples, unsigned int num_samples);
|
||||||
void StartAudioDump();
|
void StartAudioDump();
|
||||||
void StopAudioDump();
|
void StopAudioDump();
|
||||||
void IncreaseVolume(unsigned short offset);
|
void IncreaseVolume(unsigned short offset);
|
||||||
void DecreaseVolume(unsigned short offset);
|
void DecreaseVolume(unsigned short offset);
|
||||||
void ToggleMuteVolume();
|
void ToggleMuteVolume();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,13 @@
|
|||||||
#include "AudioCommon/CoreAudioSoundStream.h"
|
#include "AudioCommon/CoreAudioSoundStream.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
OSStatus CoreAudioSound::callback(void *inRefCon,
|
OSStatus CoreAudioSound::callback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
|
||||||
AudioUnitRenderActionFlags *ioActionFlags,
|
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber,
|
||||||
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
|
UInt32 inNumberFrames, AudioBufferList* ioData)
|
||||||
UInt32 inNumberFrames, AudioBufferList *ioData)
|
|
||||||
{
|
{
|
||||||
for (UInt32 i = 0; i < ioData->mNumberBuffers; i++)
|
for (UInt32 i = 0; i < ioData->mNumberBuffers; i++)
|
||||||
((CoreAudioSound *)inRefCon)->m_mixer->
|
((CoreAudioSound*)inRefCon)
|
||||||
Mix((short *)ioData->mBuffers[i].mData,
|
->m_mixer->Mix((short*)ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize / 4);
|
||||||
ioData->mBuffers[i].mDataByteSize / 4);
|
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
@@ -47,12 +45,9 @@ bool CoreAudioSound::Start()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FillOutASBDForLPCM(format, m_mixer->GetSampleRate(),
|
FillOutASBDForLPCM(format, m_mixer->GetSampleRate(), 2, 16, 16, false, false, false);
|
||||||
2, 16, 16, false, false, false);
|
err = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0,
|
||||||
err = AudioUnitSetProperty(audioUnit,
|
&format, sizeof(AudioStreamBasicDescription));
|
||||||
kAudioUnitProperty_StreamFormat,
|
|
||||||
kAudioUnitScope_Input, 0, &format,
|
|
||||||
sizeof(AudioStreamBasicDescription));
|
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
ERROR_LOG(AUDIO, "error setting audio format");
|
ERROR_LOG(AUDIO, "error setting audio format");
|
||||||
@@ -61,19 +56,15 @@ bool CoreAudioSound::Start()
|
|||||||
|
|
||||||
callback_struct.inputProc = callback;
|
callback_struct.inputProc = callback;
|
||||||
callback_struct.inputProcRefCon = this;
|
callback_struct.inputProcRefCon = this;
|
||||||
err = AudioUnitSetProperty(audioUnit,
|
err = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
|
||||||
kAudioUnitProperty_SetRenderCallback,
|
0, &callback_struct, sizeof callback_struct);
|
||||||
kAudioUnitScope_Input, 0, &callback_struct,
|
|
||||||
sizeof callback_struct);
|
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
ERROR_LOG(AUDIO, "error setting audio callback");
|
ERROR_LOG(AUDIO, "error setting audio callback");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AudioUnitSetParameter(audioUnit,
|
err = AudioUnitSetParameter(audioUnit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0,
|
||||||
kHALOutputParam_Volume,
|
|
||||||
kAudioUnitScope_Output, 0,
|
|
||||||
m_volume / 100., 0);
|
m_volume / 100., 0);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
ERROR_LOG(AUDIO, "error setting volume");
|
ERROR_LOG(AUDIO, "error setting volume");
|
||||||
@@ -100,9 +91,7 @@ void CoreAudioSound::SetVolume(int volume)
|
|||||||
OSStatus err;
|
OSStatus err;
|
||||||
m_volume = volume;
|
m_volume = volume;
|
||||||
|
|
||||||
err = AudioUnitSetParameter(audioUnit,
|
err = AudioUnitSetParameter(audioUnit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0,
|
||||||
kHALOutputParam_Volume,
|
|
||||||
kAudioUnitScope_Output, 0,
|
|
||||||
volume / 100., 0);
|
volume / 100., 0);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
ERROR_LOG(AUDIO, "error setting volume");
|
ERROR_LOG(AUDIO, "error setting volume");
|
||||||
|
|||||||
@@ -20,19 +20,13 @@ public:
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
static bool isValid()
|
static bool isValid() { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioUnit audioUnit;
|
AudioUnit audioUnit;
|
||||||
int m_volume;
|
int m_volume;
|
||||||
|
|
||||||
static OSStatus callback(void *inRefCon,
|
static OSStatus callback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
|
||||||
AudioUnitRenderActionFlags *ioActionFlags,
|
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber,
|
||||||
const AudioTimeStamp *inTimeStamp,
|
UInt32 inNumberFrames, AudioBufferList* ioData);
|
||||||
UInt32 inBusNumber, UInt32 inNumberFrames,
|
|
||||||
AudioBufferList *ioData);
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ static float adapt_l_gain, adapt_r_gain, adapt_lpr_gain, adapt_lmr_gain;
|
|||||||
static std::vector<float> lf, rf, lr, rr, cf, cr;
|
static std::vector<float> lf, rf, lr, rr, cf, cr;
|
||||||
static float LFE_buf[256];
|
static float LFE_buf[256];
|
||||||
static unsigned int lfe_pos;
|
static unsigned int lfe_pos;
|
||||||
static float *filter_coefs_lfe;
|
static float* filter_coefs_lfe;
|
||||||
static unsigned int len125;
|
static unsigned int len125;
|
||||||
|
|
||||||
template<class T, class _ftype_t>
|
template <class T, class _ftype_t>
|
||||||
static _ftype_t DotProduct(int count, const T *buf, const _ftype_t *coefficients)
|
static _ftype_t DotProduct(int count, const T* buf, const _ftype_t* coefficients)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float sum0 = 0.0f, sum1 = 0.0f, sum2 = 0.0f, sum3 = 0.0f;
|
float sum0 = 0.0f, sum1 = 0.0f, sum2 = 0.0f, sum3 = 0.0f;
|
||||||
@@ -60,15 +60,16 @@ static _ftype_t DotProduct(int count, const T *buf, const _ftype_t *coefficients
|
|||||||
return sum0 + sum1 + sum2 + sum3;
|
return sum0 + sum1 + sum2 + sum3;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
static T FIRFilter(const T *buf, int pos, int len, int count, const float *coefficients)
|
static T FIRFilter(const T* buf, int pos, int len, int count, const float* coefficients)
|
||||||
{
|
{
|
||||||
int count1, count2;
|
int count1, count2;
|
||||||
|
|
||||||
if (pos >= count)
|
if (pos >= count)
|
||||||
{
|
{
|
||||||
pos -= count;
|
pos -= count;
|
||||||
count1 = count; count2 = 0;
|
count1 = count;
|
||||||
|
count2 = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -78,9 +79,10 @@ static T FIRFilter(const T *buf, int pos, int len, int count, const float *coeff
|
|||||||
}
|
}
|
||||||
|
|
||||||
// high part of window
|
// high part of window
|
||||||
const T *ptr = &buf[pos];
|
const T* ptr = &buf[pos];
|
||||||
|
|
||||||
float r1 = DotProduct(count1, ptr, coefficients); coefficients += count1;
|
float r1 = DotProduct(count1, ptr, coefficients);
|
||||||
|
coefficients += count1;
|
||||||
float r2 = DotProduct(count2, buf, coefficients);
|
float r2 = DotProduct(count2, buf, coefficients);
|
||||||
return T(r1 + r2);
|
return T(r1 + r2);
|
||||||
}
|
}
|
||||||
@@ -96,11 +98,11 @@ static T FIRFilter(const T *buf, int pos, int len, int count, const float *coeff
|
|||||||
*/
|
*/
|
||||||
static void Hamming(int n, float* w)
|
static void Hamming(int n, float* w)
|
||||||
{
|
{
|
||||||
float k = float(2*M_PI/((float)(n - 1))); // 2*pi/(N-1)
|
float k = float(2 * M_PI / ((float)(n - 1))); // 2*pi/(N-1)
|
||||||
|
|
||||||
// Calculate window coefficients
|
// Calculate window coefficients
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
*w++ = float(0.54 - 0.46*cos(k*(float)i));
|
*w++ = float(0.54 - 0.46 * cos(k * (float)i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@@ -120,7 +122,7 @@ opt beta constant used only when designing using kaiser windows
|
|||||||
|
|
||||||
returns 0 if OK, -1 if fail
|
returns 0 if OK, -1 if fail
|
||||||
*/
|
*/
|
||||||
static float* DesignFIR(unsigned int *n, float* fc, float opt)
|
static float* DesignFIR(unsigned int* n, float* fc, float opt)
|
||||||
{
|
{
|
||||||
unsigned int o = *n & 1; // Indicator for odd filter length
|
unsigned int o = *n & 1; // Indicator for odd filter length
|
||||||
unsigned int end = ((*n + 1) >> 1) - o; // Loop end
|
unsigned int end = ((*n + 1) >> 1) - o; // Loop end
|
||||||
@@ -137,7 +139,7 @@ static float* DesignFIR(unsigned int *n, float* fc, float opt)
|
|||||||
|
|
||||||
fc[0] = MathUtil::Clamp(fc[0], 0.001f, 1.0f);
|
fc[0] = MathUtil::Clamp(fc[0], 0.001f, 1.0f);
|
||||||
|
|
||||||
float *w = (float*)calloc(sizeof(float), *n);
|
float* w = (float*)calloc(sizeof(float), *n);
|
||||||
|
|
||||||
// Get window coefficients
|
// Get window coefficients
|
||||||
Hamming(*n, w);
|
Hamming(*n, w);
|
||||||
@@ -163,13 +165,12 @@ static float* DesignFIR(unsigned int *n, float* fc, float opt)
|
|||||||
for (u32 i = 0; i < end; i++)
|
for (u32 i = 0; i < end; i++)
|
||||||
{
|
{
|
||||||
t1 = (float)(i + 1) - k2;
|
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
|
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
|
g += 2 * w[end - i - 1]; // Total gain in filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Normalize gain
|
// Normalize gain
|
||||||
g = 1/g;
|
g = 1 / g;
|
||||||
for (u32 i = 0; i < *n; i++)
|
for (u32 i = 0; i < *n; i++)
|
||||||
w[i] *= g;
|
w[i] *= g;
|
||||||
|
|
||||||
@@ -208,7 +209,7 @@ static float* CalculateCoefficients125HzLowpass(int rate)
|
|||||||
{
|
{
|
||||||
len125 = 256;
|
len125 = 256;
|
||||||
float f = 125.0f / (rate / 2);
|
float f = 125.0f / (rate / 2);
|
||||||
float *coeffs = DesignFIR(&len125, &f, 0);
|
float* coeffs = DesignFIR(&len125, &f, 0);
|
||||||
static const float M3_01DB = 0.7071067812f;
|
static const float M3_01DB = 0.7071067812f;
|
||||||
for (unsigned int i = 0; i < len125; i++)
|
for (unsigned int i = 0; i < len125; i++)
|
||||||
{
|
{
|
||||||
@@ -219,26 +220,24 @@ static float* CalculateCoefficients125HzLowpass(int rate)
|
|||||||
|
|
||||||
static float PassiveLock(float x)
|
static float PassiveLock(float x)
|
||||||
{
|
{
|
||||||
static const float MATAGCLOCK = 0.2f; /* AGC range (around 1) where the matrix behaves passively */
|
static const float MATAGCLOCK =
|
||||||
|
0.2f; /* AGC range (around 1) where the matrix behaves passively */
|
||||||
const float x1 = x - 1;
|
const float x1 = x - 1;
|
||||||
const float ax1s = fabs(x - 1) * (1.0f / MATAGCLOCK);
|
const float ax1s = fabs(x - 1) * (1.0f / MATAGCLOCK);
|
||||||
return x1 - x1 / (1 + ax1s * ax1s) + 1;
|
return x1 - x1 / (1 + ax1s * ax1s) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MatrixDecode(const float *in, const int k, const int il,
|
static void MatrixDecode(const float* in, const int k, const int il, const int ir, bool decode_rear,
|
||||||
const int ir, bool decode_rear,
|
const int _dlbuflen, float _l_fwr, float _r_fwr, float _lpr_fwr,
|
||||||
const int _dlbuflen,
|
float _lmr_fwr, float* _adapt_l_gain, float* _adapt_r_gain,
|
||||||
float _l_fwr, float _r_fwr,
|
float* _adapt_lpr_gain, float* _adapt_lmr_gain, float* _lf, float* _rf,
|
||||||
float _lpr_fwr, float _lmr_fwr,
|
float* _lr, float* _rr, float* _cf)
|
||||||
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 M9_03DB = 0.3535533906f;
|
||||||
static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
|
static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
|
||||||
static const float MATAGCDECAY = 1.0f; /* AGC baseline decay rate (1/samp.) */
|
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. */
|
static const float MATCOMPGAIN =
|
||||||
|
0.37f; /* Cross talk compensation gain, 0.50 - 0.55 is full cancellation. */
|
||||||
|
|
||||||
const int kr = (k + olddelay) % _dlbuflen;
|
const int kr = (k + olddelay) % _dlbuflen;
|
||||||
float l_gain = (_l_fwr + _r_fwr) / (1 + _l_fwr + _l_fwr);
|
float l_gain = (_l_fwr + _r_fwr) / (1 + _l_fwr + _l_fwr);
|
||||||
@@ -310,7 +309,7 @@ static void MatrixDecode(const float *in, const int k, const int il,
|
|||||||
_cf[k] += c_agc_cfk + c_agc_cfk;
|
_cf[k] += c_agc_cfk + c_agc_cfk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DPL2Decode(float *samples, int numsamples, float *out)
|
void DPL2Decode(float* samples, int numsamples, float* out)
|
||||||
{
|
{
|
||||||
static const unsigned int FWRDURATION = 240; // FWR average duration (samples)
|
static const unsigned int FWRDURATION = 240; // FWR average duration (samples)
|
||||||
static const int cfg_delay = 0;
|
static const int cfg_delay = 0;
|
||||||
@@ -339,8 +338,8 @@ void DPL2Decode(float *samples, int numsamples, float *out)
|
|||||||
memset(LFE_buf, 0, sizeof(LFE_buf));
|
memset(LFE_buf, 0, sizeof(LFE_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
float *in = samples; // Input audio data
|
float* in = samples; // Input audio data
|
||||||
float *end = in + numsamples * fmt_nchannels; // Loop end
|
float* end = in + numsamples * fmt_nchannels; // Loop end
|
||||||
|
|
||||||
while (in < end)
|
while (in < end)
|
||||||
{
|
{
|
||||||
@@ -357,12 +356,9 @@ void DPL2Decode(float *samples, int numsamples, float *out)
|
|||||||
/* Matrix encoded 2 channel sources */
|
/* Matrix encoded 2 channel sources */
|
||||||
fwrbuf_l[k] = in[0];
|
fwrbuf_l[k] = in[0];
|
||||||
fwrbuf_r[k] = in[1];
|
fwrbuf_r[k] = in[1];
|
||||||
MatrixDecode(in, k, 0, 1, true, dlbuflen,
|
MatrixDecode(in, k, 0, 1, true, dlbuflen, l_fwr, r_fwr, lpr_fwr, lmr_fwr, &adapt_l_gain,
|
||||||
l_fwr, r_fwr,
|
&adapt_r_gain, &adapt_lpr_gain, &adapt_lmr_gain, &lf[0], &rf[0], &lr[0], &rr[0],
|
||||||
lpr_fwr, lmr_fwr,
|
&cf[0]);
|
||||||
&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 + 0] = lf[k];
|
||||||
out[cur + 1] = rf[k];
|
out[cur + 1] = rf[k];
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void DPL2Decode(float *samples, int numsamples, float *out);
|
void DPL2Decode(float* samples, int numsamples, float* out);
|
||||||
void DPL2Reset();
|
void DPL2Reset();
|
||||||
|
|||||||
@@ -8,16 +8,15 @@
|
|||||||
#include "AudioCommon/Mixer.h"
|
#include "AudioCommon/Mixer.h"
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/MathUtil.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/MathUtil.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
#if _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__)
|
#if _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__)
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CMixer::CMixer(unsigned int BackendSampleRate)
|
CMixer::CMixer(unsigned int BackendSampleRate) : m_sampleRate(BackendSampleRate)
|
||||||
: m_sampleRate(BackendSampleRate)
|
|
||||||
{
|
{
|
||||||
INFO_LOG(AUDIO_INTERFACE, "Mixer is initialized");
|
INFO_LOG(AUDIO_INTERFACE, "Mixer is initialized");
|
||||||
}
|
}
|
||||||
@@ -27,7 +26,8 @@ CMixer::~CMixer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Executed from sound stream thread
|
// Executed from sound stream thread
|
||||||
unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, bool consider_framelimit)
|
unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
|
||||||
|
bool consider_framelimit)
|
||||||
{
|
{
|
||||||
unsigned int currentSample = 0;
|
unsigned int currentSample = 0;
|
||||||
|
|
||||||
@@ -45,14 +45,16 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
|
|||||||
low_waterwark = std::min(low_waterwark, MAX_SAMPLES / 2);
|
low_waterwark = std::min(low_waterwark, MAX_SAMPLES / 2);
|
||||||
|
|
||||||
float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2);
|
float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2);
|
||||||
m_numLeftI = (numLeft + m_numLeftI*(CONTROL_AVG-1)) / CONTROL_AVG;
|
m_numLeftI = (numLeft + m_numLeftI * (CONTROL_AVG - 1)) / CONTROL_AVG;
|
||||||
float offset = (m_numLeftI - low_waterwark) * CONTROL_FACTOR;
|
float offset = (m_numLeftI - low_waterwark) * CONTROL_FACTOR;
|
||||||
if (offset > MAX_FREQ_SHIFT) offset = MAX_FREQ_SHIFT;
|
if (offset > MAX_FREQ_SHIFT)
|
||||||
if (offset < -MAX_FREQ_SHIFT) offset = -MAX_FREQ_SHIFT;
|
offset = MAX_FREQ_SHIFT;
|
||||||
|
if (offset < -MAX_FREQ_SHIFT)
|
||||||
|
offset = -MAX_FREQ_SHIFT;
|
||||||
|
|
||||||
//render numleft sample pairs to samples[]
|
// render numleft sample pairs to samples[]
|
||||||
//advance indexR with sample position
|
// advance indexR with sample position
|
||||||
//remember fractional offset
|
// remember fractional offset
|
||||||
|
|
||||||
float emulationspeed = SConfig::GetInstance().m_EmulationSpeed;
|
float emulationspeed = SConfig::GetInstance().m_EmulationSpeed;
|
||||||
float aid_sample_rate = m_input_sample_rate + offset;
|
float aid_sample_rate = m_input_sample_rate + offset;
|
||||||
@@ -67,19 +69,19 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
|
|||||||
s32 rvolume = m_RVolume.load();
|
s32 rvolume = m_RVolume.load();
|
||||||
|
|
||||||
// TODO: consider a higher-quality resampling algorithm.
|
// TODO: consider a higher-quality resampling algorithm.
|
||||||
for (; currentSample < numSamples * 2 && ((indexW-indexR) & INDEX_MASK) > 2; currentSample += 2)
|
for (; currentSample < numSamples * 2 && ((indexW - indexR) & INDEX_MASK) > 2; currentSample += 2)
|
||||||
{
|
{
|
||||||
u32 indexR2 = indexR + 2; //next sample
|
u32 indexR2 = indexR + 2; // next sample
|
||||||
|
|
||||||
s16 l1 = Common::swap16(m_buffer[indexR & INDEX_MASK]); //current
|
s16 l1 = Common::swap16(m_buffer[indexR & INDEX_MASK]); // current
|
||||||
s16 l2 = Common::swap16(m_buffer[indexR2 & INDEX_MASK]); //next
|
s16 l2 = Common::swap16(m_buffer[indexR2 & INDEX_MASK]); // next
|
||||||
int sampleL = ((l1 << 16) + (l2 - l1) * (u16)m_frac) >> 16;
|
int sampleL = ((l1 << 16) + (l2 - l1) * (u16)m_frac) >> 16;
|
||||||
sampleL = (sampleL * lvolume) >> 8;
|
sampleL = (sampleL * lvolume) >> 8;
|
||||||
sampleL += samples[currentSample + 1];
|
sampleL += samples[currentSample + 1];
|
||||||
samples[currentSample + 1] = MathUtil::Clamp(sampleL, -32767, 32767);
|
samples[currentSample + 1] = MathUtil::Clamp(sampleL, -32767, 32767);
|
||||||
|
|
||||||
s16 r1 = Common::swap16(m_buffer[(indexR + 1) & INDEX_MASK]); //current
|
s16 r1 = Common::swap16(m_buffer[(indexR + 1) & INDEX_MASK]); // current
|
||||||
s16 r2 = Common::swap16(m_buffer[(indexR2 + 1) & INDEX_MASK]); //next
|
s16 r2 = Common::swap16(m_buffer[(indexR2 + 1) & INDEX_MASK]); // next
|
||||||
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)m_frac) >> 16;
|
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)m_frac) >> 16;
|
||||||
sampleR = (sampleR * rvolume) >> 8;
|
sampleR = (sampleR * rvolume) >> 8;
|
||||||
sampleR += samples[currentSample];
|
sampleR += samples[currentSample];
|
||||||
@@ -124,7 +126,7 @@ unsigned int CMixer::Mix(short* samples, unsigned int num_samples, bool consider
|
|||||||
return num_samples;
|
return num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMixer::MixerFifo::PushSamples(const short *samples, unsigned int num_samples)
|
void CMixer::MixerFifo::PushSamples(const short* samples, unsigned int num_samples)
|
||||||
{
|
{
|
||||||
// Cache access in non-volatile variable
|
// Cache access in non-volatile variable
|
||||||
// indexR isn't allowed to cache in the audio throttling loop as it
|
// indexR isn't allowed to cache in the audio throttling loop as it
|
||||||
@@ -153,21 +155,22 @@ void CMixer::MixerFifo::PushSamples(const short *samples, unsigned int num_sampl
|
|||||||
m_indexW.fetch_add(num_samples * 2);
|
m_indexW.fetch_add(num_samples * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMixer::PushSamples(const short *samples, unsigned int num_samples)
|
void CMixer::PushSamples(const short* samples, unsigned int num_samples)
|
||||||
{
|
{
|
||||||
m_dma_mixer.PushSamples(samples, num_samples);
|
m_dma_mixer.PushSamples(samples, num_samples);
|
||||||
if (m_log_dsp_audio)
|
if (m_log_dsp_audio)
|
||||||
m_wave_writer_dsp.AddStereoSamplesBE(samples, num_samples);
|
m_wave_writer_dsp.AddStereoSamplesBE(samples, num_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMixer::PushStreamingSamples(const short *samples, unsigned int num_samples)
|
void CMixer::PushStreamingSamples(const short* samples, unsigned int num_samples)
|
||||||
{
|
{
|
||||||
m_streaming_mixer.PushSamples(samples, num_samples);
|
m_streaming_mixer.PushSamples(samples, num_samples);
|
||||||
if (m_log_dtk_audio)
|
if (m_log_dtk_audio)
|
||||||
m_wave_writer_dtk.AddStereoSamplesBE(samples, num_samples);
|
m_wave_writer_dtk.AddStereoSamplesBE(samples, num_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMixer::PushWiimoteSpeakerSamples(const short *samples, unsigned int num_samples, unsigned int sample_rate)
|
void CMixer::PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples,
|
||||||
|
unsigned int sample_rate)
|
||||||
{
|
{
|
||||||
short samples_stereo[MAX_SAMPLES * 2];
|
short samples_stereo[MAX_SAMPLES * 2];
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ public:
|
|||||||
// Called from main thread
|
// Called from main thread
|
||||||
void PushSamples(const short* samples, unsigned int num_samples);
|
void PushSamples(const short* samples, unsigned int num_samples);
|
||||||
void PushStreamingSamples(const short* samples, unsigned int num_samples);
|
void PushStreamingSamples(const short* samples, unsigned int num_samples);
|
||||||
void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, unsigned int sample_rate);
|
void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples,
|
||||||
|
unsigned int sample_rate);
|
||||||
unsigned int GetSampleRate() const { return m_sampleRate; }
|
unsigned int GetSampleRate() const { return m_sampleRate; }
|
||||||
|
|
||||||
void SetDMAInputSampleRate(unsigned int rate);
|
void SetDMAInputSampleRate(unsigned int rate);
|
||||||
void SetStreamInputSampleRate(unsigned int rate);
|
void SetStreamInputSampleRate(unsigned int rate);
|
||||||
void SetStreamingVolume(unsigned int lvolume, unsigned int rvolume);
|
void SetStreamingVolume(unsigned int lvolume, unsigned int rvolume);
|
||||||
@@ -38,7 +38,6 @@ public:
|
|||||||
|
|
||||||
float GetCurrentSpeed() const { return m_speed.load(); }
|
float GetCurrentSpeed() const { return m_speed.load(); }
|
||||||
void UpdateSpeed(float val) { m_speed.store(val); }
|
void UpdateSpeed(float val) { m_speed.store(val); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr u32 MAX_SAMPLES = 1024 * 4; // 128 ms
|
static constexpr u32 MAX_SAMPLES = 1024 * 4; // 128 ms
|
||||||
static constexpr u32 INDEX_MASK = MAX_SAMPLES * 2 - 1;
|
static constexpr u32 INDEX_MASK = MAX_SAMPLES * 2 - 1;
|
||||||
@@ -50,14 +49,14 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MixerFifo(CMixer* mixer, unsigned sample_rate)
|
MixerFifo(CMixer* mixer, unsigned sample_rate)
|
||||||
: m_mixer(mixer)
|
: m_mixer(mixer), m_input_sample_rate(sample_rate)
|
||||||
, m_input_sample_rate(sample_rate)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void PushSamples(const short* samples, unsigned int num_samples);
|
void PushSamples(const short* samples, unsigned int num_samples);
|
||||||
unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true);
|
unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true);
|
||||||
void SetInputSampleRate(unsigned int rate);
|
void SetInputSampleRate(unsigned int rate);
|
||||||
void SetVolume(unsigned int lvolume, unsigned int rvolume);
|
void SetVolume(unsigned int lvolume, unsigned int rvolume);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CMixer* m_mixer;
|
CMixer* m_mixer;
|
||||||
unsigned m_input_sample_rate;
|
unsigned m_input_sample_rate;
|
||||||
|
|||||||
@@ -25,9 +25,12 @@ void NullSound::Update()
|
|||||||
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
|
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
|
||||||
constexpr u32 stereo_16_bit_size = 4;
|
constexpr u32 stereo_16_bit_size = 4;
|
||||||
constexpr u32 dma_length = 32;
|
constexpr u32 dma_length = 32;
|
||||||
const u64 audio_dma_period = SystemTimers::GetTicksPerSecond() / (AudioInterface::GetAIDSampleRate() * stereo_16_bit_size / dma_length);
|
const u64 audio_dma_period =
|
||||||
|
SystemTimers::GetTicksPerSecond() /
|
||||||
|
(AudioInterface::GetAIDSampleRate() * stereo_16_bit_size / dma_length);
|
||||||
const u64 ais_samples_per_second = 48000 * stereo_16_bit_size;
|
const u64 ais_samples_per_second = 48000 * stereo_16_bit_size;
|
||||||
const u64 num_samples_to_render = (audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond();
|
const u64 num_samples_to_render =
|
||||||
|
(audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond();
|
||||||
|
|
||||||
m_mixer->Mix(m_realtime_buffer.data(), (unsigned int)num_samples_to_render);
|
m_mixer->Mix(m_realtime_buffer.data(), (unsigned int)num_samples_to_render);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
static bool isValid() { return true; }
|
static bool isValid() { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t BUFFER_SIZE = 48000 * 4 / 32;
|
static constexpr size_t BUFFER_SIZE = 48000 * 4 / 32;
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "AudioCommon/aldlist.h"
|
|
||||||
#include "AudioCommon/DPL2Decoder.h"
|
#include "AudioCommon/DPL2Decoder.h"
|
||||||
#include "AudioCommon/OpenALStream.h"
|
#include "AudioCommon/OpenALStream.h"
|
||||||
#include "Common/Thread.h"
|
#include "AudioCommon/aldlist.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/Thread.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
#if defined HAVE_OPENAL && HAVE_OPENAL
|
#if defined HAVE_OPENAL && HAVE_OPENAL
|
||||||
@@ -31,20 +31,20 @@ bool OpenALStream::Start()
|
|||||||
ALDeviceList pDeviceList;
|
ALDeviceList pDeviceList;
|
||||||
if (pDeviceList.GetNumDevices())
|
if (pDeviceList.GetNumDevices())
|
||||||
{
|
{
|
||||||
char *defDevName = pDeviceList.GetDeviceName(pDeviceList.GetDefaultDevice());
|
char* defDevName = pDeviceList.GetDeviceName(pDeviceList.GetDefaultDevice());
|
||||||
|
|
||||||
WARN_LOG(AUDIO, "Found OpenAL device %s", defDevName);
|
WARN_LOG(AUDIO, "Found OpenAL device %s", defDevName);
|
||||||
|
|
||||||
ALCdevice *pDevice = alcOpenDevice(defDevName);
|
ALCdevice* pDevice = alcOpenDevice(defDevName);
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
{
|
{
|
||||||
ALCcontext *pContext = alcCreateContext(pDevice, nullptr);
|
ALCcontext* pContext = alcCreateContext(pDevice, nullptr);
|
||||||
if (pContext)
|
if (pContext)
|
||||||
{
|
{
|
||||||
// Used to determine an appropriate period size (2x period = total buffer size)
|
// Used to determine an appropriate period size (2x period = total buffer size)
|
||||||
//ALCint refresh;
|
// ALCint refresh;
|
||||||
//alcGetIntegerv(pDevice, ALC_REFRESH, 1, &refresh);
|
// alcGetIntegerv(pDevice, ALC_REFRESH, 1, &refresh);
|
||||||
//period_size_in_millisec = 1000 / refresh;
|
// period_size_in_millisec = 1000 / refresh;
|
||||||
|
|
||||||
alcMakeContextCurrent(pContext);
|
alcMakeContextCurrent(pContext);
|
||||||
thread = std::thread(&OpenALStream::SoundLoop, this);
|
thread = std::thread(&OpenALStream::SoundLoop, this);
|
||||||
@@ -91,8 +91,8 @@ void OpenALStream::Stop()
|
|||||||
uiSource = 0;
|
uiSource = 0;
|
||||||
alDeleteBuffers(numBuffers, uiBuffers);
|
alDeleteBuffers(numBuffers, uiBuffers);
|
||||||
|
|
||||||
ALCcontext *pContext = alcGetCurrentContext();
|
ALCcontext* pContext = alcGetCurrentContext();
|
||||||
ALCdevice *pDevice = alcGetContextsDevice(pContext);
|
ALCdevice* pDevice = alcGetContextsDevice(pContext);
|
||||||
|
|
||||||
alcMakeContextCurrent(nullptr);
|
alcMakeContextCurrent(nullptr);
|
||||||
alcDestroyContext(pContext);
|
alcDestroyContext(pContext);
|
||||||
@@ -149,12 +149,13 @@ void OpenALStream::SoundLoop()
|
|||||||
memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
|
memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
|
||||||
uiSource = 0;
|
uiSource = 0;
|
||||||
|
|
||||||
// Checks if a X-Fi is being used. If it is, disable FLOAT32 support as this sound card has no support for it even though it reports it does.
|
// Checks if a X-Fi is being used. If it is, disable FLOAT32 support as this sound card has no
|
||||||
|
// support for it even though it reports it does.
|
||||||
if (strstr(alGetString(AL_RENDERER), "X-Fi"))
|
if (strstr(alGetString(AL_RENDERER), "X-Fi"))
|
||||||
float32_capable = false;
|
float32_capable = false;
|
||||||
|
|
||||||
// Generate some AL Buffers for streaming
|
// Generate some AL Buffers for streaming
|
||||||
alGenBuffers(numBuffers, (ALuint *)uiBuffers);
|
alGenBuffers(numBuffers, (ALuint*)uiBuffers);
|
||||||
// Generate a Source to playback the Buffers
|
// Generate a Source to playback the Buffers
|
||||||
alGenSources(1, &uiSource);
|
alGenSources(1, &uiSource);
|
||||||
|
|
||||||
@@ -171,13 +172,16 @@ void OpenALStream::SoundLoop()
|
|||||||
if (surround_capable)
|
if (surround_capable)
|
||||||
{
|
{
|
||||||
if (float32_capable)
|
if (float32_capable)
|
||||||
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * FRAME_SURROUND_FLOAT, ulFrequency);
|
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * FRAME_SURROUND_FLOAT,
|
||||||
|
ulFrequency);
|
||||||
else
|
else
|
||||||
alBufferData(uiBuffers[i], AL_FORMAT_51CHN16, sampleBuffer, 4 * FRAME_SURROUND_SHORT, ulFrequency);
|
alBufferData(uiBuffers[i], AL_FORMAT_51CHN16, sampleBuffer, 4 * FRAME_SURROUND_SHORT,
|
||||||
|
ulFrequency);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * FRAME_STEREO_SHORT, ulFrequency);
|
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * FRAME_STEREO_SHORT,
|
||||||
|
ulFrequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
|
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
|
||||||
@@ -187,12 +191,12 @@ void OpenALStream::SoundLoop()
|
|||||||
alSourcef(uiSource, AL_GAIN, fVolume);
|
alSourcef(uiSource, AL_GAIN, fVolume);
|
||||||
|
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
//ALenum err = alGetError();
|
// ALenum err = alGetError();
|
||||||
|
|
||||||
ALint iBuffersFilled = 0;
|
ALint iBuffersFilled = 0;
|
||||||
ALint iBuffersProcessed = 0;
|
ALint iBuffersProcessed = 0;
|
||||||
ALint iState = 0;
|
ALint iState = 0;
|
||||||
ALuint uiBufferTemp[OAL_MAX_BUFFERS] = { 0 };
|
ALuint uiBufferTemp[OAL_MAX_BUFFERS] = {0};
|
||||||
|
|
||||||
soundTouch.setChannels(2);
|
soundTouch.setChannels(2);
|
||||||
soundTouch.setSampleRate(ulFrequency);
|
soundTouch.setSampleRate(ulFrequency);
|
||||||
@@ -209,11 +213,14 @@ void OpenALStream::SoundLoop()
|
|||||||
const u32 stereo_16_bit_size = 4;
|
const u32 stereo_16_bit_size = 4;
|
||||||
const u32 dma_length = 32;
|
const u32 dma_length = 32;
|
||||||
const u64 ais_samples_per_second = 48000 * stereo_16_bit_size;
|
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 audio_dma_period = SystemTimers::GetTicksPerSecond() /
|
||||||
u64 num_samples_to_render = (audio_dma_period * ais_samples_per_second) / 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;
|
unsigned int numSamples = (unsigned int)num_samples_to_render;
|
||||||
unsigned int minSamples = surround_capable ? 240 : 0; // DPL2 accepts 240 samples minimum (FWRDURATION)
|
unsigned int minSamples =
|
||||||
|
surround_capable ? 240 : 0; // DPL2 accepts 240 samples minimum (FWRDURATION)
|
||||||
|
|
||||||
numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
|
numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
|
||||||
numSamples = m_mixer->Mix(realtimeBuffer, numSamples, false);
|
numSamples = m_mixer->Mix(realtimeBuffer, numSamples, false);
|
||||||
@@ -256,7 +263,8 @@ void OpenALStream::SoundLoop()
|
|||||||
if (nSamples <= minSamples)
|
if (nSamples <= minSamples)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
|
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued
|
||||||
|
// Buffer)
|
||||||
if (iBuffersFilled == 0)
|
if (iBuffersFilled == 0)
|
||||||
{
|
{
|
||||||
alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
|
alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
|
||||||
@@ -278,12 +286,13 @@ void OpenALStream::SoundLoop()
|
|||||||
// DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
|
// DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
|
||||||
for (u32 i = 0; i < nSamples; ++i)
|
for (u32 i = 0; i < nSamples; ++i)
|
||||||
{
|
{
|
||||||
dpl2[i*SURROUND_CHANNELS + 3 /*sub/lfe*/] = 0.0f;
|
dpl2[i * SURROUND_CHANNELS + 3 /*sub/lfe*/] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (float32_capable)
|
if (float32_capable)
|
||||||
{
|
{
|
||||||
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
|
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2,
|
||||||
|
nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -291,14 +300,16 @@ void OpenALStream::SoundLoop()
|
|||||||
for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
|
for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
|
||||||
surround_short[i] = (short)((float)dpl2[i] * (1 << 15));
|
surround_short[i] = (short)((float)dpl2[i] * (1 << 15));
|
||||||
|
|
||||||
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN16, surround_short, nSamples * FRAME_SURROUND_SHORT, ulFrequency);
|
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN16, surround_short,
|
||||||
|
nSamples * FRAME_SURROUND_SHORT, ulFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALenum err = alGetError();
|
ALenum err = alGetError();
|
||||||
if (err == AL_INVALID_ENUM)
|
if (err == AL_INVALID_ENUM)
|
||||||
{
|
{
|
||||||
// 5.1 is not supported by the host, fallback to stereo
|
// 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.");
|
WARN_LOG(AUDIO,
|
||||||
|
"Unable to set 5.1 surround mode. Updating OpenAL Soft might fix this issue.");
|
||||||
surround_capable = false;
|
surround_capable = false;
|
||||||
}
|
}
|
||||||
else if (err != 0)
|
else if (err != 0)
|
||||||
@@ -311,7 +322,8 @@ void OpenALStream::SoundLoop()
|
|||||||
{
|
{
|
||||||
if (float32_capable)
|
if (float32_capable)
|
||||||
{
|
{
|
||||||
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * FRAME_STEREO_FLOAT, ulFrequency);
|
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer,
|
||||||
|
nSamples * FRAME_STEREO_FLOAT, ulFrequency);
|
||||||
ALenum err = alGetError();
|
ALenum err = alGetError();
|
||||||
if (err == AL_INVALID_ENUM)
|
if (err == AL_INVALID_ENUM)
|
||||||
{
|
{
|
||||||
@@ -330,7 +342,8 @@ void OpenALStream::SoundLoop()
|
|||||||
for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
|
for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
|
||||||
stereo[i] = (short)((float)sampleBuffer[i] * (1 << 15));
|
stereo[i] = (short)((float)sampleBuffer[i] * (1 << 15));
|
||||||
|
|
||||||
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * FRAME_STEREO_SHORT, ulFrequency);
|
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo,
|
||||||
|
nSamples * FRAME_STEREO_SHORT, ulFrequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,5 +384,4 @@ void OpenALStream::SoundLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //HAVE_OPENAL
|
#endif // HAVE_OPENAL
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
#define BOOL SoundTouch_BOOL
|
#define BOOL SoundTouch_BOOL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <soundtouch/SoundTouch.h>
|
|
||||||
#include <soundtouch/STTypes.h>
|
#include <soundtouch/STTypes.h>
|
||||||
|
#include <soundtouch/SoundTouch.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#undef BOOL
|
#undef BOOL
|
||||||
@@ -47,20 +47,17 @@
|
|||||||
#define SURROUND_CHANNELS 6 // number of channels in surround mode
|
#define SURROUND_CHANNELS 6 // number of channels in surround mode
|
||||||
#define SIZE_SHORT 2
|
#define SIZE_SHORT 2
|
||||||
#define SIZE_FLOAT 4 // size of a float in bytes
|
#define SIZE_FLOAT 4 // size of a float in bytes
|
||||||
#define FRAME_STEREO_SHORT STEREO_CHANNELS * SIZE_SHORT
|
#define FRAME_STEREO_SHORT STEREO_CHANNELS* SIZE_SHORT
|
||||||
#define FRAME_STEREO_FLOAT STEREO_CHANNELS * SIZE_FLOAT
|
#define FRAME_STEREO_FLOAT STEREO_CHANNELS* SIZE_FLOAT
|
||||||
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS * SIZE_FLOAT
|
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS* SIZE_FLOAT
|
||||||
#define FRAME_SURROUND_SHORT SURROUND_CHANNELS * SIZE_SHORT
|
#define FRAME_SURROUND_SHORT SURROUND_CHANNELS* SIZE_SHORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class OpenALStream final : public SoundStream
|
class OpenALStream final : public SoundStream
|
||||||
{
|
{
|
||||||
#if defined HAVE_OPENAL && HAVE_OPENAL
|
#if defined HAVE_OPENAL && HAVE_OPENAL
|
||||||
public:
|
public:
|
||||||
OpenALStream() : uiSource(0)
|
OpenALStream() : uiSource(0) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Start() override;
|
bool Start() override;
|
||||||
void SoundLoop() override;
|
void SoundLoop() override;
|
||||||
void SetVolume(int volume) override;
|
void SetVolume(int volume) override;
|
||||||
@@ -69,7 +66,6 @@ public:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
static bool isValid() { return true; }
|
static bool isValid() { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
std::atomic<bool> m_run_thread;
|
std::atomic<bool> m_run_thread;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ static SLPlayItf bqPlayerPlay;
|
|||||||
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
|
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
|
||||||
static SLMuteSoloItf bqPlayerMuteSolo;
|
static SLMuteSoloItf bqPlayerMuteSolo;
|
||||||
static SLVolumeItf bqPlayerVolume;
|
static SLVolumeItf bqPlayerVolume;
|
||||||
static CMixer *g_mixer;
|
static CMixer* g_mixer;
|
||||||
#define BUFFER_SIZE 512
|
#define BUFFER_SIZE 512
|
||||||
#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2)
|
#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2)
|
||||||
|
|
||||||
@@ -32,14 +32,15 @@ static CMixer *g_mixer;
|
|||||||
static short buffer[2][BUFFER_SIZE];
|
static short buffer[2][BUFFER_SIZE];
|
||||||
static int curBuffer = 0;
|
static int curBuffer = 0;
|
||||||
|
|
||||||
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
|
||||||
{
|
{
|
||||||
assert(bq == bqPlayerBufferQueue);
|
assert(bq == bqPlayerBufferQueue);
|
||||||
assert(nullptr == context);
|
assert(nullptr == context);
|
||||||
|
|
||||||
// Render to the fresh buffer
|
// Render to the fresh buffer
|
||||||
g_mixer->Mix(reinterpret_cast<short *>(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES);
|
g_mixer->Mix(reinterpret_cast<short*>(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES);
|
||||||
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[0]));
|
SLresult result =
|
||||||
|
(*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[0]));
|
||||||
curBuffer ^= 1; // Switch buffer
|
curBuffer ^= 1; // Switch buffer
|
||||||
|
|
||||||
// Comment from sample code:
|
// Comment from sample code:
|
||||||
@@ -64,15 +65,13 @@ bool OpenSLESStream::Start()
|
|||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
|
|
||||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||||
SLDataFormat_PCM format_pcm = {
|
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,
|
||||||
SL_DATAFORMAT_PCM,
|
|
||||||
2,
|
2,
|
||||||
m_mixer->GetSampleRate() * 1000,
|
m_mixer->GetSampleRate() * 1000,
|
||||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
||||||
SL_BYTEORDER_LITTLEENDIAN
|
SL_BYTEORDER_LITTLEENDIAN};
|
||||||
};
|
|
||||||
|
|
||||||
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
|
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
|
||||||
|
|
||||||
@@ -83,15 +82,17 @@ bool OpenSLESStream::Start()
|
|||||||
// create audio player
|
// create audio player
|
||||||
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
|
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
|
||||||
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||||
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
result =
|
||||||
|
(*engineEngine)
|
||||||
|
->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
|
|
||||||
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
|
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
|
result =
|
||||||
&bqPlayerBufferQueue);
|
(*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &bqPlayerBufferQueue);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
|
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user