mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-03 07:33:06 +02:00
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:
@@ -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) {
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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];
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user