Update to 20180729 release.

byuu wrote:

Sigh ...

asio.hpp needs #include <nall/windows/registry.hpp>

[Since the last WIP, byuu also posted the following message. -Ed.]

ruby drivers have all been updated (but not tested outside of BSD), and
I redesigned the settings window. The driver functionality all exists on
a new "Drivers" panel, the emulator/hack settings go to a
"Configuration" panel, and the video/audio panels lose driver settings.
As does the settings menu and its synchronize options.

I want to start pushing toward a v107 release. Critically, I will need
DirectSound and ALSA to support dynamic rate control. I'd also like to
eliminate the other system manifest.bml files. I need to update the
cheat code database format, and bundle at least a few quark shaders --
although I still need to default to Direct3D on Windows.

Turbo keys would be nice, if it's not too much effort. Aside from
netplay, it's the last significant feature I'm missing.

I think for v107, higan is going to be a bit rough around the edges
compared to bsnes. And I don't think it's practical to finish the bsnes
localization support.

I'm thinking we probably want another WIP to iron out any critical
issues, but this time there should be a feature freeze with the next
WIP.
This commit is contained in:
Tim Allen
2018-07-29 23:24:38 +10:00
parent 716c95f279
commit 5deba5cbc1
182 changed files with 1533 additions and 2674 deletions

View File

