koda's OpenAL conversion:
authorunc0rr
Wed, 24 Jun 2009 15:59:32 +0000
changeset 2191 20c62f787a4d
parent 2190 cfcad6142d48
child 2192 4763a778c033
koda's OpenAL conversion: - Freezes program for fadein/fadeout time - Has a problem with quickplay
CMakeLists.txt
QTfrontend/CMakeLists.txt
QTfrontend/SDLs.cpp
QTfrontend/SDLs.h
QTfrontend/pages.cpp
cmake_modules/FindQCA2.cmake
hedgewars/CMakeLists.txt
hedgewars/SDLh.pas
hedgewars/hwengine.dpr
hedgewars/uSound.pas
openalbridge/CMakeLists.txt
openalbridge/endianness.c
openalbridge/endianness.h
openalbridge/loaders.c
openalbridge/loaders.h
openalbridge/openalwrap.c
openalbridge/openalwrap.h
openalbridge/wrappers.c
openalbridge/wrappers.h
--- a/CMakeLists.txt	Mon Jun 22 13:49:16 2009 +0000
+++ b/CMakeLists.txt	Wed Jun 24 15:59:32 2009 +0000
@@ -43,6 +43,7 @@
 endif(WITH_SERVER)
 
 add_subdirectory(bin)
+add_subdirectory(openalbridge)
 add_subdirectory(QTfrontend)
 add_subdirectory(hedgewars)
 add_subdirectory(share)
--- a/QTfrontend/CMakeLists.txt	Mon Jun 22 13:49:16 2009 +0000
+++ b/QTfrontend/CMakeLists.txt	Wed Jun 24 15:59:32 2009 +0000
@@ -17,10 +17,11 @@
 
 # Configure for SDL
 find_package(SDL REQUIRED)
-find_package(SDL_mixer REQUIRED)
+find_package(OpenAL REQUIRED)
+find_package(OggVorbis REQUIRED)
 
 include_directories(${SDL_INCLUDE_DIR})
-include_directories(${SDLMIXER_INCLUDE_DIR})
+
 if(UNIX)
 	include_directories("/usr/local/include") # HACK: in freebsd cannot find iconv.h included via SDL.h
 endif(UNIX)
@@ -164,13 +165,18 @@
 	${hwfr_moc_srcs}
 	${hwfr_hdrs}
 	${hwfr_rez_src})
-	
+
+find_library(OPENALBRIDGE_LIBRARY libopenalbridge.a PATH ${EXECUTABLE_OUTPUT_PATH} )
+
 set(HW_LINK_LIBS 
 	${QT_LIBRARIES}
-#	${QCA2_LIBRARIES}
 	${SDL_LIBRARY}
-	${SDLMIXER_LIBRARY}
-	)
+	${OPENAL_LIBRARY}
+	${OGG_LIBRARY}
+	${VORBIS_LIBRARY}
+	${VORBISFILE_LIBRARY}
+	${OPENALBRIDGE_LIBRARY}
+)
 
 if(WIN32 AND NOT UNIX)
 	if(NOT SDL_LIBRARY)
--- a/QTfrontend/SDLs.cpp	Mon Jun 22 13:49:16 2009 +0000
+++ b/QTfrontend/SDLs.cpp	Wed Jun 24 15:59:32 2009 +0000
@@ -23,14 +23,17 @@
 
 SDLInteraction::SDLInteraction()
 {
-	music = NULL;
+	music = -1;
 
 	SDL_Init(SDL_INIT_VIDEO);
+	openal_init(50);
+
 }
 
 SDLInteraction::~SDLInteraction()
 {
 	SDL_Quit();
+	openal_close();
 }
 
 QStringList SDLInteraction::getResolutions() const
@@ -53,21 +56,18 @@
 
 	return result;
 }
