bsnes/ruby/audio/asio.cpp

283 lines
8.2 KiB
C++
Raw Normal View History

#include "asio.hpp"
struct AudioASIO : Audio {
static AudioASIO* self;
AudioASIO() { self = this; initialize(); }
~AudioASIO() { terminate(); }
auto ready() -> bool { return _ready; }
auto information() -> Information {
Information information;
for(auto& device : _devices) information.devices.append(device.name);
information.frequencies = {_frequency};
uint latencies[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 6144}; //factors of 6144
for(auto& latency : latencies) {
if(latency < _active.minimumBufferSize) continue;
if(latency > _active.maximumBufferSize) continue;
information.latencies.append(latency);
}
information.channels = {1, 2};
return information;
}
auto context() -> uintptr { return _context; }
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
auto device() -> string { return _device; }
auto blocking() -> bool { return _blocking; }
auto channels() -> uint { return _channels; }
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
auto frequency() -> double { return _frequency; }
auto latency() -> uint { return _latency; }
auto setContext(uintptr context) -> bool {
if(_context == context) return true;
_context = context;
return initialize();
}
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
auto setDevice(string device) -> bool {
if(_device == device) return true;
_device = device;
return initialize();
}
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
return initialize();
}
auto setChannels(uint channels) -> bool {
if(_channels == channels) return true;
_channels = channels;
return initialize();
}
auto setLatency(uint latency) -> bool {
if(_latency == latency) return true;
_latency = latency;
return initialize();
}
auto clear() -> void {
Update to v103r22 release. byuu says: Changelog: - ruby: ported all remaining drivers to new API¹ - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan] - gb: emulated most of the TAMA RTC; but RTC state is still volatile² ¹: the new ports are: - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao} - input/{udev, quartz, carbon} It's pretty much guaranteed many of them will have compilation errors. Please paste the error logs and I'll try to fix them up. It may take a WIP or two to get there. It's also possible things broke from the updates. If so, I could use help comparing the old file to the new file, looking for mistakes, since I can't test on these platforms apart from audio/directsound. Please report working drivers in this list, so we can mark them off the list. I'll need both macOS and Linux testers. audio/directsound.cpp:112:    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false; ²: once I get this working, I'll add load/save support for the RTC values. For now, the RTC data will be lost when you close the emulator. Right now, you can set the date/time in real-time mode, and when you start the game, the time will be correct, and the time will tick forward. Note that it runs off emulated time instead of actual real time, so if you fast-forward to 300%, one minute will be 20 seconds. The really big limitation right now is that when you exit the game, and restart it, and resume a new game, the hour spot gets corrupted, and this seems to instantly kill your pet. Fun. This is crazy because the commands the game sends to the TAMA interface are identical between starting a new game and getting in-game versus loading a game. It's likely going to require disassembling the game's code and seeing what in the hell it's doing, but I am extremely bad at LR35092 assembly. Hopefully endrift can help here :|
2017-07-28 11:42:24 +00:00
if(!ready()) return;
for(uint n : range(_channels)) {
memory::fill(_channel[n].buffers[0], _latency * _sampleSize);
memory::fill(_channel[n].buffers[1], _latency * _sampleSize);
}
memory::fill(_queue.samples, sizeof(_queue.samples));
_queue.read = 0;
_queue.write = 0;
_queue.count = 0;
}
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
auto output(const double samples[]) -> void {
Update to v103r22 release. byuu says: Changelog: - ruby: ported all remaining drivers to new API¹ - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan] - gb: emulated most of the TAMA RTC; but RTC state is still volatile² ¹: the new ports are: - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao} - input/{udev, quartz, carbon} It's pretty much guaranteed many of them will have compilation errors. Please paste the error logs and I'll try to fix them up. It may take a WIP or two to get there. It's also possible things broke from the updates. If so, I could use help comparing the old file to the new file, looking for mistakes, since I can't test on these platforms apart from audio/directsound. Please report working drivers in this list, so we can mark them off the list. I'll need both macOS and Linux testers. audio/directsound.cpp:112:    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false; ²: once I get this working, I'll add load/save support for the RTC values. For now, the RTC data will be lost when you close the emulator. Right now, you can set the date/time in real-time mode, and when you start the game, the time will be correct, and the time will tick forward. Note that it runs off emulated time instead of actual real time, so if you fast-forward to 300%, one minute will be 20 seconds. The really big limitation right now is that when you exit the game, and restart it, and resume a new game, the hour spot gets corrupted, and this seems to instantly kill your pet. Fun. This is crazy because the commands the game sends to the TAMA interface are identical between starting a new game and getting in-game versus loading a game. It's likely going to require disassembling the game's code and seeing what in the hell it's doing, but I am extremely bad at LR35092 assembly. Hopefully endrift can help here :|
2017-07-28 11:42:24 +00:00
if(!ready()) return;
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
if(_blocking) {
while(_queue.count >= _latency);
}
for(uint n : range(_channels)) {
_queue.samples[_queue.write][n] = samples[n];
}
_queue.write++;
_queue.count++;
}
private:
auto initialize() -> bool {
terminate();
//enumerate available ASIO drivers from the registry
for(auto candidate : registry::contents("HKLM\\SOFTWARE\\ASIO\\")) {
if(auto classID = registry::read({"HKLM\\SOFTWARE\\ASIO\\", candidate, "CLSID"})) {
_devices.append({candidate.trimRight("\\", 1L), classID});
if(candidate == _device) _active = _devices.right();
}
}
if(!_devices) return false;
if(!_active.name) {
_active = _devices.left();
_device = _active.name;
}
CLSID classID;
if(CLSIDFromString((LPOLESTR)utf16_t(_active.classID), (LPCLSID)&classID) != S_OK) return false;
if(CoCreateInstance(classID, 0, CLSCTX_INPROC_SERVER, classID, (void**)&_asio) != S_OK) return false;
if(!_asio->init((void*)_context)) return false;
if(_asio->getSampleRate(&_active.sampleRate) != ASE_OK) return false;
if(_asio->getChannels(&_active.inputChannels, &_active.outputChannels) != ASE_OK) return false;
if(_asio->getBufferSize(
&_active.minimumBufferSize,
&_active.maximumBufferSize,
&_active.preferredBufferSize,
&_active.granularity
) != ASE_OK) return false;
_frequency = _active.sampleRate;
_latency = _latency < _active.minimumBufferSize ? _active.minimumBufferSize : _latency;
_latency = _latency > _active.maximumBufferSize ? _active.maximumBufferSize : _latency;
for(auto n : range(_channels)) {
_channel[n].isInput = false;
_channel[n].channelNum = n;
_channel[n].buffers[0] = nullptr;
_channel[n].buffers[1] = nullptr;
}
ASIOCallbacks callbacks;
callbacks.bufferSwitch = &AudioASIO::_bufferSwitch;
callbacks.sampleRateDidChange = &AudioASIO::_sampleRateDidChange;
callbacks.asioMessage = &AudioASIO::_asioMessage;
callbacks.bufferSwitchTimeInfo = &AudioASIO::_bufferSwitchTimeInfo;
if(_asio->createBuffers(_channel, _channels, _latency, &callbacks) != ASE_OK) return false;
if(_asio->getLatencies(&_active.inputLatency, &_active.outputLatency) != ASE_OK) return false;
//assume for the sake of sanity that all buffers use the same sample format ...
ASIOChannelInfo channelInformation = {};
channelInformation.channel = 0;
channelInformation.isInput = false;
if(_asio->getChannelInfo(&channelInformation) != ASE_OK) return false;
switch(_sampleFormat = channelInformation.type) {
case ASIOSTInt16LSB: _sampleSize = 2; break;
case ASIOSTInt24LSB: _sampleSize = 3; break;
case ASIOSTInt32LSB: _sampleSize = 4; break;
case ASIOSTFloat32LSB: _sampleSize = 4; break;
case ASIOSTFloat64LSB: _sampleSize = 8; break;
default: return false; //unsupported sample format
}
Update to v103r22 release. byuu says: Changelog: - ruby: ported all remaining drivers to new API¹ - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan] - gb: emulated most of the TAMA RTC; but RTC state is still volatile² ¹: the new ports are: - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao} - input/{udev, quartz, carbon} It's pretty much guaranteed many of them will have compilation errors. Please paste the error logs and I'll try to fix them up. It may take a WIP or two to get there. It's also possible things broke from the updates. If so, I could use help comparing the old file to the new file, looking for mistakes, since I can't test on these platforms apart from audio/directsound. Please report working drivers in this list, so we can mark them off the list. I'll need both macOS and Linux testers. audio/directsound.cpp:112:    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false; ²: once I get this working, I'll add load/save support for the RTC values. For now, the RTC data will be lost when you close the emulator. Right now, you can set the date/time in real-time mode, and when you start the game, the time will be correct, and the time will tick forward. Note that it runs off emulated time instead of actual real time, so if you fast-forward to 300%, one minute will be 20 seconds. The really big limitation right now is that when you exit the game, and restart it, and resume a new game, the hour spot gets corrupted, and this seems to instantly kill your pet. Fun. This is crazy because the commands the game sends to the TAMA interface are identical between starting a new game and getting in-game versus loading a game. It's likely going to require disassembling the game's code and seeing what in the hell it's doing, but I am extremely bad at LR35092 assembly. Hopefully endrift can help here :|
2017-07-28 11:42:24 +00:00
_ready = true;
clear();
Update to v103r22 release. byuu says: Changelog: - ruby: ported all remaining drivers to new API¹ - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan] - gb: emulated most of the TAMA RTC; but RTC state is still volatile² ¹: the new ports are: - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao} - input/{udev, quartz, carbon} It's pretty much guaranteed many of them will have compilation errors. Please paste the error logs and I'll try to fix them up. It may take a WIP or two to get there. It's also possible things broke from the updates. If so, I could use help comparing the old file to the new file, looking for mistakes, since I can't test on these platforms apart from audio/directsound. Please report working drivers in this list, so we can mark them off the list. I'll need both macOS and Linux testers. audio/directsound.cpp:112:    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false; ²: once I get this working, I'll add load/save support for the RTC values. For now, the RTC data will be lost when you close the emulator. Right now, you can set the date/time in real-time mode, and when you start the game, the time will be correct, and the time will tick forward. Note that it runs off emulated time instead of actual real time, so if you fast-forward to 300%, one minute will be 20 seconds. The really big limitation right now is that when you exit the game, and restart it, and resume a new game, the hour spot gets corrupted, and this seems to instantly kill your pet. Fun. This is crazy because the commands the game sends to the TAMA interface are identical between starting a new game and getting in-game versus loading a game. It's likely going to require disassembling the game's code and seeing what in the hell it's doing, but I am extremely bad at LR35092 assembly. Hopefully endrift can help here :|
2017-07-28 11:42:24 +00:00
if(_asio->start() != ASE_OK) return _ready = false;
return true;
}
auto terminate() -> void {
_ready = false;
_devices.reset();
_active = {};
Update to v103r22 release. byuu says: Changelog: - ruby: ported all remaining drivers to new API¹ - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan] - gb: emulated most of the TAMA RTC; but RTC state is still volatile² ¹: the new ports are: - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao} - input/{udev, quartz, carbon} It's pretty much guaranteed many of them will have compilation errors. Please paste the error logs and I'll try to fix them up. It may take a WIP or two to get there. It's also possible things broke from the updates. If so, I could use help comparing the old file to the new file, looking for mistakes, since I can't test on these platforms apart from audio/directsound. Please report working drivers in this list, so we can mark them off the list. I'll need both macOS and Linux testers. audio/directsound.cpp:112:    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false; ²: once I get this working, I'll add load/save support for the RTC values. For now, the RTC data will be lost when you close the emulator. Right now, you can set the date/time in real-time mode, and when you start the game, the time will be correct, and the time will tick forward. Note that it runs off emulated time instead of actual real time, so if you fast-forward to 300%, one minute will be 20 seconds. The really big limitation right now is that when you exit the game, and restart it, and resume a new game, the hour spot gets corrupted, and this seems to instantly kill your pet. Fun. This is crazy because the commands the game sends to the TAMA interface are identical between starting a new game and getting in-game versus loading a game. It's likely going to require disassembling the game's code and seeing what in the hell it's doing, but I am extremely bad at LR35092 assembly. Hopefully endrift can help here :|
2017-07-28 11:42:24 +00:00
if(_asio) {
_asio->stop();
_asio->disposeBuffers();
_asio->Release();
_asio = nullptr;
}
}
private:
static auto _bufferSwitch(long doubleBufferInput, ASIOBool directProcess) -> void {
return self->bufferSwitch(doubleBufferInput, directProcess);
}
static auto _sampleRateDidChange(ASIOSampleRate sampleRate) -> void {
return self->sampleRateDidChange(sampleRate);
}
static auto _asioMessage(long selector, long value, void* message, double* optional) -> long {
return self->asioMessage(selector, value, message, optional);
}
static auto _bufferSwitchTimeInfo(ASIOTime* parameters, long doubleBufferIndex, ASIOBool directProcess) -> ASIOTime* {
return self->bufferSwitchTimeInfo(parameters, doubleBufferIndex, directProcess);
}
auto bufferSwitch(long doubleBufferInput, ASIOBool directProcess) -> void {
for(uint sampleIndex : range(_latency)) {
double samples[8] = {0};
if(_queue.count) {
for(uint n : range(_channels)) {
samples[n] = _queue.samples[_queue.read][n];
}
_queue.read++;
_queue.count--;
}
for(uint n : range(_channels)) {
auto buffer = (uint8_t*)_channel[n].buffers[doubleBufferInput];
buffer += sampleIndex * _sampleSize;
switch(_sampleFormat) {
case ASIOSTInt16LSB: {
*(int16_t*)buffer = samples[n] * double(1 << 15);
break;
}
case ASIOSTInt24LSB: {
int value = samples[n] * double(1 << 23);
buffer[0] = value >> 0;
buffer[1] = value >> 8;
buffer[2] = value >> 16;
break;
}
case ASIOSTInt32LSB: {
*(int32_t*)buffer = samples[n] * double(1 << 31);
break;
}
case ASIOSTFloat32LSB: {
*(float*)buffer = samples[n];
break;
}
case ASIOSTFloat64LSB: {
*(double*)buffer = samples[n];
break;
}
}
}
}
}
auto sampleRateDidChange(ASIOSampleRate sampleRate) -> void {
}
auto asioMessage(long selector, long value, void* message, double* optional) -> long {
return ASE_OK;
}
auto bufferSwitchTimeInfo(ASIOTime* parameters, long doubleBufferIndex, ASIOBool directProcess) -> ASIOTime* {
return nullptr;
}
bool _ready = false;
uintptr _context = 0;
string _device;
bool _blocking = true;
uint _channels = 2;
Update to v103r16 release. byuu says: Changelog: - emulator/audio: added the ability to change the output frequency at run-time without emulator reset - tomoko: display video synchronize option again¹ - tomoko: Settings→Configuration expanded to Settings→{Video, Audio, Input, Hotkey, Advanced} Settings² - tomoko: fix default population of audio settings tab - ruby: Audio::frequency is a double now (to match both Emulator::Audio and ASIO)³ - tomoko: changing the audio device will repopulate the frequency and latency lists - tomoko: changing the audio frequency can now be done in real-time - ruby/audio/asio: added missing device() information, so devices can be changed now - ruby/audio/openal: ported to new API; added device selection support - ruby/audio/wasapi: ported to new API, but did not test yet (it's assuredly still broken)⁴ ¹: I'm uneasy about this ... but, I guess if people want to disable audio and just have smooth scrolling video ... so be it. With Screwtape's documentation, hopefully that'll help people understand that video synchronization always breaks audio synchronization. I may change this to a child menu that lets you pick between {no synchronization, video synchronization, audio synchronization} as a radio selection. ²: given how much more useful the video and audio tabs are now, I felt that four extra menu items were worth saving a click and going right to the tab you want. This also matches the behavior of the Tools menu displaying all tool options and taking you directly to each tab. This is kind of a hard change to get used to ... but I think it's for the better. ³: kind of stupid because I've never seen a hardware sound card where floor(frequency) != frequency, but whatever. Yay consistency. ⁴: I'm going to move it to be event-driven, and try to support 24-bit sample formats if possible. Who knows which cards that'll fix and which cards that'll break. I may end up making multiple WASAPI drivers so people can find one that actually works for them. We'll see.
2017-07-17 10:32:36 +00:00
double _frequency = 48000.0;
uint _latency = 0;
struct Queue {
double samples[65536][8];
uint16_t read;
uint16_t write;
std::atomic<uint16_t> count;
};
struct Device {
string name;
string classID;
ASIOSampleRate sampleRate;
long inputChannels;
long outputChannels;
long inputLatency;
long outputLatency;
long minimumBufferSize;
long maximumBufferSize;
long preferredBufferSize;
long granularity;
};
Queue _queue;
vector<Device> _devices;
Device _active;
IASIO* _asio = nullptr;
ASIOBufferInfo _channel[8];
long _sampleFormat;
long _sampleSize;
};
AudioASIO* AudioASIO::self = nullptr;