mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
ALSA Audio Renderer (Linux)
This commit is contained in:
parent
dc3d38c255
commit
4c741e93c3
@ -66,6 +66,7 @@ addons:
|
||||
- llvm-toolchain-trusty-4.0
|
||||
packages:
|
||||
- cmake
|
||||
- libasound2-dev
|
||||
- libopenal-dev
|
||||
- freeglut3-dev
|
||||
- libglew-dev
|
||||
|
@ -28,7 +28,7 @@ __Windows__
|
||||
|
||||
__Linux__
|
||||
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libopenal-dev libwxgtk3.0-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev git`
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libwxgtk3.0-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev git`
|
||||
* Arch: `sudo pacman -S glew openal wxgtk cmake llvm`
|
||||
|
||||
__Mac OSX__
|
||||
|
@ -49,7 +49,7 @@ endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
#on some Linux distros shm_unlink and similar functions are in librt only
|
||||
set(ADDITIONAL_LIBS "rt" "X11")
|
||||
set(ADDITIONAL_LIBS "rt" "X11" "asound")
|
||||
elseif(UNIX OR NOT MSVC)
|
||||
#it seems like glibc includes the iconv functions we use but other libc
|
||||
#implementations like the one on OSX don't seem implement them
|
||||
|
136
rpcs3/Emu/Audio/ALSA/ALSAThread.cpp
Normal file
136
rpcs3/Emu/Audio/ALSA/ALSAThread.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/GSL.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "ALSAThread.h"
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
extern cfg::bool_entry g_cfg_audio_convert_to_u16;
|
||||
|
||||
thread_local static snd_pcm_t* s_tls_handle{nullptr};
|
||||
|
||||
static void error(int err, const char* reason)
|
||||
{
|
||||
fprintf(stderr, "ALSA: %s failed: %s\n", reason, snd_strerror(err));
|
||||
}
|
||||
|
||||
static bool check(int err, const char* reason)
|
||||
{
|
||||
if (err < 0)
|
||||
{
|
||||
error(err, reason);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ALSAThread::ALSAThread()
|
||||
{
|
||||
snd_pcm_hw_params_t* hw_params{nullptr};
|
||||
|
||||
auto at_ret = gsl::finally([&]()
|
||||
{
|
||||
if (hw_params)
|
||||
{
|
||||
snd_pcm_hw_params_free(hw_params);
|
||||
}
|
||||
});
|
||||
|
||||
if (!check(snd_pcm_open(&s_tls_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK), "snd_pcm_open"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_malloc(&hw_params), "snd_pcm_hw_params_malloc"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_any(s_tls_handle, hw_params), "snd_pcm_hw_params_any"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_access(s_tls_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED), "snd_pcm_hw_params_set_access"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_format(s_tls_handle, hw_params, g_cfg_audio_convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_rate(s_tls_handle, hw_params, 48000, 0), "snd_pcm_hw_params_set_rate_near"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, 8), "snd_pcm_hw_params_set_channels"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 64 * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
|
||||
return;
|
||||
|
||||
//if (!check(snd_pcm_hw_params_set_periods(s_tls_handle, hw_params, 2, 0), "snd_pcm_hw_params_set_periods"))
|
||||
// return;
|
||||
|
||||
if (!check(snd_pcm_hw_params(s_tls_handle, hw_params), "snd_pcm_hw_params"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_prepare(s_tls_handle), "snd_pcm_prepare"))
|
||||
return;
|
||||
}
|
||||
|
||||
ALSAThread::~ALSAThread()
|
||||
{
|
||||
if (s_tls_handle)
|
||||
{
|
||||
snd_pcm_close(s_tls_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void ALSAThread::Play()
|
||||
{
|
||||
}
|
||||
|
||||
void ALSAThread::Close()
|
||||
{
|
||||
}
|
||||
|
||||
void ALSAThread::Stop()
|
||||
{
|
||||
}
|
||||
|
||||
void ALSAThread::Open(const void* src, int size)
|
||||
{
|
||||
AddData(src, size);
|
||||
}
|
||||
|
||||
void ALSAThread::AddData(const void* src, int size)
|
||||
{
|
||||
size /= g_cfg_audio_convert_to_u16 ? 2 * 8 : 4 * 8;
|
||||
|
||||
int res;
|
||||
|
||||
while (true)
|
||||
{
|
||||
res = snd_pcm_writei(s_tls_handle, src, size);
|
||||
|
||||
if (res == -EAGAIN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (res == -EPIPE)
|
||||
{
|
||||
snd_pcm_prepare(s_tls_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != size)
|
||||
{
|
||||
error(res, "snd_pcm_writei");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
20
rpcs3/Emu/Audio/ALSA/ALSAThread.h
Normal file
20
rpcs3/Emu/Audio/ALSA/ALSAThread.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
class ALSAThread : public AudioThread
|
||||
{
|
||||
public:
|
||||
ALSAThread();
|
||||
virtual ~ALSAThread() override;
|
||||
|
||||
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
|
@ -42,6 +42,9 @@
|
||||
#include "Emu/Audio/XAudio2/XAudio2Thread.h"
|
||||
#include <wx/msw/wrapwin.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#include "Emu/Audio/ALSA/ALSAThread.h"
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
#include <X11/Xlib.h>
|
||||
@ -107,6 +110,8 @@ cfg::map_entry<std::function<std::shared_ptr<AudioThread>()>> g_cfg_audio_render
|
||||
{ "Null", &std::make_shared<NullAudioThread> },
|
||||
#ifdef _WIN32
|
||||
{ "XAudio2", &std::make_shared<XAudio2Thread> },
|
||||
#elif __linux__
|
||||
{ "ALSA", &std::make_shared<ALSAThread> },
|
||||
#endif
|
||||
{ "OpenAL", &std::make_shared<OpenALThread> },
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user