Partial commit: Audio

This commit is contained in:
Nekotekina 2016-02-02 00:51:35 +03:00
parent 766f1b2b01
commit edd0965c1a
9 changed files with 79 additions and 152 deletions

View File

@ -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();
}
}

View File

@ -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;
};

View File

@ -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;
}
}

View File

@ -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; }
};

View File

@ -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();
}

View File

@ -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; }
};

View File

@ -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;

View File

@ -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();
}

View File

@ -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