Avoid AL/ALC types in the backends
This commit is contained in:
parent
5edd5a11fc
commit
6ae0115bf7
@ -2130,7 +2130,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
|||||||
uint64_t usemask{~sublist.FreeMask};
|
uint64_t usemask{~sublist.FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{CountTrailingZeros(usemask)};
|
||||||
ALeffectslot *slot{sublist.EffectSlots + idx};
|
ALeffectslot *slot{sublist.EffectSlots + idx};
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
|
|
||||||
@ -2153,7 +2153,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
|||||||
uint64_t usemask{~sublist.FreeMask};
|
uint64_t usemask{~sublist.FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{CountTrailingZeros(usemask)};
|
||||||
ALsource *source{sublist.Sources + idx};
|
ALsource *source{sublist.Sources + idx};
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
|
|
||||||
@ -2724,7 +2724,7 @@ START_API_FUNC
|
|||||||
END_API_FUNC
|
END_API_FUNC
|
||||||
|
|
||||||
|
|
||||||
static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
|
static inline int NumAttrsForDevice(ALCdevice *device)
|
||||||
{
|
{
|
||||||
if(device->Type == DeviceType::Capture) return 9;
|
if(device->Type == DeviceType::Capture) return 9;
|
||||||
if(device->Type != DeviceType::Loopback) return 29;
|
if(device->Type != DeviceType::Loopback) return 29;
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr ALCchar alsaDevice[] = "ALSA Default";
|
constexpr char alsaDevice[] = "ALSA Default";
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DYNLOAD
|
#ifdef HAVE_DYNLOAD
|
||||||
@ -325,7 +325,7 @@ al::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
|
|||||||
ERR("snd_ctl_pcm_next_device failed\n");
|
ERR("snd_ctl_pcm_next_device failed\n");
|
||||||
if(dev < 0) break;
|
if(dev < 0) break;
|
||||||
|
|
||||||
snd_pcm_info_set_device(pcminfo, static_cast<ALuint>(dev));
|
snd_pcm_info_set_device(pcminfo, static_cast<uint>(dev));
|
||||||
snd_pcm_info_set_subdevice(pcminfo, 0);
|
snd_pcm_info_set_subdevice(pcminfo, 0);
|
||||||
snd_pcm_info_set_stream(pcminfo, stream);
|
snd_pcm_info_set_stream(pcminfo, stream);
|
||||||
if((err=snd_ctl_pcm_info(handle, pcminfo)) < 0)
|
if((err=snd_ctl_pcm_info(handle, pcminfo)) < 0)
|
||||||
@ -416,7 +416,7 @@ struct AlsaPlayback final : public BackendBase {
|
|||||||
int mixerProc();
|
int mixerProc();
|
||||||
int mixerNoMMapProc();
|
int mixerNoMMapProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -510,7 +510,7 @@ int AlsaPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *WritePtr{static_cast<char*>(areas->addr) + (offset * areas->step / 8)};
|
char *WritePtr{static_cast<char*>(areas->addr) + (offset * areas->step / 8)};
|
||||||
mDevice->renderSamples(WritePtr, static_cast<ALuint>(frames), areas->step/samplebits);
|
mDevice->renderSamples(WritePtr, static_cast<uint>(frames), areas->step/samplebits);
|
||||||
|
|
||||||
snd_pcm_sframes_t commitres{snd_pcm_mmap_commit(mPcmHandle, offset, frames)};
|
snd_pcm_sframes_t commitres{snd_pcm_mmap_commit(mPcmHandle, offset, frames)};
|
||||||
if(commitres < 0 || static_cast<snd_pcm_uframes_t>(commitres) != frames)
|
if(commitres < 0 || static_cast<snd_pcm_uframes_t>(commitres) != frames)
|
||||||
@ -578,7 +578,7 @@ int AlsaPlayback::mixerNoMMapProc()
|
|||||||
al::byte *WritePtr{mBuffer.data()};
|
al::byte *WritePtr{mBuffer.data()};
|
||||||
avail = snd_pcm_bytes_to_frames(mPcmHandle, static_cast<ssize_t>(mBuffer.size()));
|
avail = snd_pcm_bytes_to_frames(mPcmHandle, static_cast<ssize_t>(mBuffer.size()));
|
||||||
std::lock_guard<std::mutex> _{mMutex};
|
std::lock_guard<std::mutex> _{mMutex};
|
||||||
mDevice->renderSamples(WritePtr, static_cast<ALuint>(avail), frame_step);
|
mDevice->renderSamples(WritePtr, static_cast<uint>(avail), frame_step);
|
||||||
while(avail > 0)
|
while(avail > 0)
|
||||||
{
|
{
|
||||||
snd_pcm_sframes_t ret{snd_pcm_writei(mPcmHandle, WritePtr,
|
snd_pcm_sframes_t ret{snd_pcm_writei(mPcmHandle, WritePtr,
|
||||||
@ -616,7 +616,7 @@ int AlsaPlayback::mixerNoMMapProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AlsaPlayback::open(const ALCchar *name)
|
void AlsaPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *driver{};
|
const char *driver{};
|
||||||
if(name)
|
if(name)
|
||||||
@ -680,9 +680,9 @@ bool AlsaPlayback::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", 1)};
|
bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", 1)};
|
||||||
ALuint periodLen{static_cast<ALuint>(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)};
|
uint periodLen{static_cast<uint>(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)};
|
||||||
ALuint bufferLen{static_cast<ALuint>(mDevice->BufferSize * 1000000_u64 / mDevice->Frequency)};
|
uint bufferLen{static_cast<uint>(mDevice->BufferSize * 1000000_u64 / mDevice->Frequency)};
|
||||||
ALuint rate{mDevice->Frequency};
|
uint rate{mDevice->Frequency};
|
||||||
|
|
||||||
int err{};
|
int err{};
|
||||||
HwParamsPtr hp{CreateHwParams()};
|
HwParamsPtr hp{CreateHwParams()};
|
||||||
@ -785,8 +785,8 @@ bool AlsaPlayback::reset()
|
|||||||
#undef CHECK
|
#undef CHECK
|
||||||
sp = nullptr;
|
sp = nullptr;
|
||||||
|
|
||||||
mDevice->BufferSize = static_cast<ALuint>(bufferSizeInFrames);
|
mDevice->BufferSize = static_cast<uint>(bufferSizeInFrames);
|
||||||
mDevice->UpdateSize = static_cast<ALuint>(periodSizeInFrames);
|
mDevice->UpdateSize = static_cast<uint>(periodSizeInFrames);
|
||||||
mDevice->Frequency = rate;
|
mDevice->Frequency = rate;
|
||||||
|
|
||||||
setDefaultChannelOrder();
|
setDefaultChannelOrder();
|
||||||
@ -869,7 +869,7 @@ struct AlsaCapture final : public BackendBase {
|
|||||||
AlsaCapture(ALCdevice *device) noexcept : BackendBase{device} { }
|
AlsaCapture(ALCdevice *device) noexcept : BackendBase{device} { }
|
||||||
~AlsaCapture() override;
|
~AlsaCapture() override;
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -896,7 +896,7 @@ AlsaCapture::~AlsaCapture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AlsaCapture::open(const ALCchar *name)
|
void AlsaCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *driver{};
|
const char *driver{};
|
||||||
if(name)
|
if(name)
|
||||||
@ -1017,7 +1017,7 @@ void AlsaCapture::stop()
|
|||||||
* snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's
|
* snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's
|
||||||
* available now so it'll be available later after the drop.
|
* available now so it'll be available later after the drop.
|
||||||
*/
|
*/
|
||||||
ALCuint avail{availableSamples()};
|
uint avail{availableSamples()};
|
||||||
if(!mRing && avail > 0)
|
if(!mRing && avail > 0)
|
||||||
{
|
{
|
||||||
/* The ring buffer implicitly captures when checking availability.
|
/* The ring buffer implicitly captures when checking availability.
|
||||||
@ -1088,7 +1088,7 @@ void AlsaCapture::captureSamples(al::byte *buffer, uint samples)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer = buffer + amt;
|
buffer = buffer + amt;
|
||||||
samples -= static_cast<ALCuint>(amt);
|
samples -= static_cast<uint>(amt);
|
||||||
}
|
}
|
||||||
if(samples > 0)
|
if(samples > 0)
|
||||||
std::fill_n(buffer, snd_pcm_frames_to_bytes(mPcmHandle, samples),
|
std::fill_n(buffer, snd_pcm_frames_to_bytes(mPcmHandle, samples),
|
||||||
@ -1199,10 +1199,10 @@ bool AlsaBackendFactory::init()
|
|||||||
if(!alsa_handle)
|
if(!alsa_handle)
|
||||||
{
|
{
|
||||||
WARN("Failed to load %s\n", "libasound.so.2");
|
WARN("Failed to load %s\n", "libasound.so.2");
|
||||||
return ALC_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ALC_FALSE;
|
error = false;
|
||||||
#define LOAD_FUNC(f) do { \
|
#define LOAD_FUNC(f) do { \
|
||||||
p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f)); \
|
p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f)); \
|
||||||
if(p##f == nullptr) { \
|
if(p##f == nullptr) { \
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
#include <mmreg.h>
|
#include <mmreg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "AL/alc.h"
|
|
||||||
|
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alexcpt.h"
|
#include "alexcpt.h"
|
||||||
#include "alnumeric.h"
|
#include "alnumeric.h"
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const ALCchar ca_device[] = "CoreAudio Default";
|
static const char ca_device[] = "CoreAudio Default";
|
||||||
|
|
||||||
|
|
||||||
struct CoreAudioPlayback final : public BackendBase {
|
struct CoreAudioPlayback final : public BackendBase {
|
||||||
@ -62,14 +62,14 @@ struct CoreAudioPlayback final : public BackendBase {
|
|||||||
inBusNumber, inNumberFrames, ioData);
|
inBusNumber, inNumberFrames, ioData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
AudioUnit mAudioUnit{};
|
AudioUnit mAudioUnit{};
|
||||||
|
|
||||||
ALuint mFrameSize{0u};
|
uint mFrameSize{0u};
|
||||||
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
|
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
|
||||||
|
|
||||||
DEF_NEWDEL(CoreAudioPlayback)
|
DEF_NEWDEL(CoreAudioPlayback)
|
||||||
@ -95,7 +95,7 @@ OSStatus CoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags*, const AudioTi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CoreAudioPlayback::open(const ALCchar *name)
|
void CoreAudioPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = ca_device;
|
name = ca_device;
|
||||||
@ -171,9 +171,9 @@ bool CoreAudioPlayback::reset()
|
|||||||
|
|
||||||
if(mDevice->Frequency != streamFormat.mSampleRate)
|
if(mDevice->Frequency != streamFormat.mSampleRate)
|
||||||
{
|
{
|
||||||
mDevice->BufferSize = static_cast<ALuint>(uint64_t{mDevice->BufferSize} *
|
mDevice->BufferSize = static_cast<uint>(uint64_t{mDevice->BufferSize} *
|
||||||
streamFormat.mSampleRate / mDevice->Frequency);
|
streamFormat.mSampleRate / mDevice->Frequency);
|
||||||
mDevice->Frequency = static_cast<ALuint>(streamFormat.mSampleRate);
|
mDevice->Frequency = static_cast<uint>(streamFormat.mSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: How to tell what channels are what in the output device, and how
|
/* FIXME: How to tell what channels are what in the output device, and how
|
||||||
@ -309,7 +309,7 @@ struct CoreAudioCapture final : public BackendBase {
|
|||||||
inBusNumber, inNumberFrames, ioData);
|
inBusNumber, inNumberFrames, ioData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -317,7 +317,7 @@ struct CoreAudioCapture final : public BackendBase {
|
|||||||
|
|
||||||
AudioUnit mAudioUnit{0};
|
AudioUnit mAudioUnit{0};
|
||||||
|
|
||||||
ALuint mFrameSize{0u};
|
uint mFrameSize{0u};
|
||||||
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
|
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
|
||||||
|
|
||||||
SampleConverterPtr mConverter;
|
SampleConverterPtr mConverter;
|
||||||
@ -359,7 +359,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags*,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto remaining = static_cast<ALuint>(inNumberFrames - rec_vec.first.len);
|
const auto remaining = static_cast<uint>(inNumberFrames - rec_vec.first.len);
|
||||||
audiobuf.list.mNumberBuffers = 2;
|
audiobuf.list.mNumberBuffers = 2;
|
||||||
audiobuf.list.mBuffers[0].mNumberChannels = mFormat.mChannelsPerFrame;
|
audiobuf.list.mBuffers[0].mNumberChannels = mFormat.mChannelsPerFrame;
|
||||||
audiobuf.list.mBuffers[0].mData = rec_vec.first.buf;
|
audiobuf.list.mBuffers[0].mData = rec_vec.first.buf;
|
||||||
@ -382,7 +382,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags*,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CoreAudioCapture::open(const ALCchar *name)
|
void CoreAudioCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
AudioStreamBasicDescription requestedFormat; // The application requested format
|
AudioStreamBasicDescription requestedFormat; // The application requested format
|
||||||
AudioStreamBasicDescription hardwareFormat; // The hardware format
|
AudioStreamBasicDescription hardwareFormat; // The hardware format
|
||||||
@ -424,7 +424,7 @@ void CoreAudioCapture::open(const ALCchar *name)
|
|||||||
// Turn off AudioUnit output
|
// Turn off AudioUnit output
|
||||||
enableIO = 0;
|
enableIO = 0;
|
||||||
err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
|
err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
|
||||||
kAudioUnitScope_Output, 0, &enableIO, sizeof(ALuint));
|
kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
|
||||||
if(err != noErr)
|
if(err != noErr)
|
||||||
throw al::backend_exception{al::backend_error::DeviceError,
|
throw al::backend_exception{al::backend_error::DeviceError,
|
||||||
"Could not disable audio unit output property: %u", err};
|
"Could not disable audio unit output property: %u", err};
|
||||||
@ -432,7 +432,7 @@ void CoreAudioCapture::open(const ALCchar *name)
|
|||||||
// Turn on AudioUnit input
|
// Turn on AudioUnit input
|
||||||
enableIO = 1;
|
enableIO = 1;
|
||||||
err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
|
err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
|
||||||
kAudioUnitScope_Input, 1, &enableIO, sizeof(ALuint));
|
kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
|
||||||
if(err != noErr)
|
if(err != noErr)
|
||||||
throw al::backend_exception{al::backend_error::DeviceError,
|
throw al::backend_exception{al::backend_error::DeviceError,
|
||||||
"Could not enable audio unit input property: %u", err};
|
"Could not enable audio unit input property: %u", err};
|
||||||
@ -598,7 +598,7 @@ void CoreAudioCapture::open(const ALCchar *name)
|
|||||||
/* Set up sample converter if needed */
|
/* Set up sample converter if needed */
|
||||||
if(outputFormat.mSampleRate != mDevice->Frequency)
|
if(outputFormat.mSampleRate != mDevice->Frequency)
|
||||||
mConverter = CreateSampleConverter(mDevice->FmtType, mDevice->FmtType,
|
mConverter = CreateSampleConverter(mDevice->FmtType, mDevice->FmtType,
|
||||||
mFormat.mChannelsPerFrame, static_cast<ALuint>(hardwareFormat.mSampleRate),
|
mFormat.mChannelsPerFrame, static_cast<uint>(hardwareFormat.mSampleRate),
|
||||||
mDevice->Frequency, Resampler::FastBSinc24);
|
mDevice->Frequency, Resampler::FastBSinc24);
|
||||||
|
|
||||||
mDevice->DeviceName = name;
|
mDevice->DeviceName = name;
|
||||||
@ -630,13 +630,13 @@ void CoreAudioCapture::captureSamples(al::byte *buffer, uint samples)
|
|||||||
|
|
||||||
auto rec_vec = mRing->getReadVector();
|
auto rec_vec = mRing->getReadVector();
|
||||||
const void *src0{rec_vec.first.buf};
|
const void *src0{rec_vec.first.buf};
|
||||||
auto src0len = static_cast<ALuint>(rec_vec.first.len);
|
auto src0len = static_cast<uint>(rec_vec.first.len);
|
||||||
uint got{mConverter->convert(&src0, &src0len, buffer, samples)};
|
uint got{mConverter->convert(&src0, &src0len, buffer, samples)};
|
||||||
size_t total_read{rec_vec.first.len - src0len};
|
size_t total_read{rec_vec.first.len - src0len};
|
||||||
if(got < samples && !src0len && rec_vec.second.len > 0)
|
if(got < samples && !src0len && rec_vec.second.len > 0)
|
||||||
{
|
{
|
||||||
const void *src1{rec_vec.second.buf};
|
const void *src1{rec_vec.second.buf};
|
||||||
auto src1len = static_cast<ALuint>(rec_vec.second.len);
|
auto src1len = static_cast<uint>(rec_vec.second.len);
|
||||||
got += mConverter->convert(&src1, &src1len, buffer + got*mFrameSize, samples-got);
|
got += mConverter->convert(&src1, &src1len, buffer + got*mFrameSize, samples-got);
|
||||||
total_read += rec_vec.second.len - src1len;
|
total_read += rec_vec.second.len - src1len;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ FORCE_ALIGN int DSoundPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const size_t FrameStep{mDevice->channelsFromFmt()};
|
const size_t FrameStep{mDevice->channelsFromFmt()};
|
||||||
ALuint FrameSize{mDevice->frameSizeFromFmt()};
|
uint FrameSize{mDevice->frameSizeFromFmt()};
|
||||||
DWORD FragSize{mDevice->UpdateSize * FrameSize};
|
DWORD FragSize{mDevice->UpdateSize * FrameSize};
|
||||||
|
|
||||||
bool Playing{false};
|
bool Playing{false};
|
||||||
@ -306,7 +306,7 @@ FORCE_ALIGN int DSoundPlayback::mixerProc()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSoundPlayback::open(const ALCchar *name)
|
void DSoundPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if(PlaybackDevices.empty())
|
if(PlaybackDevices.empty())
|
||||||
@ -474,7 +474,7 @@ retry_open:
|
|||||||
|
|
||||||
if(SUCCEEDED(hr))
|
if(SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
uint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||||
if(num_updates > MAX_UPDATES)
|
if(num_updates > MAX_UPDATES)
|
||||||
num_updates = MAX_UPDATES;
|
num_updates = MAX_UPDATES;
|
||||||
mDevice->BufferSize = mDevice->UpdateSize * num_updates;
|
mDevice->BufferSize = mDevice->UpdateSize * num_updates;
|
||||||
@ -502,11 +502,11 @@ retry_open:
|
|||||||
{
|
{
|
||||||
mNotifies = static_cast<IDirectSoundNotify*>(ptr);
|
mNotifies = static_cast<IDirectSoundNotify*>(ptr);
|
||||||
|
|
||||||
ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
uint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||||
assert(num_updates <= MAX_UPDATES);
|
assert(num_updates <= MAX_UPDATES);
|
||||||
|
|
||||||
std::array<DSBPOSITIONNOTIFY,MAX_UPDATES> nots;
|
std::array<DSBPOSITIONNOTIFY,MAX_UPDATES> nots;
|
||||||
for(ALuint i{0};i < num_updates;++i)
|
for(uint i{0};i < num_updates;++i)
|
||||||
{
|
{
|
||||||
nots[i].dwOffset = i * mDevice->UpdateSize * OutputType.Format.nBlockAlign;
|
nots[i].dwOffset = i * mDevice->UpdateSize * OutputType.Format.nBlockAlign;
|
||||||
nots[i].hEventNotify = mNotifyEvent;
|
nots[i].hEventNotify = mNotifyEvent;
|
||||||
@ -562,7 +562,7 @@ struct DSoundCapture final : public BackendBase {
|
|||||||
DSoundCapture(ALCdevice *device) noexcept : BackendBase{device} { }
|
DSoundCapture(ALCdevice *device) noexcept : BackendBase{device} { }
|
||||||
~DSoundCapture() override;
|
~DSoundCapture() override;
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -593,7 +593,7 @@ DSoundCapture::~DSoundCapture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DSoundCapture::open(const ALCchar *name)
|
void DSoundCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if(CaptureDevices.empty())
|
if(CaptureDevices.empty())
|
||||||
@ -684,7 +684,7 @@ void DSoundCapture::open(const ALCchar *name)
|
|||||||
InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALuint samples{mDevice->BufferSize};
|
uint samples{mDevice->BufferSize};
|
||||||
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
||||||
|
|
||||||
DSCBUFFERDESC DSCBDescription{};
|
DSCBUFFERDESC DSCBDescription{};
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr ALCchar jackDevice[] = "JACK Default";
|
constexpr char jackDevice[] = "JACK Default";
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DYNLOAD
|
#ifdef HAVE_DYNLOAD
|
||||||
@ -214,7 +214,7 @@ struct JackPlayback final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -266,7 +266,7 @@ int JackPlayback::process(jack_nframes_t numframes) noexcept
|
|||||||
if LIKELY(mPlaying.load(std::memory_order_acquire))
|
if LIKELY(mPlaying.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
auto data = mRing->getReadVector();
|
auto data = mRing->getReadVector();
|
||||||
jack_nframes_t todo{minu(numframes, static_cast<ALuint>(data.first.len))};
|
jack_nframes_t todo{minu(numframes, static_cast<uint>(data.first.len))};
|
||||||
auto write_first = [&data,numchans,todo](float *outbuf) -> float*
|
auto write_first = [&data,numchans,todo](float *outbuf) -> float*
|
||||||
{
|
{
|
||||||
const float *RESTRICT in = reinterpret_cast<float*>(data.first.buf);
|
const float *RESTRICT in = reinterpret_cast<float*>(data.first.buf);
|
||||||
@ -283,7 +283,7 @@ int JackPlayback::process(jack_nframes_t numframes) noexcept
|
|||||||
std::transform(out.begin(), out.begin()+numchans, out.begin(), write_first);
|
std::transform(out.begin(), out.begin()+numchans, out.begin(), write_first);
|
||||||
total += todo;
|
total += todo;
|
||||||
|
|
||||||
todo = minu(numframes-total, static_cast<ALuint>(data.second.len));
|
todo = minu(numframes-total, static_cast<uint>(data.second.len));
|
||||||
if(todo > 0)
|
if(todo > 0)
|
||||||
{
|
{
|
||||||
auto write_second = [&data,numchans,todo](float *outbuf) -> float*
|
auto write_second = [&data,numchans,todo](float *outbuf) -> float*
|
||||||
@ -334,11 +334,11 @@ int JackPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto data = mRing->getWriteVector();
|
auto data = mRing->getWriteVector();
|
||||||
auto todo = static_cast<ALuint>(data.first.len + data.second.len);
|
size_t todo{data.first.len + data.second.len};
|
||||||
todo -= todo%mDevice->UpdateSize;
|
todo -= todo%mDevice->UpdateSize;
|
||||||
|
|
||||||
ALuint len1{minu(static_cast<ALuint>(data.first.len), todo)};
|
const auto len1 = static_cast<uint>(minz(data.first.len, todo));
|
||||||
ALuint len2{minu(static_cast<ALuint>(data.second.len), todo-len1)};
|
const auto len2 = static_cast<uint>(minz(data.second.len, todo-len1));
|
||||||
|
|
||||||
std::lock_guard<std::mutex> _{mMutex};
|
std::lock_guard<std::mutex> _{mMutex};
|
||||||
mDevice->renderSamples(data.first.buf, len1, frame_step);
|
mDevice->renderSamples(data.first.buf, len1, frame_step);
|
||||||
@ -351,7 +351,7 @@ int JackPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JackPlayback::open(const ALCchar *name)
|
void JackPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
mPortPattern.clear();
|
mPortPattern.clear();
|
||||||
|
|
||||||
@ -406,7 +406,7 @@ bool JackPlayback::reset()
|
|||||||
mDevice->BufferSize = mDevice->UpdateSize * 2;
|
mDevice->BufferSize = mDevice->UpdateSize * 2;
|
||||||
|
|
||||||
const char *devname{mDevice->DeviceName.c_str()};
|
const char *devname{mDevice->DeviceName.c_str()};
|
||||||
ALuint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
|
uint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
|
||||||
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
||||||
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ void JackPlayback::start()
|
|||||||
mDevice->UpdateSize = jack_get_buffer_size(mClient);
|
mDevice->UpdateSize = jack_get_buffer_size(mClient);
|
||||||
mDevice->BufferSize = mDevice->UpdateSize * 2;
|
mDevice->BufferSize = mDevice->UpdateSize * 2;
|
||||||
|
|
||||||
ALuint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
|
uint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
|
||||||
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
||||||
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ using std::chrono::seconds;
|
|||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using std::chrono::nanoseconds;
|
using std::chrono::nanoseconds;
|
||||||
|
|
||||||
constexpr ALCchar nullDevice[] = "No Output";
|
constexpr char nullDevice[] = "No Output";
|
||||||
|
|
||||||
|
|
||||||
struct NullBackend final : public BackendBase {
|
struct NullBackend final : public BackendBase {
|
||||||
@ -51,7 +51,7 @@ struct NullBackend final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -106,7 +106,7 @@ int NullBackend::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NullBackend::open(const ALCchar *name)
|
void NullBackend::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = nullDevice;
|
name = nullDevice;
|
||||||
|
@ -25,7 +25,7 @@ struct OboePlayback final : public BackendBase, public oboe::AudioStreamCallback
|
|||||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData,
|
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData,
|
||||||
int32_t numFrames) override;
|
int32_t numFrames) override;
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -55,7 +55,7 @@ oboe::DataCallbackResult OboePlayback::onAudioReady(oboe::AudioStream *oboeStrea
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OboePlayback::open(const ALCchar *name)
|
void OboePlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = device_name;
|
name = device_name;
|
||||||
|
@ -54,7 +54,7 @@ namespace {
|
|||||||
#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
|
#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
|
||||||
|
|
||||||
|
|
||||||
constexpr ALCchar opensl_device[] = "OpenSL";
|
constexpr char opensl_device[] = "OpenSL";
|
||||||
|
|
||||||
|
|
||||||
SLuint32 GetChannelMask(DevFmtChannels chans)
|
SLuint32 GetChannelMask(DevFmtChannels chans)
|
||||||
@ -153,7 +153,7 @@ struct OpenSLPlayback final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -266,10 +266,10 @@ int OpenSLPlayback::mixerProc()
|
|||||||
std::unique_lock<std::mutex> dlock{mMutex};
|
std::unique_lock<std::mutex> dlock{mMutex};
|
||||||
auto data = mRing->getWriteVector();
|
auto data = mRing->getWriteVector();
|
||||||
mDevice->renderSamples(data.first.buf,
|
mDevice->renderSamples(data.first.buf,
|
||||||
static_cast<ALuint>(data.first.len*mDevice->UpdateSize), frame_step);
|
static_cast<uint>(data.first.len)*mDevice->UpdateSize, frame_step);
|
||||||
if(data.second.len > 0)
|
if(data.second.len > 0)
|
||||||
mDevice->renderSamples(data.second.buf,
|
mDevice->renderSamples(data.second.buf,
|
||||||
static_cast<ALuint>(data.second.len*mDevice->UpdateSize), frame_step);
|
static_cast<uint>(data.second.len)*mDevice->UpdateSize, frame_step);
|
||||||
|
|
||||||
size_t todo{data.first.len + data.second.len};
|
size_t todo{data.first.len + data.second.len};
|
||||||
mRing->writeAdvance(todo);
|
mRing->writeAdvance(todo);
|
||||||
@ -301,7 +301,7 @@ int OpenSLPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpenSLPlayback::open(const ALCchar *name)
|
void OpenSLPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = opensl_device;
|
name = opensl_device;
|
||||||
@ -525,7 +525,7 @@ bool OpenSLPlayback::reset()
|
|||||||
}
|
}
|
||||||
if(SL_RESULT_SUCCESS == result)
|
if(SL_RESULT_SUCCESS == result)
|
||||||
{
|
{
|
||||||
const ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
const uint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||||
mRing = RingBuffer::Create(num_updates, mFrameSize*mDevice->UpdateSize, true);
|
mRing = RingBuffer::Create(num_updates, mFrameSize*mDevice->UpdateSize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,7 +630,7 @@ struct OpenSLCapture final : public BackendBase {
|
|||||||
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context) noexcept
|
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context) noexcept
|
||||||
{ static_cast<OpenSLCapture*>(context)->process(bq); }
|
{ static_cast<OpenSLCapture*>(context)->process(bq); }
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -671,7 +671,7 @@ void OpenSLCapture::process(SLAndroidSimpleBufferQueueItf) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpenSLCapture::open(const ALCchar* name)
|
void OpenSLCapture::open(const char* name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = opensl_device;
|
name = opensl_device;
|
||||||
@ -695,16 +695,16 @@ void OpenSLCapture::open(const ALCchar* name)
|
|||||||
{
|
{
|
||||||
mFrameSize = mDevice->frameSizeFromFmt();
|
mFrameSize = mDevice->frameSizeFromFmt();
|
||||||
/* Ensure the total length is at least 100ms */
|
/* Ensure the total length is at least 100ms */
|
||||||
ALuint length{maxu(mDevice->BufferSize, mDevice->Frequency/10)};
|
uint length{maxu(mDevice->BufferSize, mDevice->Frequency/10)};
|
||||||
/* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
|
/* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
|
||||||
ALuint update_len{clampu(mDevice->BufferSize/3, mDevice->Frequency/100,
|
uint update_len{clampu(mDevice->BufferSize/3, mDevice->Frequency/100,
|
||||||
mDevice->Frequency/100*5)};
|
mDevice->Frequency/100*5)};
|
||||||
ALuint num_updates{(length+update_len-1) / update_len};
|
uint num_updates{(length+update_len-1) / update_len};
|
||||||
|
|
||||||
mRing = RingBuffer::Create(num_updates, update_len*mFrameSize, false);
|
mRing = RingBuffer::Create(num_updates, update_len*mFrameSize, false);
|
||||||
|
|
||||||
mDevice->UpdateSize = update_len;
|
mDevice->UpdateSize = update_len;
|
||||||
mDevice->BufferSize = static_cast<ALuint>(mRing->writeSpace() * update_len);
|
mDevice->BufferSize = static_cast<uint>(mRing->writeSpace() * update_len);
|
||||||
}
|
}
|
||||||
if(SL_RESULT_SUCCESS == result)
|
if(SL_RESULT_SUCCESS == result)
|
||||||
{
|
{
|
||||||
@ -805,7 +805,7 @@ void OpenSLCapture::open(const ALCchar* name)
|
|||||||
}
|
}
|
||||||
if(SL_RESULT_SUCCESS == result)
|
if(SL_RESULT_SUCCESS == result)
|
||||||
{
|
{
|
||||||
const ALuint chunk_size{mDevice->UpdateSize * mFrameSize};
|
const uint chunk_size{mDevice->UpdateSize * mFrameSize};
|
||||||
|
|
||||||
auto data = mRing->getWriteVector();
|
auto data = mRing->getWriteVector();
|
||||||
for(size_t i{0u};i < data.first.len && SL_RESULT_SUCCESS == result;i++)
|
for(size_t i{0u};i < data.first.len && SL_RESULT_SUCCESS == result;i++)
|
||||||
@ -882,16 +882,16 @@ void OpenSLCapture::captureSamples(al::byte *buffer, uint samples)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALuint update_size{mDevice->UpdateSize};
|
const uint update_size{mDevice->UpdateSize};
|
||||||
const ALuint chunk_size{update_size * mFrameSize};
|
const uint chunk_size{update_size * mFrameSize};
|
||||||
|
|
||||||
/* Read the desired samples from the ring buffer then advance its read
|
/* Read the desired samples from the ring buffer then advance its read
|
||||||
* pointer.
|
* pointer.
|
||||||
*/
|
*/
|
||||||
auto data = mRing->getReadVector();
|
auto data = mRing->getReadVector();
|
||||||
for(ALCuint i{0};i < samples;)
|
for(uint i{0};i < samples;)
|
||||||
{
|
{
|
||||||
const ALCuint rem{minu(samples - i, update_size - mSplOffset)};
|
const uint rem{minu(samples - i, update_size - mSplOffset)};
|
||||||
std::copy_n(data.first.buf + mSplOffset*mFrameSize, rem*mFrameSize, buffer + i*mFrameSize);
|
std::copy_n(data.first.buf + mSplOffset*mFrameSize, rem*mFrameSize, buffer + i*mFrameSize);
|
||||||
|
|
||||||
mSplOffset += rem;
|
mSplOffset += rem;
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alconfig.h"
|
#include "alconfig.h"
|
||||||
|
#include "albyte.h"
|
||||||
#include "alexcpt.h"
|
#include "alexcpt.h"
|
||||||
#include "almalloc.h"
|
#include "almalloc.h"
|
||||||
#include "alnumeric.h"
|
#include "alnumeric.h"
|
||||||
@ -215,9 +216,9 @@ done:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ALCuint log2i(ALCuint x)
|
uint log2i(uint x)
|
||||||
{
|
{
|
||||||
ALCuint y{0};
|
uint y{0};
|
||||||
while(x > 1)
|
while(x > 1)
|
||||||
{
|
{
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
@ -233,14 +234,14 @@ struct OSSPlayback final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
int mFd{-1};
|
int mFd{-1};
|
||||||
|
|
||||||
al::vector<ALubyte> mMixData;
|
al::vector<al::byte> mMixData;
|
||||||
|
|
||||||
std::atomic<bool> mKillNow{true};
|
std::atomic<bool> mKillNow{true};
|
||||||
std::thread mThread;
|
std::thread mThread;
|
||||||
@ -262,10 +263,10 @@ int OSSPlayback::mixerProc()
|
|||||||
althrd_setname(MIXER_THREAD_NAME);
|
althrd_setname(MIXER_THREAD_NAME);
|
||||||
|
|
||||||
const size_t frame_step{mDevice->channelsFromFmt()};
|
const size_t frame_step{mDevice->channelsFromFmt()};
|
||||||
const ALuint frame_size{mDevice->frameSizeFromFmt()};
|
const size_t frame_size{mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
while(!mKillNow.load(std::memory_order_acquire)
|
||||||
mDevice->Connected.load(std::memory_order_acquire))
|
&& mDevice->Connected.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
pollfd pollitem{};
|
pollfd pollitem{};
|
||||||
pollitem.fd = mFd;
|
pollitem.fd = mFd;
|
||||||
@ -286,9 +287,9 @@ int OSSPlayback::mixerProc()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALubyte *write_ptr{mMixData.data()};
|
al::byte *write_ptr{mMixData.data()};
|
||||||
size_t to_write{mMixData.size()};
|
size_t to_write{mMixData.size()};
|
||||||
mDevice->renderSamples(write_ptr, static_cast<ALuint>(to_write/frame_size), frame_step);
|
mDevice->renderSamples(write_ptr, static_cast<uint>(to_write/frame_size), frame_step);
|
||||||
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
|
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
ssize_t wrote{write(mFd, write_ptr, to_write)};
|
ssize_t wrote{write(mFd, write_ptr, to_write)};
|
||||||
@ -310,7 +311,7 @@ int OSSPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSSPlayback::open(const ALCchar *name)
|
void OSSPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *devname{DefaultPlayback.c_str()};
|
const char *devname{DefaultPlayback.c_str()};
|
||||||
if(!name)
|
if(!name)
|
||||||
@ -360,13 +361,13 @@ bool OSSPlayback::reset()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALuint periods{mDevice->BufferSize / mDevice->UpdateSize};
|
uint periods{mDevice->BufferSize / mDevice->UpdateSize};
|
||||||
ALuint numChannels{mDevice->channelsFromFmt()};
|
uint numChannels{mDevice->channelsFromFmt()};
|
||||||
ALuint ossSpeed{mDevice->Frequency};
|
uint ossSpeed{mDevice->Frequency};
|
||||||
ALuint frameSize{numChannels * mDevice->bytesFromFmt()};
|
uint frameSize{numChannels * mDevice->bytesFromFmt()};
|
||||||
/* According to the OSS spec, 16 bytes (log2(16)) is the minimum. */
|
/* According to the OSS spec, 16 bytes (log2(16)) is the minimum. */
|
||||||
ALuint log2FragmentSize{maxu(log2i(mDevice->UpdateSize*frameSize), 4)};
|
uint log2FragmentSize{maxu(log2i(mDevice->UpdateSize*frameSize), 4)};
|
||||||
ALuint numFragmentsLogSize{(periods << 16) | log2FragmentSize};
|
uint numFragmentsLogSize{(periods << 16) | log2FragmentSize};
|
||||||
|
|
||||||
audio_buf_info info{};
|
audio_buf_info info{};
|
||||||
const char *err;
|
const char *err;
|
||||||
@ -406,8 +407,8 @@ bool OSSPlayback::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mDevice->Frequency = ossSpeed;
|
mDevice->Frequency = ossSpeed;
|
||||||
mDevice->UpdateSize = static_cast<ALuint>(info.fragsize) / frameSize;
|
mDevice->UpdateSize = static_cast<uint>(info.fragsize) / frameSize;
|
||||||
mDevice->BufferSize = static_cast<ALuint>(info.fragments) * mDevice->UpdateSize;
|
mDevice->BufferSize = static_cast<uint>(info.fragments) * mDevice->UpdateSize;
|
||||||
|
|
||||||
setDefaultChannelOrder();
|
setDefaultChannelOrder();
|
||||||
|
|
||||||
@ -445,7 +446,7 @@ struct OSScapture final : public BackendBase {
|
|||||||
|
|
||||||
int recordProc();
|
int recordProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -474,7 +475,7 @@ int OSScapture::recordProc()
|
|||||||
SetRTPriority();
|
SetRTPriority();
|
||||||
althrd_setname(RECORD_THREAD_NAME);
|
althrd_setname(RECORD_THREAD_NAME);
|
||||||
|
|
||||||
const ALuint frame_size{mDevice->frameSizeFromFmt()};
|
const size_t frame_size{mDevice->frameSizeFromFmt()};
|
||||||
while(!mKillNow.load(std::memory_order_acquire))
|
while(!mKillNow.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
pollfd pollitem{};
|
pollfd pollitem{};
|
||||||
@ -506,7 +507,7 @@ int OSScapture::recordProc()
|
|||||||
mDevice->handleDisconnect("Failed reading capture samples: %s", strerror(errno));
|
mDevice->handleDisconnect("Failed reading capture samples: %s", strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mRing->writeAdvance(static_cast<ALuint>(amt)/frame_size);
|
mRing->writeAdvance(static_cast<size_t>(amt)/frame_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +515,7 @@ int OSScapture::recordProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OSScapture::open(const ALCchar *name)
|
void OSScapture::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *devname{DefaultCapture.c_str()};
|
const char *devname{DefaultCapture.c_str()};
|
||||||
if(!name)
|
if(!name)
|
||||||
@ -559,13 +560,13 @@ void OSScapture::open(const ALCchar *name)
|
|||||||
"%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
|
"%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
|
||||||
}
|
}
|
||||||
|
|
||||||
ALuint periods{4};
|
uint periods{4};
|
||||||
ALuint numChannels{mDevice->channelsFromFmt()};
|
uint numChannels{mDevice->channelsFromFmt()};
|
||||||
ALuint frameSize{numChannels * mDevice->bytesFromFmt()};
|
uint frameSize{numChannels * mDevice->bytesFromFmt()};
|
||||||
ALuint ossSpeed{mDevice->Frequency};
|
uint ossSpeed{mDevice->Frequency};
|
||||||
/* according to the OSS spec, 16 bytes are the minimum */
|
/* according to the OSS spec, 16 bytes are the minimum */
|
||||||
ALuint log2FragmentSize{maxu(log2i(mDevice->BufferSize * frameSize / periods), 4)};
|
uint log2FragmentSize{maxu(log2i(mDevice->BufferSize * frameSize / periods), 4)};
|
||||||
ALuint numFragmentsLogSize{(periods << 16) | log2FragmentSize};
|
uint numFragmentsLogSize{(periods << 16) | log2FragmentSize};
|
||||||
|
|
||||||
audio_buf_info info{};
|
audio_buf_info info{};
|
||||||
#define CHECKERR(func) if((func) < 0) { \
|
#define CHECKERR(func) if((func) < 0) { \
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr ALCchar pa_device[] = "PortAudio Default";
|
constexpr char pa_device[] = "PortAudio Default";
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DYNLOAD
|
#ifdef HAVE_DYNLOAD
|
||||||
@ -86,14 +86,14 @@ struct PortPlayback final : public BackendBase {
|
|||||||
framesPerBuffer, timeInfo, statusFlags);
|
framesPerBuffer, timeInfo, statusFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
PaStream *mStream{nullptr};
|
PaStream *mStream{nullptr};
|
||||||
PaStreamParameters mParams{};
|
PaStreamParameters mParams{};
|
||||||
ALuint mUpdateSize{0u};
|
uint mUpdateSize{0u};
|
||||||
|
|
||||||
DEF_NEWDEL(PortPlayback)
|
DEF_NEWDEL(PortPlayback)
|
||||||
};
|
};
|
||||||
@ -110,13 +110,13 @@ PortPlayback::~PortPlayback()
|
|||||||
int PortPlayback::writeCallback(const void*, void *outputBuffer, unsigned long framesPerBuffer,
|
int PortPlayback::writeCallback(const void*, void *outputBuffer, unsigned long framesPerBuffer,
|
||||||
const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept
|
const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept
|
||||||
{
|
{
|
||||||
mDevice->renderSamples(outputBuffer, static_cast<ALuint>(framesPerBuffer),
|
mDevice->renderSamples(outputBuffer, static_cast<uint>(framesPerBuffer),
|
||||||
static_cast<ALuint>(mParams.channelCount));
|
static_cast<uint>(mParams.channelCount));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PortPlayback::open(const ALCchar *name)
|
void PortPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = pa_device;
|
name = pa_device;
|
||||||
@ -177,7 +177,7 @@ retry_open:
|
|||||||
bool PortPlayback::reset()
|
bool PortPlayback::reset()
|
||||||
{
|
{
|
||||||
const PaStreamInfo *streamInfo{Pa_GetStreamInfo(mStream)};
|
const PaStreamInfo *streamInfo{Pa_GetStreamInfo(mStream)};
|
||||||
mDevice->Frequency = static_cast<ALuint>(streamInfo->sampleRate);
|
mDevice->Frequency = static_cast<uint>(streamInfo->sampleRate);
|
||||||
mDevice->UpdateSize = mUpdateSize;
|
mDevice->UpdateSize = mUpdateSize;
|
||||||
|
|
||||||
if(mParams.sampleFormat == paInt8)
|
if(mParams.sampleFormat == paInt8)
|
||||||
@ -240,7 +240,7 @@ struct PortCapture final : public BackendBase {
|
|||||||
framesPerBuffer, timeInfo, statusFlags);
|
framesPerBuffer, timeInfo, statusFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -271,7 +271,7 @@ int PortCapture::readCallback(const void *inputBuffer, void*, unsigned long fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PortCapture::open(const ALCchar *name)
|
void PortCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = pa_device;
|
name = pa_device;
|
||||||
@ -279,9 +279,9 @@ void PortCapture::open(const ALCchar *name)
|
|||||||
throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
|
throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
|
||||||
name};
|
name};
|
||||||
|
|
||||||
ALuint samples{mDevice->BufferSize};
|
uint samples{mDevice->BufferSize};
|
||||||
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
||||||
ALuint frame_size{mDevice->frameSizeFromFmt()};
|
uint frame_size{mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
mRing = RingBuffer::Create(samples, frame_size, false);
|
mRing = RingBuffer::Create(samples, frame_size, false);
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ al::optional<Channel> ChannelFromPulse(pa_channel_position_t chan)
|
|||||||
void SetChannelOrderFromMap(ALCdevice *device, const pa_channel_map &chanmap)
|
void SetChannelOrderFromMap(ALCdevice *device, const pa_channel_map &chanmap)
|
||||||
{
|
{
|
||||||
device->RealOut.ChannelIndex.fill(INVALID_CHANNEL_INDEX);
|
device->RealOut.ChannelIndex.fill(INVALID_CHANNEL_INDEX);
|
||||||
for(ALuint i{0};i < chanmap.channels;++i)
|
for(uint i{0};i < chanmap.channels;++i)
|
||||||
{
|
{
|
||||||
if(auto label = ChannelFromPulse(chanmap.map[i]))
|
if(auto label = ChannelFromPulse(chanmap.map[i]))
|
||||||
device->RealOut.ChannelIndex[*label] = i;
|
device->RealOut.ChannelIndex[*label] = i;
|
||||||
@ -719,7 +719,7 @@ struct PulsePlayback final : public BackendBase {
|
|||||||
static void streamMovedCallbackC(pa_stream *stream, void *pdata) noexcept
|
static void streamMovedCallbackC(pa_stream *stream, void *pdata) noexcept
|
||||||
{ static_cast<PulsePlayback*>(pdata)->streamMovedCallback(stream); }
|
{ static_cast<PulsePlayback*>(pdata)->streamMovedCallback(stream); }
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -735,7 +735,7 @@ struct PulsePlayback final : public BackendBase {
|
|||||||
pa_stream *mStream{nullptr};
|
pa_stream *mStream{nullptr};
|
||||||
pa_context *mContext{nullptr};
|
pa_context *mContext{nullptr};
|
||||||
|
|
||||||
ALuint mFrameSize{0u};
|
uint mFrameSize{0u};
|
||||||
|
|
||||||
DEF_NEWDEL(PulsePlayback)
|
DEF_NEWDEL(PulsePlayback)
|
||||||
};
|
};
|
||||||
@ -788,7 +788,7 @@ void PulsePlayback::streamWriteCallback(pa_stream *stream, size_t nbytes) noexce
|
|||||||
buflen = minz(buflen, nbytes);
|
buflen = minz(buflen, nbytes);
|
||||||
nbytes -= buflen;
|
nbytes -= buflen;
|
||||||
|
|
||||||
mDevice->renderSamples(buf, static_cast<ALuint>(buflen/mFrameSize), mSpec.channels);
|
mDevice->renderSamples(buf, static_cast<uint>(buflen/mFrameSize), mSpec.channels);
|
||||||
|
|
||||||
int ret{pa_stream_write(stream, buf, buflen, free_func, 0, PA_SEEK_RELATIVE)};
|
int ret{pa_stream_write(stream, buf, buflen, free_func, 0, PA_SEEK_RELATIVE)};
|
||||||
if UNLIKELY(ret != PA_OK)
|
if UNLIKELY(ret != PA_OK)
|
||||||
@ -857,7 +857,7 @@ void PulsePlayback::streamMovedCallback(pa_stream *stream) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PulsePlayback::open(const ALCchar *name)
|
void PulsePlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *pulse_name{nullptr};
|
const char *pulse_name{nullptr};
|
||||||
const char *dev_name{nullptr};
|
const char *dev_name{nullptr};
|
||||||
@ -899,7 +899,7 @@ void PulsePlayback::open(const ALCchar *name)
|
|||||||
BackendType::Playback);
|
BackendType::Playback);
|
||||||
|
|
||||||
pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
|
pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
|
||||||
mFrameSize = static_cast<ALuint>(pa_frame_size(pa_stream_get_sample_spec(mStream)));
|
mFrameSize = static_cast<uint>(pa_frame_size(pa_stream_get_sample_spec(mStream)));
|
||||||
|
|
||||||
mDeviceName = pa_stream_get_device_name(mStream);
|
mDeviceName = pa_stream_get_device_name(mStream);
|
||||||
if(!dev_name)
|
if(!dev_name)
|
||||||
@ -1007,7 +1007,7 @@ bool PulsePlayback::reset()
|
|||||||
if(pa_sample_spec_valid(&mSpec) == 0)
|
if(pa_sample_spec_valid(&mSpec) == 0)
|
||||||
throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample spec"};
|
throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample spec"};
|
||||||
|
|
||||||
const ALuint frame_size{static_cast<ALuint>(pa_frame_size(&mSpec))};
|
const auto frame_size = static_cast<uint>(pa_frame_size(&mSpec));
|
||||||
mAttr.maxlength = ~0u;
|
mAttr.maxlength = ~0u;
|
||||||
mAttr.tlength = mDevice->BufferSize * frame_size;
|
mAttr.tlength = mDevice->BufferSize * frame_size;
|
||||||
mAttr.prebuf = 0u;
|
mAttr.prebuf = 0u;
|
||||||
@ -1021,7 +1021,7 @@ bool PulsePlayback::reset()
|
|||||||
pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
|
pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
|
||||||
|
|
||||||
mSpec = *(pa_stream_get_sample_spec(mStream));
|
mSpec = *(pa_stream_get_sample_spec(mStream));
|
||||||
mFrameSize = static_cast<ALuint>(pa_frame_size(&mSpec));
|
mFrameSize = static_cast<uint>(pa_frame_size(&mSpec));
|
||||||
|
|
||||||
if(mDevice->Frequency != mSpec.rate)
|
if(mDevice->Frequency != mSpec.rate)
|
||||||
{
|
{
|
||||||
@ -1029,10 +1029,10 @@ bool PulsePlayback::reset()
|
|||||||
* accordingly.
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
const auto scale = static_cast<double>(mSpec.rate) / mDevice->Frequency;
|
const auto scale = static_cast<double>(mSpec.rate) / mDevice->Frequency;
|
||||||
const ALuint perlen{static_cast<ALuint>(clampd(scale*mDevice->UpdateSize + 0.5, 64.0,
|
const auto perlen = static_cast<uint>(clampd(scale*mDevice->UpdateSize + 0.5, 64.0,
|
||||||
8192.0))};
|
8192.0));
|
||||||
const ALuint buflen{static_cast<ALuint>(clampd(scale*mDevice->BufferSize + 0.5, perlen*2,
|
const auto buflen = static_cast<uint>(clampd(scale*mDevice->BufferSize + 0.5, perlen*2,
|
||||||
std::numeric_limits<int>::max()/mFrameSize))};
|
std::numeric_limits<int>::max()/mFrameSize));
|
||||||
|
|
||||||
mAttr.maxlength = ~0u;
|
mAttr.maxlength = ~0u;
|
||||||
mAttr.tlength = buflen * mFrameSize;
|
mAttr.tlength = buflen * mFrameSize;
|
||||||
@ -1148,7 +1148,7 @@ struct PulseCapture final : public BackendBase {
|
|||||||
static void streamMovedCallbackC(pa_stream *stream, void *pdata) noexcept
|
static void streamMovedCallbackC(pa_stream *stream, void *pdata) noexcept
|
||||||
{ static_cast<PulseCapture*>(pdata)->streamMovedCallback(stream); }
|
{ static_cast<PulseCapture*>(pdata)->streamMovedCallback(stream); }
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -1212,7 +1212,7 @@ void PulseCapture::streamMovedCallback(pa_stream *stream) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PulseCapture::open(const ALCchar *name)
|
void PulseCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *pulse_name{nullptr};
|
const char *pulse_name{nullptr};
|
||||||
if(name)
|
if(name)
|
||||||
@ -1288,8 +1288,8 @@ void PulseCapture::open(const ALCchar *name)
|
|||||||
if(pa_sample_spec_valid(&mSpec) == 0)
|
if(pa_sample_spec_valid(&mSpec) == 0)
|
||||||
throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample format"};
|
throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample format"};
|
||||||
|
|
||||||
const ALuint frame_size{static_cast<ALuint>(pa_frame_size(&mSpec))};
|
const auto frame_size = static_cast<uint>(pa_frame_size(&mSpec));
|
||||||
const ALuint samples{maxu(mDevice->BufferSize, 100 * mDevice->Frequency / 1000)};
|
const uint samples{maxu(mDevice->BufferSize, 100 * mDevice->Frequency / 1000)};
|
||||||
mAttr.minreq = ~0u;
|
mAttr.minreq = ~0u;
|
||||||
mAttr.prebuf = ~0u;
|
mAttr.prebuf = ~0u;
|
||||||
mAttr.maxlength = samples * frame_size;
|
mAttr.maxlength = samples * frame_size;
|
||||||
|
@ -46,7 +46,7 @@ namespace {
|
|||||||
#define DEVNAME_PREFIX ""
|
#define DEVNAME_PREFIX ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr ALCchar defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
|
constexpr char defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
|
||||||
|
|
||||||
struct Sdl2Backend final : public BackendBase {
|
struct Sdl2Backend final : public BackendBase {
|
||||||
Sdl2Backend(ALCdevice *device) noexcept : BackendBase{device} { }
|
Sdl2Backend(ALCdevice *device) noexcept : BackendBase{device} { }
|
||||||
@ -56,7 +56,7 @@ struct Sdl2Backend final : public BackendBase {
|
|||||||
static void audioCallbackC(void *ptr, Uint8 *stream, int len) noexcept
|
static void audioCallbackC(void *ptr, Uint8 *stream, int len) noexcept
|
||||||
{ static_cast<Sdl2Backend*>(ptr)->audioCallback(stream, len); }
|
{ static_cast<Sdl2Backend*>(ptr)->audioCallback(stream, len); }
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -86,7 +86,7 @@ void Sdl2Backend::audioCallback(Uint8 *stream, int len) noexcept
|
|||||||
mDevice->renderSamples(stream, ulen / mFrameSize, mDevice->channelsFromFmt());
|
mDevice->renderSamples(stream, ulen / mFrameSize, mDevice->channelsFromFmt());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sdl2Backend::open(const ALCchar *name)
|
void Sdl2Backend::open(const char *name)
|
||||||
{
|
{
|
||||||
SDL_AudioSpec want{}, have{};
|
SDL_AudioSpec want{}, have{};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const ALCchar sndio_device[] = "SndIO Default";
|
static const char sndio_device[] = "SndIO Default";
|
||||||
|
|
||||||
|
|
||||||
struct SndioPlayback final : public BackendBase {
|
struct SndioPlayback final : public BackendBase {
|
||||||
@ -51,7 +51,7 @@ struct SndioPlayback final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -95,7 +95,7 @@ int SndioPlayback::mixerProc()
|
|||||||
al::byte *WritePtr{mBuffer.data()};
|
al::byte *WritePtr{mBuffer.data()};
|
||||||
size_t len{mBuffer.size()};
|
size_t len{mBuffer.size()};
|
||||||
|
|
||||||
mDevice->renderSamples(WritePtr, static_cast<ALuint>(len)/frameSize, frameStep);
|
mDevice->renderSamples(WritePtr, static_cast<uint>(len/frameSize), frameStep);
|
||||||
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
|
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
size_t wrote{sio_write(mSndHandle, WritePtr, len)};
|
size_t wrote{sio_write(mSndHandle, WritePtr, len)};
|
||||||
@ -115,7 +115,7 @@ int SndioPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SndioPlayback::open(const ALCchar *name)
|
void SndioPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = sndio_device;
|
name = sndio_device;
|
||||||
@ -294,7 +294,7 @@ struct SndioCapture final : public BackendBase {
|
|||||||
|
|
||||||
int recordProc();
|
int recordProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
@ -322,10 +322,10 @@ int SndioCapture::recordProc()
|
|||||||
SetRTPriority();
|
SetRTPriority();
|
||||||
althrd_setname(RECORD_THREAD_NAME);
|
althrd_setname(RECORD_THREAD_NAME);
|
||||||
|
|
||||||
const ALuint frameSize{mDevice->frameSizeFromFmt()};
|
const uint frameSize{mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
while(!mKillNow.load(std::memory_order_acquire)
|
||||||
mDevice->Connected.load(std::memory_order_acquire))
|
&& mDevice->Connected.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
auto data = mRing->getWriteVector();
|
auto data = mRing->getWriteVector();
|
||||||
size_t todo{data.first.len + data.second.len};
|
size_t todo{data.first.len + data.second.len};
|
||||||
@ -364,7 +364,7 @@ int SndioCapture::recordProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SndioCapture::open(const ALCchar *name)
|
void SndioCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = sndio_device;
|
name = sndio_device;
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
|
#include "albyte.h"
|
||||||
#include "alexcpt.h"
|
#include "alexcpt.h"
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "alconfig.h"
|
#include "alconfig.h"
|
||||||
@ -52,7 +53,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr ALCchar solaris_device[] = "Solaris Default";
|
constexpr char solaris_device[] = "Solaris Default";
|
||||||
|
|
||||||
std::string solaris_driver{"/dev/audio"};
|
std::string solaris_driver{"/dev/audio"};
|
||||||
|
|
||||||
@ -63,14 +64,14 @@ struct SolarisBackend final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
int mFd{-1};
|
int mFd{-1};
|
||||||
|
|
||||||
al::vector<ALubyte> mBuffer;
|
al::vector<al::byte> mBuffer;
|
||||||
|
|
||||||
std::atomic<bool> mKillNow{true};
|
std::atomic<bool> mKillNow{true};
|
||||||
std::thread mThread;
|
std::thread mThread;
|
||||||
@ -91,10 +92,10 @@ int SolarisBackend::mixerProc()
|
|||||||
althrd_setname(MIXER_THREAD_NAME);
|
althrd_setname(MIXER_THREAD_NAME);
|
||||||
|
|
||||||
const size_t frame_step{mDevice->channelsFromFmt()};
|
const size_t frame_step{mDevice->channelsFromFmt()};
|
||||||
const ALuint frame_size{mDevice->frameSizeFromFmt()};
|
const uint frame_size{mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
while(!mKillNow.load(std::memory_order_acquire)
|
||||||
mDevice->Connected.load(std::memory_order_acquire))
|
&& mDevice->Connected.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
pollfd pollitem{};
|
pollfd pollitem{};
|
||||||
pollitem.fd = mFd;
|
pollitem.fd = mFd;
|
||||||
@ -115,9 +116,9 @@ int SolarisBackend::mixerProc()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALubyte *write_ptr{mBuffer.data()};
|
al::byte *write_ptr{mBuffer.data()};
|
||||||
size_t to_write{mBuffer.size()};
|
size_t to_write{mBuffer.size()};
|
||||||
mDevice->renderSamples(write_ptr, static_cast<ALuint>(to_write/frame_size), frame_step);
|
mDevice->renderSamples(write_ptr, static_cast<uint>(to_write/frame_size), frame_step);
|
||||||
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
|
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
ssize_t wrote{write(mFd, write_ptr, to_write)};
|
ssize_t wrote{write(mFd, write_ptr, to_write)};
|
||||||
@ -139,7 +140,7 @@ int SolarisBackend::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SolarisBackend::open(const ALCchar *name)
|
void SolarisBackend::open(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if(!name)
|
||||||
name = solaris_device;
|
name = solaris_device;
|
||||||
@ -164,32 +165,32 @@ bool SolarisBackend::reset()
|
|||||||
|
|
||||||
if(mDevice->FmtChans != DevFmtMono)
|
if(mDevice->FmtChans != DevFmtMono)
|
||||||
mDevice->FmtChans = DevFmtStereo;
|
mDevice->FmtChans = DevFmtStereo;
|
||||||
ALuint numChannels{mDevice->channelsFromFmt()};
|
uint numChannels{mDevice->channelsFromFmt()};
|
||||||
info.play.channels = numChannels;
|
info.play.channels = numChannels;
|
||||||
|
|
||||||
switch(mDevice->FmtType)
|
switch(mDevice->FmtType)
|
||||||
{
|
{
|
||||||
case DevFmtByte:
|
case DevFmtByte:
|
||||||
info.play.precision = 8;
|
info.play.precision = 8;
|
||||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||||
break;
|
break;
|
||||||
case DevFmtUByte:
|
case DevFmtUByte:
|
||||||
info.play.precision = 8;
|
info.play.precision = 8;
|
||||||
info.play.encoding = AUDIO_ENCODING_LINEAR8;
|
info.play.encoding = AUDIO_ENCODING_LINEAR8;
|
||||||
break;
|
break;
|
||||||
case DevFmtUShort:
|
case DevFmtUShort:
|
||||||
case DevFmtInt:
|
case DevFmtInt:
|
||||||
case DevFmtUInt:
|
case DevFmtUInt:
|
||||||
case DevFmtFloat:
|
case DevFmtFloat:
|
||||||
mDevice->FmtType = DevFmtShort;
|
mDevice->FmtType = DevFmtShort;
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case DevFmtShort:
|
case DevFmtShort:
|
||||||
info.play.precision = 16;
|
info.play.precision = 16;
|
||||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALuint frameSize{numChannels * mDevice->bytesFromFmt()};
|
uint frameSize{numChannels * mDevice->bytesFromFmt()};
|
||||||
info.play.buffer_size = mDevice->BufferSize * frameSize;
|
info.play.buffer_size = mDevice->BufferSize * frameSize;
|
||||||
|
|
||||||
if(ioctl(mFd, AUDIO_SETINFO, &info) < 0)
|
if(ioctl(mFd, AUDIO_SETINFO, &info) < 0)
|
||||||
@ -222,7 +223,7 @@ bool SolarisBackend::reset()
|
|||||||
setDefaultChannelOrder();
|
setDefaultChannelOrder();
|
||||||
|
|
||||||
mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
|
mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
|
||||||
std::fill(mBuffer.begin(), mBuffer.end(), 0);
|
std::fill(mBuffer.begin(), mBuffer.end(), al::byte{});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -122,10 +122,10 @@ constexpr DWORD X71Mask{MaskFromTopBits(X7DOT1)};
|
|||||||
|
|
||||||
|
|
||||||
/* Scales the given reftime value, rounding the result. */
|
/* Scales the given reftime value, rounding the result. */
|
||||||
inline ALuint RefTime2Samples(const ReferenceTime &val, ALuint srate)
|
inline uint RefTime2Samples(const ReferenceTime &val, uint srate)
|
||||||
{
|
{
|
||||||
const auto retval = (val*srate + ReferenceTime{seconds{1}}/2) / seconds{1};
|
const auto retval = (val*srate + ReferenceTime{seconds{1}}/2) / seconds{1};
|
||||||
return static_cast<ALuint>(mini64(retval, std::numeric_limits<ALuint>::max()));
|
return static_cast<uint>(mini64(retval, std::numeric_limits<uint>::max()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -596,12 +596,12 @@ int WasapiProxy::messageHandler(std::promise<HRESULT> *promise)
|
|||||||
promise = nullptr;
|
promise = nullptr;
|
||||||
|
|
||||||
TRACE("Starting message loop\n");
|
TRACE("Starting message loop\n");
|
||||||
ALuint deviceCount{0};
|
uint deviceCount{0};
|
||||||
Msg msg;
|
Msg msg;
|
||||||
while(popMessage(msg))
|
while(popMessage(msg))
|
||||||
{
|
{
|
||||||
TRACE("Got message \"%s\" (0x%04x, this=%p)\n",
|
TRACE("Got message \"%s\" (0x%04x, this=%p)\n",
|
||||||
MessageStr[static_cast<size_t>(msg.mType)], static_cast<int>(msg.mType),
|
MessageStr[static_cast<size_t>(msg.mType)], static_cast<uint>(msg.mType),
|
||||||
decltype(std::declval<void*>()){msg.mProxy});
|
decltype(std::declval<void*>()){msg.mProxy});
|
||||||
|
|
||||||
switch(msg.mType)
|
switch(msg.mType)
|
||||||
@ -670,7 +670,7 @@ int WasapiProxy::messageHandler(std::promise<HRESULT> *promise)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERR("Unexpected message: %u\n", static_cast<unsigned int>(msg.mType));
|
ERR("Unexpected message: %u\n", static_cast<uint>(msg.mType));
|
||||||
msg.mPromise.set_value(E_FAIL);
|
msg.mPromise.set_value(E_FAIL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -687,7 +687,7 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
HRESULT openProxy() override;
|
HRESULT openProxy() override;
|
||||||
void closeProxy() override;
|
void closeProxy() override;
|
||||||
|
|
||||||
@ -744,7 +744,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
|
|||||||
SetRTPriority();
|
SetRTPriority();
|
||||||
althrd_setname(MIXER_THREAD_NAME);
|
althrd_setname(MIXER_THREAD_NAME);
|
||||||
|
|
||||||
const ALuint update_size{mDevice->UpdateSize};
|
const uint update_size{mDevice->UpdateSize};
|
||||||
const UINT32 buffer_len{mDevice->BufferSize};
|
const UINT32 buffer_len{mDevice->BufferSize};
|
||||||
while(!mKillNow.load(std::memory_order_relaxed))
|
while(!mKillNow.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
@ -758,7 +758,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
mPadding.store(written, std::memory_order_relaxed);
|
mPadding.store(written, std::memory_order_relaxed);
|
||||||
|
|
||||||
ALuint len{buffer_len - written};
|
uint len{buffer_len - written};
|
||||||
if(len < update_size)
|
if(len < update_size)
|
||||||
{
|
{
|
||||||
DWORD res{WaitForSingleObjectEx(mNotifyEvent, 2000, FALSE)};
|
DWORD res{WaitForSingleObjectEx(mNotifyEvent, 2000, FALSE)};
|
||||||
@ -792,7 +792,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WasapiPlayback::open(const ALCchar *name)
|
void WasapiPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
HRESULT hr{S_OK};
|
HRESULT hr{S_OK};
|
||||||
|
|
||||||
@ -1225,7 +1225,7 @@ struct WasapiCapture final : public BackendBase, WasapiProxy {
|
|||||||
|
|
||||||
int recordProc();
|
int recordProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
HRESULT openProxy() override;
|
HRESULT openProxy() override;
|
||||||
void closeProxy() override;
|
void closeProxy() override;
|
||||||
|
|
||||||
@ -1311,10 +1311,10 @@ FORCE_ALIGN int WasapiCapture::recordProc()
|
|||||||
if(mSampleConv)
|
if(mSampleConv)
|
||||||
{
|
{
|
||||||
const void *srcdata{rdata};
|
const void *srcdata{rdata};
|
||||||
ALuint srcframes{numsamples};
|
uint srcframes{numsamples};
|
||||||
|
|
||||||
dstframes = mSampleConv->convert(&srcdata, &srcframes, data.first.buf,
|
dstframes = mSampleConv->convert(&srcdata, &srcframes, data.first.buf,
|
||||||
static_cast<ALuint>(minz(data.first.len, INT_MAX)));
|
static_cast<uint>(minz(data.first.len, INT_MAX)));
|
||||||
if(srcframes > 0 && dstframes == data.first.len && data.second.len > 0)
|
if(srcframes > 0 && dstframes == data.first.len && data.second.len > 0)
|
||||||
{
|
{
|
||||||
/* If some source samples remain, all of the first dest
|
/* If some source samples remain, all of the first dest
|
||||||
@ -1322,12 +1322,12 @@ FORCE_ALIGN int WasapiCapture::recordProc()
|
|||||||
* dest block, do another run for the second block.
|
* dest block, do another run for the second block.
|
||||||
*/
|
*/
|
||||||
dstframes += mSampleConv->convert(&srcdata, &srcframes, data.second.buf,
|
dstframes += mSampleConv->convert(&srcdata, &srcframes, data.second.buf,
|
||||||
static_cast<ALuint>(minz(data.second.len, INT_MAX)));
|
static_cast<uint>(minz(data.second.len, INT_MAX)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto framesize = static_cast<ALuint>(mDevice->frameSizeFromFmt());
|
const uint framesize{mDevice->frameSizeFromFmt()};
|
||||||
size_t len1{minz(data.first.len, numsamples)};
|
size_t len1{minz(data.first.len, numsamples)};
|
||||||
size_t len2{minz(data.second.len, numsamples-len1)};
|
size_t len2{minz(data.second.len, numsamples-len1)};
|
||||||
|
|
||||||
@ -1360,7 +1360,7 @@ FORCE_ALIGN int WasapiCapture::recordProc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WasapiCapture::open(const ALCchar *name)
|
void WasapiCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
HRESULT hr{S_OK};
|
HRESULT hr{S_OK};
|
||||||
|
|
||||||
@ -1639,7 +1639,7 @@ HRESULT WasapiCapture::resetProxy()
|
|||||||
|
|
||||||
if(mDevice->FmtChans == DevFmtMono && InputType.Format.nChannels != 1)
|
if(mDevice->FmtChans == DevFmtMono && InputType.Format.nChannels != 1)
|
||||||
{
|
{
|
||||||
ALuint chanmask{(1u<<InputType.Format.nChannels) - 1u};
|
uint chanmask{(1u<<InputType.Format.nChannels) - 1u};
|
||||||
/* Exclude LFE from the downmix. */
|
/* Exclude LFE from the downmix. */
|
||||||
if((InputType.dwChannelMask&SPEAKER_LOW_FREQUENCY))
|
if((InputType.dwChannelMask&SPEAKER_LOW_FREQUENCY))
|
||||||
{
|
{
|
||||||
@ -1799,7 +1799,7 @@ bool WasapiBackendFactory::init()
|
|||||||
catch(...) {
|
catch(...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCEEDED(InitResult) ? ALC_TRUE : ALC_FALSE;
|
return SUCCEEDED(InitResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WasapiBackendFactory::querySupport(BackendType type)
|
bool WasapiBackendFactory::querySupport(BackendType type)
|
||||||
|
@ -56,37 +56,40 @@ using std::chrono::seconds;
|
|||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using std::chrono::nanoseconds;
|
using std::chrono::nanoseconds;
|
||||||
|
|
||||||
constexpr ALCchar waveDevice[] = "Wave File Writer";
|
using ubyte = unsigned char;
|
||||||
|
using ushort = unsigned short;
|
||||||
|
|
||||||
constexpr ALubyte SUBTYPE_PCM[]{
|
constexpr char waveDevice[] = "Wave File Writer";
|
||||||
|
|
||||||
|
constexpr ubyte SUBTYPE_PCM[]{
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
||||||
0x00, 0x38, 0x9b, 0x71
|
0x00, 0x38, 0x9b, 0x71
|
||||||
};
|
};
|
||||||
constexpr ALubyte SUBTYPE_FLOAT[]{
|
constexpr ubyte SUBTYPE_FLOAT[]{
|
||||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
||||||
0x00, 0x38, 0x9b, 0x71
|
0x00, 0x38, 0x9b, 0x71
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr ALubyte SUBTYPE_BFORMAT_PCM[]{
|
constexpr ubyte SUBTYPE_BFORMAT_PCM[]{
|
||||||
0x01, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
|
0x01, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
|
||||||
0xca, 0x00, 0x00, 0x00
|
0xca, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr ALubyte SUBTYPE_BFORMAT_FLOAT[]{
|
constexpr ubyte SUBTYPE_BFORMAT_FLOAT[]{
|
||||||
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
|
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
|
||||||
0xca, 0x00, 0x00, 0x00
|
0xca, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
void fwrite16le(ALushort val, FILE *f)
|
void fwrite16le(ushort val, FILE *f)
|
||||||
{
|
{
|
||||||
ALubyte data[2]{ static_cast<ALubyte>(val&0xff), static_cast<ALubyte>((val>>8)&0xff) };
|
ubyte data[2]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff) };
|
||||||
fwrite(data, 1, 2, f);
|
fwrite(data, 1, 2, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fwrite32le(ALuint val, FILE *f)
|
void fwrite32le(uint val, FILE *f)
|
||||||
{
|
{
|
||||||
ALubyte data[4]{ static_cast<ALubyte>(val&0xff), static_cast<ALubyte>((val>>8)&0xff),
|
ubyte data[4]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
|
||||||
static_cast<ALubyte>((val>>16)&0xff), static_cast<ALubyte>((val>>24)&0xff) };
|
static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff) };
|
||||||
fwrite(data, 1, 4, f);
|
fwrite(data, 1, 4, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ struct WaveBackend final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
@ -127,7 +130,7 @@ int WaveBackend::mixerProc()
|
|||||||
althrd_setname(MIXER_THREAD_NAME);
|
althrd_setname(MIXER_THREAD_NAME);
|
||||||
|
|
||||||
const size_t frameStep{mDevice->channelsFromFmt()};
|
const size_t frameStep{mDevice->channelsFromFmt()};
|
||||||
const ALuint frameSize{mDevice->frameSizeFromFmt()};
|
const size_t frameSize{mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
int64_t done{0};
|
int64_t done{0};
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start = std::chrono::steady_clock::now();
|
||||||
@ -151,25 +154,25 @@ int WaveBackend::mixerProc()
|
|||||||
|
|
||||||
if /*constexpr*/(!IS_LITTLE_ENDIAN)
|
if /*constexpr*/(!IS_LITTLE_ENDIAN)
|
||||||
{
|
{
|
||||||
const ALuint bytesize{mDevice->bytesFromFmt()};
|
const uint bytesize{mDevice->bytesFromFmt()};
|
||||||
|
|
||||||
if(bytesize == 2)
|
if(bytesize == 2)
|
||||||
{
|
{
|
||||||
ALushort *samples = reinterpret_cast<ALushort*>(mBuffer.data());
|
ushort *samples = reinterpret_cast<ushort*>(mBuffer.data());
|
||||||
const size_t len{mBuffer.size() / 2};
|
const size_t len{mBuffer.size() / 2};
|
||||||
for(size_t i{0};i < len;i++)
|
for(size_t i{0};i < len;i++)
|
||||||
{
|
{
|
||||||
const ALushort samp{samples[i]};
|
const ushort samp{samples[i]};
|
||||||
samples[i] = static_cast<ALushort>((samp>>8) | (samp<<8));
|
samples[i] = static_cast<ushort>((samp>>8) | (samp<<8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(bytesize == 4)
|
else if(bytesize == 4)
|
||||||
{
|
{
|
||||||
ALuint *samples = reinterpret_cast<ALuint*>(mBuffer.data());
|
uint *samples = reinterpret_cast<uint*>(mBuffer.data());
|
||||||
const size_t len{mBuffer.size() / 4};
|
const size_t len{mBuffer.size() / 4};
|
||||||
for(size_t i{0};i < len;i++)
|
for(size_t i{0};i < len;i++)
|
||||||
{
|
{
|
||||||
const ALuint samp{samples[i]};
|
const uint samp{samples[i]};
|
||||||
samples[i] = (samp>>24) | ((samp>>8)&0x0000ff00) |
|
samples[i] = (samp>>24) | ((samp>>8)&0x0000ff00) |
|
||||||
((samp<<8)&0x00ff0000) | (samp<<24);
|
((samp<<8)&0x00ff0000) | (samp<<24);
|
||||||
}
|
}
|
||||||
@ -202,7 +205,7 @@ int WaveBackend::mixerProc()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveBackend::open(const ALCchar *name)
|
void WaveBackend::open(const char *name)
|
||||||
{
|
{
|
||||||
const char *fname{GetConfigValue(nullptr, "wave", "file", "")};
|
const char *fname{GetConfigValue(nullptr, "wave", "file", "")};
|
||||||
if(!fname[0]) throw al::backend_exception{al::backend_error::NoDevice,
|
if(!fname[0]) throw al::backend_exception{al::backend_error::NoDevice,
|
||||||
@ -231,8 +234,8 @@ void WaveBackend::open(const ALCchar *name)
|
|||||||
|
|
||||||
bool WaveBackend::reset()
|
bool WaveBackend::reset()
|
||||||
{
|
{
|
||||||
ALuint channels=0, bytes=0, chanmask=0;
|
uint channels{0}, bytes{0}, chanmask{0};
|
||||||
int isbformat = 0;
|
bool isbformat{false};
|
||||||
size_t val;
|
size_t val;
|
||||||
|
|
||||||
fseek(mFile, 0, SEEK_SET);
|
fseek(mFile, 0, SEEK_SET);
|
||||||
@ -246,38 +249,38 @@ bool WaveBackend::reset()
|
|||||||
|
|
||||||
switch(mDevice->FmtType)
|
switch(mDevice->FmtType)
|
||||||
{
|
{
|
||||||
case DevFmtByte:
|
case DevFmtByte:
|
||||||
mDevice->FmtType = DevFmtUByte;
|
mDevice->FmtType = DevFmtUByte;
|
||||||
break;
|
break;
|
||||||
case DevFmtUShort:
|
case DevFmtUShort:
|
||||||
mDevice->FmtType = DevFmtShort;
|
mDevice->FmtType = DevFmtShort;
|
||||||
break;
|
break;
|
||||||
case DevFmtUInt:
|
case DevFmtUInt:
|
||||||
mDevice->FmtType = DevFmtInt;
|
mDevice->FmtType = DevFmtInt;
|
||||||
break;
|
break;
|
||||||
case DevFmtUByte:
|
case DevFmtUByte:
|
||||||
case DevFmtShort:
|
case DevFmtShort:
|
||||||
case DevFmtInt:
|
case DevFmtInt:
|
||||||
case DevFmtFloat:
|
case DevFmtFloat:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch(mDevice->FmtChans)
|
switch(mDevice->FmtChans)
|
||||||
{
|
{
|
||||||
case DevFmtMono: chanmask = 0x04; break;
|
case DevFmtMono: chanmask = 0x04; break;
|
||||||
case DevFmtStereo: chanmask = 0x01 | 0x02; break;
|
case DevFmtStereo: chanmask = 0x01 | 0x02; break;
|
||||||
case DevFmtQuad: chanmask = 0x01 | 0x02 | 0x10 | 0x20; break;
|
case DevFmtQuad: chanmask = 0x01 | 0x02 | 0x10 | 0x20; break;
|
||||||
case DevFmtX51: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x200 | 0x400; break;
|
case DevFmtX51: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x200 | 0x400; break;
|
||||||
case DevFmtX51Rear: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020; break;
|
case DevFmtX51Rear: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020; break;
|
||||||
case DevFmtX61: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x100 | 0x200 | 0x400; break;
|
case DevFmtX61: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x100 | 0x200 | 0x400; break;
|
||||||
case DevFmtX71: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400; break;
|
case DevFmtX71: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400; break;
|
||||||
case DevFmtAmbi3D:
|
case DevFmtAmbi3D:
|
||||||
/* .amb output requires FuMa */
|
/* .amb output requires FuMa */
|
||||||
mDevice->mAmbiOrder = minu(mDevice->mAmbiOrder, 3);
|
mDevice->mAmbiOrder = minu(mDevice->mAmbiOrder, 3);
|
||||||
mDevice->mAmbiLayout = DevAmbiLayout::FuMa;
|
mDevice->mAmbiLayout = DevAmbiLayout::FuMa;
|
||||||
mDevice->mAmbiScale = DevAmbiScaling::FuMa;
|
mDevice->mAmbiScale = DevAmbiScaling::FuMa;
|
||||||
isbformat = 1;
|
isbformat = true;
|
||||||
chanmask = 0;
|
chanmask = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes = mDevice->bytesFromFmt();
|
bytes = mDevice->bytesFromFmt();
|
||||||
channels = mDevice->channelsFromFmt();
|
channels = mDevice->channelsFromFmt();
|
||||||
@ -295,19 +298,19 @@ bool WaveBackend::reset()
|
|||||||
// 16-bit val, format type id (extensible: 0xFFFE)
|
// 16-bit val, format type id (extensible: 0xFFFE)
|
||||||
fwrite16le(0xFFFE, mFile);
|
fwrite16le(0xFFFE, mFile);
|
||||||
// 16-bit val, channel count
|
// 16-bit val, channel count
|
||||||
fwrite16le(static_cast<ALushort>(channels), mFile);
|
fwrite16le(static_cast<ushort>(channels), mFile);
|
||||||
// 32-bit val, frequency
|
// 32-bit val, frequency
|
||||||
fwrite32le(mDevice->Frequency, mFile);
|
fwrite32le(mDevice->Frequency, mFile);
|
||||||
// 32-bit val, bytes per second
|
// 32-bit val, bytes per second
|
||||||
fwrite32le(mDevice->Frequency * channels * bytes, mFile);
|
fwrite32le(mDevice->Frequency * channels * bytes, mFile);
|
||||||
// 16-bit val, frame size
|
// 16-bit val, frame size
|
||||||
fwrite16le(static_cast<ALushort>(channels * bytes), mFile);
|
fwrite16le(static_cast<ushort>(channels * bytes), mFile);
|
||||||
// 16-bit val, bits per sample
|
// 16-bit val, bits per sample
|
||||||
fwrite16le(static_cast<ALushort>(bytes * 8), mFile);
|
fwrite16le(static_cast<ushort>(bytes * 8), mFile);
|
||||||
// 16-bit val, extra byte count
|
// 16-bit val, extra byte count
|
||||||
fwrite16le(22, mFile);
|
fwrite16le(22, mFile);
|
||||||
// 16-bit val, valid bits per sample
|
// 16-bit val, valid bits per sample
|
||||||
fwrite16le(static_cast<ALushort>(bytes * 8), mFile);
|
fwrite16le(static_cast<ushort>(bytes * 8), mFile);
|
||||||
// 32-bit val, channel mask
|
// 32-bit val, channel mask
|
||||||
fwrite32le(chanmask, mFile);
|
fwrite32le(chanmask, mFile);
|
||||||
// 16 byte GUID, sub-type format
|
// 16 byte GUID, sub-type format
|
||||||
@ -328,7 +331,7 @@ bool WaveBackend::reset()
|
|||||||
|
|
||||||
setDefaultWFXChannelOrder();
|
setDefaultWFXChannelOrder();
|
||||||
|
|
||||||
const ALuint bufsize{mDevice->frameSizeFromFmt() * mDevice->UpdateSize};
|
const uint bufsize{mDevice->frameSizeFromFmt() * mDevice->UpdateSize};
|
||||||
mBuffer.resize(bufsize);
|
mBuffer.resize(bufsize);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -357,9 +360,9 @@ void WaveBackend::stop()
|
|||||||
{
|
{
|
||||||
long dataLen{size - mDataStart};
|
long dataLen{size - mDataStart};
|
||||||
if(fseek(mFile, mDataStart-4, SEEK_SET) == 0)
|
if(fseek(mFile, mDataStart-4, SEEK_SET) == 0)
|
||||||
fwrite32le(static_cast<ALuint>(dataLen), mFile); // 'data' header len
|
fwrite32le(static_cast<uint>(dataLen), mFile); // 'data' header len
|
||||||
if(fseek(mFile, 4, SEEK_SET) == 0)
|
if(fseek(mFile, 4, SEEK_SET) == 0)
|
||||||
fwrite32le(static_cast<ALuint>(size-8), mFile); // 'WAVE' header len
|
fwrite32le(static_cast<uint>(size-8), mFile); // 'WAVE' header len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,9 @@ void ProbePlaybackDevices(void)
|
|||||||
{
|
{
|
||||||
PlaybackDevices.clear();
|
PlaybackDevices.clear();
|
||||||
|
|
||||||
ALuint numdevs{waveOutGetNumDevs()};
|
UINT numdevs{waveOutGetNumDevs()};
|
||||||
PlaybackDevices.reserve(numdevs);
|
PlaybackDevices.reserve(numdevs);
|
||||||
for(ALuint i{0};i < numdevs;i++)
|
for(UINT i{0};i < numdevs;++i)
|
||||||
{
|
{
|
||||||
std::string dname;
|
std::string dname;
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ void ProbeCaptureDevices(void)
|
|||||||
{
|
{
|
||||||
CaptureDevices.clear();
|
CaptureDevices.clear();
|
||||||
|
|
||||||
ALuint numdevs{waveInGetNumDevs()};
|
UINT numdevs{waveInGetNumDevs()};
|
||||||
CaptureDevices.reserve(numdevs);
|
CaptureDevices.reserve(numdevs);
|
||||||
for(ALuint i{0};i < numdevs;i++)
|
for(UINT i{0};i < numdevs;++i)
|
||||||
{
|
{
|
||||||
std::string dname;
|
std::string dname;
|
||||||
|
|
||||||
@ -135,14 +135,14 @@ struct WinMMPlayback final : public BackendBase {
|
|||||||
|
|
||||||
int mixerProc();
|
int mixerProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
bool reset() override;
|
bool reset() override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
std::atomic<ALuint> mWritable{0u};
|
std::atomic<uint> mWritable{0u};
|
||||||
al::semaphore mSem;
|
al::semaphore mSem;
|
||||||
ALuint mIdx{0u};
|
uint mIdx{0u};
|
||||||
std::array<WAVEHDR,4> mWaveBuffer{};
|
std::array<WAVEHDR,4> mWaveBuffer{};
|
||||||
|
|
||||||
HWAVEOUT mOutHdl{nullptr};
|
HWAVEOUT mOutHdl{nullptr};
|
||||||
@ -184,10 +184,10 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
|
|||||||
|
|
||||||
const size_t frame_step{mDevice->channelsFromFmt()};
|
const size_t frame_step{mDevice->channelsFromFmt()};
|
||||||
|
|
||||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
while(!mKillNow.load(std::memory_order_acquire)
|
||||||
mDevice->Connected.load(std::memory_order_acquire))
|
&& mDevice->Connected.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
ALsizei todo = mWritable.load(std::memory_order_acquire);
|
uint todo{mWritable.load(std::memory_order_acquire)};
|
||||||
if(todo < 1)
|
if(todo < 1)
|
||||||
{
|
{
|
||||||
mSem.wait();
|
mSem.wait();
|
||||||
@ -203,14 +203,14 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
|
|||||||
mWritable.fetch_sub(1, std::memory_order_acq_rel);
|
mWritable.fetch_sub(1, std::memory_order_acq_rel);
|
||||||
waveOutWrite(mOutHdl, &waveHdr, sizeof(WAVEHDR));
|
waveOutWrite(mOutHdl, &waveHdr, sizeof(WAVEHDR));
|
||||||
} while(--todo);
|
} while(--todo);
|
||||||
mIdx = static_cast<ALuint>(widx);
|
mIdx = static_cast<uint>(widx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WinMMPlayback::open(const ALCchar *name)
|
void WinMMPlayback::open(const char *name)
|
||||||
{
|
{
|
||||||
if(PlaybackDevices.empty())
|
if(PlaybackDevices.empty())
|
||||||
ProbePlaybackDevices();
|
ProbePlaybackDevices();
|
||||||
@ -263,7 +263,7 @@ retry_open:
|
|||||||
|
|
||||||
bool WinMMPlayback::reset()
|
bool WinMMPlayback::reset()
|
||||||
{
|
{
|
||||||
mDevice->BufferSize = static_cast<ALuint>(uint64_t{mDevice->BufferSize} *
|
mDevice->BufferSize = static_cast<uint>(uint64_t{mDevice->BufferSize} *
|
||||||
mFormat.nSamplesPerSec / mDevice->Frequency);
|
mFormat.nSamplesPerSec / mDevice->Frequency);
|
||||||
mDevice->BufferSize = (mDevice->BufferSize+3) & ~0x3u;
|
mDevice->BufferSize = (mDevice->BufferSize+3) & ~0x3u;
|
||||||
mDevice->UpdateSize = mDevice->BufferSize / 4;
|
mDevice->UpdateSize = mDevice->BufferSize / 4;
|
||||||
@ -297,7 +297,7 @@ bool WinMMPlayback::reset()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALuint chanmask{};
|
uint chanmask{};
|
||||||
if(mFormat.nChannels == 2)
|
if(mFormat.nChannels == 2)
|
||||||
{
|
{
|
||||||
mDevice->FmtChans = DevFmtStereo;
|
mDevice->FmtChans = DevFmtStereo;
|
||||||
@ -315,7 +315,7 @@ bool WinMMPlayback::reset()
|
|||||||
}
|
}
|
||||||
setChannelOrderFromWFXMask(chanmask);
|
setChannelOrderFromWFXMask(chanmask);
|
||||||
|
|
||||||
ALuint BufferSize{mDevice->UpdateSize * mDevice->frameSizeFromFmt()};
|
uint BufferSize{mDevice->UpdateSize * mDevice->frameSizeFromFmt()};
|
||||||
|
|
||||||
al_free(mWaveBuffer[0].lpData);
|
al_free(mWaveBuffer[0].lpData);
|
||||||
mWaveBuffer[0] = WAVEHDR{};
|
mWaveBuffer[0] = WAVEHDR{};
|
||||||
@ -337,9 +337,8 @@ void WinMMPlayback::start()
|
|||||||
try {
|
try {
|
||||||
std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
|
std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
|
||||||
[this](WAVEHDR &waveHdr) -> void
|
[this](WAVEHDR &waveHdr) -> void
|
||||||
{ waveOutPrepareHeader(mOutHdl, &waveHdr, static_cast<UINT>(sizeof(WAVEHDR))); }
|
{ waveOutPrepareHeader(mOutHdl, &waveHdr, sizeof(WAVEHDR)); });
|
||||||
);
|
mWritable.store(static_cast<uint>(mWaveBuffer.size()), std::memory_order_release);
|
||||||
mWritable.store(static_cast<ALuint>(mWaveBuffer.size()), std::memory_order_release);
|
|
||||||
|
|
||||||
mKillNow.store(false, std::memory_order_release);
|
mKillNow.store(false, std::memory_order_release);
|
||||||
mThread = std::thread{std::mem_fn(&WinMMPlayback::mixerProc), this};
|
mThread = std::thread{std::mem_fn(&WinMMPlayback::mixerProc), this};
|
||||||
@ -360,8 +359,7 @@ void WinMMPlayback::stop()
|
|||||||
mSem.wait();
|
mSem.wait();
|
||||||
std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
|
std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
|
||||||
[this](WAVEHDR &waveHdr) -> void
|
[this](WAVEHDR &waveHdr) -> void
|
||||||
{ waveOutUnprepareHeader(mOutHdl, &waveHdr, sizeof(WAVEHDR)); }
|
{ waveOutUnprepareHeader(mOutHdl, &waveHdr, sizeof(WAVEHDR)); });
|
||||||
);
|
|
||||||
mWritable.store(0, std::memory_order_release);
|
mWritable.store(0, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,15 +374,15 @@ struct WinMMCapture final : public BackendBase {
|
|||||||
|
|
||||||
int captureProc();
|
int captureProc();
|
||||||
|
|
||||||
void open(const ALCchar *name) override;
|
void open(const char *name) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void captureSamples(al::byte *buffer, uint samples) override;
|
void captureSamples(al::byte *buffer, uint samples) override;
|
||||||
uint availableSamples() override;
|
uint availableSamples() override;
|
||||||
|
|
||||||
std::atomic<ALuint> mReadable{0u};
|
std::atomic<uint> mReadable{0u};
|
||||||
al::semaphore mSem;
|
al::semaphore mSem;
|
||||||
ALuint mIdx{0};
|
uint mIdx{0};
|
||||||
std::array<WAVEHDR,4> mWaveBuffer{};
|
std::array<WAVEHDR,4> mWaveBuffer{};
|
||||||
|
|
||||||
HWAVEIN mInHdl{nullptr};
|
HWAVEIN mInHdl{nullptr};
|
||||||
@ -429,7 +427,7 @@ int WinMMCapture::captureProc()
|
|||||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
while(!mKillNow.load(std::memory_order_acquire) &&
|
||||||
mDevice->Connected.load(std::memory_order_acquire))
|
mDevice->Connected.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
ALuint todo{mReadable.load(std::memory_order_acquire)};
|
uint todo{mReadable.load(std::memory_order_acquire)};
|
||||||
if(todo < 1)
|
if(todo < 1)
|
||||||
{
|
{
|
||||||
mSem.wait();
|
mSem.wait();
|
||||||
@ -445,14 +443,14 @@ int WinMMCapture::captureProc()
|
|||||||
mReadable.fetch_sub(1, std::memory_order_acq_rel);
|
mReadable.fetch_sub(1, std::memory_order_acq_rel);
|
||||||
waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR));
|
waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR));
|
||||||
} while(--todo);
|
} while(--todo);
|
||||||
mIdx = static_cast<ALuint>(widx);
|
mIdx = static_cast<uint>(widx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WinMMCapture::open(const ALCchar *name)
|
void WinMMCapture::open(const char *name)
|
||||||
{
|
{
|
||||||
if(CaptureDevices.empty())
|
if(CaptureDevices.empty())
|
||||||
ProbeCaptureDevices();
|
ProbeCaptureDevices();
|
||||||
@ -519,8 +517,8 @@ void WinMMCapture::open(const ALCchar *name)
|
|||||||
|
|
||||||
// Allocate circular memory buffer for the captured audio
|
// Allocate circular memory buffer for the captured audio
|
||||||
// Make sure circular buffer is at least 100ms in size
|
// Make sure circular buffer is at least 100ms in size
|
||||||
ALuint CapturedDataSize{mDevice->BufferSize};
|
uint CapturedDataSize{mDevice->BufferSize};
|
||||||
CapturedDataSize = static_cast<ALuint>(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size()));
|
CapturedDataSize = static_cast<uint>(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size()));
|
||||||
|
|
||||||
mRing = RingBuffer::Create(CapturedDataSize, mFormat.nBlockAlign, false);
|
mRing = RingBuffer::Create(CapturedDataSize, mFormat.nBlockAlign, false);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user