diff --git a/desmume/configure.ac b/desmume/configure.ac index a8625d0ec..3f56a28f8 100644 --- a/desmume/configure.ac +++ b/desmume/configure.ac @@ -89,6 +89,7 @@ fi dnl - Check for GTK and/or libglade FOUND_GLIB=no +HAVE_ALSA=no GLIB_VER=2.8 GTK_VER=2.6 AC_CHECK_TOOL(HAVE_PKG, pkg-config) @@ -142,6 +143,10 @@ AC_PROVIDE_IFELSE([PKG_PROG_PKG_CONFIG], [ HAVE_LUA=no) AC_SUBST(LUA_CFLAGS) AC_SUBST(LUA_LIBS) + + PKG_CHECK_MODULES(ALSA, alsa >= 1.0, HAVE_ALSA=yes, HAVE_ALSA=no) + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LIBS) fi ],[ echo "WARNING: pkg-config is not available therefore gtk, gtk-glade UIs and lua scripting are not available either." @@ -150,6 +155,11 @@ AC_PROVIDE_IFELSE([PKG_PROG_PKG_CONFIG], [ dnl -- force lua disabled AM_CONDITIONAL([HAVE_LUA], [test "${HAVE_LUA}x" = "yes"]) +AM_CONDITIONAL([HAVE_ALSA], [test "${HAVE_ALSA}" = "yes"]) +if test "x$HAVE_ALSA" = "xno"; then + AC_DEFINE([FAKE_MIC]) +fi + dnl - set conditional for glib, needed to avoid commandline.cpp compilation for cli frontend since it depends on glib AM_CONDITIONAL([HAVE_GLIB], [test "${FOUND_GLIB}" = "yes"]) diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 44a593170..4a6124144 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -55,13 +55,17 @@ libdesmume_a_SOURCES = \ agg/src/agg_trans_affine.cpp agg/src/agg_trans_double_path.cpp agg/src/agg_trans_single_path.cpp agg/src/agg_trans_warp_magnifier.cpp \ agg/src/agg_vcgen_bspline.cpp agg/src/agg_vcgen_contour.cpp agg/src/agg_vcgen_dash.cpp agg/src/agg_vcgen_markers_term.cpp agg/src/agg_vcgen_smooth_poly1.cpp agg/src/agg_vcgen_stroke.cpp \ agg/src/agg_vpgen_clip_polygon.cpp agg/src/agg_vpgen_clip_polyline.cpp agg/src/agg_vpgen_segmentator \ - mic.cpp mic.h \ cheatSystem.cpp cheatSystem.h \ texcache.cpp texcache.h rasterize.cpp rasterize.h \ version.h if HAVE_GLIB libdesmume_a_SOURCES += commandline.h commandline.cpp endif +if HAVE_ALSA +libdesmume_a_SOURCES += mic_alsa.cpp +else +libdesmume_a_SOURCES += mic.cpp +endif if HAVE_LUA libdesmume_a_SOURCES += lua-engine.cpp endif diff --git a/desmume/src/cli/main.cpp b/desmume/src/cli/main.cpp index f65f2cdd0..837bdb7b6 100644 --- a/desmume/src/cli/main.cpp +++ b/desmume/src/cli/main.cpp @@ -684,10 +684,12 @@ static void desmume_cycle(int *sdl_quit, int *boost, struct my_config * my_confi case SDLK_ESCAPE: *sdl_quit = 1; break; +#ifdef FAKE_MIC case SDLK_m: enable_fake_mic = !enable_fake_mic; Mic_DoNoise(enable_fake_mic); break; +#endif case SDLK_o: *boost = !(*boost); break; diff --git a/desmume/src/gtk/main.cpp b/desmume/src/gtk/main.cpp index 600feb80e..d3849a870 100644 --- a/desmume/src/gtk/main.cpp +++ b/desmume/src/gtk/main.cpp @@ -111,7 +111,9 @@ static void ToggleMenuVisible(GtkToggleAction *action); static void ToggleStatusbarVisible(GtkToggleAction *action); static void ToggleToolbarVisible(GtkToggleAction *action); static void ToggleAudio (GtkToggleAction *action); +#ifdef FAKE_MIC static void ToggleMicNoise (GtkToggleAction *action); +#endif static void ToggleGap (GtkToggleAction *action); static void SetRotation (GtkAction *action); static void ToggleLayerVisibility(GtkToggleAction* action, gpointer data); @@ -167,7 +169,9 @@ static const char *ui_description = " " " " " " +#ifdef FAKE_MIC " " +#endif " " " " " " @@ -285,7 +289,9 @@ static const GtkActionEntry action_entries[] = { static const GtkToggleActionEntry toggle_entries[] = { { "enableaudio", NULL, "_Enable audio", NULL, NULL, G_CALLBACK(ToggleAudio), TRUE}, +#ifdef FAKE_MIC { "micnoise", NULL, "Fake mic _noise", NULL, NULL, G_CALLBACK(ToggleMicNoise), FALSE}, +#endif { "gap", NULL, "_Gap", NULL, NULL, G_CALLBACK(ToggleGap), FALSE}, { "view_menu", NULL, "View _menu", NULL, NULL, G_CALLBACK(ToggleMenuVisible), TRUE}, { "view_toolbar", NULL, "View _toolbar", NULL, NULL, G_CALLBACK(ToggleToolbarVisible), TRUE}, @@ -1672,10 +1678,12 @@ static void ToggleAudio (GtkToggleAction *action) } } +#ifdef FAKE_MIC static void ToggleMicNoise (GtkToggleAction *action) { Mic_DoNoise((BOOL)gtk_toggle_action_get_active(action)); } +#endif static void desmume_gtk_menu_tools (GtkActionGroup *ag) { diff --git a/desmume/src/mic.h b/desmume/src/mic.h index 508895bd0..c7478c145 100644 --- a/desmume/src/mic.h +++ b/desmume/src/mic.h @@ -7,7 +7,9 @@ extern int MicButtonPressed; static char MicSampleName[256]; char* LoadSample(const char *name); extern int MicDisplay; -#else +#endif + +#ifdef FAKE_MIC void Mic_DoNoise(BOOL); #endif diff --git a/desmume/src/mic_alsa.cpp b/desmume/src/mic_alsa.cpp new file mode 100644 index 000000000..cbfc933d3 --- /dev/null +++ b/desmume/src/mic_alsa.cpp @@ -0,0 +1,111 @@ +#include +#include "types.h" +#include "mic.h" + +#define MIC_BUFSIZE 4096 + +BOOL Mic_Inited = FALSE; +u8 Mic_Buffer[2][MIC_BUFSIZE]; +u16 Mic_BufPos; +u8 Mic_PlayBuf; + +int MicButtonPressed; + +// Handle for the PCM device +static snd_pcm_t *pcm_handle; + +BOOL Mic_Init() +{ + snd_pcm_hw_params_t *hwparams; + + if (Mic_Inited) + return TRUE; + + // Open the default sound card in capture + if (snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0) < 0) + return FALSE; + + // Allocate the snd_pcm_hw_params_t structure and fill it. + snd_pcm_hw_params_alloca(&hwparams); + if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) + return FALSE; + + //Set the access + if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) + return FALSE ; + + //dir 0 == exacte (Rate = 16K exacte) + if (snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0) < 0) + return FALSE; + /* Set sample format */ + if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8) < 0) + return FALSE; + // Set one channel (mono) + if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1) < 0) + return FALSE; + + // Set 2 periods + if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, 2, 0) < 0) + return FALSE; + + // Set the buffer sise + if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, MIC_BUFSIZE) < 0) + return FALSE; + + //Set the params + if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) + return FALSE; + + Mic_Inited = TRUE; + + return TRUE; +} + +void Mic_Reset() +{ + if (!Mic_Inited) + return; + + memset(Mic_Buffer[0], 0, MIC_BUFSIZE); + memset(Mic_Buffer[1], 0, MIC_BUFSIZE); + Mic_BufPos = 0; + + Mic_PlayBuf = 1; +} + +void Mic_DeInit() +{ + if (!Mic_Inited) + return; + + Mic_Inited = FALSE; + + snd_pcm_drop(pcm_handle); + snd_pcm_close(pcm_handle); +} + +u8 Mic_ReadSample() +{ + u8 tmp; + u8 ret; + + if (!Mic_Inited) + return 0; + + tmp = Mic_Buffer[Mic_PlayBuf][Mic_BufPos >> 1]; + + if (Mic_BufPos & 0x1) { + ret = ((tmp & 0x1) << 7); + } else { + ret = ((tmp & 0xFE) >> 1); + } + + Mic_BufPos++; + if (Mic_BufPos >= (MIC_BUFSIZE << 1)) { + Mic_BufPos = 0; + snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_PlayBuf], MIC_BUFSIZE); + Mic_PlayBuf ^= 1; + } + + return ret; +}