+
 void SDLInteraction::StartMusic()
 {
-	if (!music)
-    {
-   	    SDL_Init(SDL_INIT_AUDIO);
-	    Mix_OpenAudio(22050, 0x8010, 2, 512);
-  
-	    Mix_VolumeMusic(33);
-		music = Mix_LoadMUS(QString(datadir->absolutePath() + "/Music/main theme.ogg").toLocal8Bit().constData());
+	if (music < 0) {
+		music = openal_loadfile(QString(datadir->absolutePath() + "/Music/main theme.ogg").toLocal8Bit().constData());
+		openal_toggleloop(music);
+		openal_setvolume(music,66);
     }
-
-	Mix_FadeInMusic(music, -1, 3000);
+	openal_fadein(music, 50);
 }
 
 void SDLInteraction::StopMusic()
 {
-	Mix_FadeOutMusic(2000);
+	openal_fadeout(music, 50);
 }
--- a/QTfrontend/SDLs.h	Mon Jun 22 13:49:16 2009 +0000
+++ b/QTfrontend/SDLs.h	Wed Jun 24 15:59:32 2009 +0000
@@ -21,15 +21,27 @@
 
 #include <QStringList>
 
-#include "SDL_mixer.h"
+//#include "SDL_mixer.h"
 
+extern	"C" int		openal_init			(int);
+extern	"C" int		openal_close		(void);
+extern	"C" int		openal_loadfile		(const char*);
+extern	"C" int		openal_toggleloop	(int);
+extern	"C" int		openal_setvolume	(int, unsigned char);
+extern	"C" int		openal_setglobalvolume	(unsigned char);
+extern  "C" int		openal_togglemute	(void);
+extern	"C" int		openal_fadeout		(int, unsigned int);
+extern	"C" int		openal_fadein		(int, unsigned int);
+extern	"C" int		openal_playsound 	(int);
+extern	"C" int		openal_stopsound	(int);
+extern	"C" int		openal_pausesound	(int);
 
 class SDLInteraction : public QObject
 {
 	Q_OBJECT
 
 private:
-	Mix_Music * music;
+	int music;
 
 public:
 	SDLInteraction();
--- a/QTfrontend/pages.cpp	Mon Jun 22 13:49:16 2009 +0000
+++ b/QTfrontend/pages.cpp	Wed Jun 24 15:59:32 2009 +0000
@@ -37,7 +37,6 @@
 #include <QTableWidget>
 #include <QAction>
 #include <QMenu>
-#include <QSound>
 #include <QDataWidgetMapper>
 
 
@@ -61,6 +60,7 @@
 #include "misc.h"
 #include "togglebutton.h"
 #include "hwform.h"
+#include "SDLs.h"
 
 PageMain::PageMain(QWidget* parent) : 
   AbstractPage(parent)
@@ -290,9 +290,14 @@
 	tmpdir.cd(datadir->absolutePath());
 	tmpdir.cd("Sounds/voices");
 	tmpdir.cd(CBVoicepack->currentText());
-	QStringList list = tmpdir.entryList(QStringList() << "*.wav", QDir::Files);
-	if (list.size())
-		QSound::play(tmpdir.absolutePath() + "/" + list[rand() % list.size()]);
+	QStringList list = tmpdir.entryList(QStringList() << "Illgetyou.ogg" << "Incoming.ogg" << "Stupid.ogg" << "Coward.ogg" << "Firstblood.ogg", QDir::Files);
+	if (list.size()) {
+	//	printf("%s\n", QString(tmpdir.absolutePath() + "/" + list[rand() % list.size()]).toLocal8Bit().constData());
+		int tmp =openal_loadfile(QString(tmpdir.absolutePath() + "/" + list[rand() % list.size()]).toLocal8Bit().constData());
+		openal_playsound(tmp);										   
+	}
+		
+		//QSound::play(tmpdir.absolutePath() + "/" + list[rand() % list.size()]);
 }
 
 PageMultiplayer::PageMultiplayer(QWidget* parent) :
--- a/cmake_modules/FindQCA2.cmake	Mon Jun 22 13:49:16 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-# - Try to find QCA2 (Qt Cryptography Architecture 2)
-# Once done this will define
-#
-#  QCA2_FOUND - system has QCA2
-#  QCA2_INCLUDE_DIR - the QCA2 include directory
-#  QCA2_LIBRARIES - the libraries needed to use QCA2
-#  QCA2_DEFINITIONS - Compiler switches required for using QCA2
-#
-# use pkg-config to get the directories and then use these values
-# in the FIND_PATH() and FIND_LIBRARY() calls
-
-# Copyright (c) 2006, Michael Larouche, <michael.larouche@kdemail.net>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-include(FindLibraryWithDebug)
-
-if (QCA2_INCLUDE_DIR AND QCA2_LIBRARIES)
-
-  # in cache already
-  set(QCA2_FOUND TRUE)
-
-else (QCA2_INCLUDE_DIR AND QCA2_LIBRARIES)
-
-
-  if (NOT WIN32)
-    find_package(PkgConfig)
-    pkg_check_modules(PC_QCA2 qca2)
-    set(QCA2_DEFINITIONS ${PC_QCA2_CFLAGS_OTHER})
-  endif (NOT WIN32)
-
-  find_library_with_debug(QCA2_LIBRARIES
-                  WIN32_DEBUG_POSTFIX d
-                  NAMES qca
-                  HINTS ${PC_QCA2_LIBDIR} ${PC_QCA2_LIBRARY_DIRS}
-                  )
-
-  find_path(QCA2_INCLUDE_DIR qca.h 
-            HINTS ${PC_QCA2_INCLUDEDIR} ${PC_QCA2_INCLUDE_DIRS}
-            PATH_SUFFIXES QtCrypto)
-
-  include(FindPackageHandleStandardArgs)
-  find_package_handle_standard_args(QCA2  DEFAULT_MSG  QCA2_LIBRARIES QCA2_INCLUDE_DIR)
-
-  mark_as_advanced(QCA2_INCLUDE_DIR QCA2_LIBRARIES)
-
-endif (QCA2_INCLUDE_DIR AND QCA2_LIBRARIES)
--- a/hedgewars/CMakeLists.txt	Mon Jun 22 13:49:16 2009 +0000
+++ b/hedgewars/CMakeLists.txt	Wed Jun 24 15:59:32 2009 +0000
@@ -113,7 +113,7 @@
 		message("Minimum required version of FreePascal is 2.2.0")
 	else (fpc_ver LESS "020200")
 		set(pascal_compiler ${fpc_executable})
-		set(pascal_compiler_flags ${noexecstack_flags} "-B" "-FE../bin" "-Fl../bin" "-Cs2000000" "-vwi" "-O2" ${hwengine_project})
+		set(pascal_compiler_flags ${noexecstack_flags} "-B" "-FE../bin" "-Fl../bin/" "-Fl../openalbridge/" "-Cs2000000" "-vwi" "-O2" ${hwengine_project})
 	endif (fpc_ver LESS "020200")
 endif (fpc_version)
 
@@ -154,7 +154,7 @@
 add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}"
 		COMMAND "lipo"
 		ARGS ${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.386 ${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.ppc -create -output ${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}
-		DEPENDS "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.386" "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.ppc" 
+		DEPENDS "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.386" "${EXECUTABLE_OUTPUT_PATH}/hwengine${CMAKE_EXECUTABLE_SUFFIX}.ppc"
 		)
 ENDIF(NOT APPLE OR NOT universal_build MATCHES "1")
 
--- a/hedgewars/SDLh.pas	Mon Jun 22 13:49:16 2009 +0000
+++ b/hedgewars/SDLh.pas	Wed Jun 24 15:59:32 2009 +0000
@@ -40,12 +40,9 @@
 {$IFNDEF IPHONEOS}
 	  {$linkframework Cocoa}
 	  {$linkframework SDL}
-	  {$linkframework SDL_mixer}
 	  {$linkframework SDL_net}
 	  {$linkframework SDL_image}
 	  {$linkframework SDL_ttf}
-	  {$linkframework Vorbis}
-	  {$linkframework Ogg}
 	  {$linklib SDLmain}
 	  {$linklib gcc}
 {$ENDIF}
@@ -322,70 +319,6 @@
 function TTF_OpenFont(const filename: PChar; size: LongInt): PTTF_Font; cdecl; external SDL_TTFLibName;
 procedure TTF_SetFontStyle(font: PTTF_Font; style: LongInt); cdecl; external SDL_TTFLibName;
 
-(*  SDL_mixer  *)
-
-const {$IFDEF WIN32}
-      SDL_MixerLibName = 'SDL_mixer.dll';
-      {$ENDIF}
-      {$IFDEF UNIX}
-	{$IFDEF DARWIN}
-	  SDL_MixerLibName = 'SDL_mixer';
-	{$ELSE}
-          SDL_MixerLibName = 'libSDL_mixer.so';
-	{$ENDIF}
-      {$ENDIF}
-
-const MIX_MAX_VOLUME = 128;
-
-type PMixChunk = ^TMixChunk;
-     TMixChunk = record
-                 allocated: Longword;
-                 abuf     : PByte;
-                 alen     : Longword;
-                 volume   : PByte;
-                 end;
-     TMusic = (MUS_CMD, MUS_WAV, MUS_MOD, MUS_MID, MUS_OGG, MUS_MP3);
-     TMix_Fading = (MIX_NO_FADING, MIX_FADING_OUT, MIX_FADING_IN);
-
-     TMidiSong = record
-               samples : LongInt;
-               events  : pointer;
-               end;
-
-     TMusicUnion = record
-        case Byte of
-             0: ( midi : TMidiSong );
-             1: ( ogg  : pointer);
-             end;
-
-     PMixMusic = ^TMixMusic;
-     TMixMusic = record
-                 end;
-
-function  Mix_OpenAudio(frequency: LongInt; format: Word; channels: LongInt; chunksize: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-procedure Mix_CloseAudio; cdecl; external SDL_MixerLibName;
-
-function  Mix_Volume(channel: LongInt; volume: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_SetDistance(channel: LongInt; distance: Byte): LongInt;  cdecl; external SDL_MixerLibName;
-function  Mix_VolumeMusic(volume: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-
-function  Mix_AllocateChannels(numchans: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-procedure Mix_FreeChunk(chunk: PMixChunk); cdecl; external SDL_MixerLibName;
-procedure Mix_FreeMusic(music: PMixMusic); cdecl; external SDL_MixerLibName;
-
-function  Mix_LoadWAV_RW(src: PSDL_RWops; freesrc: LongInt): PMixChunk; cdecl; external SDL_MixerLibName;
-function  Mix_LoadMUS(const filename: PChar): PMixMusic; cdecl; external SDL_MixerLibName;
-
-function  Mix_Playing(channel: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_PlayingMusic: LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_FadeInMusic(music: PMixMusic; loops: LongInt; ms: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-
-function  Mix_PlayChannelTimed(channel: LongInt; chunk: PMixChunk; loops: LongInt; ticks: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_PlayMusic(music: PMixMusic; loops: LongInt): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_PausedMusic(music: PMixMusic): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_PauseMusic(music: PMixMusic): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_ResumeMusic(music: PMixMusic): LongInt; cdecl; external SDL_MixerLibName;
-function  Mix_HaltChannel(channel: LongInt): LongInt; cdecl; external SDL_MixerLibName;
 
 (*  SDL_image  *)
 
--- a/hedgewars/hwengine.dpr	Mon Jun 22 13:49:16 2009 +0000
+++ b/hedgewars/hwengine.dpr	Wed Jun 24 15:59:32 2009 +0000
@@ -169,6 +169,7 @@
 repeat
 while SDL_PollEvent(@event) <> 0 do
 	case event.type_ of
+		{thinker here for adding touch events}
 		SDL_KEYDOWN: if GameState = gsChat then KeyPressChat(event.key.keysym.unicode);
 		SDL_ACTIVEEVENT: if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
 				cHasFocus:= event.active.gain = 1;
--- a/hedgewars/uSound.pas	Mon Jun 22 13:49:16 2009 +0000
+++ b/hedgewars/uSound.pas	Wed Jun 24 15:59:32 2009 +0000
@@ -18,15 +18,30 @@
 
 unit uSound;
 interface
-uses SDLh, uConsts;
+
+{$IFDEF DARWIN}
+	{$linkframework OpenAL}
+	{$linkframework Ogg}
+	{$linkframework Vorbis}
+	{$linklib openalbridge}
+{$ELSE}
+	{$linklib openal}
+	{$linklib ogg}
+	{$linklib vorbis}
+	{$linklib vorbisfile}
+{$ENDIF}
+
+uses uConsts;
 {$INCLUDE options.inc}
 
 type PVoicepack = ^TVoicepack;
 	TVoicepack = record
 		name: shortstring;
-		chunks: array [TSound] of PMixChunk;
+		chunks: array [TSound] of LongInt;
 		end;
 
+const OpenALBridge = 'libopenalbridge';
+
 procedure InitSound;
 procedure ReleaseSound;
 procedure SoundLoad;
@@ -36,20 +51,32 @@
 procedure ResumeMusic;
 procedure StopSound(snd: TSound);
 function  ChangeVolume(voldelta: LongInt): LongInt;
+function  AskForVoicepack(name: shortstring): Pointer;
 
-function  AskForVoicepack(name: shortstring): Pointer;
+
+function openal_init		(memsize: LongInt)			: boolean; cdecl; external OpenALBridge;
+function openal_close							: boolean; cdecl; external OpenALBridge;
+function openal_loadfile	(filename: PChar)			: LongInt; cdecl; external OpenALBridge;
+function openal_toggleloop	(index: LongInt)			: boolean; cdecl; external OpenALBridge;
+function openal_setvolume	(index: LongInt; percentage: byte)	: boolean; cdecl; external OpenALBridge; 
+function openal_fadeout		(index: LongInt; quantity: byte)	: boolean; cdecl; external OpenALBridge;
+function openal_fadein		(index: LongInt; quantity: byte)	: boolean; cdecl; external OpenALBridge;
+function openal_playsound	(index: LongInt)			: boolean; cdecl; external OpenALBridge;
+function openal_pausesound	(index: LongInt)			: boolean; cdecl; external OpenALBridge;
+function openal_stopsound	(index: LongInt)			: boolean; cdecl; external OpenALBridge;
+function openal_setglobalvolume	(percentage: byte)			: boolean; cdecl; external OpenALBridge;
 
 var MusicFN: shortstring = '';
 
 implementation
+
 uses uMisc, uConsole;
 
 const chanTPU = 12;
-var Volume: LongInt;
-	lastChan: array [TSound] of LongInt;
+var	lastChan: array [TSound] of LongInt;
 	voicepacks: array[0..cMaxTeams] of TVoicepack;
 	defVoicepack: PVoicepack;
-	Mus: PMixMusic = nil;
+	Mus: LongInt = 0;
 
 function  AskForVoicepack(name: shortstring): Pointer;
 var i: Longword;
@@ -66,33 +93,19 @@
 end;
 
 procedure InitSound;
+const numSounds = 200;
 begin
 if not isSoundEnabled then exit;
-WriteToConsole('Init sound...');
-isSoundEnabled:= SDL_Init(SDL_INIT_AUDIO) >= 0;
-if isSoundEnabled then
-   isSoundEnabled:= Mix_OpenAudio(22050, $8010, 2, 512) = 0;
+WriteToConsole('Init OpenAL sound...');
+isSoundEnabled:= openal_init(numSounds);
 if isSoundEnabled then WriteLnToConsole(msgOK)
                   else WriteLnToConsole(msgFailed);
-Mix_AllocateChannels(Succ(chanTPU));
-if isMusicEnabled then Mix_VolumeMusic(50);
-
-Volume:= 0;
 ChangeVolume(cInitVolume)
 end;
 
 procedure ReleaseSound;
-var i: TSound;
-	t: Longword;
 begin
-for t:= 0 to cMaxTeams do
-	if voicepacks[t].name <> '' then
-		for i:= Low(TSound) to High(TSound) do
-			if voicepacks[t].chunks[i] <> nil then
-				Mix_FreeChunk(voicepacks[t].chunks[i]);
-
-Mix_FreeMusic(Mus);
-Mix_CloseAudio
+openal_close();
 end;
 
 procedure SoundLoad;
@@ -109,8 +122,8 @@
 		begin
 		s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
 		WriteToConsole(msgLoading + s + ' ');
-		defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
-		TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
+		defVoicepack^.chunks[i]:= openal_loadfile (Str2PChar(s));
+		TryDo(defVoicepack^.chunks[i] >= 0, msgFailed, true);
 		WriteLnToConsole(msgOK);
 		end;
 
@@ -121,11 +134,8 @@
 				begin
 				s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName;
 				WriteToConsole(msgLoading + s + ' ');
-				{$IFNDEF IPHONEOS}
-				//broken for unknown reasons (most likely poor SDL_Mixer)
-				voicepacks[t].chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
-				{$ENDIF}
-				if voicepacks[t].chunks[i] = nil then
+				voicepacks[t].chunks[i]:= openal_loadfile (Str2PChar(s));
+				if voicepacks[t].chunks[i] < 0 then
 					WriteLnToConsole(msgFailed)
 				else
 					WriteLnToConsole(msgOK)
@@ -133,22 +143,28 @@
 end;
 
 procedure PlaySound(snd: TSound; infinite: boolean; voicepack: PVoicepack);
-var loops: LongInt;
 begin
 if (not isSoundEnabled) or fastUntilLag then exit;
-if infinite then loops:= -1 else loops:= 0;
 
-if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
-	lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], loops, -1)
+if (voicepack <> nil) and (voicepack^.chunks[snd] >= 0) then
+begin
+	if infinite then openal_toggleloop(voicepack^.chunks[snd]);
+	openal_playsound(voicepack^.chunks[snd]);
+	lastChan[snd]:=voicepack^.chunks[snd];
+end
 else
-	lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], loops, -1)
+begin
+	if infinite then openal_toggleloop(defVoicepack^.chunks[snd]);
+	openal_playsound(defVoicepack^.chunks[snd]);
+	lastChan[snd]:=defVoicepack^.chunks[snd];
+
+end
 end;
 
 procedure StopSound(snd: TSound);
 begin
 if not isSoundEnabled then exit;
-if Mix_Playing(lastChan[snd]) <> 0 then
-	Mix_HaltChannel(lastChan[snd])
+	openal_stopsound(lastChan[snd])
 end;
 
 procedure PlayMusic;
@@ -161,38 +177,30 @@
 s:= PathPrefix + '/Music/' + MusicFN;
 WriteToConsole(msgLoading + s + ' ');
 
-Mus:= Mix_LoadMUS(Str2PChar(s));
-TryDo(Mus <> nil, msgFailed, false);
+Mus:= openal_loadfile(Str2PChar(s));
+TryDo(Mus >= 0, msgFailed, false);
 WriteLnToConsole(msgOK);
 
-SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
+openal_fadein(Mus, 50);
+openal_toggleloop(Mus);
 end;
 
 function ChangeVolume(voldelta: LongInt): LongInt;
 begin
-if not isSoundEnabled then
-	exit(0);
-
-inc(Volume, voldelta);
-if Volume < 0 then Volume:= 0;
-Mix_Volume(-1, Volume);
-Volume:= Mix_Volume(-1, -1);
-if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
-ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
+if not isSoundEnabled then exit(0);
+openal_setglobalvolume(voldelta);
 end;
 
 procedure PauseMusic;
 begin
 if (MusicFN = '') or (not isMusicEnabled) then exit;
-
-Mix_PauseMusic(Mus);
+openal_pausesound(Mus);
 end;
 
 procedure ResumeMusic;
 begin
 if (MusicFN = '') or (not isMusicEnabled) then exit;
-
-Mix_ResumeMusic(Mus);
+openal_playsound(Mus);
 end;
 
 end.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/CMakeLists.txt	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,31 @@
+find_package(OpenAL REQUIRED)
+include_directories(${OPENAL_INCLUDE_DIR})
+
+#add_library (openalbridge openalwrap.c loaders.c endianness.c wrappers.c)
+exec_program(${CMAKE_C_COMPILER}
+			ARGS ${arch_to_build} -o ${EXECUTABLE_OUTPUT_PATH}/loaders.o -c ${hedgewars_SOURCE_DIR}/openalbridge/loaders.c -I ${OPENAL_INCLUDE_DIR} -O2
+			OUTPUT_VARIABLE noout
+)
+exec_program(${CMAKE_C_COMPILER}
+			ARGS ${arch_to_build} -o ${EXECUTABLE_OUTPUT_PATH}/endianness.o -c ${hedgewars_SOURCE_DIR}/openalbridge/endianness.c -I ${OPENAL_INCLUDE_DIR} -O2 
+	OUTPUT_VARIABLE noout
+)
+
+exec_program(${CMAKE_C_COMPILER}
+			ARGS ${arch_to_build} -o ${EXECUTABLE_OUTPUT_PATH}/openalwrap.o -c ${hedgewars_SOURCE_DIR}/openalbridge/openalwrap.c -I ${OPENAL_INCLUDE_DIR} -O2 
+			OUTPUT_VARIABLE noout
+)
+
+exec_program(${CMAKE_C_COMPILER}
+			ARGS ${arch_to_build} -o ${EXECUTABLE_OUTPUT_PATH}/wrappers.o -c ${hedgewars_SOURCE_DIR}/openalbridge/wrappers.c -I ${OPENAL_INCLUDE_DIR} -O2 
+			OUTPUT_VARIABLE noout
+			)
+		exec_program(${CMAKE_AR}
+			ARGS -rvu ${EXECUTABLE_OUTPUT_PATH}/libopenalbridge.a ${EXECUTABLE_OUTPUT_PATH}/loaders.o ${EXECUTABLE_OUTPUT_PATH}/endianness.o ${EXECUTABLE_OUTPUT_PATH}/openalwrap.o ${EXECUTABLE_OUTPUT_PATH}/wrappers.o 
+			OUTPUT_VARIABLE noout
+			)
+		exec_program(${CMAKE_RANLIB}
+			ARGS ${EXECUTABLE_OUTPUT_PATH}/libopenalbridge.a
+			OUTPUT_VARIABLE noout
+			)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/endianness.c	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,51 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "endianness.h"
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+	//from big endian to little endian
+	int invert_endianness(int number){
+		uint8_t n1,n2,n3,n4;
+		uint32_t a1,a2,a3,a4;
+		uint32_t done = 0;
+		
+		n1 = number;
+		n2 = number >> 8;
+		n3 = number >> 16;
+		n4 = number >> 24;
+		
+		//printf("%X, %X, %X, %X\n", n1, n2, n3, n4);
+		a1 = (uint32_t) n1 << 24;
+		a2 = (uint32_t) n2 << 16;
+		a3 = (uint32_t) n3 << 8;
+		a4 = (uint32_t) n4;
+		done = a1 + a2 + a3 + a4;
+		//printf("%08X %08X %08X %08X = %08X\n", a1, a2, a3, a4, done);
+		return done;
+	}
+	
+#ifdef __CPLUSPLUS
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/endianness.h	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,29 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+
+#pragma once
+
+int invert_endianness(int number);
+
+#ifdef __CPLUSPLUS
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/loaders.c	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,212 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "al.h"
+#include "alc.h"
+#include "loaders.h"
+#include "endianness.h"
+#include "wrappers.h"
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+	extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
+	extern long ov_read(OggVorbis_File *vf,char *buffer,int length,int bigendianp,int word,int sgned,int *bitstream);
+	extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
+	extern long ov_read(OggVorbis_File *vf,char *buffer,int length,int bigendianp,int word,int sgned,int *bitstream);
+	extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+	extern vorbis_comment *ov_comment(OggVorbis_File *f, int num);
+	
+	int load_WavPcm (const char *filename, ALenum *format, uint8_t** data, ALsizei *bitsize, ALsizei *freq) {
+		WAV_header_t WAVHeader;
+		FILE *wavfile;
+		int t, n = 0;
+		
+		wavfile = Fopen(filename, "rb");
+		
+		fread(&WAVHeader.ChunkID, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.ChunkSize, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.Format, sizeof(uint32_t), 1, wavfile);
+		
+#ifdef DEBUG
+		fprintf(stderr, "ChunkID: %X\n", invert_endianness(WAVHeader.ChunkID));
+		fprintf(stderr, "ChunkSize: %d\n", WAVHeader.ChunkSize);
+		fprintf(stderr, "Format: %X\n", invert_endianness(WAVHeader.Format));
+#endif
+		
+		fread(&WAVHeader.Subchunk1ID, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.Subchunk1Size, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.AudioFormat, sizeof(uint16_t), 1, wavfile);
+		fread(&WAVHeader.NumChannels, sizeof(uint16_t), 1, wavfile);
+		fread(&WAVHeader.SampleRate, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.ByteRate, sizeof(uint32_t), 1, wavfile);
+		fread(&WAVHeader.BlockAlign, sizeof(uint16_t), 1, wavfile);
+		fread(&WAVHeader.BitsPerSample, sizeof(uint16_t), 1, wavfile);
+		
+#ifdef DEBUG
+		fprintf(stderr, "Subchunk1ID: %X\n", invert_endianness(WAVHeader.Subchunk1ID));
+		fprintf(stderr, "Subchunk1Size: %d\n", WAVHeader.Subchunk1Size);
+		fprintf(stderr, "AudioFormat: %d\n", WAVHeader.AudioFormat);
+		fprintf(stderr, "NumChannels: %d\n", WAVHeader.NumChannels);
+		fprintf(stderr, "SampleRate: %d\n", WAVHeader.SampleRate);
+		fprintf(stderr, "ByteRate: %d\n", WAVHeader.ByteRate);
+		fprintf(stderr, "BlockAlign: %d\n", WAVHeader.BlockAlign);
+		fprintf(stderr, "BitsPerSample: %d\n", WAVHeader.BitsPerSample);
+#endif
+		
+		do { //remove useless header chunks (plenty room for improvements)
+			t = fread(&WAVHeader.Subchunk2ID, sizeof(uint32_t), 1, wavfile);
+			if (invert_endianness(WAVHeader.Subchunk2ID) == 0x64617461)
+				break;
+			if (t <= 0) { //eof found
+				fprintf(stderr, "ERROR: wrong WAV header\n");
+				return AL_FALSE;
+			}
+		} while (1);
+		fread(&WAVHeader.Subchunk2Size, sizeof(uint32_t), 1, wavfile);
+		
+#ifdef DEBUG
+		fprintf(stderr, "Subchunk2ID: %X\n", invert_endianness(WAVHeader.Subchunk2ID));
+		fprintf(stderr, "Subchunk2Size: %d\n", WAVHeader.Subchunk2Size);
+#endif
+		
+		*data = (uint8_t*) malloc (sizeof(uint8_t) * WAVHeader.Subchunk2Size);
+		
+		//this could be improved
+		do {
+			n += fread(&((*data)[n]), sizeof(uint8_t), 1, wavfile);
+		} while (n < WAVHeader.Subchunk2Size);
+		
+		fclose(wavfile);	
+		
+#ifdef DEBUG
+		fprintf(stderr, "Last two bytes of data: %X%X\n", (*data)[n-2], (*data)[n-1]);
+#endif
+		
+		/*remaining parameters*/
+		//Valid formats are AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8, and AL_FORMAT_STEREO16. 
+		if (WAVHeader.NumChannels == 1) {
+			if (WAVHeader.BitsPerSample == 8)
+				*format = AL_FORMAT_MONO8;
+			else {
+				if (WAVHeader.BitsPerSample == 16)
+					*format = AL_FORMAT_MONO16;
+				else {
+					fprintf(stderr, "ERROR: wrong WAV header - bitsample value\n");
+					return AL_FALSE;
+				}
+			} 
+		} else {
+			if (WAVHeader.NumChannels == 2) {
+				if (WAVHeader.BitsPerSample == 8)
+					*format = AL_FORMAT_STEREO8;
+				else {
+					if (WAVHeader.BitsPerSample == 16)
+						*format = AL_FORMAT_STEREO16;
+					else {
+						fprintf(stderr, "ERROR: wrong WAV header - bitsample value\n");
+						return AL_FALSE;
+					}				
+				}
+			} else {
+				fprintf(stderr, "ERROR: wrong WAV header - format value\n");
+				return AL_FALSE;
+			}
+		}
+		
+		*bitsize = WAVHeader.Subchunk2Size;
+		*freq = WAVHeader.SampleRate;
+		return AL_TRUE;
+	}
+	
+	int load_OggVorbis (const char *filename, ALenum *format, uint8_t**data, ALsizei *bitsize, ALsizei *freq) {
+		//implementation inspired from http://www.devmaster.net/forums/showthread.php?t=1153
+		FILE			*oggFile;		// ogg handle
+		OggVorbis_File  oggStream;		// stream handle
+		vorbis_info		*vorbisInfo;	// some formatting data
+		vorbis_comment	*vorbisComment;	// other less useful data
+		int64_t			pcm_length;		// length of the decoded data
+		int size = 0;
+		int section, result, i;
+		
+		oggFile = Fopen(filename, "rb");
+		result = ov_open(oggFile, &oggStream, NULL, 0);
+		//TODO: check returning value of result
+		
+		vorbisInfo = ov_info(&oggStream, -1);
+		pcm_length = ov_pcm_total(&oggStream,-1) << vorbisInfo->channels;	
+		
+#ifdef DEBUG
+		vorbisComment = ov_comment(&oggStream, -1);
+		fprintf(stderr, "Version: %d\n", vorbisInfo->version);
+		fprintf(stderr, "Channels: %d\n", vorbisInfo->channels);
+		fprintf(stderr, "Rate (Hz): %d\n", vorbisInfo->rate);
+		fprintf(stderr, "Bitrate Upper: %d\n", vorbisInfo->bitrate_upper);
+		fprintf(stderr, "Bitrate Nominal: %d\n", vorbisInfo->bitrate_nominal);
+		fprintf(stderr, "Bitrate Lower: %d\n", vorbisInfo->bitrate_lower);
+		fprintf(stderr, "Bitrate Windows: %d\n", vorbisInfo->bitrate_window);
+		fprintf(stderr, "Vendor: %s\n", vorbisComment->vendor);
+		fprintf(stderr, "PCM data size: %d\n", pcm_length);
+		fprintf(stderr, "# comment: %d\n", vorbisComment->comments);
+		for (i = 0; i < vorbisComment->comments; i++)
+			fprintf(stderr, "\tComment %d: %s\n", i, vorbisComment->user_comments[i]);
+#endif
+		
+		//allocates enough room for the decoded data
+		*data = (uint8_t*) malloc (sizeof(uint8_t) * pcm_length);
+		
+		//there *should* not be ogg at 8 bits
+		if (vorbisInfo->channels == 1)
+			*format = AL_FORMAT_MONO16;
+		else {
+			if (vorbisInfo->channels == 2)
+				*format = AL_FORMAT_STEREO16;
+			else {
+				fprintf(stderr, "ERROR: wrong OGG header - channel value (%d)\n", vorbisInfo->channels);
+				return AL_FALSE;
+			}
+		}
+		
+		while(size < pcm_length)	{
+			//ov_read decodes the ogg stream and storse the pcm in data 
+			result = ov_read (&oggStream, *data + size, pcm_length - size, 0, 2, 1, &section);
+			if(result > 0) {
+				size += result;
+			} else {
+				if (result == 0)
+					break;
+				else { 
+					fprintf(stderr, "ERROR: end of file from OGG stream\n");
+					return AL_FALSE;
+				}
+			}
+		}
+		
+		//records the last fields
+		*bitsize = size;
+		*freq = vorbisInfo->rate;
+		return AL_TRUE;
+	}
+	
+#ifdef __CPLUSPLUS
+}
+#endif	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/loaders.h	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,245 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+#pragma once
+	
+#pragma pack(1)
+	typedef struct _WAV_header_t {
+		uint32_t ChunkID;
+		uint32_t ChunkSize;
+		uint32_t Format;
+		uint32_t Subchunk1ID;
+		uint32_t Subchunk1Size;
+		uint16_t AudioFormat;
+		uint16_t NumChannels;
+		uint32_t SampleRate;
+		uint32_t ByteRate;
+		uint16_t BlockAlign;
+		uint16_t BitsPerSample;
+		uint32_t Subchunk2ID;
+		uint32_t Subchunk2Size;
+	} WAV_header_t;
+#pragma pack()
+	
+	/*data types for ogg and vorbis*/
+#ifndef ogg_int64_t	
+#define ogg_int64_t int64_t
+#endif
+	
+	typedef struct {
+		unsigned char *data;
+		int storage;
+		int fill;
+		int returned;
+		
+		int unsynced;
+		int headerbytes;
+		int bodybytes;
+	} ogg_sync_state;
+	typedef struct vorbis_info{
+		int version;
+		int channels;
+		long rate;
+		
+		/* The below bitrate declarations are *hints*.
+		 Combinations of the three values carry the following implications:
+		 
+		 all three set to the same value:
+		 implies a fixed rate bitstream
+		 only nominal set:
+		 implies a VBR stream that averages the nominal bitrate.  No hard
+		 upper/lower limit
+		 upper and or lower set:
+		 implies a VBR bitstream that obeys the bitrate limits. nominal
+		 may also be set to give a nominal rate.
+		 none set:
+		 the coder does not care to speculate.
+		 */
+		
+		long bitrate_upper;
+		long bitrate_nominal;
+		long bitrate_lower;
+		long bitrate_window;
+		
+		void *codec_setup;
+	} vorbis_info;
+	typedef struct vorbis_comment{
+		/* unlimited user comment fields.  libvorbis writes 'libvorbis'
+		 whatever vendor is set to in encode */
+		char **user_comments;
+		int   *comment_lengths;
+		int    comments;
+		char  *vendor;
+		
+	} vorbis_comment;
+	typedef struct {
+		unsigned char   *body_data;    /* bytes from packet bodies */
+		long    body_storage;          /* storage elements allocated */
+		long    body_fill;             /* elements stored; fill mark */
+		long    body_returned;         /* elements of fill returned */
+		
+		
+		int     *lacing_vals;      /* The values that will go to the segment table */
+		ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
+		 this way, but it is simple coupled to the
+		 lacing fifo */
+		long    lacing_storage;
+		long    lacing_fill;
+		long    lacing_packet;
+		long    lacing_returned;
+		
+		unsigned char    header[282];      /* working space for header encode */
+		int              header_fill;
+		
+		int     e_o_s;          /* set when we have buffered the last packet in the
+		 logical bitstream */
+		int     b_o_s;          /* set after we've written the initial page
+		 of a logical bitstream */
+		long    serialno;
+		long    pageno;
+		ogg_int64_t  packetno;      /* sequence number for decode; the framing
+		 knows where there's a hole in the data,
+		 but we need coupling so that the codec
+		 (which is in a seperate abstraction
+		 layer) also knows about the gap */
+		ogg_int64_t   granulepos;
+		
+	} ogg_stream_state;
+	typedef struct vorbis_dsp_state{
+		int analysisp;
+		vorbis_info *vi;
+		
+		float **pcm;
+		float **pcmret;
+		int      pcm_storage;
+		int      pcm_current;
+		int      pcm_returned;
+		
+		int  preextrapolate;
+		int  eofflag;
+		
+		long lW;
+		long W;
+		long nW;
+		long centerW;
+		
+		ogg_int64_t granulepos;
+		ogg_int64_t sequence;
+		
+		ogg_int64_t glue_bits;
+		ogg_int64_t time_bits;
+		ogg_int64_t floor_bits;
+		ogg_int64_t res_bits;
+		
+		void       *backend_state;
+	} vorbis_dsp_state;
+	typedef struct {
+		long endbyte;
+		int  endbit;
+		
+		unsigned char *buffer;
+		unsigned char *ptr;
+		long storage;
+	} oggpack_buffer;
+	typedef struct vorbis_block{
+		/* necessary stream state for linking to the framing abstraction */
+		float  **pcm;       /* this is a pointer into local storage */
+		oggpack_buffer opb;
+		
+		long  lW;
+		long  W;
+		long  nW;
+		int   pcmend;
+		int   mode;
+		
+		int         eofflag;
+		ogg_int64_t granulepos;
+		ogg_int64_t sequence;
+		vorbis_dsp_state *vd; /* For read-only access of configuration */
+		
+		/* local storage to avoid remallocing; it's up to the mapping to
+		 structure it */
+		void               *localstore;
+		long                localtop;
+		long                localalloc;
+		long                totaluse;
+		struct alloc_chain *reap;
+		
+		/* bitmetrics for the frame */
+		long glue_bits;
+		long time_bits;
+		long floor_bits;
+		long res_bits;
+		
+		void *internal;
+		
+	} vorbis_block;
+	typedef struct {
+		size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);
+		int    (*seek_func)  (void *datasource, ogg_int64_t offset, int whence);
+		int    (*close_func) (void *datasource);
+		long   (*tell_func)  (void *datasource);
+	} ov_callbacks;
+	typedef struct OggVorbis_File {
+		void            *datasource; /* Pointer to a FILE *, etc. */
+		int              seekable;
+		ogg_int64_t      offset;
+		ogg_int64_t      end;
+		ogg_sync_state   oy;
+		
+		/* If the FILE handle isn't seekable (eg, a pipe), only the current
+		 stream appears */
+		int              links;
+		ogg_int64_t     *offsets;
+		ogg_int64_t     *dataoffsets;
+		long            *serialnos;
+		ogg_int64_t     *pcmlengths; /* overloaded to maintain binary
+		 compatability; x2 size, stores both
+		 beginning and end values */
+		vorbis_info     *vi;
+		vorbis_comment  *vc;
+		
+		/* Decoding working state local storage */
+		ogg_int64_t      pcm_offset;
+		int              ready_state;
+		long             current_serialno;
+		int              current_link;
+		
+		double           bittrack;
+		double           samptrack;
+		
+		ogg_stream_state os; /* take physical pages, weld into a logical
+		 stream of packets */
+		vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+		vorbis_block     vb; /* local working space for packet->PCM decode */
+		
+		ov_callbacks callbacks;
+		
+	} OggVorbis_File;
+	
+	
+	int load_WavPcm		(const char *filename, ALenum *format, uint8_t **data, ALsizei *bitsize, ALsizei *freq);
+	int load_OggVorbis	(const char *filename, ALenum *format, uint8_t **data, ALsizei *bitsize, ALsizei *freq);
+	
+#ifdef __CPLUSPLUS
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/openalwrap.c	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,386 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "al.h"
+#include "alc.h"
+#include "openalwrap.h"
+#include "loaders.h"
+#include "wrappers.h"
+#include "endianness.h"
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+	// Sources are points emitting sound.
+	ALuint *Sources;
+	// Buffers hold sound data.
+	ALuint *Buffers;
+	//index for Sources and Buffers
+	ALuint globalindex, globalsize;
+	// Position of the source sound.
+	ALfloat **SourcePos;
+	// Velocity of the source sound.
+	ALfloat **SourceVel;
+	
+	
+	ALint openal_close(void) {
+		/* This function stops all the sounds, deallocates all memory and closes OpenAL */
+		int i;
+		ALCcontext *context;
+		ALCdevice  *device;
+		
+		alSourceStopv	(globalsize, Sources);
+		alDeleteSources (globalsize, Sources);
+		alDeleteBuffers (globalsize, Buffers);
+		
+		for (i = 0; i < globalsize; i++) {
+			free(SourcePos[i]);
+			free(SourceVel[i]);
+		}
+		free(SourcePos);
+		free(SourceVel);
+		free(Sources);
+		free(Buffers);
+		
+		context = alcGetCurrentContext();
+		device  = alcGetContextsDevice(context);
+		
+		alcMakeContextCurrent(NULL);
+		alcDestroyContext(context);
+		alcCloseDevice(device);
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_init(int memorysize) {	
+		/* This function initializes an OpenAL contex, allocates memory space for data and prepares OpenAL buffers*/
+		ALCcontext *context;
+		ALCdevice *device;
+		ALenum error;
+
+		const ALCchar *default_device;
+		// Position of the listener.
+		ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };
+		// Velocity of the listener.
+		ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };
+		// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
+		ALfloat ListenerOri[] = { 0.0, 0.0, -1.0,  0.0, 1.0, 0.0 };
+		
+		default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+		
+		fprintf(stderr, "Using default device: %s\n", default_device);
+		
+		if ((device = alcOpenDevice(default_device)) == NULL) {
+			fprintf(stderr, "ERROR %d: Failed to open sound device\n", error);
+			return AL_FALSE;
+		}
+		context = alcCreateContext(device, NULL);
+		alcMakeContextCurrent(context);
+		alcProcessContext(context);
+		
+		if (AlGetError("ERROR %d: Creating a new contex\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		//allocate memory space for buffers and sources
+		globalsize = memorysize;
+		Buffers   = (ALuint*)   Malloc(sizeof(ALuint  )*globalsize);
+		Sources   = (ALuint*)   Malloc(sizeof(ALuint  )*globalsize);
+		SourcePos = (ALfloat**) Malloc(sizeof(ALfloat*)*globalsize);
+		SourceVel = (ALfloat**) Malloc(sizeof(ALfloat*)*globalsize);
+		
+		//set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation
+		alListenerf (AL_GAIN,		 1.0f		);
+		alListenerfv(AL_POSITION,    ListenerPos);
+		alListenerfv(AL_VELOCITY,    ListenerVel);
+		alListenerfv(AL_ORIENTATION, ListenerOri);
+		
+		if (AlGetError("ERROR %d: Setting Listener properties\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+		return AL_TRUE;
+	}
+	
+	
+	int openal_loadfile (const char *filename){
+		/* This function opens a file, loads into memory and allocates the Source buffer for playing*/
+		ALenum format;
+		ALsizei bitsize;
+		ALsizei freq;
+		uint8_t *data;
+		uint32_t fileformat;
+		int i, error;
+		FILE *fp;
+		
+		
+		/*detect the file format, as written in the first 4 bytes of the header*/
+		fp = Fopen (filename, "rb");
+		if (fp == NULL)
+			return -1;
+		error = fread (&fileformat, sizeof(uint32_t), 1, fp);
+		fclose (fp);
+		
+		if (error < 0) {
+			fprintf(stderr, "ERROR: file %s is too short \n", filename);
+			return -2;
+		}
+		
+		//prepare the buffers to receive data
+		alGenBuffers(1, &Buffers[globalindex]);
+		
+		if (AlGetError("ERROR %d: Allocating memory for buffers\n") != AL_TRUE)
+			return -3;
+		
+		//prepare the sources to emit sound
+		alGenSources(1, &Sources[globalindex]);
+		
+		if (AlGetError("ERROR %d: Allocating memory for sources\n") != AL_TRUE)
+			return -4;
+				
+		
+		if (fileformat == 0x5367674F) //check if ogg
+			error = load_OggVorbis (filename, &format, &data, &bitsize, &freq);
+		else {
+			if (fileformat == 0x46464952) //check if wav
+				error = load_WavPcm (filename, &format, &data, &bitsize, &freq);
+			else {
+				fprintf(stderr, "ERROR: File format (%08X) not supported!\n", invert_endianness(fileformat));
+				return -5;
+			}
+		}
+		
+		//copy pcm data in one buffer
+		alBufferData(Buffers[globalindex], format, data, bitsize, freq);
+		free(data);		//deallocate data to save memory
+		
+		if (AlGetError("ERROR %d: Writing data to buffer\n") != AL_TRUE)
+			return -5;
+		
+		//memory allocation for source position and velocity
+		SourcePos[globalindex] = (ALfloat*) Malloc(sizeof(ALfloat)*3);
+		SourceVel[globalindex] = (ALfloat*) Malloc(sizeof(ALfloat)*3);
+		
+		if (SourcePos[globalindex] == NULL || SourceVel[globalindex] == NULL)
+			return -6;
+			
+		//source properties that it will use when it's in playback
+		for (i = 0; i < 3; i++) {
+			SourcePos[globalindex][i] = 0.0;
+			SourceVel[globalindex][i] = 0.1;
+		}	
+		alSourcei (Sources[globalindex], AL_BUFFER,   Buffers[globalindex]  );
+		alSourcef (Sources[globalindex], AL_PITCH,    1.0f					);
+		alSourcef (Sources[globalindex], AL_GAIN,     1.0f					);
+		alSourcefv(Sources[globalindex], AL_POSITION, SourcePos[globalindex]);
+		alSourcefv(Sources[globalindex], AL_VELOCITY, SourceVel[globalindex]);
+		alSourcei (Sources[globalindex], AL_LOOPING,  0						);
+		
+		if (AlGetError("ERROR %d: Setting source properties\n") != AL_TRUE)
+			return -7;
+		
+		alGetError();  /* clear any AL errors beforehand */
+		
+		//returns the index of the source you just loaded, increments it and exits
+		return globalindex++;
+	}
+	
+	
+	ALint openal_toggleloop (int index){
+		/*Set or unset looping mode*/
+		ALint loop;
+		
+		if (index >= globalsize) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		
+		alGetSourcei (Sources[index], AL_LOOPING, &loop);
+		alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
+		if (AlGetError("ERROR %d: Getting or setting loop property\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_setvolume (int index, unsigned char percentage) {
+		/*Set volume for sound number index*/
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		
+		if (percentage > 100)
+			percentage = 100;
+		alSourcef (Sources[index], AL_GAIN, (ALfloat) percentage/100.0f);
+		if (AlGetError("ERROR %d: Setting volume for last sound\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_setglobalvolume (unsigned char percentage) {
+		/*Set volume for all sounds*/		
+		if (percentage > 100)
+			percentage = 100;
+		alListenerf (AL_GAIN, (ALfloat) percentage/100.0f);
+		if (AlGetError("ERROR %d: Setting global volume\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_togglemute () {
+		/*Mute or unmute sound*/
+		ALfloat mute;
+		
+		alGetListenerf (AL_GAIN, &mute);
+		if (mute > 0) 
+			mute = 0;
+		else
+			mute = 1.0;
+		alListenerf (AL_GAIN, mute);
+		if (AlGetError("ERROR %d: Setting mute property\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_fadeout(int index, unsigned int quantity) {
+		ALfloat gain;
+		
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		
+		alGetSourcef(Sources[index], AL_GAIN, &gain);
+
+		for ( ; gain >= 0.00f; gain -= (float) quantity/10000){
+#ifdef DEBUG
+			fprintf(stderr, "Fade-out: Set gain to: %f\n", gain);
+#endif
+			alSourcef(Sources[index], AL_GAIN, gain);
+			usleep(10000);
+		}
+		
+		if (AlGetError("ERROR %d: Setting fade out volume\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		//stop that sound and reset its gain
+		alSourceStop (Sources[index]);
+		alSourcef (Sources[index], AL_GAIN, 1.0f);
+
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_fadein(int index, unsigned int quantity) {
+		ALfloat gain;
+		
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		
+		gain = 0.0f;
+		alSourcef(Sources[index], AL_GAIN, gain);
+		alSourcePlay(Sources[index]);
+		
+		for ( ; gain <= 1.00f; gain += (float) quantity/10000){
+#ifdef DEBUG
+			fprintf(stderr, "Fade-in: Set gain to: %f\n", gain);
+#endif
+			alSourcef(Sources[index], AL_GAIN, gain);
+			usleep(10000);
+		}
+		
+		if (AlGetError("ERROR %d: Setting fade in volume\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_playsound(int index){
+		/*Play sound number index*/
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		alSourcePlay(Sources[index]);
+		if (AlGetError("ERROR %d: Playing last sound\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_pausesound(int index){
+		/*Pause sound number index*/
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		alSourcePause(Sources[index]);
+		if (AlGetError("ERROR %d: Pausing last sound\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		return AL_TRUE;
+	}
+	
+	
+	ALint openal_stopsound(int index){
+		/*Stop sound number index*/
+		if (index >= globalindex) {
+			fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex);
+			return AL_FALSE;
+		}
+		alSourceStop(Sources[index]);
+		if (AlGetError("ERROR %d: Stopping last sound\n") != AL_TRUE)
+			return AL_FALSE;
+		
+		alGetError();  /* clear any AL errors beforehand */
+
+		return AL_TRUE;
+	}
+	
+#ifdef __CPLUSPLUS
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/openalwrap.h	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,64 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _SLEEP_H
+#define _SLEEP_H
+/** 1.0 02/03/10 - Defines cross-platform sleep, usleep, etc. * By Wu Yongwei **/
+#ifdef _WIN32
+# if defined(_NEED_SLEEP_ONLY) && (defined(_MSC_VER) || defined(__MINGW32__))
+#  include <stdlib.h>
+#  define sleep(t) _sleep((t) * 1000)
+# else
+#  include <windows.h>
+#  define sleep(t)  Sleep((t) * 1000)
+# endif
+# ifndef _NEED_SLEEP_ONLY
+#  define msleep(t) Sleep(t)
+#  define usleep(t) Sleep((t) / 1000)
+# endif
+#else
+# include <unistd.h>
+# ifndef _NEED_SLEEP_ONLY
+#  define msleep(t) usleep((t) * 1000)
+# endif
+#endif
+
+#endif /* _SLEEP_H */
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+#pragma once
+	
+	ALint	openal_init				(int memorysize);
+	ALint	openal_close			(void);
+	int		openal_loadfile			(const char *filename);
+	ALint	openal_toggleloop		(int index);
+	ALint	openal_setvolume		(int index, unsigned char percentage);
+	ALint	openal_setglobalvolume	(unsigned char percentage);
+	ALint	openal_togglemute		(void);
+	ALint	openal_fadeout			(int index, unsigned int quantity);
+	ALint	openal_fadein			(int index, unsigned int quantity);
+	ALint	openal_playsound		(int index);	
+	ALint	openal_pausesound		(int index);
+	ALint	openal_stopsound		(int index);
+	
+#ifdef __CPLUSPLUS
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/wrappers.c	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,57 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "wrappers.h"
+#include "al.h"
+
+#ifdef __CPLUSPLUS
+extern "C" {
+#endif 
+	
+	void *Malloc (size_t nbytes)
+	{
+		void *aptr;
+		if ( (aptr = malloc(nbytes)) == NULL)
+			fprintf(stderr, "ERROR: not enough memory! malloc() failed");
+		return aptr;
+	}
+	
+	FILE *Fopen (const char *fname, char *mode)
+	{
+		FILE *fp;
+		if ((fp=fopen(fname,mode)) == NULL)
+			fprintf (stderr, "ERROR: can't open file %s in mode '%s'", fname, mode);
+		return fp;
+	}
+	
+	ALint AlGetError (const char *str) {
+		ALenum error;
+		
+		error = alGetError();
+		if (error != AL_NO_ERROR) {
+			fprintf(stderr, str, error);
+			return -2;
+		} else 
+			return AL_TRUE;
+	}
+	
+#ifdef __CPLUSPLUS
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openalbridge/wrappers.h	Wed Jun 24 15:59:32 2009 +0000
@@ -0,0 +1,25 @@
+/*
+ * OpenAL Bridge - a simple portable library for OpenAL interface
+ * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "al.h"
+
+void *Malloc (size_t nbytes);
+FILE *Fopen (const char *fname, char *mode);
+ALint AlGetError (const char *str);