From a11364e8d95250bdf9b3183ebb99332fef284fbf Mon Sep 17 00:00:00 2001 From: riccardom Date: Mon, 21 Dec 2009 18:36:40 +0000 Subject: [PATCH] Add experimental OpenAL microphone support (patch #2918507) Add OpenAL microphone support as provided by ncalexan. [rm: cleaned up the patch a bit using debug macros instead of plain printf and cleaning autotools stuff a bit. Not so sure it still builds on macos x so please raise your hand :) ] --- desmume/configure.ac | 32 +++++++- desmume/src/Makefile.am | 6 ++ desmume/src/mic_openal.cpp | 158 +++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 desmume/src/mic_openal.cpp diff --git a/desmume/configure.ac b/desmume/configure.ac index 678dad60e..35d8d148b 100644 --- a/desmume/configure.ac +++ b/desmume/configure.ac @@ -92,6 +92,21 @@ AC_ARG_ENABLE(macosxhack, [AC_HELP_STRING(--enable-macosxhack, hack to build MacOSX package)], [GTK_MACOSX_HACK=yes]) +HAVE_OPENAL=no +dnl - openal support +AC_ARG_ENABLE(openal, + [AC_HELP_STRING(--enable-openal, enable experimental OpenAL microphone input)], + [openal=$enableval], + [openal=yes]) + +if test "x$openal" = "xyes" ; then + AC_CHECK_LIB([openal], [main],[ + HAVE_OPENAL=yes + AC_DEFINE(HAVE_OPENAL) + LIBS="$LIBS -lopenal" + ]) +fi + dnl - Check for GTK and/or libglade FOUND_GLIB=no HAVE_ALSA=no @@ -149,9 +164,11 @@ AC_PROVIDE_IFELSE([PKG_PROG_PKG_CONFIG], [ 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) + if test ! "x$HAVE_OPENAL" = "xyes" ; then + PKG_CHECK_MODULES(ALSA, alsa >= 1.0, HAVE_ALSA=yes, HAVE_ALSA=no) + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LIBS) + fi PKG_CHECK_MODULES(LIBAGG, libagg >= 2.5.0, HAVE_LIBAGG=yes, HAVE_LIBAGG=no) AC_SUBST(LIBAGG_CFLAGS) @@ -166,9 +183,12 @@ AC_PROVIDE_IFELSE([PKG_PROG_PKG_CONFIG], [ dnl -- force lua disabled AM_CONDITIONAL([HAVE_LUA], [test "${HAVE_LUA}x" = "yes"]) +AM_CONDITIONAL([HAVE_OPENAL], [test "${HAVE_OPENAL}" = "yes"]) AM_CONDITIONAL([HAVE_ALSA], [test "${HAVE_ALSA}" = "yes"]) if test "x$HAVE_ALSA" = "xno"; then - AC_DEFINE([FAKE_MIC]) + if test "x$HAVE_OPENAL" = "xno"; then + AC_DEFINE([FAKE_MIC]) + fi fi AM_CONDITIONAL([HAVE_LIBAGG], [test "${HAVE_LIBAGG}" = "yes"]) @@ -260,6 +280,10 @@ case $target in ;; *darwin*) LIBS="$LIBS -framework OpenGL" + if test "x$HAVE_OPENAL" = "xyes"; then + LIBS="$LIBS -framework OpenAL" + CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/OpenAL.framework/Headers/" + fi if test "x$GTK_MACOSX_HACK" = "xyes" ; then LIBS="$LIBS -framework OpenGL -framework Gtk -framework GLib" CPPFLAGS="$CPPFLAGS -I/Library/Frameworks/Cairo.framework/Headers -I/Library/Frameworks/Gtk.framework/Headers -I/Library/Frameworks/GLib.framework/Headers " diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 004cc2d64..1daed22c3 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -57,11 +57,17 @@ libdesmume_a_SOURCES = \ if HAVE_WX libdesmume_a_SOURCES += wxdlg/wxdlg3dViewer.cpp endif + +if HAVE_OPENAL +libdesmume_a_SOURCES += mic_openal.cpp +else if HAVE_ALSA libdesmume_a_SOURCES += mic_alsa.cpp else libdesmume_a_SOURCES += mic.cpp endif +endif + if HAVE_LIBAGG libdesmume_a_SOURCES += aggdraw.cpp endif diff --git a/desmume/src/mic_openal.cpp b/desmume/src/mic_openal.cpp new file mode 100644 index 000000000..cfdbf8ee2 --- /dev/null +++ b/desmume/src/mic_openal.cpp @@ -0,0 +1,158 @@ +/* mic_openal.cpp - this file is part of DeSmuME + * + * Copyright (C) 2009 DeSmuME Team + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef WIN32 + +#include +#include + +#include "types.h" +#include "mic.h" +#include "readwrite.h" +#include "emufile.h" +#include "debug.h" + +#define MIC_BUFSIZE 512 + +BOOL Mic_Inited = FALSE; +u8 Mic_Buffer[2][2*MIC_BUFSIZE]; +u16 Mic_BufPos; +u8 Mic_PlayBuf; +u8 Mic_WriteBuf; + +int MicButtonPressed; + +ALCdevice *alDevice = 0; +ALCdevice *alCaptureDevice = 0; +ALCcontext *alContext = 0; + +BOOL Mic_Init() +{ + if (!(alDevice = alcOpenDevice(0))) { + INFO("Failed to Initialize Open AL\n"); + return FALSE; + } + if( !(alContext = alcCreateContext(alDevice, 0))) { + INFO("Failed to create OpenAL context\n"); + return 0; + } + if( !alcMakeContextCurrent(alContext)) { + INFO("Failed to make OpenAL context current\n"); + return 0; + } + alDistanceModel(AL_INVERSE_DISTANCE); + + const char *szDefaultCaptureDevice = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); + LOG("Default OpenAL Capture Device is '%s'\n\n", szDefaultCaptureDevice); + alCaptureDevice = alcCaptureOpenDevice(szDefaultCaptureDevice, 16000, AL_FORMAT_STEREO8, MIC_BUFSIZE); + ALenum err = alGetError(); + if (err != AL_NO_ERROR) { + INFO("Failed to alCaptureOpenDevice, ALenum %i\n", err); + return 0; + } + alcCaptureStart(alCaptureDevice); + + Mic_Inited = TRUE; + Mic_Reset(); + return TRUE; +} + +void Mic_Reset() +{ + if (!Mic_Inited) + return; + memset(Mic_Buffer, 0, MIC_BUFSIZE*2*2); + Mic_BufPos = 0; + Mic_PlayBuf = 1; + Mic_WriteBuf = 0; +} + +void Mic_DeInit() +{ + if (!Mic_Inited) + return; + Mic_Inited = FALSE; + + if (alDevice) { + if (alCaptureDevice) { + alcCaptureStop(alCaptureDevice); + alcCaptureCloseDevice(alCaptureDevice); + } + if (alContext) { + alcMakeContextCurrent(0); + alcDestroyContext(alContext); + } + alcCloseDevice(alDevice); + } +} + + +static void alReadSound() +{ + int num; + alcGetIntegerv(alCaptureDevice, ALC_CAPTURE_SAMPLES, 1, &num); + if (num < MIC_BUFSIZE-1) { + LOG("not enough microphone data waiting! (%i samples)\n", num); + } + LOG("%i samples waiting\n", num); + if (num > MIC_BUFSIZE) + num = MIC_BUFSIZE; + alcCaptureSamples(alCaptureDevice, Mic_Buffer[Mic_WriteBuf], num); + ALenum err = alGetError(); + if (err != AL_NO_ERROR) { + INFO("Failed to alcCaptureSamples, ALenum %i\n", err); + return; + } +} + +u8 stats_max; +u8 stats_min; + +u8 Mic_ReadSample() +{ + if (Mic_BufPos >= MIC_BUFSIZE) { + alReadSound(); + Mic_BufPos = 0; + Mic_PlayBuf ^= 1; + Mic_WriteBuf ^= 1; + } + u8 ret; + ret = Mic_Buffer[Mic_PlayBuf][Mic_BufPos >> 1]; + if (ret > stats_max) + stats_max = ret; + if (ret < stats_min) + stats_min = ret; + Mic_BufPos += 2; + return ret; +} + +void mic_savestate(EMUFILE* os) +{ + write32le(-1,os); +} + +bool mic_loadstate(EMUFILE* is, int size) +{ + is->fseek(size, SEEK_CUR); + return TRUE; +} + +#endif +