mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-16 19:54:10 +02:00
Update to v094r25 release.
byuu says: Windows port should run mostly well now, although exiting fullscreen breaks the application in a really bizarre way. (clicking on the window makes it sink to background rather than come to the foreground o_O) I also need to add the doModalChange => audio.clear() thing for the accursed menu stuttering with DirectSound. I also finished porting all of the ruby drivers over to the newer API changes from nall. Since I can't compile the Linux or OS X drivers, I have no idea if there are any typos that will result in compilation errors. If so, please let me know where they're at and I'll try and fix them. If they're simple, please try and fix them on your end to test further if you can. I'm hopeful the udev crash will be gone now that nall::string checks for null char* values passed to its stringify function. Of course, it's a problem it's getting a null value in the first place, so it may not work at all. If you can compile on Linux (or by some miracle, OS X), please test each video/audio/input driver if you don't mind, to make sure there's no "compiles okay but still typos exist" bugs.
This commit is contained in:
@@ -1,66 +1,66 @@
|
||||
//audio.alsa (2009-11-30)
|
||||
//authors: BearOso, byuu, Nach, RedDwarf
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pAudioALSA {
|
||||
public:
|
||||
struct pAudioALSA {
|
||||
struct {
|
||||
snd_pcm_t* handle;
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_t* handle = nullptr;
|
||||
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_uframes_t period_size;
|
||||
int channels;
|
||||
const char* name;
|
||||
int channels = 2;
|
||||
const char* name = "default";
|
||||
} device;
|
||||
|
||||
struct {
|
||||
uint32_t* data;
|
||||
unsigned length;
|
||||
uint32_t* data = nullptr;
|
||||
unsigned length = 0;
|
||||
} buffer;
|
||||
|
||||
struct {
|
||||
bool synchronize;
|
||||
unsigned frequency;
|
||||
unsigned latency;
|
||||
bool synchronize = false;
|
||||
unsigned frequency = 22050;
|
||||
unsigned latency = 60;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
~pAudioALSA() {
|
||||
term();
|
||||
}
|
||||
|
||||
auto cap(const string& name) -> bool {
|
||||
if(name == Audio::Synchronize) return true;
|
||||
if(name == Audio::Frequency) return true;
|
||||
if(name == Audio::Latency) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
auto get(const string& name) -> any {
|
||||
if(name == Audio::Synchronize) return settings.synchronize;
|
||||
if(name == Audio::Frequency) return settings.frequency;
|
||||
if(name == Audio::Latency) return settings.latency;
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool set(const string& name, const any& value) {
|
||||
if(name == Audio::Synchronize) {
|
||||
if(settings.synchronize != any_cast<bool>(value)) {
|
||||
settings.synchronize = any_cast<bool>(value);
|
||||
auto set(const string& name, const any& value) -> bool {
|
||||
if(name == Audio::Synchronize && value.is<bool>()) {
|
||||
if(settings.synchronize != value.get<bool>()) {
|
||||
settings.synchronize = value.get<bool>();
|
||||
if(device.handle) init();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Audio::Frequency) {
|
||||
if(settings.frequency != any_cast<unsigned>(value)) {
|
||||
settings.frequency = any_cast<unsigned>(value);
|
||||
if(name == Audio::Frequency && value.is<unsigned>()) {
|
||||
if(settings.frequency != value.get<unsigned>()) {
|
||||
settings.frequency = value.get<unsigned>();
|
||||
if(device.handle) init();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Audio::Latency) {
|
||||
if(settings.latency != any_cast<unsigned>(value)) {
|
||||
settings.latency = any_cast<unsigned>(value);
|
||||
if(name == Audio::Latency && value.is<unsigned>()) {
|
||||
if(settings.latency != value.get<unsigned>()) {
|
||||
settings.latency = value.get<unsigned>();
|
||||
if(device.handle) init();
|
||||
}
|
||||
return true;
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void sample(uint16_t left, uint16_t right) {
|
||||
auto sample(uint16_t left, uint16_t right) -> void {
|
||||
if(!device.handle) return;
|
||||
|
||||
buffer.data[buffer.length++] = left + (right << 16);
|
||||
@@ -123,10 +123,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
auto clear() -> void {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
auto init() -> bool {
|
||||
term();
|
||||
|
||||
if(snd_pcm_open(&device.handle, device.name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) {
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
auto term() -> void {
|
||||
if(device.handle) {
|
||||
//snd_pcm_drain(device.handle); //prevents popping noise; but causes multi-second lag
|
||||
snd_pcm_close(device.handle);
|
||||
@@ -215,24 +215,6 @@ public:
|
||||
buffer.data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pAudioALSA() {
|
||||
device.handle = 0;
|
||||
device.format = SND_PCM_FORMAT_S16_LE;
|
||||
device.channels = 2;
|
||||
device.name = "default";
|
||||
|
||||
buffer.data = 0;
|
||||
buffer.length = 0;
|
||||
|
||||
settings.synchronize = false;
|
||||
settings.frequency = 22050;
|
||||
settings.latency = 60;
|
||||
}
|
||||
|
||||
~pAudioALSA() {
|
||||
term();
|
||||
}
|
||||
};
|
||||
|
||||
DeclareAudio(ALSA)
|
||||
|
@@ -1,35 +1,38 @@
|
||||
/*
|
||||
audio.ao (2008-06-01)
|
||||
authors: Nach, RedDwarf
|
||||
*/
|
||||
|
||||
#include <ao/ao.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pAudioAO {
|
||||
public:
|
||||
struct pAudioAO {
|
||||
int driver_id;
|
||||
ao_sample_format driver_format;
|
||||
ao_device* audio_device;
|
||||
ao_device* audio_device = nullptr;
|
||||
|
||||
struct {
|
||||
unsigned frequency;
|
||||
unsigned frequency = 22050;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
pAudioAO() {
|
||||
ao_initialize();
|
||||
}
|
||||
|
||||
~pAudioAO() {
|
||||
term();
|
||||
//ao_shutdown(); //FIXME: this is causing a segfault for some reason when called ...
|
||||
}
|
||||
|
||||
auto cap(const string& name) -> bool {
|
||||
if(name == Audio::Frequency) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
auto get(const string& name) -> any {
|
||||
if(name == Audio::Frequency) return settings.frequency;
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool set(const string& name, const any& value) {
|
||||
if(name == Audio::Frequency) {
|
||||
settings.frequency = any_cast<unsigned>(value);
|
||||
auto set(const string& name, const any& value) -> bool {
|
||||
if(name == Audio::Frequency && value.is<unsigned>()) {
|
||||
settings.frequency = value.get<unsigned>();
|
||||
if(audio_device) init();
|
||||
return true;
|
||||
}
|
||||
@@ -37,15 +40,15 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void sample(uint16_t l_sample, uint16_t r_sample) {
|
||||
auto sample(uint16_t l_sample, uint16_t r_sample) -> void {
|
||||
uint32_t samp = (l_sample << 0) + (r_sample << 16);
|
||||
ao_play(audio_device, (char*)&samp, 4); //This may need to be byte swapped for Big Endian
|
||||
}
|
||||
|
||||
void clear() {
|
||||
auto clear() -> void {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
auto init() -> bool {
|
||||
term();
|
||||
|
||||
driver_id = ao_default_driver_id(); //ao_driver_id((const char*)driver)
|
||||
@@ -69,24 +72,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
auto term() -> void {
|
||||
if(audio_device) {
|
||||
ao_close(audio_device);
|
||||
audio_device = 0;
|
||||
audio_device = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
pAudioAO() {
|
||||
audio_device = 0;
|
||||
ao_initialize();
|
||||
|
||||
settings.frequency = 22050;
|
||||
}
|
||||
|
||||
~pAudioAO() {
|
||||
term();
|
||||
//ao_shutdown(); //FIXME: this is causing a segfault for some reason when called ...
|
||||
}
|
||||
};
|
||||
|
||||
DeclareAudio(AO)
|
||||
|
@@ -1,70 +1,74 @@
|
||||
//audio.pulseaudio (2010-01-05)
|
||||
//author: RedDwarf
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pAudioPulseAudio {
|
||||
public:
|
||||
struct pAudioPulseAudio {
|
||||
struct {
|
||||
pa_mainloop* mainloop;
|
||||
pa_context* context;
|
||||
pa_stream* stream;
|
||||
pa_mainloop* mainloop = nullptr;
|
||||
pa_context* context = nullptr;
|
||||
pa_stream* stream = nullptr;
|
||||
pa_sample_spec spec;
|
||||
pa_buffer_attr buffer_attr;
|
||||
bool first;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
uint32_t* data;
|
||||
uint32_t* data = nullptr;
|
||||
size_t size;
|
||||
unsigned offset;
|
||||
} buffer;
|
||||
|
||||
struct {
|
||||
bool synchronize;
|
||||
unsigned frequency;
|
||||
unsigned latency;
|
||||
bool synchronize = false;
|
||||
unsigned frequency = 22050;
|
||||
unsigned latency = 60;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
~pAudioPulseAudio() {
|
||||
term();
|
||||
}
|
||||
|
||||
auto cap(const string& name) -> bool {
|
||||
if(name == Audio::Synchronize) return true;
|
||||
if(name == Audio::Frequency) return true;
|
||||
if(name == Audio::Latency) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
auto get(const string& name) -> any {
|
||||
if(name == Audio::Synchronize) return settings.synchronize;
|
||||
if(name == Audio::Frequency) return settings.frequency;
|
||||
if(name == Audio::Latency) return settings.latency;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool set(const string& name, const any& value) {
|
||||
if(name == Audio::Synchronize) {
|
||||
settings.synchronize = any_cast<bool>(value);
|
||||
auto set(const string& name, const any& value) -> bool {
|
||||
if(name == Audio::Synchronize && value.is<bool>()) {
|
||||
settings.synchronize = value.get<bool>();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Audio::Frequency) {
|
||||
settings.frequency = any_cast<unsigned>(value);
|
||||
if(name == Audio::Frequency && value.is<unsigned>()) {
|
||||
settings.frequency = value.get<unsigned>();
|
||||
if(device.stream) {
|
||||
pa_operation_unref(pa_stream_update_sample_rate(device.stream, settings.frequency, NULL, NULL));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Audio::Latency) {
|
||||
settings.latency = any_cast<unsigned>(value);
|
||||
if(name == Audio::Latency && value.is<unsigned>()) {
|
||||
settings.latency = value.get<unsigned>();
|
||||
if(device.stream) {
|
||||
device.buffer_attr.tlength = pa_usec_to_bytes(settings.latency * PA_USEC_PER_MSEC, &device.spec);
|
||||
pa_stream_set_buffer_attr(device.stream, &device.buffer_attr, NULL, NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sample(uint16_t left, uint16_t right) {
|
||||
auto sample(uint16_t left, uint16_t right) -> void {
|
||||
pa_stream_begin_write(device.stream, (void**)&buffer.data, &buffer.size);
|
||||
buffer.data[buffer.offset++] = left + (right << 16);
|
||||
if((buffer.offset + 1) * pa_frame_size(&device.spec) <= buffer.size) return;
|
||||
@@ -89,10 +93,10 @@ public:
|
||||
buffer.offset = 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
auto clear() -> void {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
auto init() -> bool {
|
||||
device.mainloop = pa_mainloop_new();
|
||||
|
||||
device.context = pa_context_new(pa_mainloop_get_api(device.mainloop), "ruby::pulseaudio");
|
||||
@@ -133,43 +137,29 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
auto term() -> void {
|
||||
if(buffer.data) {
|
||||
pa_stream_cancel_write(device.stream);
|
||||
buffer.data = 0;
|
||||
buffer.data = nullptr;
|
||||
}
|
||||
|
||||
if(device.stream) {
|
||||
pa_stream_disconnect(device.stream);
|
||||
pa_stream_unref(device.stream);
|
||||
device.stream = 0;
|
||||
device.stream = nullptr;
|
||||
}
|
||||
|
||||
if(device.context) {
|
||||
pa_context_disconnect(device.context);
|
||||
pa_context_unref(device.context);
|
||||
device.context = 0;
|
||||
device.context = nullptr;
|
||||
}
|
||||
|
||||
if(device.mainloop) {
|
||||
pa_mainloop_free(device.mainloop);
|
||||
device.mainloop = 0;
|
||||
device.mainloop = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
pAudioPulseAudio() {
|
||||
device.mainloop = 0;
|
||||
device.context = 0;
|
||||
device.stream = 0;
|
||||
buffer.data = 0;
|
||||
settings.synchronize = false;
|
||||
settings.frequency = 22050;
|
||||
settings.latency = 60;
|
||||
}
|
||||
|
||||
~pAudioPulseAudio() {
|
||||
term();
|
||||
}
|
||||
};
|
||||
|
||||
DeclareAudio(PulseAudio)
|
||||
|
@@ -1,40 +1,40 @@
|
||||
//audio.pulseaudiosimple (2010-01-05)
|
||||
//author: byuu
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pAudioPulseAudioSimple {
|
||||
public:
|
||||
struct pAudioPulseAudioSimple {
|
||||
struct {
|
||||
pa_simple* handle;
|
||||
pa_simple* handle = nullptr;
|
||||
pa_sample_spec spec;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
uint32_t* data;
|
||||
unsigned offset;
|
||||
uint32_t* data = nullptr;
|
||||
unsigned offset = 0;
|
||||
} buffer;
|
||||
|
||||
struct {
|
||||
unsigned frequency;
|
||||
unsigned frequency = 22050;
|
||||
} settings;
|
||||
|
||||
bool cap(const string& name) {
|
||||
~pAudioPulseAudioSimple() {
|
||||
term();
|
||||
}
|
||||
|
||||
auto cap(const string& name) -> bool {
|
||||
if(name == Audio::Frequency) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
auto get(const string& name) -> any {
|
||||
if(name == Audio::Frequency) return settings.frequency;
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool set(const string& name, const any& value) {
|
||||
if(name == Audio::Frequency) {
|
||||
settings.frequency = any_cast<unsigned>(value);
|
||||
auto set(const string& name, const any& value) -> bool {
|
||||
if(name == Audio::Frequency && value.is<unsigned>()) {
|
||||
settings.frequency = value.get<unsigned>();
|
||||
if(device.handle) init();
|
||||
return true;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void sample(uint16_t left, uint16_t right) {
|
||||
auto sample(uint16_t left, uint16_t right) -> void {
|
||||
if(!device.handle) return;
|
||||
|
||||
buffer.data[buffer.offset++] = left + (right << 16);
|
||||
@@ -53,10 +53,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
auto clear() -> void {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
auto init() -> bool {
|
||||
term();
|
||||
|
||||
device.spec.format = PA_SAMPLE_S16LE;
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
auto term() -> void {
|
||||
if(device.handle) {
|
||||
int error;
|
||||
pa_simple_flush(device.handle, &error);
|
||||
@@ -98,16 +98,6 @@ public:
|
||||
buffer.data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
pAudioPulseAudioSimple() {
|
||||
device.handle = nullptr;
|
||||
buffer.data = nullptr;
|
||||
settings.frequency = 22050;
|
||||
}
|
||||
|
||||
~pAudioPulseAudioSimple() {
|
||||
term();
|
||||
}
|
||||
};
|
||||
|
||||
DeclareAudio(PulseAudioSimple)
|
||||
|
Reference in New Issue
Block a user