mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 04:14:35 +00:00
Partial commit: Audio
This commit is contained in:
parent
766f1b2b01
commit
edd0965c1a
@ -1,9 +1,11 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/state.h"
|
||||
|
||||
#include "OpenALThread.h"
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "OpenAL32.lib")
|
||||
#endif
|
||||
@ -32,30 +34,27 @@ void printAlcError(ALCenum err, const char* situation)
|
||||
}
|
||||
}
|
||||
|
||||
OpenALThread::~OpenALThread()
|
||||
OpenALThread::OpenALThread()
|
||||
{
|
||||
Quit();
|
||||
}
|
||||
|
||||
void OpenALThread::Init()
|
||||
{
|
||||
m_device = alcOpenDevice(nullptr);
|
||||
ALCdevice* m_device = alcOpenDevice(nullptr);
|
||||
checkForAlcError("alcOpenDevice");
|
||||
|
||||
m_context = alcCreateContext(m_device, nullptr);
|
||||
ALCcontext* m_context = alcCreateContext(m_device, nullptr);
|
||||
checkForAlcError("alcCreateContext");
|
||||
|
||||
alcMakeContextCurrent(m_context);
|
||||
checkForAlcError("alcMakeContextCurrent");
|
||||
}
|
||||
|
||||
void OpenALThread::Quit()
|
||||
OpenALThread::~OpenALThread()
|
||||
{
|
||||
m_context = alcGetCurrentContext();
|
||||
m_device = alcGetContextsDevice(m_context);
|
||||
alcMakeContextCurrent(nullptr);
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
if (ALCcontext* m_context = alcGetCurrentContext())
|
||||
{
|
||||
ALCdevice* m_device = alcGetContextsDevice(m_context);
|
||||
alcMakeContextCurrent(nullptr);
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenALThread::Play()
|
||||
@ -103,7 +102,7 @@ void OpenALThread::Open(const void* src, int size)
|
||||
|
||||
for (uint i = 0; i<g_al_buffers_count; ++i)
|
||||
{
|
||||
alBufferData(m_buffers[i], rpcs3::config.audio.convert_to_u16.value() ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32, src, m_buffer_size, 48000);
|
||||
alBufferData(m_buffers[i], g_cfg_audio_convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32, src, m_buffer_size, 48000);
|
||||
checkForAlError("alBufferData");
|
||||
}
|
||||
|
||||
@ -138,7 +137,7 @@ void OpenALThread::AddData(const void* src, int size)
|
||||
|
||||
int bsize = size < m_buffer_size ? size : m_buffer_size;
|
||||
|
||||
alBufferData(buffer, rpcs3::config.audio.convert_to_u16.value() ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32, bsrc, bsize, 48000);
|
||||
alBufferData(buffer, g_cfg_audio_convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32, bsrc, bsize, 48000);
|
||||
checkForAlError("alBufferData");
|
||||
|
||||
alSourceQueueBuffers(m_source, 1, &buffer);
|
||||
@ -149,4 +148,4 @@ void OpenALThread::AddData(const void* src, int size)
|
||||
}
|
||||
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
@ -6,22 +6,19 @@
|
||||
class OpenALThread : public AudioThread
|
||||
{
|
||||
private:
|
||||
static const uint g_al_buffers_count = 16;
|
||||
static const uint g_al_buffers_count = 24;
|
||||
|
||||
ALuint m_source;
|
||||
ALuint m_buffers[g_al_buffers_count];
|
||||
ALCdevice* m_device;
|
||||
ALCcontext* m_context;
|
||||
ALsizei m_buffer_size;
|
||||
|
||||
public:
|
||||
virtual ~OpenALThread();
|
||||
OpenALThread();
|
||||
virtual ~OpenALThread() override;
|
||||
|
||||
virtual void Init();
|
||||
virtual void Quit();
|
||||
virtual void Play();
|
||||
virtual void Open(const void* src, int size);
|
||||
virtual void Close();
|
||||
virtual void Stop();
|
||||
virtual void AddData(const void* src, int size);
|
||||
virtual void Play() override;
|
||||
virtual void Open(const void* src, int size) override;
|
||||
virtual void Close() override;
|
||||
virtual void Stop() override;
|
||||
virtual void AddData(const void* src, int size) override;
|
||||
};
|
||||
|
@ -1,67 +1,31 @@
|
||||
#include "stdafx.h"
|
||||
#include "AudioDumper.h"
|
||||
|
||||
AudioDumper::AudioDumper() : m_header(0), m_init(false)
|
||||
AudioDumper::AudioDumper(u16 ch)
|
||||
: m_header(ch)
|
||||
{
|
||||
if (GetCh())
|
||||
{
|
||||
m_output.open(fs::get_config_dir() + "audio.wav", fs::rewrite);
|
||||
m_output.write(m_header); // write initial file header
|
||||
}
|
||||
}
|
||||
|
||||
AudioDumper::~AudioDumper()
|
||||
{
|
||||
Finalize();
|
||||
}
|
||||
|
||||
bool AudioDumper::Init(u8 ch)
|
||||
{
|
||||
if ((m_init = m_output.open("audio.wav", fom::rewrite)))
|
||||
{
|
||||
m_header = WAVHeader(ch);
|
||||
WriteHeader();
|
||||
}
|
||||
|
||||
return m_init;
|
||||
}
|
||||
|
||||
void AudioDumper::WriteHeader()
|
||||
{
|
||||
if (m_init)
|
||||
{
|
||||
m_output.write(&m_header, sizeof(m_header)); // write file header
|
||||
}
|
||||
}
|
||||
|
||||
size_t AudioDumper::WriteData(const void* buffer, size_t size)
|
||||
{
|
||||
#ifdef SKIP_EMPTY_AUDIO
|
||||
bool do_save = false;
|
||||
for (u32 i = 0; i < size / 8; i++)
|
||||
{
|
||||
if (((u64*)buffer)[i]) do_save = true;
|
||||
}
|
||||
for (u32 i = 0; i < size % 8; i++)
|
||||
{
|
||||
if (((u8*)buffer)[i + (size & ~7)]) do_save = true;
|
||||
}
|
||||
|
||||
if (m_init && do_save)
|
||||
#else
|
||||
if (m_init)
|
||||
#endif
|
||||
{
|
||||
size_t ret = m_output.write(buffer, size);
|
||||
m_header.Size += (u32)ret;
|
||||
m_header.RIFF.Size += (u32)ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void AudioDumper::Finalize()
|
||||
{
|
||||
if (m_init)
|
||||
if (GetCh())
|
||||
{
|
||||
m_output.seek(0);
|
||||
m_output.write(&m_header, sizeof(m_header)); // write fixed file header
|
||||
m_output.close();
|
||||
m_output.write(m_header); // rewrite file header
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDumper::WriteData(const void* buffer, u32 size)
|
||||
{
|
||||
if (GetCh())
|
||||
{
|
||||
ASSERT(m_output.write(buffer, size) == size);
|
||||
m_header.Size += size;
|
||||
m_header.RIFF.Size += size;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ struct WAVHeader
|
||||
u32 Size; // FileSize - 8
|
||||
u32 WAVE; // "WAVE"
|
||||
|
||||
RIFFHeader() = default;
|
||||
|
||||
RIFFHeader(u32 size)
|
||||
: ID(*(u32*)"RIFF")
|
||||
, WAVE(*(u32*)"WAVE")
|
||||
@ -15,6 +17,7 @@ struct WAVHeader
|
||||
{
|
||||
}
|
||||
} RIFF;
|
||||
|
||||
struct FMTHeader
|
||||
{
|
||||
u32 ID; // "fmt "
|
||||
@ -26,7 +29,9 @@ struct WAVHeader
|
||||
u16 BlockAlign; // NumChannels * BitsPerSample/8
|
||||
u16 BitsPerSample; // sizeof(float) * 8
|
||||
|
||||
FMTHeader(u8 ch)
|
||||
FMTHeader() = default;
|
||||
|
||||
FMTHeader(u16 ch)
|
||||
: ID(*(u32*)"fmt ")
|
||||
, Size(16)
|
||||
, AudioFormat(3)
|
||||
@ -38,10 +43,13 @@ struct WAVHeader
|
||||
{
|
||||
}
|
||||
} FMT;
|
||||
|
||||
u32 ID; // "data"
|
||||
u32 Size; // size of data (256 * NumChannels * sizeof(float))
|
||||
|
||||
WAVHeader(u8 ch)
|
||||
WAVHeader() = default;
|
||||
|
||||
WAVHeader(u16 ch)
|
||||
: ID(*(u32*)"data")
|
||||
, Size(0)
|
||||
, FMT(ch)
|
||||
@ -50,21 +58,15 @@ struct WAVHeader
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AudioDumper
|
||||
{
|
||||
WAVHeader m_header;
|
||||
fs::file m_output;
|
||||
bool m_init;
|
||||
|
||||
public:
|
||||
AudioDumper();
|
||||
AudioDumper(u16 ch);
|
||||
~AudioDumper();
|
||||
|
||||
public:
|
||||
bool Init(u8 ch);
|
||||
void WriteHeader();
|
||||
size_t WriteData(const void* buffer, size_t size);
|
||||
void Finalize();
|
||||
void WriteData(const void* buffer, u32 size);
|
||||
const u16 GetCh() const { return m_header.FMT.NumChannels; }
|
||||
};
|
||||
|
@ -1,13 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "AudioManager.h"
|
||||
|
||||
void AudioManager::Init()
|
||||
{
|
||||
if (!m_audio_out) m_audio_out = Emu.GetCallbacks().get_audio();
|
||||
}
|
||||
|
||||
void AudioManager::Close()
|
||||
{
|
||||
m_audio_out.reset();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AudioThread.h"
|
||||
|
||||
class AudioManager
|
||||
{
|
||||
std::shared_ptr<AudioThread> m_audio_out;
|
||||
|
||||
public:
|
||||
void Init();
|
||||
void Close();
|
||||
|
||||
AudioThread& GetAudioOut() { return *m_audio_out; }
|
||||
};
|
@ -3,10 +3,8 @@
|
||||
class AudioThread
|
||||
{
|
||||
public:
|
||||
virtual ~AudioThread() {}
|
||||
virtual ~AudioThread() = default;
|
||||
|
||||
virtual void Init() = 0;
|
||||
virtual void Quit() = 0;
|
||||
virtual void Play() = 0;
|
||||
virtual void Open(const void* src, int size) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
@ -1,20 +1,16 @@
|
||||
#include "stdafx.h"
|
||||
#ifdef _MSC_VER
|
||||
#include "Utilities/Config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/state.h"
|
||||
|
||||
#include "XAudio2Thread.h"
|
||||
|
||||
XAudio2Thread::~XAudio2Thread()
|
||||
{
|
||||
Quit();
|
||||
}
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
|
||||
XAudio2Thread::XAudio2Thread() : m_xaudio2_instance(nullptr), m_master_voice(nullptr), m_source_voice(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void XAudio2Thread::Init()
|
||||
XAudio2Thread::XAudio2Thread()
|
||||
: m_xaudio2_instance(nullptr)
|
||||
, m_master_voice(nullptr)
|
||||
, m_source_voice(nullptr)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
@ -43,24 +39,23 @@ void XAudio2Thread::Init()
|
||||
}
|
||||
}
|
||||
|
||||
void XAudio2Thread::Quit()
|
||||
XAudio2Thread::~XAudio2Thread()
|
||||
{
|
||||
if (m_source_voice != nullptr)
|
||||
if (m_source_voice != nullptr)
|
||||
{
|
||||
Stop();
|
||||
m_source_voice->Stop();
|
||||
m_source_voice->DestroyVoice();
|
||||
m_source_voice = nullptr;
|
||||
}
|
||||
|
||||
if (m_master_voice != nullptr)
|
||||
{
|
||||
m_master_voice->DestroyVoice();
|
||||
m_master_voice = nullptr;
|
||||
}
|
||||
|
||||
if (m_xaudio2_instance != nullptr)
|
||||
{
|
||||
m_xaudio2_instance->StopEngine();
|
||||
m_xaudio2_instance->Release();
|
||||
m_xaudio2_instance = nullptr;
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
@ -101,11 +96,11 @@ void XAudio2Thread::Open(const void* src, int size)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
WORD sample_size = rpcs3::config.audio.convert_to_u16.value() ? sizeof(u16) : sizeof(float);
|
||||
WORD sample_size = g_cfg_audio_convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
WORD channels = 8;
|
||||
|
||||
WAVEFORMATEX waveformatex;
|
||||
waveformatex.wFormatTag = rpcs3::config.audio.convert_to_u16.value() ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.wFormatTag = g_cfg_audio_convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = channels;
|
||||
waveformatex.nSamplesPerSec = 48000;
|
||||
waveformatex.nAvgBytesPerSec = 48000 * (DWORD)channels * (DWORD)sample_size;
|
||||
@ -121,6 +116,8 @@ void XAudio2Thread::Open(const void* src, int size)
|
||||
return;
|
||||
}
|
||||
|
||||
m_source_voice->SetVolume(4.0);
|
||||
|
||||
AddData(src, size);
|
||||
Play();
|
||||
}
|
||||
|
@ -11,21 +11,18 @@
|
||||
|
||||
class XAudio2Thread : public AudioThread
|
||||
{
|
||||
private:
|
||||
IXAudio2* m_xaudio2_instance;
|
||||
IXAudio2MasteringVoice* m_master_voice;
|
||||
IXAudio2SourceVoice* m_source_voice;
|
||||
|
||||
public:
|
||||
virtual ~XAudio2Thread();
|
||||
XAudio2Thread();
|
||||
virtual ~XAudio2Thread() override;
|
||||
|
||||
virtual void Init();
|
||||
virtual void Quit();
|
||||
virtual void Play();
|
||||
virtual void Open(const void* src, int size);
|
||||
virtual void Close();
|
||||
virtual void Stop();
|
||||
virtual void AddData(const void* src, int size);
|
||||
virtual void Play() override;
|
||||
virtual void Open(const void* src, int size) override;
|
||||
virtual void Close() override;
|
||||
virtual void Stop() override;
|
||||
virtual void AddData(const void* src, int size) override;
|
||||
};
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user