Skip to content

Commit

Permalink
implemented sound for SDL interface. closes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
nadavbh12 committed Feb 25, 2017
1 parent 511a656 commit cbfe65b
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 20 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if(USE_SDL)
find_package(SDL)
if(SDL_FOUND AND ${SDL_VERSION_STRING} VERSION_LESS 2)
include_directories(${SDL_INCLUDE_DIR})
list(APPEND LINK_LIBS ${SDL_LIBRARY} ${SDL_MAIN_LIBRARY} SDL_gfx)
list(APPEND LINK_LIBS ${SDL_LIBRARY} ${SDL_MAIN_LIBRARY} SDL_gfx asound)
message("sdl_library:" ${SDL_LIBRARY} ${SDL_MAIN_LIBRARY})
else()
# Uncomment below to specify the path to your SDL library. Run "locate libSDL" if unsure.
Expand Down
6 changes: 3 additions & 3 deletions doc/examples/python_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
if sys.platform == 'darwin':
import pygame
pygame.init()
# rle.setBool('sound', False) # Sound doesn't work on OSX
# elif sys.platform.startswith('linux'):
# rle.setBool('sound', True)
rle.setBool('sound', False) # Sound doesn't work on OSX
elif sys.platform.startswith('linux'):
rle.setBool('sound', True)
rle.setBool('display_screen', True)

