bsnes/ruby/audio/ao.cpp
Tim Allen bb3c69a30d 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.
2015-06-16 20:30:04 +10:00

86 lines
1.9 KiB
C++

#include <ao/ao.h>
namespace ruby {
struct pAudioAO {
int driver_id;
ao_sample_format driver_format;
ao_device* audio_device = nullptr;
struct {
unsigned frequency = 22050;
} settings;
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;
}
auto get(const string& name) -> any {
if(name == Audio::Frequency) return settings.frequency;
return {};
}
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;
}
return false;
}
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
}
auto clear() -> void {
}
auto init() -> bool {
term();
driver_id = ao_default_driver_id(); //ao_driver_id((const char*)driver)
if(driver_id < 0) return false;
driver_format.bits = 16;
driver_format.channels = 2;
driver_format.rate = settings.frequency;
driver_format.byte_format = AO_FMT_LITTLE;
ao_option* options = nullptr;
ao_info *di = ao_driver_info(driver_id);
if(!di) return false;
if(!strcmp(di->short_name, "alsa")) {
ao_append_option(&options, "buffer_time", "100000"); //100ms latency (default was 500ms)
}
audio_device = ao_open_live(driver_id, &driver_format, options);
if(!audio_device) return false;
return true;
}
auto term() -> void {
if(audio_device) {
ao_close(audio_device);
audio_device = nullptr;
}
}
};
DeclareAudio(AO)
};