@@ -4,13 +4,14 @@ struct AudioALSA : Audio {
AudioALSA() { initialize(); }
~AudioALSA() { terminate(); }
auto driver() -> string override {
return "ALSA";
}
auto driver() -> string override { return "ALSA"; }
auto ready() -> bool override { return _ready; }
auto ready() -> bool override {
return _ready;
}
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableDevices() -> vector<string> override {
return queryDevices();
@@ -28,48 +29,48 @@ struct AudioALSA : Audio {
return {20, 40, 60, 80, 100};
}
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto setDevice(string device) -> bool override {
if(device == this->device()) return true;
if(device == Audio::device()) return true;
if(!Audio::setDevice(device)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == this->blocking()) return true;
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return true;
}
auto setChannels(uint channels) -> bool override {
if(channels == this->channels()) return true;
if(channels == Audio::channels()) return true;
if(!Audio::setChannels(channels)) return false;
return true;
}
auto setFrequency(double frequency) -> bool override {
if(frequency == this->frequency()) return true;
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool override {
if(latency == this->latency()) return true;
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto level() -> double override {
snd_pcm_sframes_t available = snd_pcm_avail_update(_interface);
if(available < 0) return 0.5;
return (double)(_bufferSize - available) / _bufferSize;
}
auto output(const double samples[]) -> void override {
if(!ready()) return;
_buffer[_offset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
_buffer[_offset] |= (uint16_t)sclamp<16>(samples[1] * 32767.0) << 16;
if(++_offset < _periodSize) return;
_offset++;
snd_pcm_sframes_t available;
do {
@@ -118,7 +119,7 @@ private:
uint rate = (uint)_frequency;
uint bufferTime = _latency * 1000;
uint periodTime = _latency * 1000 / 4;
uint periodTime = _latency * 1000 / 8;
snd_pcm_hw_params_t* hardwareParameters;
snd_pcm_hw_params_alloca(&hardwareParameters);
@@ -138,9 +139,7 @@ private:
snd_pcm_sw_params_t* softwareParameters;
snd_pcm_sw_params_alloca(&softwareParameters);
if(snd_pcm_sw_params_current(_interface, softwareParameters) < 0) return terminate(), false;
if(snd_pcm_sw_params_set_start_threshold(_interface, softwareParameters,
(_bufferSize / _periodSize) * _periodSize) < 0
) return terminate(), false;
if(snd_pcm_sw_params_set_start_threshold(_interface, softwareParameters, _bufferSize / 2) < 0) return terminate(), false;
if(snd_pcm_sw_params(_interface, softwareParameters) < 0) return terminate(), false;
_buffer = new uint32_t[_periodSize]();
@@ -163,8 +162,8 @@ private:
}
}
auto queryDevices() -> string_vector {
string_vector devices;
auto queryDevices() -> vector<string> {
vector<string> devices;
char** list;
if(snd_device_name_hint(-1, "pcm", (void***)&list) == 0) {

View File

@@ -4,41 +4,29 @@ struct AudioAO : Audio {
AudioAO() { initialize(); }
~AudioAO() { terminate(); }
auto availableDevices() -> string_vector {
return {"Default"};
}
auto driver() -> string override { return "libao"; }
auto ready() -> bool override { return _ready; }
auto availableFrequencies() -> vector<double> {
auto hasFrequencies() -> bool override { return true; }
auto availableFrequencies() -> vector<double> override {
return {44100.0, 48000.0, 96000.0};
}
auto availableLatencies() -> vector<uint> {
return {100};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto blocking() -> bool { return true; }
auto channels() -> uint { return 2; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return 100; }
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
uint32_t sample = 0;
sample |= (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
sample |= (uint16_t)sclamp<16>(samples[1] * 32767.0) << 16;
ao_play(_interface, (char*)&sample, 4);
}
private:
auto initialize() -> bool {
terminate();
@@ -56,10 +44,10 @@ struct AudioAO : Audio {
ao_info* information = ao_driver_info(driverID);
if(!information) return false;
_device = information->short_name;
string device = information->short_name;
ao_option* options = nullptr;
if(_device == "alsa") {
if(device == "alsa") {
ao_append_option(&options, "buffer_time", "100000"); //100ms latency (default was 500ms)
}
@@ -79,8 +67,6 @@ struct AudioAO : Audio {
}
bool _ready = false;
string _device = "Default";
double _frequency = 48000.0;
ao_device* _interface = nullptr;
};

View File

@@ -5,17 +5,31 @@ struct AudioASIO : Audio {
AudioASIO() { self = this; initialize(); }
~AudioASIO() { terminate(); }
auto availableDevices() -> string_vector {
string_vector devices;
auto driver() -> string override { return "ASIO"; }
auto ready() -> bool override { return _ready; }
auto hasContext() -> bool override { return true; }
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableDevices() -> vector<string> override {
vector<string> devices;
for(auto& device : _devices) devices.append(device.name);
return devices;
}
auto availableFrequencies() -> vector<double> {
auto availableChannels() -> vector<uint> override {
return {1, 2};
}
auto availableFrequencies() -> vector<double> override {
return {_frequency};
}
auto availableLatencies() -> vector<uint> {
auto availableLatencies() -> vector<uint> override {
vector<uint> latencies;
uint latencyList[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 6144}; //factors of 6144
for(auto& latency : latencyList) {
@@ -26,49 +40,37 @@ struct AudioASIO : Audio {
return latencies;
}
auto availableChannels() -> vector<uint> {
return {1, 2};
}
auto ready() -> bool { return _ready; }
auto context() -> uintptr { return _context; }
auto device() -> string { return _device; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return _channels; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return _latency; }
auto setContext(uintptr context) -> bool {
if(_context == context) return true;
_context = context;
auto setContext(uintptr context) -> bool override {
if(context == Audio::context()) return true;
if(!Audio::setContext(context)) return false;
return initialize();
}
auto setDevice(string device) -> bool {
if(_device == device) return true;
_device = device;
auto setDevice(string device) -> bool override {
if(device == Audio::device()) return true;
if(!Audio::setDevice(device)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
auto setBlocking(bool blocking) -> bool override {
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return initialize();
}
auto setChannels(uint channels) -> bool {
if(_channels == channels) return true;
_channels = channels;
auto setChannels(uint channels) -> bool override {
if(channels == Audio::channels()) return true;
if(!Audio::setChannels(channels)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
auto setLatency(uint latency) -> bool override {
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto clear() -> void {
auto clear() -> void override {
if(!ready()) return;
for(uint n : range(_channels)) {
memory::fill<uint8_t>(_channel[n].buffers[0], _latency * _sampleSize);
@@ -80,7 +82,7 @@ struct AudioASIO : Audio {
_queue.count = 0;
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
if(!ready()) return;
if(_blocking) {
while(_queue.count >= _latency);
@@ -251,12 +253,6 @@ private:
}
bool _ready = false;
uintptr _context = 0;
string _device;
bool _blocking = true;
uint _channels = 2;
double _frequency = 48000.0;
uint _latency = 0;
struct Queue {
double samples[65536][8];

View File

@@ -4,47 +4,40 @@ struct AudioDirectSound : Audio {
AudioDirectSound() { initialize(); }
~AudioDirectSound() { terminate(); }
auto availableDevices() -> string_vector {
return {"Default"};
}
auto driver() -> string override { return "DirectSound"; }
auto ready() -> bool override { return _ready; }
auto availableFrequencies() -> vector<double> {
auto hasBlocking() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableFrequencies() -> vector<double> override {
return {44100.0, 48000.0, 96000.0};
}
auto availableLatencies() -> vector<uint> {
auto availableLatencies() -> vector<uint> override {
return {40, 60, 80, 100};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return _channels; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return _latency; }
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
auto setBlocking(bool blocking) -> bool override {
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return true;
}
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
auto setLatency(uint latency) -> bool override {
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto clear() -> void {
auto clear() -> void override {
if(!ready()) return;
_ringRead = 0;
@@ -67,7 +60,7 @@ struct AudioDirectSound : Audio {
_secondary->Play(0, 0, DSBPLAY_LOOPING);
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
if(!ready()) return;
_buffer[_offset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
@@ -159,10 +152,6 @@ private:
}
bool _ready = false;
bool _blocking = true;
uint _channels = 2;
double _frequency = 48000.0;
uint _latency = 40;
LPDIRECTSOUND _interface = nullptr;
LPDIRECTSOUNDBUFFER _primary = nullptr;

View File

@@ -10,13 +10,14 @@ struct AudioOpenAL : Audio {
AudioOpenAL() { initialize(); }
~AudioOpenAL() { terminate(); }
auto driver() -> string override {
return "OpenAL";
}
auto driver() -> string override { return "OpenAL"; }
auto ready() -> bool override { return _ready; }
auto ready() -> bool override {
return _ready;
}
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableDevices() -> vector<string> override {
vector<string> devices;
@@ -36,12 +37,6 @@ struct AudioOpenAL : Audio {
return {20, 40, 60, 80, 100};
}
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto setDevice(string device) -> bool override {
if(device == this->device()) return true;
if(!Audio::setDevice(device)) return false;

View File

@@ -17,13 +17,15 @@ struct AudioOSS : Audio {
AudioOSS() { initialize(); }
~AudioOSS() { terminate(); }
auto driver() -> string override {
return "OSS";
}
auto driver() -> string override { return "OSS"; }
auto ready() -> bool override { return _fd >= 0; }
auto ready() -> bool override {
return _fd >= 0;
}
auto hasDevice() -> bool override { return true; }
auto hasDynamic() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableDevices() -> vector<string> override {
vector<string> devices;
@@ -32,6 +34,10 @@ struct AudioOSS : Audio {
return devices;
}
auto defaultChannels() -> uint override { return 2; }
auto defaultFrequency() -> double override { return 48000.0; }
auto defaultLatency() -> uint override { return 3; }
auto availableChannels() -> vector<uint> override {
return {1, 2};
}
@@ -44,45 +50,38 @@ struct AudioOSS : Audio {
return {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}
auto hasDevice() -> bool override { return true; }
auto hasDynamic() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasChannels() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto setDevice(string device) -> bool override {
if(device == this->device()) return true;
if(device == Audio::device()) return true;
if(!Audio::setDevice(device)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool override {
if(blocking == this->blocking()) return true;
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return updateBlocking();
}
auto setDynamic(bool dynamic) -> bool override {
if(dynamic == this->dynamic()) return true;
if(dynamic == Audio::dynamic()) return true;
if(!Audio::setDynamic(dynamic)) return false;
return true;
}
auto setChannels(uint channels) -> bool override {
if(channels == this->channels()) return true;
if(channels == Audio::channels()) return true;
if(!Audio::setChannels(channels)) return false;
return initialize();
}
auto setFrequency(double frequency) -> bool override {
if(frequency == this->frequency()) return true;
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool override {
if(latency == this->latency()) return true;
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
@@ -169,5 +168,5 @@ private:
int _bufferSize = 1;
uint _outputOffset = 0;
uint16_t _outputBuffer[256];
uint16_t _outputBuffer[64];
};

View File

@@ -4,47 +4,40 @@ struct AudioPulseAudio : Audio {
AudioPulseAudio() { initialize(); }
~AudioPulseAudio() { terminate(); }
auto availableDevices() -> string_vector {
return {"Default"};
}
auto driver() -> string override { return "PulseAudio"; }
auto ready() -> bool override { return _ready; }
auto availableFrequencies() -> vector<double> {
auto hasBlocking() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableFrequencies() -> vector<double> override {
return {44100.0, 48000.0, 96000.0};
}
auto availableLatencies() -> vector<uint> {
auto availableLatencies() -> vector<uint> override {
return {20, 40, 60, 80, 100};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return 2; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return _latency; }
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
auto setBlocking(bool blocking) -> bool override {
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return true;
}
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
auto setLatency(uint latency) -> bool override {
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
pa_stream_begin_write(_stream, (void**)&_buffer, &_period);
_buffer[_offset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
_buffer[_offset] |= (uint16_t)sclamp<16>(samples[1] * 32767.0) << 16;
@@ -140,9 +133,6 @@ private:
}
bool _ready = false;
bool _blocking = true;
double _frequency = 48000.0;
uint _latency = 40;
uint32_t* _buffer = nullptr;
size_t _period = 0;

View File

@@ -5,35 +5,22 @@ struct AudioPulseAudioSimple : Audio {
AudioPulseAudioSimple() { initialize(); }
~AudioPulseAudioSimple() { terminate(); }
auto availableDevices() -> string_vector {
return {"Default"};
}
auto driver() -> string override { return "PulseAudioSimple"; }
auto ready() -> bool override { return _ready; }
auto availableFrequencies() -> vector<double> {
auto hasFrequency() -> bool override { return true; }
auto availableFrequencies() -> vector<double> override {
return {44100.0, 48000.0, 96000.0};
}
auto availableLatencies() -> vector<uint> {
return {40};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto blocking() -> bool { return true; }
auto channels() -> uint { return 2; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return 40; }
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
if(!ready()) return;
_buffer[_offset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
@@ -90,7 +77,6 @@ private:
}
bool _ready = false;
double _frequency = 48000.0;
pa_simple* _interface = nullptr;

View File

@@ -10,61 +10,58 @@ struct AudioWASAPI : Audio {
AudioWASAPI() { initialize(); }
~AudioWASAPI() { terminate(); }
auto availableDevices() -> string_vector {
auto driver() -> string override { return "WASAPI"; }
auto ready() -> bool override { return _ready; }
auto hasExclusive() -> bool override { return true; }
auto hasDevice() -> bool override { return true; }
auto hasBlocking() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableDevices() -> vector<string> override {
return _devices;
}
auto availableFrequencies() -> vector<double> {
return {(double)_frequency};
auto availableFrequencies() -> vector<double> override {
return {_frequency};
}
auto availableLatencies() -> vector<uint> {
auto availableLatencies() -> vector<uint> override {
return {0, 20, 40, 60, 80, 100};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto exclusive() -> bool { return _exclusive; }
auto device() -> string { return _device; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return _channels; }
auto frequency() -> double { return (double)_frequency; }
auto latency() -> uint { return _latency; }
auto setExclusive(bool exclusive) -> bool {
if(_exclusive == exclusive) return true;
_exclusive = exclusive;
auto setExclusive(bool exclusive) -> bool override {
if(exclusive == Audio::exclusive()) return true;
if(!Audio::setExclusive(exclusive)) return false;
return initialize();
}
auto setDevice(string device) -> bool {
if(_device == device) return true;
_device = device;
auto setDevice(string device) -> bool override {
if(device == Audio::device()) return true;
if(!Audio::setDevice(device)) return false;
return initialize();
}
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
auto setBlocking(bool blocking) -> bool override {
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return true;
}
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
auto setLatency(uint latency) -> bool override {
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto clear() -> void {
auto clear() -> void override {
if(!ready()) return;
_queue.read = 0;
_queue.write = 0;
@@ -74,7 +71,7 @@ struct AudioWASAPI : Audio {
_audioClient->Start();
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
if(!ready()) return;
for(uint n : range(_channels)) {
@@ -227,12 +224,6 @@ private:
}
bool _ready = false;
bool _exclusive = false;
string _device;
bool _blocking = true;
uint _channels = 2;
uint _frequency = 48000;
uint _latency = 20;
uint _mode = 0;
uint _precision = 0;
@@ -245,7 +236,7 @@ private:
} _queue;
IMMDeviceEnumerator* _enumerator = nullptr;
string_vector _devices;
vector<string> _devices;
IMMDevice* _audioDevice = nullptr;
IAudioClient* _audioClient = nullptr;
IAudioRenderClient* _renderClient = nullptr;

View File

@@ -5,47 +5,40 @@ struct AudioXAudio2 : Audio, public IXAudio2VoiceCallback {
AudioXAudio2() { initialize(); }
~AudioXAudio2() { terminate(); }
auto availableDevices() -> string_vector {
return {"Default"};
}
auto driver() -> string override { return "XAudio2"; }
auto ready() -> bool override { return _ready; }
auto availableFrequencies() -> vector<double> {
auto hasBlocking() -> bool override { return true; }
auto hasFrequency() -> bool override { return true; }
auto hasLatency() -> bool override { return true; }
auto availableFrequencies() -> vector<double> override {
return {44100.0, 48000.0, 96000.0};
}
auto availableLatencies() -> vector<uint> {
auto availableLatencies() -> vector<uint> override {
return {20, 40, 60, 80, 100};
}
auto availableChannels() -> vector<uint> {
return {2};
}
auto ready() -> bool { return _ready; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return _channels; }
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return _latency; }
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
auto setBlocking(bool blocking) -> bool override {
if(blocking == Audio::blocking()) return true;
if(!Audio::setBlocking(blocking)) return false;
return true;
}
auto setFrequency(double frequency) -> bool {
if(_frequency == frequency) return true;
_frequency = frequency;
auto setFrequency(double frequency) -> bool override {
if(frequency == Audio::frequency()) return true;
if(!Audio::setFrequency(frequency)) return false;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
auto setLatency(uint latency) -> bool override {
if(latency == Audio::latency()) return true;
if(!Audio::setLatency(latency)) return false;
return initialize();
}
auto clear() -> void {
auto clear() -> void override {
if(!_sourceVoice) return;
_sourceVoice->Stop(0);
_sourceVoice->FlushSourceBuffers(); //calls OnBufferEnd for all currently submitted buffers
@@ -58,7 +51,7 @@ struct AudioXAudio2 : Audio, public IXAudio2VoiceCallback {
_sourceVoice->Start(0);
}
auto output(const double samples[]) -> void {
auto output(const double samples[]) -> void override {
_buffer[_bufferIndex * _period + _bufferOffset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0;
_buffer[_bufferIndex * _period + _bufferOffset] |= (uint16_t)sclamp<16>(samples[1] * 32767.0) << 16;
if(++_bufferOffset < _period) return;
@@ -151,10 +144,6 @@ private:
}
bool _ready = false;
bool _blocking = true;
uint _channels = 2;
double _frequency = 48000.0;
uint _latency = 80;
uint32_t* _buffer = nullptr;
uint _period = 0;