# Load the ROM file
Expand Down
6 changes: 1 addition & 5 deletions doc/examples/sharedLibraryInterfaceExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,8 @@ int main(int argc, char** argv) {

#ifdef __USE_SDL
rle.setBool("display_screen", true);
// rle.setBool("sound", true);
rle.setBool("sound", true);
#endif

rle.setString("MK_player1_character", "cage");
// rle.setString("MK_player2_character", "scorpion");
rle.setInt("MK_opponent_character", 4);
// Load the ROM file. (Also resets the system for new settings to
// take effect.)
rle.loadROM(argv[1], argv[2]);
Expand Down
51 changes: 41 additions & 10 deletions src/environment/RetroAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
#include "Serializer.hxx"
#include "Deserializer.hxx"

#include <alsa/asoundlib.h>
#include <alsa/control.h>

using namespace rle;

std::atomic_uint RetroAgent::numAgents{0};
thread_local struct RetroAgent::g_retro_ RetroAgent::g_retro;
thread_local struct RetroAgent::g_video_ RetroAgent::g_video;
thread_local static snd_pcm_t *g_pcm = NULL;

struct keymap {
unsigned k;
Expand Down Expand Up @@ -219,10 +223,32 @@ static void video_refresh(const void *data, unsigned width, unsigned height, uns
}

static void audio_init(int frequency) {
}
int err;

if ((err = snd_pcm_open(&g_pcm, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
die("Failed to open playback device: %s", snd_strerror(err));

err = snd_pcm_set_params(g_pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 2, frequency, 1, 64 * 1000);

if (err < 0)
die("Failed to configure playback device: %s", snd_strerror(err));
}

static void audio_deinit() {
snd_pcm_close(g_pcm);
}

static size_t audio_write(const void *buf, unsigned frames) {
int written = snd_pcm_writei(g_pcm, buf, frames);

if (written < 0) {
printf("Alsa warning/error #%i: ", -written);
snd_pcm_recover(g_pcm, written, 0);

return 0;
}

return written;
}

static void core_log(enum retro_log_level level, const char *fmt, ...) {
Expand Down Expand Up @@ -290,13 +316,11 @@ static bool core_environment(unsigned cmd, void *data) {
return true;
}


static void core_video_refresh(const void *data, unsigned width, unsigned height, size_t pitch) {
if (data)
video_refresh(data, width, height, pitch);
}


static void core_input_poll(void) {
int i;
for (i = 0; g_binds[i].k || g_binds[i].rk; ++i){
Expand All @@ -311,23 +335,29 @@ static void core_input_poll(void) {

}


// port == player number
static int16_t core_input_state(unsigned port, unsigned device, unsigned index, unsigned id) {
if (index || device != RETRO_DEVICE_JOYPAD)
return 0;
return RetroAgent::g_joy[port][id];
}


static void core_audio_sample(int16_t left, int16_t right) {
int16_t buf[2] = {left, right};
if(RetroAgent::g_retro.audioEnabled){
audio_write(buf, 1);
}
}


static size_t core_audio_sample_batch(const int16_t *data, size_t frames) {
if(RetroAgent::g_retro.audioEnabled){
return audio_write(data, frames);
}else{
return 0;
}
}


static void core_load(const char *sofile) {
void (*set_environment)(retro_environment_t) = NULL;
void (*set_video_refresh)(retro_video_refresh_t) = NULL;
Expand Down Expand Up @@ -380,7 +410,6 @@ static void core_load(const char *sofile) {
puts("Core loaded");
}


static void core_load_game(const char *filename) {
struct retro_system_av_info av = {0};
struct retro_system_info system = {0};
Expand Down Expand Up @@ -419,7 +448,6 @@ static void core_load_game(const char *filename) {
die("Failed to load content '%s': %s", filename, strerror(errno));
}


static void core_unload() {
if (RetroAgent::g_retro.initialized)
RetroAgent::g_retro.retro_deinit();
Expand All @@ -435,7 +463,6 @@ RetroAgent::RetroAgent() : coreLoaded(false), romLoaded(false){
RetroAgent::~RetroAgent(){
unloadRom();
core_unload();
// --numAgents;
}

static bool replace(std::string& str, const std::string& from, const std::string& to) {
Expand Down Expand Up @@ -480,6 +507,7 @@ void RetroAgent::loadCore(const string& coreName){

void RetroAgent::unloadCore(){
core_unload();
audio_deinit();
coreLoaded = false;
}

Expand All @@ -504,6 +532,10 @@ void RetroAgent::run(){
RetroAgent::g_retro.retro_run();
}

void RetroAgent::audioEnable(bool audioState){
RetroAgent::g_retro.audioEnabled = audioState;
}

int RetroAgent::getHeight(){
return RetroAgent::g_video.rGeom.base_height;
}
Expand Down Expand Up @@ -574,7 +606,6 @@ void RetroAgent::getRgbMask(uint32_t& rmask, uint32_t& gmask, uint32_t& bmask, u
amask = RetroAgent::g_video.amask;
}


uint32_t RetroAgent::getBufferSize() const{
return RetroAgent::g_video.rGeom.base_width * RetroAgent::g_video.rGeom.base_height;

Expand Down
2 changes: 2 additions & 0 deletions src/environment/RetroAgent.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class RetroAgent{
void loadCore(const string& corePath);
void loadRom(const string& romPath);
void run();
void audioEnable(bool audioState);
void videoRender();
void swapBuffers();
void videoDeinit();
Expand Down Expand Up @@ -76,6 +77,7 @@ class RetroAgent{
// string saveFolder = "/home/administrator/DQN/rle-nano/SNES-Learning-Environment/saves/";
string corePath;
size_t serializeSize;
bool audioEnabled;
};
thread_local static struct g_retro_ g_retro;

Expand Down
1 change: 1 addition & 0 deletions src/environment/Settings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ void Settings::setDefaultSettings() {

// Display Settings
boolSettings.emplace(std::make_pair("display_screen", false));
boolSettings.emplace(std::make_pair("sound", false));

// Game-Specific Settings

Expand Down
3 changes: 3 additions & 0 deletions src/environment/retro_environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ void RetroEnvironment::reset() {

// Reset the emulator
m_rlesystem->getRetroAgent()->reset();
bool audio = m_rlesystem->settings()->getBool("sound", true);
m_rlesystem->getRetroAgent()->audioEnable(false);

// NOOP for 60 steps in the deterministic environment setting, or some random amount otherwise
int noopSteps;
Expand All @@ -125,6 +127,7 @@ void RetroEnvironment::reset() {
// m_rlesystem->p_display_screen->display_screen();
}
m_settings->startingOperations(*m_rlesystem);
m_rlesystem->getRetroAgent()->audioEnable(audio);
}

/** Save/restore the environment state. */
Expand Down
1 change: 0 additions & 1 deletion src/environment/retro_environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ class RetroEnvironment {
pRleSystem m_rlesystem;
pRomSettings m_settings;
PhosphorBlend m_phosphor_blend; // For performing phosphor colour averaging, if so desired
// std::string m_cartridge_md5; // Necessary for saving and loading emulator state

std::stack<RLEState> m_saved_states; // States are saved on a stack

Expand Down

0 comments on commit cbfe65b

Please sign in to comment.