Browse Source

Major developments to love.audio/love.sound. Music and Sound are gone. There are only Sources now, which is much cleaner.
The audio module was not really stable in 0.6.0, it takes very little messing around to cause OpenAL to do horrible things. It should now be much more stable,
and you *should* be able to play/stop/pause/resume/rewind/loop like a madman without disasters. Seek and tell, however, are still not tested and verified for
all decoders, but that's less important. Also, all objects now have object:type() and object:typeOf(), which returns the type name of the object,
and checks whether an object is of a certain type, respectively.

rude 15 years ago
parent
commit
5b30c7fcfe
51 changed files with 895 additions and 1694 deletions
  1. 0 108
      platform/msvc2008/audio/audio.vcproj
  2. 0 152
      platform/msvc2008/love.vcproj
  3. 1 17
      platform/msvc2008/sound/sound.vcproj
  4. 83 0
      src/common/runtime.cpp
  5. 2 0
      src/common/runtime.h
  6. 9 13
      src/common/types.h
  7. 0 48
      src/modules/audio/Audible.h
  8. 8 42
      src/modules/audio/Audio.h
  9. 0 63
      src/modules/audio/Music.h
  10. 0 42
      src/modules/audio/Sound.h
  11. 14 29
      src/modules/audio/Source.cpp
  12. 26 8
      src/modules/audio/Source.h
  13. 2 20
      src/modules/audio/null/Audio.cpp
  14. 3 9
      src/modules/audio/null/Audio.h
  15. 0 63
      src/modules/audio/null/Music.cpp
  16. 0 57
      src/modules/audio/null/Music.h
  17. 0 55
      src/modules/audio/null/Sound.cpp
  18. 0 54
      src/modules/audio/null/Sound.h
  19. 22 5
      src/modules/audio/null/Source.cpp
  20. 23 22
      src/modules/audio/null/Source.h
  21. 4 30
      src/modules/audio/openal/Audio.cpp
  22. 2 8
      src/modules/audio/openal/Audio.h
  23. 0 134
      src/modules/audio/openal/Music.cpp
  24. 0 79
      src/modules/audio/openal/Music.h
  25. 123 60
      src/modules/audio/openal/Pool.cpp
  26. 15 23
      src/modules/audio/openal/Pool.h
  27. 0 87
      src/modules/audio/openal/Sound.cpp
  28. 0 77
      src/modules/audio/openal/Sound.h
  29. 212 56
      src/modules/audio/openal/Source.cpp
  30. 54 24
      src/modules/audio/openal/Source.h
  31. 24 71
      src/modules/audio/wrap_Audio.cpp
  32. 3 5
      src/modules/audio/wrap_Audio.h
  33. 0 42
      src/modules/audio/wrap_Music.cpp
  34. 0 37
      src/modules/audio/wrap_Music.h
  35. 0 42
      src/modules/audio/wrap_Sound.cpp
  36. 0 37
      src/modules/audio/wrap_Sound.h
  37. 8 0
      src/modules/audio/wrap_Source.cpp
  38. 1 0
      src/modules/audio/wrap_Source.h
  39. 2 2
      src/modules/sound/Decoder.h
  40. 5 1
      src/modules/sound/lullaby/ModPlugDecoder.cpp
  41. 1 1
      src/modules/sound/lullaby/ModPlugDecoder.h
  42. 72 33
      src/modules/sound/lullaby/Mpg123Decoder.cpp
  43. 8 2
      src/modules/sound/lullaby/Mpg123Decoder.h
  44. 2 2
      src/modules/sound/lullaby/Sound.cpp
  45. 10 31
      src/modules/sound/lullaby/VorbisDecoder.cpp
  46. 1 1
      src/modules/sound/lullaby/VorbisDecoder.h
  47. 1 1
      src/modules/sound/wrap_Sound.cpp
  48. 41 0
      src/scripts/audio.lua
  49. 93 0
      src/scripts/audio.lua.h
  50. 19 0
      src/scripts/boot.lua
  51. 1 1
      src/scripts/graphics.lua

+ 0 - 108
platform/msvc2008/audio/audio.vcproj

@@ -188,22 +188,6 @@
 				RelativePath="..\..\..\src\modules\audio\openal\Audio.h"
 				>
 			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\openal\Music.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)\audio\openal\"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\openal\Music.h"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\modules\audio\openal\Pool.cpp"
 				>
@@ -220,22 +204,6 @@
 				RelativePath="..\..\..\src\modules\audio\openal\Pool.h"
 				>
 			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\openal\Sound.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)\audio\openal\"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\openal\Sound.h"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\modules\audio\openal\Source.cpp"
 				>
@@ -272,38 +240,6 @@
 				RelativePath="..\..\..\src\modules\audio\null\Audio.h"
 				>
 			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\null\Music.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)\audio\null\"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\null\Music.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\null\Sound.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)\audio\null\"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\audio\null\Sound.h"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\modules\audio\null\Source.cpp"
 				>
@@ -321,22 +257,10 @@
 				>
 			</File>
 		</Filter>
-		<File
-			RelativePath="..\..\..\src\modules\audio\Audible.h"
-			>
-		</File>
 		<File
 			RelativePath="..\..\..\src\modules\audio\Audio.h"
 			>
 		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\Music.h"
-			>
-		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\Sound.h"
-			>
-		</File>
 		<File
 			RelativePath="..\..\..\src\modules\audio\Source.cpp"
 			>
@@ -369,38 +293,6 @@
 			RelativePath="..\..\..\src\modules\audio\wrap_Audio.h"
 			>
 		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\wrap_Music.cpp"
-			>
-			<FileConfiguration
-				Name="Debug|Win32"
-				>
-				<Tool
-					Name="VCCLCompilerTool"
-					ObjectFile="$(IntDir)\audio\"
-				/>
-			</FileConfiguration>
-		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\wrap_Music.h"
-			>
-		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\wrap_Sound.cpp"
-			>
-			<FileConfiguration
-				Name="Debug|Win32"
-				>
-				<Tool
-					Name="VCCLCompilerTool"
-					ObjectFile="$(IntDir)\audio\"
-				/>
-			</FileConfiguration>
-		</File>
-		<File
-			RelativePath="..\..\..\src\modules\audio\wrap_Sound.h"
-			>
-		</File>
 		<File
 			RelativePath="..\..\..\src\modules\audio\wrap_Source.cpp"
 			>

+ 0 - 152
platform/msvc2008/love.vcproj

@@ -182,14 +182,6 @@
 					RelativePath="..\..\src\modules\audio\Audio.h"
 					>
 				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\Music.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\Sound.h"
-					>
-				</File>
 				<File
 					RelativePath="..\..\src\modules\audio\Source.cpp"
 					>
@@ -238,54 +230,6 @@
 					RelativePath="..\..\src\modules\audio\wrap_Audio.h"
 					>
 				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\wrap_Music.cpp"
-					>
-					<FileConfiguration
-						Name="Debug|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							ObjectFile="$(IntDir)\audio\"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							ObjectFile="$(IntDir)\audio\"
-						/>
-					</FileConfiguration>
-				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\wrap_Music.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\wrap_Sound.cpp"
-					>
-					<FileConfiguration
-						Name="Debug|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							ObjectFile="$(IntDir)\audio\"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							ObjectFile="$(IntDir)\audio\"
-						/>
-					</FileConfiguration>
-				</File>
-				<File
-					RelativePath="..\..\src\modules\audio\wrap_Sound.h"
-					>
-				</File>
 				<File
 					RelativePath="..\..\src\modules\audio\wrap_Source.cpp"
 					>
@@ -337,30 +281,6 @@
 						RelativePath="..\..\src\modules\audio\openal\Audio.h"
 						>
 					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\openal\Music.cpp"
-						>
-						<FileConfiguration
-							Name="Debug|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\openal\"
-							/>
-						</FileConfiguration>
-						<FileConfiguration
-							Name="Release|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\openal\"
-							/>
-						</FileConfiguration>
-					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\openal\Music.h"
-						>
-					</File>
 					<File
 						RelativePath="..\..\src\modules\audio\openal\Pool.cpp"
 						>
@@ -385,30 +305,6 @@
 						RelativePath="..\..\src\modules\audio\openal\Pool.h"
 						>
 					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\openal\Sound.cpp"
-						>
-						<FileConfiguration
-							Name="Debug|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\openal\"
-							/>
-						</FileConfiguration>
-						<FileConfiguration
-							Name="Release|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\openal\"
-							/>
-						</FileConfiguration>
-					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\openal\Sound.h"
-						>
-					</File>
 					<File
 						RelativePath="..\..\src\modules\audio\openal\Source.cpp"
 						>
@@ -461,54 +357,6 @@
 						RelativePath="..\..\src\modules\audio\null\Audio.h"
 						>
 					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\null\Music.cpp"
-						>
-						<FileConfiguration
-							Name="Debug|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\null\"
-							/>
-						</FileConfiguration>
-						<FileConfiguration
-							Name="Release|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\null\"
-							/>
-						</FileConfiguration>
-					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\null\Music.h"
-						>
-					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\null\Sound.cpp"
-						>
-						<FileConfiguration
-							Name="Debug|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\null\"
-							/>
-						</FileConfiguration>
-						<FileConfiguration
-							Name="Release|Win32"
-							>
-							<Tool
-								Name="VCCLCompilerTool"
-								ObjectFile="$(IntDir)\audio\null\"
-							/>
-						</FileConfiguration>
-					</File>
-					<File
-						RelativePath="..\..\src\modules\audio\null\Sound.h"
-						>
-					</File>
 					<File
 						RelativePath="..\..\src\modules\audio\null\Source.cpp"
 						>

+ 1 - 17
platform/msvc2008/sound/sound.vcproj

@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="libmodplug.lib libmpg123.lib libogg.lib libvorbis.lib libvorbisfile.lib libFLAC_static_d.lib libFLAC++_static_d.lib"
+				AdditionalDependencies="libmodplug.lib libmpg123.lib libogg.lib libvorbis.lib libvorbisfile.lib"
 				OutputFile="$(OutDir)\love\$(ProjectName).dll"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories="..\lib"
@@ -188,22 +188,6 @@
 				RelativePath="..\..\..\src\modules\sound\lullaby\Decoder.h"
 				>
 			</File>
-			<File
-				RelativePath="..\..\..\src\modules\sound\lullaby\FLACDecoder.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)\sound\lullaby\"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\..\src\modules\sound\lullaby\FLACDecoder.h"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\modules\sound\lullaby\ModPlugDecoder.cpp"
 				>

+ 83 - 0
src/common/runtime.cpp

@@ -24,6 +24,7 @@
 #include "Module.h"
 #include "Object.h"
 #include "Reference.h"
+#include "StringMap.h"
 
 // STD
 #include <iostream>
@@ -50,6 +51,14 @@ namespace love
 		return 1;
 	}
 
+	static int w__typeOf(lua_State * L)
+	{
+		Proxy * p = (Proxy *)lua_touserdata(L, 1);
+		Type t = luax_type(L, 2);
+		luax_pushboolean(L, p->flags.at(t));
+		return 1;
+	}
+
 	Reference * luax_refif(lua_State * L, int type)
 	{
 		Reference * r = 0;
@@ -178,6 +187,15 @@ namespace love
 		lua_pushcclosure(L, w__tostring, 1);
 		lua_setfield(L, -2, "__tostring");
 
+		// Add tostring to as type() as well.
+		lua_pushstring(L, tname);
+		lua_pushcclosure(L, w__tostring, 1);
+		lua_setfield(L, -2, "type");
+
+		// Add typeOf
+		lua_pushcfunction(L, w__typeOf);
+		lua_setfield(L, -2, "typeOf");
+
 		if(f != 0)
 			luaL_register(L, 0, f);
 
@@ -316,5 +334,70 @@ namespace love
 		}
 	}
 
+	StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] = 
+	{
+		{"Invalid", INVALID_ID},
+
+		{"Object", OBJECT_ID},
+		{"Data", DATA_ID},
+		{"Module", MODULE_ID},
+
+		// Filesystem
+		{"File", FILESYSTEM_FILE_ID},
+		{"FileData", FILESYSTEM_FILE_DATA_ID},
+
+		// Font
+		{"GlyphData", FONT_GLYPH_DATA_ID},
+		{"Rasterizer", FONT_RASTERIZER_ID},
+
+		// Graphics
+		{"Drawable", GRAPHICS_DRAWABLE_ID},
+		{"Image", GRAPHICS_IMAGE_ID},
+		{"Quad", GRAPHICS_QUAD_ID},
+		{"Glyph", GRAPHICS_GLYPH_ID},
+		{"Font", GRAPHICS_FONT_ID},
+		{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
+		{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
+		{"VertexBuffer", GRAPHICS_VERTEX_BUFFER_ID},
+
+		// Image
+		{"ImageData", IMAGE_IMAGE_DATA_ID},
+
+		// Audio
+		{"Source", AUDIO_SOURCE_ID},
+
+		// Sound
+		{"SoundData", SOUND_SOUND_DATA_ID},
+		{"Decoder", SOUND_DECODER_ID},
+
+		// Physics
+		{"World", PHYSICS_WORLD_ID},
+		{"Contact", PHYSICS_CONTACT_ID},
+		{"Body", PHYSICS_BODY_ID},
+		{"Shape", PHYSICS_SHAPE_ID},
+		{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
+		{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
+		{"Joint", PHYSICS_JOINT_ID},
+		{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
+		{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
+		{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
+		{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
+		{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
+		{"GearJoint", PHYSICS_GEAR_JOINT_ID},
+
+		// The modules themselves. Only add abstracted modules here. 
+		{"filesystem", MODULE_FILESYSTEM_ID},
+		{"image", MODULE_IMAGE_ID},
+		{"sound", MODULE_SOUND_ID},
+	};
+
+	StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
+
+	Type luax_type(lua_State * L, int idx)
+	{
+		Type t = INVALID_ID;
+		types.find(luaL_checkstring(L, idx), t);
+		return t;
+	}
 
 } // love

+ 2 - 0
src/common/runtime.h

@@ -252,6 +252,8 @@ namespace love
 	**/
 	int luax_getregistry(lua_State * L, Registry r);
 
+	Type luax_type(lua_State * L, int idx);
+
 	/**
 	* Converts the value at idx to the specified type without checking that
 	* this conversion is valid. If the type has been previously verified with

+ 9 - 13
src/common/types.h

@@ -28,8 +28,9 @@ namespace love
 {
 	enum Type
 	{
+		INVALID_ID = 0,
 		// Cross-module types.
-		OBJECT_ID = 0,
+		OBJECT_ID,
 		DATA_ID,
 		MODULE_ID,
 
@@ -46,8 +47,6 @@ namespace love
 		GRAPHICS_IMAGE_ID,
 		GRAPHICS_QUAD_ID,
 		GRAPHICS_GLYPH_ID,
-		GRAPHICS_ANIMATION_ID,
-		GRAPHICS_COLOR_ID,
 		GRAPHICS_FONT_ID,
 		GRAPHICS_PARTICLE_SYSTEM_ID,
 		GRAPHICS_SPRITE_BATCH_ID,
@@ -57,9 +56,6 @@ namespace love
 		IMAGE_IMAGE_DATA_ID,
 
 		// Audio
-		AUDIO_AUDIBLE_ID,
-		AUDIO_SOUND_ID,
-		AUDIO_MUSIC_ID,
 		AUDIO_SOURCE_ID,
 
 		// Sound
@@ -87,10 +83,12 @@ namespace love
 		MODULE_SOUND_ID,
 
 		// Count the number of bits needed.
-		BIT_SIZE
+		TYPE_MAX_ENUM
 	};
 
-	typedef std::bitset<BIT_SIZE> bits;
+	typedef std::bitset<TYPE_MAX_ENUM> bits;
+
+	const bits INVALID_T = bits(1) << INVALID_ID;
 
 	const bits OBJECT_T = bits(1) << OBJECT_ID;
 	const bits DATA_T = (bits(1) << DATA_ID) | OBJECT_T;
@@ -108,8 +106,6 @@ namespace love
 	const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWABLE_T;
 	const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
 	const bits GRAPHICS_GLYPH_T = (bits(1) << GRAPHICS_GLYPH_ID) | GRAPHICS_DRAWABLE_T;
-	const bits GRAPHICS_ANIMATION_T = (bits(1) << GRAPHICS_ANIMATION_ID) | GRAPHICS_DRAWABLE_T;
-	const bits GRAPHICS_COLOR_T = (bits(1) << GRAPHICS_COLOR_ID) | OBJECT_T;
 	const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T;
 	const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
 	const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
@@ -119,9 +115,6 @@ namespace love
 	const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
 	
 	// Audio.
-	const bits AUDIO_AUDIBLE_T = (bits(1) << AUDIO_AUDIBLE_ID) | OBJECT_T;
-	const bits AUDIO_SOUND_T = (bits(1) << AUDIO_SOUND_ID) | AUDIO_AUDIBLE_T;
-	const bits AUDIO_MUSIC_T = (bits(1) << AUDIO_MUSIC_ID) | AUDIO_AUDIBLE_T;
 	const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
 
 	// Sound.
@@ -148,6 +141,9 @@ namespace love
 	const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T;
 	const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T;
 
+	bool getType(const char * in, Type & out);
+	bool getType(Type in, const char *& out);
+
 } // love
 
 #endif // LOVE_TYPES_H

+ 0 - 48
src/modules/audio/Audible.h

@@ -1,48 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_AUDIBLE_H
-#define LOVE_AUDIO_AUDIBLE_H
-
-// LOVE
-#include <common/Object.h>
-
-namespace love
-{
-namespace audio
-{
-	class Source;
-
-	class Audible : public Object
-	{
-	public:
-
-		virtual ~Audible(){};
-		virtual void play(Source * source) = 0;
-		virtual void update(Source * source) = 0;
-		virtual void stop(Source * source) = 0;
-		virtual void rewind(Source * source) = 0;
-		
-	}; // Audible
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_AUDIBLE_H

+ 8 - 42
src/modules/audio/Audio.h

@@ -23,11 +23,14 @@
 
 #include <common/Module.h>
 #include "Source.h"
-#include "Sound.h"
-#include "Music.h"
 
 namespace love
 {
+namespace sound
+{
+	class Decoder;
+	class SoundData;
+}
 namespace audio
 {
 	/**
@@ -42,26 +45,9 @@ namespace audio
 		**/
 		virtual ~Audio(){};
 
-		/**
-		* Creates a new Sound with the specified SoundData.
-		* @param data The SoundData from which to create the sound.
-		* @return A new Sound if successful, zero otherwise.
-		**/
-		virtual Sound * newSound(love::sound::SoundData * data) = 0;
-
-		/**
-		* Creates a new Music (stream) using the specified SoundData.
-		* @param decoder The object to use to decode the sound stream.
-		**/
-		virtual Music * newMusic(love::sound::Decoder * decoder) = 0;
-
-		/**
-		* Creates a new Source.
-		* @returns A new Source.
-		**/
-		virtual Source * newSource(Sound * sound) = 0;
-		virtual Source * newSource(Music * music) = 0;
-
+		virtual Source * newSource(love::sound::Decoder * decoder) = 0;
+		virtual Source * newSource(love::sound::SoundData * soundData) = 0;
+
 		/**
 		* Gets the current number of simulatenous playing sources.
 		* @return The current number of simulatenous playing sources.
@@ -80,26 +66,6 @@ namespace audio
 		**/
 		virtual void play(Source * source) = 0;
 
-		/**
-		* Plays one Sound on the specified Source. We need separate
-		* Sound and Music play functions because Music must be cloned, 
-		* whereas Sound needs not be.
-		* 
-		* @param sound The Sound to play.
-		* @param source The Source on which to play the Sound.
-		**/
-		virtual void play(Sound * sound) = 0;
-
-		/**
-		* Plays one Music on the specified Source. We need separate
-		* Sound and Music play functions because Music must be cloned, 
-		* whereas Sound needs not be.
-		* 
-		* @param music The Music to play.
-		* @param source The Source on which to play the Music.
-		**/
-		virtual void play(Music * music) = 0;
-
 		/**
 		* Stops playback on the specified source.
 		* @param source The source on which to stop the playback.

+ 0 - 63
src/modules/audio/Music.h

@@ -1,63 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_MUSIC_H
-#define LOVE_AUDIO_MUSIC_H
-
-// LOVE
-#include "Audible.h"
-#include <sound/Decoder.h>
-
-namespace love
-{
-namespace audio
-{
-	/**
-	* A Music object represents a stream of sound samples which are gradually
-	* acquired somehow. Compare with Sounds, which have all the needed sound
-	* samples pre-decoded.
-	* 
-	* Typically, you would want to use love::sound::Decoder to decode samples
-	* from some encoded format, like OGG or MP3, however, Music can come from 
-	* other sources as well. 
-	**/
-	class Music : public Audible
-	{
-	public:
-
-		/**
-		* Destructor.
-		**/
-		virtual ~Music(){};
-		
-		/**
-		* Creates a clone of the music stream. Music objects are gradually
-		* decoded, so if the client wants to play the same Music object, we can't
-		* use the same object. We must clone the entire stream.
-		* @return A clone of this object, but rewound to the start.
-		**/
-		virtual Music * clone() = 0;
-
-	}; // Music
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_MUSIC_H

+ 0 - 42
src/modules/audio/Sound.h

@@ -1,42 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_SOUND_H
-#define LOVE_AUDIO_SOUND_H
-
-// LOVE
-#include <sound/SoundData.h>
-#include "Audible.h"
-
-namespace love
-{
-namespace audio
-{
-	class Sound : public Audible
-	{
-	private:
-	public:
-		virtual ~Sound(){};
-	}; // Sound
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_SOUND_H

+ 14 - 29
src/modules/audio/Source.cpp

@@ -24,47 +24,32 @@ namespace love
 {
 namespace audio
 {
-	Source::Source()
-		: audible(0), looping(false)
+	Source::Source(Type type)
+		: type(type)
 	{
 	}
 
 	Source::~Source()
 	{
-		if(audible != 0)
-		{
-			audible->stop(this);
-			audible->release();
-		}
-	}
-
-	void Source::setAudible(Audible * audible)
+	}
+
+	bool Source::getConstant(const char * in, Type & out)
 	{
-		// If this source already has an audible, remove it.
-		if(this->audible != 0)
-		{
-			this->audible->stop(this);
-			this->audible->release();
-		}
-
-		this->audible = audible;
-		audible->retain();
+		return types.find(in, out);
 	}
 
-	Audible * Source::getAudible() const
-	{
-		return audible;
+	bool Source::getConstant(Type in, const char *& out)
+	{
+		return types.find(in, out);
 	}
 
-	void Source::setLooping(bool looping)
+	StringMap<Source::Type, Source::TYPE_MAX_ENUM>::Entry Source::typeEntries[] = 
 	{
-		this->looping = looping;
-	}
+		{"static", Source::TYPE_STATIC},
+		{"stream", Source::TYPE_STREAM},
+	};
 
-	bool Source::isLooping() const
-	{
-		return looping;
-	}
+	StringMap<Source::Type, Source::TYPE_MAX_ENUM> Source::types(Source::typeEntries, sizeof(Source::typeEntries));
 
 } // audio
 } // love

+ 26 - 8
src/modules/audio/Source.h

@@ -23,7 +23,7 @@
 
 // LOVE
 #include <common/Object.h>
-#include "Audible.h"
+#include <common/StringMap.h>
 
 namespace love
 {
@@ -31,14 +31,23 @@ namespace audio
 {
 	class Source : public Object
 	{
+	public:
+
+		enum Type
+		{
+			TYPE_STATIC = 1,
+			TYPE_STREAM,
+			TYPE_MAX_ENUM
+		}; // Type
+
 	protected:
-		Audible * audible;
-		bool looping;
+		Type type;
 	public:
-		Source();
+
+		Source(Type type);
 		virtual ~Source();
-		void setAudible(Audible * audible);
-		Audible * getAudible() const;
+
+		virtual Source * copy() = 0;
 		
 		virtual void play() = 0;
 		virtual void stop() = 0;
@@ -46,6 +55,7 @@ namespace audio
 		virtual void resume() = 0;
 		virtual void rewind() = 0;
 		virtual bool isStopped() const = 0;
+		virtual bool isFinished() const = 0;
 		virtual void update() = 0;
 
 		virtual void setPitch(float pitch) = 0;
@@ -62,8 +72,16 @@ namespace audio
 		virtual void setDirection(float * v) = 0;
 		virtual void getDirection(float * v) const = 0;
 		
-		void setLooping(bool looping);
-		bool isLooping() const;
+		virtual void setLooping(bool looping) = 0;
+		virtual bool isLooping() const = 0;
+
+		static bool getConstant(const char * in, Type & out);
+		static bool getConstant(Type in, const char *& out);
+
+	private:
+
+		static StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[];
+		static StringMap<Type, TYPE_MAX_ENUM> types;
 
 	}; // Source
 

+ 2 - 20
src/modules/audio/null/Audio.cpp

@@ -39,22 +39,12 @@ namespace null
 		return "love.audio.null";
 	}
 
-	love::audio::Sound * Audio::newSound(love::sound::SoundData * data)
-	{
-		return new Sound(data);
-	}
-
-	love::audio::Music * Audio::newMusic(love::sound::Decoder * decoder)
-	{
-		return new Music(decoder);
-	}
-
-	love::audio::Source * Audio::newSource(love::audio::Sound * sound)
+	love::audio::Source * Audio::newSource(love::sound::Decoder * decoder)
 	{
 		return new Source();
 	}
 
-	love::audio::Source * Audio::newSource(love::audio::Music * music)
+	love::audio::Source * Audio::newSource(love::sound::SoundData * soundData)
 	{
 		return new Source();
 	}
@@ -73,14 +63,6 @@ namespace null
 	{
 	}
 
-	void Audio::play(love::audio::Sound * sound)
-	{
-	}
-
-	void Audio::play(love::audio::Music * music)
-	{
-	}
-
 	void Audio::play()
 	{
 	}

+ 3 - 9
src/modules/audio/null/Audio.h

@@ -24,8 +24,6 @@
 // LOVE
 #include <audio/Audio.h>
 
-#include "Sound.h"
-#include "Music.h"
 #include "Source.h"
 
 namespace love
@@ -41,21 +39,17 @@ namespace null
 	public:
 
 		Audio();
-		~Audio();
+		virtual ~Audio();
 
 		// Implements Module.
 		const char * getName() const;
 
 		// Implements Audio.
-		love::audio::Sound * newSound(love::sound::SoundData * data);
-		love::audio::Music * newMusic(love::sound::Decoder * decoder);
-		love::audio::Source * newSource(love::audio::Sound * sound);
-		love::audio::Source * newSource(love::audio::Music * music);
+		love::audio::Source * newSource(love::sound::Decoder * decoder);
+		love::audio::Source * newSource(love::sound::SoundData * soundData);
 		int getNumSources() const;
 		int getMaxSources() const;
 		void play(love::audio::Source * source);
-		void play(love::audio::Sound * sound);
-		void play(love::audio::Music * music);
 		void play();
 		void stop(love::audio::Source * source);
 		void stop();

+ 0 - 63
src/modules/audio/null/Music.cpp

@@ -1,63 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Music.h"
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	Music::Music(love::sound::Decoder * decoder)
-		: decoder(decoder)
-	{
-		decoder->retain();
-	}
-
-	Music::~Music()
-	{
-		decoder->release();
-	}
-
-	love::audio::Music * Music::clone()
-	{
-		return new Music(decoder->clone());
-	}
-
-	void Music::play(love::audio::Source * s)
-	{
-	}
-
-	void Music::update(love::audio::Source * s)
-	{
-	}
-
-	void Music::stop(love::audio::Source * s)
-	{
-	}
-
-	void Music::rewind(love::audio::Source * s)
-	{
-	}
-
-} // null
-} // audio
-} // love

+ 0 - 57
src/modules/audio/null/Music.h

@@ -1,57 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_NULL_MUSIC_H
-#define LOVE_AUDIO_NULL_MUSIC_H
-
-// LOVE
-#include <audio/Music.h>
-#include <sound/Decoder.h>
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	class Music : public love::audio::Music
-	{
-	private:
-		love::sound::Decoder * decoder;
-	public:
-		Music(love::sound::Decoder * decoder);
-		virtual ~Music();
-		
-		// Implements Audible.
-		void play(love::audio::Source * source);
-		void update(love::audio::Source * source);
-		void stop(love::audio::Source * source);
-		void rewind(love::audio::Source * source);
-
-		// Implements Music.
-		love::audio::Music * clone();
-
-	}; // Music
-
-} // null
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_NULL_MUSIC_H

+ 0 - 55
src/modules/audio/null/Sound.cpp

@@ -1,55 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Sound.h"
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	Sound::Sound(love::sound::SoundData * data)
-	{
-	}
-
-	Sound::~Sound()
-	{
-	}
-
-	void Sound::play(love::audio::Source * s)
-	{
-	}
-
-	void Sound::update(love::audio::Source * s)
-	{
-	}
-
-	void Sound::stop(love::audio::Source * s)
-	{
-	}
-
-	void Sound::rewind(love::audio::Source * s)
-	{
-	}
-
-} // null
-} // audio
-} // love

+ 0 - 54
src/modules/audio/null/Sound.h

@@ -1,54 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_NULL_SOUND_H
-#define LOVE_AUDIO_NULL_SOUND_H
-
-// LOVE
-#include <sound/SoundData.h>
-#include <audio/Sound.h>
-
-namespace love
-{
-namespace audio
-{
-namespace null
-{
-	class Sound : public love::audio::Sound
-	{
-	private:
-
-	public:
-		Sound(love::sound::SoundData * data);
-		virtual ~Sound();
-
-		// Implements Audible.
-		void play(love::audio::Source * s);
-		void update(love::audio::Source * s);
-		void stop(love::audio::Source * s);
-		void rewind(love::audio::Source * s);
-
-	}; // Sound
-
-} // null
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_NULL_SOUND_H

+ 22 - 5
src/modules/audio/null/Source.cpp

@@ -28,18 +28,20 @@ namespace null
 {
 
 	Source::Source()
+		: love::audio::Source(Source::TYPE_STATIC)
 	{
 	}
 
-	Source::Source(Audible * audible)
-	{
-		setAudible(audible);
-	}
-
 	Source::~Source()
 	{
 	}
 
+	love::audio::Source * Source::copy()
+	{
+		this->retain();
+		return this;
+	}
+
 	void Source::play()
 	{
 	}
@@ -65,6 +67,11 @@ namespace null
 		return true;		
 	}
 
+	bool Source::isFinished() const
+	{
+		return true;		
+	}
+
 	void Source::update()
 	{
 	}
@@ -113,6 +120,16 @@ namespace null
 	{
 	}
 
+	void Source::setLooping(bool looping)
+	{
+		this->looping = looping;
+	}
+
+	bool Source::isLooping() const
+	{
+		return looping;
+	}
+
 } // null
 } // audio
 } // love

+ 23 - 22
src/modules/audio/null/Source.h

@@ -36,33 +36,34 @@ namespace null
 	private:
 
 		float pitch;
-		float volume; 
+		float volume;
+		bool looping;
 
 	public:
 		Source();
-		Source(Audible * audible);
 		virtual ~Source();
 		
-		void play();
-		void stop();
-		void pause();
-		void resume();
-		void rewind();
-		bool isStopped() const;
-		void update();
-
-		void setPitch(float pitch);
-		float getPitch() const;
-
-		void setVolume(float volume);
-		float getVolume() const;
-
-		void setPosition(float * v);
-		void getPosition(float * v) const;
-		void setVelocity(float * v);
-		void getVelocity(float * v) const;
-		void setDirection(float * v);
-		void getDirection(float * v) const;
+		virtual love::audio::Source * copy();	
+		virtual void play();
+		virtual void stop();
+		virtual void pause();
+		virtual void resume();
+		virtual void rewind();
+		virtual bool isStopped() const;
+		virtual bool isFinished() const;
+		virtual void update();
+		virtual void setPitch(float pitch);
+		virtual float getPitch() const;
+		virtual void setVolume(float volume);
+		virtual float getVolume() const;
+		virtual void setPosition(float * v);
+		virtual void getPosition(float * v) const;
+		virtual void setVelocity(float * v);
+		virtual void getVelocity(float * v) const;
+		virtual void setDirection(float * v);
+		virtual void getDirection(float * v) const;
+		void setLooping(bool looping);
+		bool isLooping() const;
 
 	}; // Source
 

+ 4 - 30
src/modules/audio/openal/Audio.cpp

@@ -82,24 +82,14 @@ namespace openal
 		return "love.audio.openal";
 	}
 
-	love::audio::Sound * Audio::newSound(love::sound::SoundData * data)
+	love::audio::Source * Audio::newSource(love::sound::Decoder * decoder)
 	{
-		return new Sound(pool, data);
+		return new Source(pool, decoder);
 	}
 
-	love::audio::Music * Audio::newMusic(love::sound::Decoder * decoder)
+	love::audio::Source * Audio::newSource(love::sound::SoundData * soundData)
 	{
-		return new Music(pool, decoder);
-	}
-
-	love::audio::Source * Audio::newSource(love::audio::Sound * sound)
-	{
-		return new Source(pool, sound);
-	}
-
-	love::audio::Source * Audio::newSource(love::audio::Music * music)
-	{
-		return new Source(pool, music->clone());
+		return new Source(pool, soundData);
 	}
 
 	int Audio::getNumSources() const
@@ -117,22 +107,6 @@ namespace openal
 		source->play();
 	}
 
-	void Audio::play(love::audio::Sound * sound)
-	{
-		Source * source = new Source(pool, sound);
-		play(source);
-		source->release();
-	}
-
-	void Audio::play(love::audio::Music * music)
-	{
-		love::audio::Music *cloned = music->clone();
-		Source * source = new Source(pool, cloned);
-		play(source);
-		cloned->release();
-		source->release();
-	}
-
 	void Audio::stop(love::audio::Source * source)
 	{
 		source->stop();

+ 2 - 8
src/modules/audio/openal/Audio.h

@@ -35,8 +35,6 @@
 #include <common/config.h>
 #include <sound/SoundData.h>
 
-#include "Sound.h"
-#include "Music.h"
 #include "Source.h"
 #include "Pool.h"
 
@@ -86,15 +84,11 @@ namespace openal
 		const char * getName() const;
 
 		// Implements Audio.
-		love::audio::Sound * newSound(love::sound::SoundData * data);
-		love::audio::Music * newMusic(love::sound::Decoder * decoder);
-		love::audio::Source * newSource(love::audio::Sound * sound);
-		love::audio::Source * newSource(love::audio::Music * music);
+		love::audio::Source * newSource(love::sound::Decoder * decoder);
+		love::audio::Source * newSource(love::sound::SoundData * soundData);
 		int getNumSources() const;
 		int getMaxSources() const;
 		void play(love::audio::Source * source);
-		void play(love::audio::Sound * sound);
-		void play(love::audio::Music * music);
 		void play();
 		void stop(love::audio::Source * source);
 		void stop();

+ 0 - 134
src/modules/audio/openal/Music.cpp

@@ -1,134 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Music.h"
-
-// STD
-#include <iostream>
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	Music::Music(Pool * pool, love::sound::Decoder * decoder)
-		: pool(pool), decoder(decoder), source(0)
-	{
-		decoder->retain();
-		alGenBuffers(NUM_BUFFERS, buffers);
-	}
-
-	Music::~Music()
-	{
-		decoder->release();
-		alDeleteBuffers(NUM_BUFFERS, buffers);
-	}
-
-	love::audio::Music * Music::clone()
-	{
-		return new Music(pool, decoder->clone());
-	}
-
-	void Music::play(love::audio::Source * s)
-	{
-		source = pool->find(s);
-
-		if(source)
-		{
-			for(int i = 0; i < NUM_BUFFERS; i++)
-			{
-				if(!stream(s, buffers[i]))
-				{
-					std::cout << "Could not stream music." << std::endl;
-					return;
-				}
-			}
-
-			alSourceQueueBuffers(source, NUM_BUFFERS, buffers);
-		}
-	}
-
-	void Music::update(love::audio::Source * s)
-	{
-		if(source)
-		{
-			// Number of processed buffers.
-			ALint processed;
-
-			alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
-
-			while(processed--)
-			{
-				ALuint buffer;
-
-				// Get a free buffer.
-				alSourceUnqueueBuffers(source, 1, &buffer);
-
-				if(stream(s, buffer))
-					alSourceQueueBuffers(source, 1, &buffer);
-			}
-		}
-	}
-
-	void Music::stop(love::audio::Source * s)
-	{
-		if(source)
-		{
-			ALuint bufs[NUM_BUFFERS];
-			alSourceStop(source);
-			alSourceUnqueueBuffers(source, NUM_BUFFERS, bufs);
-			source = 0;
-			rewind(s);
-		}
-	}
-
-	void Music::rewind(love::audio::Source * s)
-	{
-		decoder->rewind();
-	}
-
-	bool Music::stream(love::audio::Source * source, ALuint buffer)
-	{
-		if(source->isLooping() && decoder->isFinished())
-			decoder->rewind();		
-
-		// Get more sound data.
-		int decoded = decoder->decode();
-
-		int fmt = pool->getFormat(decoder->getChannels(), decoder->getBits());
-
-		if(fmt == 0)
-			return false;
-
-		if(decoded > 0)
-		{
-			alBufferData(buffer, fmt, decoder->getBuffer(), 
-				decoder->getSize(), decoder->getSampleRate());
-			return true;
-
-		}
-		return false;
-	}
-
-
-} // openal
-} // audio
-} // love

+ 0 - 79
src/modules/audio/openal/Music.h

@@ -1,79 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_OPENAL_MUSIC_H
-#define LOVE_AUDIO_OPENAL_MUSIC_H
-
-// LOVE
-#include <audio/Music.h>
-#include <common/config.h>
-#include <sound/Decoder.h>
-#include "Pool.h"
-
-// OpenAL
-#ifdef LOVE_MACOSX
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#else
-#include <AL/alc.h>
-#include <AL/al.h>
-#endif
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-
-	// Forward declarations.
-	class Audio;
-
-	class Music : public love::audio::Music
-	{
-	private:
-		static const unsigned int NUM_BUFFERS = 32;
-		ALuint buffers[NUM_BUFFERS];
-		Pool * pool;
-		love::sound::Decoder * decoder;
-		ALuint source;
-
-	public:
-		Music(Pool * pool, love::sound::Decoder * decoder);
-		virtual ~Music();
-
-		// Implements Audible.
-		void play(love::audio::Source * source);
-		void update(love::audio::Source * source);
-		void stop(love::audio::Source * source);
-		void rewind(love::audio::Source * source);
-
-		// Implements Music.
-		love::audio::Music * clone();
-
-	private:
-		bool stream(love::audio::Source * source, ALuint buffer);
-	}; // Sound
-
-} // openal
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_OPENAL_MUSIC_H

+ 123 - 60
src/modules/audio/openal/Pool.cpp

@@ -20,6 +20,8 @@
 
 #include "Pool.h"
 
+#include "Source.h"
+
 #define MUTEX_ASSERT(fn, sval) \
 	if(fn != sval) \
 	{ \
@@ -62,20 +64,6 @@ namespace openal
 		alDeleteSources(NUM_SOURCES, sources);
 	}
 
-	ALenum Pool::getFormat(int channels, int bits) const
-	{
-		if(channels == 1 && bits == 8)
-			return AL_FORMAT_MONO8;
-		else if(channels == 1 && bits == 16)
-			return AL_FORMAT_MONO16;
-		else if(channels == 2 && bits == 8)
-			return AL_FORMAT_STEREO8;
-		else if(channels == 2 && bits == 16)
-			return AL_FORMAT_STEREO16;
-		else
-			return 0;
-	}
-
 	bool Pool::isAvailable() const
 	{
 		bool has = false;
@@ -85,42 +73,11 @@ namespace openal
 		return has;
 	}
 
-	ALuint Pool::claim(love::audio::Source * source)
-	{
-		ALuint s = 0;
-		LOCK(mutex);
-		if(!available.empty())
-		{
-			// Get the first available source.
-			s = available.front();
-
-			// Remove it.
-			available.pop();
-
-			// Insert into map of playing sources.
-			playing.insert(std::pair<love::audio::Source *, ALuint>(source, s));
-
-			source->retain();
-		}
-		UNLOCK(mutex);
-
-		return s;
-	}
-
-	ALuint Pool::find(const love::audio::Source * source) const
-	{
-		ALuint r = 0;
-		LOCK(mutex);
-		r = findi(source);
-		UNLOCK(mutex);
-		return r;
-	}
-
-	bool Pool::isPlaying(love::audio::Source * s)
+	bool Pool::isPlaying(Source * s)
 	{
 		bool p = false;
 		LOCK(mutex);
-		for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
 		{
 			if(i->first == s)
 				p = true;
@@ -133,13 +90,13 @@ namespace openal
 	{
 		LOCK(mutex);
 
-		std::map<love::audio::Source *, ALuint>::iterator i = playing.begin();
+		std::map<Source *, ALuint>::iterator i = playing.begin();
 	
 		while(i != playing.end())
 		{
 			if(i->first->isStopped())
 			{
-				i->first->stop();
+				i->first->stopAtomic();
 				i->first->release();
 				available.push(i->second);
 				playing.erase(i++);
@@ -164,12 +121,56 @@ namespace openal
 		return NUM_SOURCES;
 	}
 
+	bool Pool::play(Source * source, ALuint & out)
+	{
+		bool ok;
+		out = 0;
+
+		LOCK(mutex);
+
+		bool alreadyPlaying = findSource(source, out);
+
+		if(!alreadyPlaying)
+		{
+			// Try to play.
+			if(!available.empty())
+			{
+				// Get the first available source.
+				out = available.front();
+
+				// Remove it.
+				available.pop();
+
+				// Insert into map of playing sources.
+				playing.insert(std::pair<Source *, ALuint>(source, out));
+
+				source->retain();
+
+				source->playAtomic();
+
+				ok = true;
+			}
+			else
+			{
+				ok = false;
+			}
+		}
+		else
+		{
+			ok = true;
+		}
+
+		UNLOCK(mutex);
+
+		return ok;
+	}
+
 	void Pool::stop()
 	{
 		LOCK(mutex);
-		for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+		for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
 		{
-			i->first->stop();
+			i->first->stopAtomic();
 			available.push(i->second);
 		}
 
@@ -178,31 +179,65 @@ namespace openal
 		UNLOCK(mutex);
 	}
 
+	void Pool::stop(Source * source)
+	{
+		LOCK(mutex);
+		removeSource(source);
+		UNLOCK(mutex);
+	}
+
 	void Pool::pause()
 	{
 		LOCK(mutex);
-		for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->pause();
+		for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+			i->first->pauseAtomic();
+		UNLOCK(mutex);
+	}
+
+	void Pool::pause(Source * source)
+	{
+		LOCK(mutex);
+		ALuint out;
+		if(findSource(source, out))
+			source->pauseAtomic();
 		UNLOCK(mutex);
 	}
 
 	void Pool::resume()
 	{
 		LOCK(mutex);
-		for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->resume();
+		for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+			i->first->resumeAtomic();
+		UNLOCK(mutex);
+	}
+
+	void Pool::resume(Source * source)
+	{
+		LOCK(mutex);
+		ALuint out;
+		if(findSource(source, out))
+			source->resumeAtomic();
 		UNLOCK(mutex);
 	}
 
 	void Pool::rewind()
 	{
 		LOCK(mutex);
-		for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
-			i->first->rewind();
+		for(std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
+			i->first->rewindAtomic();
 		UNLOCK(mutex);
 	}
 
-	void Pool::release(love::audio::Source * source)
+	void Pool::rewind(Source * source)
+	{
+		LOCK(mutex);
+		ALuint out;
+		if(findSource(source, out))
+			source->rewindAtomic();
+		UNLOCK(mutex);
+	}
+
+	void Pool::release(Source * source)
 	{
 		ALuint s = findi(source);
 
@@ -213,9 +248,9 @@ namespace openal
 		}
 	}
 
-	ALuint Pool::findi(const love::audio::Source * source) const
+	ALuint Pool::findi(const Source * source) const
 	{
-		std::map<love::audio::Source *, ALuint>::const_iterator i = playing.find((love::audio::Source *)source);
+		std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
 
 		if(i != playing.end())
 			return i->second;
@@ -223,6 +258,34 @@ namespace openal
 		return 0;
 	}
 
+	bool Pool::findSource(Source * source, ALuint & out)
+	{
+		std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
+
+		bool found = i != playing.end();
+
+		if(found)
+			out = i->second;
+
+		return found;
+	}
+
+	bool Pool::removeSource(Source * source)
+	{
+		std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
+
+		if(i != playing.end())
+		{
+			source->stopAtomic();
+			source->release();
+			available.push(i->second);
+			playing.erase(i++);
+			return true;
+		}
+
+		return false;
+	}
+
 } // openal
 } // audio
 } // love

+ 15 - 23
src/modules/audio/openal/Pool.h

@@ -31,7 +31,6 @@
 #include <SDL.h>
 
 // LOVE
-#include <audio/Source.h>
 #include <common/config.h>
 #include <common/Exception.h>
 
@@ -50,6 +49,9 @@ namespace audio
 {
 namespace openal
 {
+
+	class Source;
+
 	class Pool
 	{
 	private:
@@ -64,7 +66,7 @@ namespace openal
 		std::queue<ALuint> available;
 
 		// A map of playing sources.
-		std::map<love::audio::Source *, ALuint> playing;
+		std::map<Source *, ALuint> playing;
 
 		// Only one thread can access this object at the same time. This mutex will
 		// make sure of that.
@@ -75,15 +77,6 @@ namespace openal
 		Pool();
 		~Pool();
 
-		/**
-		* Gets the OpenAL format identifier based on number of
-		* channels and bits.
-		* @param channels Either 1 (mono) or 2 (stereo). 
-		* @param bits Either 8-bit samples, or 16-bit samples.
-		* @return One of AL_FORMAT_*, or 0 if unsupported format.
-		**/
-		ALenum getFormat(int channels, int bits) const;
-
 		/**
 		* Checks whether an OpenAL source is available.
 		* @return True if at least one is available, false otherwise.
@@ -93,26 +86,22 @@ namespace openal
 		/**
 		* Checks whether a Source is currently in the playing list.
 		**/
-		bool isPlaying(love::audio::Source * s);
-
-		/**
-		* Returns an available OpenAL source identifier, or 0 if
-		* none is available.
-		* @return An OpenAL source ID, or 0 if unavailable.
-		**/
-		ALuint claim(love::audio::Source * source);
-
-		ALuint find(const love::audio::Source * source) const;
+		bool isPlaying(Source * s);
 
 		void update();
 
 		int getNumSources() const;
 		int getMaxSources() const;
 
+		bool play(Source * source, ALuint & out);
 		void stop();
+		void stop(Source * source);
 		void pause();
+		void pause(Source * source);
 		void resume();
+		void resume(Source * source);
 		void rewind();
+		void rewind(Source * source);
 
 	private:
 
@@ -120,9 +109,12 @@ namespace openal
 		* Makes the specified OpenAL source available for use.
 		* @param source The OpenAL source.
 		**/
-		void release(love::audio::Source * source);
+		void release(Source * source);
+
+		ALuint findi(const Source * source) const;
 
-		ALuint findi(const love::audio::Source * source) const;
+		bool findSource(Source * source, ALuint & out);
+		bool removeSource(Source * source);
 	}; // Pool
 
 } // openal

+ 0 - 87
src/modules/audio/openal/Sound.cpp

@@ -1,87 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "Sound.h"
-
-#include <common/Exception.h>
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	Sound::Sound(Pool * pool, love::sound::SoundData * data)
-		: pool(pool), buffer(0), source(source)
-	{
-		
-		// Generate the buffer.
-		alGenBuffers(1, &buffer);
-
-		int fmt = pool->getFormat(data->getChannels(), data->getBits());
-
-		if(fmt == 0)
-			throw love::Exception("Unsupported audio format.");
-
-		alBufferData(buffer, fmt, data->getData(), data->getSize(), data->getSampleRate());
-
-		// Note: we're done with the sound data
-		// at this point. No need to retain.
-	}
-
-	Sound::~Sound()
-	{
-		if(buffer)
-			alDeleteBuffers(1, &buffer);
-	}
-
-	void Sound::play(love::audio::Source * s)
-	{
-		// Set the buffer for the sound.
-		source = pool->find(s);
-
-		if(source)
-		{
-			alSourcei(source, AL_BUFFER, buffer);
-			alSourcei(source, AL_LOOPING, s->isLooping() ? AL_TRUE : AL_FALSE);
-		}
-	}
-
-	void Sound::update(love::audio::Source * s)
-	{
-		// Looping mode could have changed.
-		alSourcei(source, AL_LOOPING, s->isLooping() ? AL_TRUE : AL_FALSE);
-	}
-
-	void Sound::stop(love::audio::Source * s)
-	{
-		if(source)
-			alSourceStop(source);
-	}
-
-	void Sound::rewind(love::audio::Source * s)
-	{
-		if(source)
-			alSourceRewind(source);
-	}
-
-} // openal
-} // audio
-} // love

+ 0 - 77
src/modules/audio/openal/Sound.h

@@ -1,77 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_OPENAL_SOUND_H
-#define LOVE_AUDIO_OPENAL_SOUND_H
-
-// LOVE
-#include <sound/SoundData.h>
-#include <audio/Sound.h>
-#include <common/config.h>
-#include "Pool.h"
-
-
-
-// OpenAL
-#ifdef LOVE_MACOSX
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#else
-#include <AL/alc.h>
-#include <AL/al.h>
-#endif
-
-namespace love
-{
-namespace audio
-{
-namespace openal
-{
-	// Forward declarations.
-	class Audio;
-
-	class Sound : public love::audio::Sound
-	{
-	private:
-	
-		Pool * pool;
-
-		// Sounds only need one buffer.
-		ALuint buffer;
-
-		ALuint source;
-
-	public:
-		Sound(Pool * pool, love::sound::SoundData * data);
-		virtual ~Sound();
-
-		// Implements Audible.
-		void play(love::audio::Source * s);
-		void update(love::audio::Source * s);
-		void stop(love::audio::Source * s);
-		void rewind(love::audio::Source * s);
-
-	}; // Sound
-
-} // openal
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_OPENAL_SOUND_H

+ 212 - 56
src/modules/audio/openal/Source.cpp

@@ -20,6 +20,8 @@
 
 #include "Source.h"
 
+#include "Pool.h"
+
 // STD
 #include <iostream>
 
@@ -30,107 +32,116 @@ namespace audio
 namespace openal
 {
 
-	Source::Source(Pool * pool)
-		: pool(pool), source(0), pitch(1.0f), volume(1.0f)
+	static int acc = 0;
+
+	Source::Source(Pool * pool, love::sound::SoundData * soundData)
+		: love::audio::Source(Source::TYPE_STATIC), pool(pool), pitch(1.0f), 
+		volume(1.0f), looping(false), decoder(0), valid(false)
 	{
+		alGenBuffers(1, buffers);
+		ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits());
+		alBufferData(buffers[0], fmt, soundData->getData(), soundData->getSize(), soundData->getSampleRate());
 	}
 
-	Source::Source(Pool * pool, Audible * audible)
-		: pool(pool), source(0), pitch(1.0f), volume(1.0f)
+	Source::Source(Pool * pool, love::sound::Decoder * decoder)
+		: love::audio::Source(Source::TYPE_STREAM), pool(pool), pitch(1.0f), 
+		volume(1.0f), looping(false), decoder(decoder), valid(false)
 	{
-		setAudible(audible);
+		decoder->retain();
+		alGenBuffers(MAX_BUFFERS, buffers);
 	}
 
 	Source::~Source()
 	{
 		stop();
+		alDeleteBuffers((type == TYPE_STATIC) ? 1 : MAX_BUFFERS, buffers);
+	}
+
+	love::audio::Source * Source::copy()
+	{
+		return 0;
 	}
 
 	void Source::play()
 	{
-		if(source != 0)
-			return; // Already playing.
-
-		if(pool->isAvailable())
-			source = pool->claim(this);
-
-		if(source != 0)
-		{
-			audible->play(this);
-
-			// Set these properties. These may have changed while we've
-			// been without an AL source.
-			alSourcef(source, AL_PITCH, pitch);
-			alSourcef(source, AL_GAIN, volume);
-
-			alSourcePlay(source);
-		}
-
+		valid = pool->play(this, source);
 	}
-
+
 	void Source::stop()
 	{
-		if(source)
-		{
-			alSourceStop(source);
-			audible->stop(this);
-			source = 0;
-		}
+		pool->stop(this);
 	}
 
 	void Source::pause()
 	{
-		if(source)
-		{
-			alSourcePause(source);
-		}
+		pool->pause();
 	}
 
 	void Source::resume()
 	{
-		if(source)
-		{
-			alSourcePlay(source);
-		}
+		pool->resume();
 	}
 
 	void Source::rewind()
 	{
-		if(audible != 0)
-			audible->rewind(this);	
+		pool->rewind();
 	}
 
 	bool Source::isStopped() const
 	{
-		if(source)
+		if(valid)
 		{
 			ALenum state;
 			alGetSourcei(source, AL_SOURCE_STATE, &state);
 			return (state == AL_STOPPED);
 		}
 
-		return true;		
+		return true;
+	}
+
+	bool Source::isFinished() const
+	{
+		return type == TYPE_STATIC ? isStopped() : isStopped() && !isLooping() && decoder->isFinished();
 	}
 
 	void Source::update()
 	{
-		if(audible != 0)
-			audible->update(this);
+		if(valid && type == TYPE_STATIC)
+		{
+			// Looping mode could have changed.
+			alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
+		}
+		else if(valid && type == TYPE_STREAM)
+		{
+			// Number of processed buffers.
+			ALint processed;
+
+			alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+
+			while(processed--)
+			{
+				ALuint buffer;
+
+				// Get a free buffer.
+				alSourceUnqueueBuffers(source, 1, &buffer);
+
+				if(streamAtomic(buffer, decoder) > 0)
+					alSourceQueueBuffers(source, 1, &buffer);
+			}
+		}
 	}
 
 	void Source::setPitch(float pitch)
 	{
-		if(source)
-		{
+		if(valid)
 			alSourcef(source, AL_PITCH, pitch);
-		}
 
 		this->pitch = pitch;
 	}
 
 	float Source::getPitch() const
 	{
-		if(source)
+		if(valid)
 		{
 			ALfloat f;
 			alGetSourcef(source, AL_PITCH, &f);
@@ -143,7 +154,7 @@ namespace openal
 
 	void Source::setVolume(float volume)
 	{
-		if(source)
+		if(valid)
 		{
 			alSourcef(source, AL_GAIN, volume);
 		}
@@ -153,7 +164,7 @@ namespace openal
 
 	float Source::getVolume() const
 	{
-		if(source)
+		if(valid)
 		{
 			ALfloat f;
 			alGetSourcef(source, AL_GAIN, &f);
@@ -166,40 +177,185 @@ namespace openal
 
 	void Source::setPosition(float * v)
 	{
-		if(source)
+		if(valid)
 			alSourcefv(source, AL_POSITION, v);
 	}
 
 	void Source::getPosition(float * v) const
 	{
-		if(source)
+		if(valid)
 			alGetSourcefv(source, AL_POSITION, v);
 	}
 
 	void Source::setVelocity(float * v)
 	{
-		if(source)
+		if(valid)
 			alSourcefv(source, AL_VELOCITY, v);
 	}
 
 	void Source::getVelocity(float * v) const
 	{
-		if(source)
+		if(valid)
 			alGetSourcefv(source, AL_VELOCITY, v);
 	}
 
 	void Source::setDirection(float * v)
 	{
-		if(source)
+		if(valid)
 			alSourcefv(source, AL_DIRECTION, v);
 	}
 
 	void Source::getDirection(float * v) const
 	{
-		if(source)
+		if(valid)
 			alGetSourcefv(source, AL_DIRECTION, v);
 	}
 
+	void Source::setLooping(bool looping)
+	{
+		this->looping = looping;
+	}
+
+	bool Source::isLooping() const
+	{
+		return looping;
+	}
+
+	void Source::playAtomic()
+	{
+		if(type == TYPE_STATIC)
+		{
+			alSourcei(source, AL_BUFFER, buffers[0]);
+			alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
+		}
+		else if(type == TYPE_STREAM)
+		{
+			int usedBuffers = 0;
+
+			for(int i = 0; i < MAX_BUFFERS; i++)
+			{
+				int decoded = streamAtomic(buffers[i], decoder);
+				++usedBuffers;
+				if(decoded < decoder->getSize())
+					break;
+			}
+
+			if(usedBuffers > 0)
+				alSourceQueueBuffers(source, usedBuffers, buffers);
+		}
+
+		// Set these properties. These may have changed while we've
+		// been without an AL source.
+		alSourcef(source, AL_PITCH, pitch);
+		alSourcef(source, AL_GAIN, volume);
+
+		alSourcePlay(source);
+	}
+
+	void Source::stopAtomic()
+	{
+		if(valid)
+		{
+			if(type == TYPE_STATIC)
+			{
+				alSourceStop(source);
+			}
+			else if(type == TYPE_STREAM)
+			{
+				alSourceStop(source);
+
+				int queued = 0;
+				alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
+
+				while(queued--)
+				{
+					ALuint buffer;
+					alSourceUnqueueBuffers(source, 1, &buffer);
+				}
+			}
+
+			reset(source);
+		}
+		rewindAtomic();
+		valid = false;
+	}
+
+	void Source::pauseAtomic()
+	{
+		if(valid)
+		{
+			alSourcePause(source);
+		}
+	}
+
+	void Source::resumeAtomic()
+	{
+		if(valid)
+		{
+			alSourcePlay(source);
+		}
+	}
+
+	void Source::rewindAtomic()
+	{
+		if(valid && type == TYPE_STATIC)
+		{
+			alSourceRewind(source);
+		}
+		else if(valid && type == TYPE_STREAM)
+		{
+			decoder->rewind();
+		}
+	}
+
+	void Source::reset(ALenum source)
+	{
+		alSourcei(source, AL_BUFFER, AL_NONE);
+	}
+
+	ALenum Source::getFormat(int channels, int bits) const
+	{
+		if(channels == 1 && bits == 8)
+			return AL_FORMAT_MONO8;
+		else if(channels == 1 && bits == 16)
+			return AL_FORMAT_MONO16;
+		else if(channels == 2 && bits == 8)
+			return AL_FORMAT_STEREO8;
+		else if(channels == 2 && bits == 16)
+			return AL_FORMAT_STEREO16;
+		else
+			return 0;
+	}
+
+	int Source::streamAtomic(ALuint buffer, love::sound::Decoder * d)
+	{
+		//if(isLooping() && d->isFinished())
+		//	d->rewind();
+
+		// Get more sound data.
+		int decoded = d->decode();
+
+		int fmt = getFormat(d->getChannels(), d->getBits());
+
+		//printf("Decoded %i ( %i )", decoded, d->getSize());
+
+		if(decoded > 0 && fmt != 0)
+		{
+			alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate());
+			acc++;
+			//printf(" [%i] ", acc);
+		}
+
+		if(decoded < d->getSize() && isLooping())
+		{
+			printf(" Rewinding at %i.\n", acc);
+			d->rewind();
+			acc = 0;
+		}
+
+		return decoded;
+	}
+
 } // openal
 } // audio
 } // love

+ 54 - 24
src/modules/audio/openal/Source.h

@@ -25,7 +25,8 @@
 #include <common/config.h>
 #include <common/Object.h>
 #include <audio/Source.h>
-#include "Pool.h"
+#include <sound/SoundData.h>
+#include <sound/Decoder.h>
 
 // OpenAL
 #ifdef LOVE_MACOSX
@@ -43,6 +44,7 @@ namespace audio
 namespace openal
 {
 	class Audio;
+	class Pool;
 
 	class Source : public love::audio::Source
 	{
@@ -50,35 +52,63 @@ namespace openal
 
 		Pool * pool;
 		ALuint source;
+		bool valid;
+		static const unsigned int MAX_BUFFERS = 32;
+		ALuint buffers[MAX_BUFFERS];
 
 		float pitch;
-		float volume; 
+		float volume;
+		bool looping;
+
+		love::sound::Decoder * decoder;
 
 	public:
-		Source(Pool * pool);
-		Source(Pool * pool, Audible * audible);
+		Source(Pool * pool, love::sound::SoundData * soundData);
+		Source(Pool * pool, love::sound::Decoder * decoder);
 		virtual ~Source();
 		
-		void play();
-		void stop();
-		void pause();
-		void resume();
-		void rewind();
-		bool isStopped() const;
-		void update();
-
-		void setPitch(float pitch);
-		float getPitch() const;
-
-		void setVolume(float volume);
-		float getVolume() const;
-
-		void setPosition(float * v);
-		void getPosition(float * v) const;
-		void setVelocity(float * v);
-		void getVelocity(float * v) const;
-		void setDirection(float * v);
-		void getDirection(float * v) const;
+		virtual love::audio::Source * copy();	
+		virtual void play();
+		virtual void stop();
+		virtual void pause();
+		virtual void resume();
+		virtual void rewind();
+		virtual bool isStopped() const;
+		virtual bool isFinished() const;
+		virtual void update();
+		virtual void setPitch(float pitch);
+		virtual float getPitch() const;
+		virtual void setVolume(float volume);
+		virtual float getVolume() const;
+		virtual void setPosition(float * v);
+		virtual void getPosition(float * v) const;
+		virtual void setVelocity(float * v);
+		virtual void getVelocity(float * v) const;
+		virtual void setDirection(float * v);
+		virtual void getDirection(float * v) const;
+		void setLooping(bool looping);
+		bool isLooping() const;
+
+		void playAtomic();
+		void stopAtomic();
+		void pauseAtomic();
+		void resumeAtomic();
+		void rewindAtomic();
+
+	private:
+
+		void reset(ALenum source);
+
+		/**
+		* Gets the OpenAL format identifier based on number of
+		* channels and bits.
+		* @param channels Either 1 (mono) or 2 (stereo). 
+		* @param bits Either 8-bit samples, or 16-bit samples.
+		* @return One of AL_FORMAT_*, or 0 if unsupported format.
+		**/
+		ALenum getFormat(int channels, int bits) const;
+
+		int streamAtomic(ALuint buffer, love::sound::Decoder * d);
 
 	}; // Source
 

+ 24 - 71
src/modules/audio/wrap_Audio.cpp

@@ -24,6 +24,8 @@
 #include "openal/Audio.h"
 #include "null/Audio.h"
 
+#include <scripts/audio.lua.h>
+
 namespace love
 {
 namespace audio
@@ -36,81 +38,31 @@ namespace audio
 		return 1;
 	}
 
-	int w_newSound(lua_State * L)
-	{
-		// Convert to File, if necessary.
-		if(lua_isstring(L, 1))
-			luax_convobj(L, 1, "filesystem", "newFile");
-
-		// Convert to SoundData, if necessary.
-		if(luax_istype(L, 1, FILESYSTEM_FILE_T))
-			luax_convobj(L, 1, "sound", "newSoundData");
-
-		love::sound::SoundData * data = luax_checktype<love::sound::SoundData>(L, 1, "SoundData", SOUND_SOUND_DATA_T);
-		Sound * t = instance->newSound(data);
-		luax_newtype(L, "Sound", AUDIO_SOUND_T, (void*)t);
-		return 1;
-	}
-
-
-	int w_newMusic(lua_State * L)
-	{
-		// Convert to Decoder, if necessary.
-		if(!luax_istype(L, 1, SOUND_DECODER_T))
-			luax_convobj(L, 1, "sound", "newDecoder");
-
-		love::sound::Decoder * decoder = luax_checktype<love::sound::Decoder>(L, 1, "Decoder", SOUND_DECODER_T);
-		Music * t = instance->newMusic(decoder);
-		luax_newtype(L, "Music", AUDIO_MUSIC_T, (void*)t);
-		return 1;
-	}
-
-	int w_newSource(lua_State * L)
+	int w_newSource1(lua_State * L)
 	{
 		Source * t = 0;
 
-		if(luax_istype(L, 1, AUDIO_SOUND_T))
-		{
-			Sound * s = luax_checksound(L, 1);
-			t = instance->newSource(s);
-		} 
-		else if(luax_istype(L, 1, AUDIO_MUSIC_T))
+		if(luax_istype(L, 1, SOUND_SOUND_DATA_T))
+			t = instance->newSource(luax_totype<love::sound::SoundData>(L, 1, "SoundData", SOUND_SOUND_DATA_T));
+		else if(luax_istype(L, 1, SOUND_DECODER_T))
+			t = instance->newSource(luax_totype<love::sound::Decoder>(L, 1, "Decoder", SOUND_DECODER_T));
+
+		if(t)
 		{
-			Music * m = luax_checkmusic(L, 1);
-			t = instance->newSource(m);
+			luax_newtype(L, "Source", AUDIO_SOURCE_T, (void*)t);
+			return 1;
 		}
-
-		if(!t)
+		else
 			return luaL_error(L, "No matching overload");
-
-		luax_newtype(L, "Source", AUDIO_SOURCE_T, (void*)t);
-		return 1;
+			
+		return 0;
 	}
 
 	int w_play(lua_State * L)
 	{
-		int argn = lua_gettop(L);
-
-		if(luax_istype(L, 1, AUDIO_SOUND_T))
-		{
-			Sound * s = luax_checksound(L, 1);
-			instance->play(s);
-			return 0;
-		} 
-		else if(luax_istype(L, 1, AUDIO_MUSIC_T))
-		{
-			Music * m = luax_checkmusic(L, 1);
-			instance->play(m);
-			return 0;
-		}
-		else if(luax_istype(L, 1, AUDIO_SOURCE_T))
-		{
-			Source * s = luax_checksource(L, 1);
-			instance->play(s);
-			return 0;
-		}
-
-		return luaL_error(L, "No matching overload");
+		Source * s = luax_checksource(L, 1);
+		instance->play(s);
+		return 0;
 	}
 
 	int w_stop(lua_State * L)
@@ -252,9 +204,7 @@ namespace audio
 	// List of functions to wrap.
 	static const luaL_Reg functions[] = {
 		{ "getNumSources", w_getNumSources },
-		{ "newSound", w_newSound },
-		{ "newMusic", w_newMusic },
-		{ "newSource", w_newSource },
+		{ "newSource1", w_newSource1 },
 		{ "play", w_play },
 		{ "stop", w_stop },
 		{ "pause", w_pause },
@@ -273,8 +223,6 @@ namespace audio
 
 	static const lua_CFunction types[] = {
 		luaopen_source,
-		luaopen_music,
-		luaopen_sound,
 		0
 	};	
 
@@ -316,7 +264,12 @@ namespace audio
 		w.functions = functions;
 		w.types = types;
 
-		return luax_register_module(L, w);
+		luax_register_module(L, w);
+
+		if (luaL_loadbuffer(L, (const char *)audio_lua, sizeof(audio_lua), "audio.lua") == 0)
+			lua_call(L, 0, 0);
+
+		return 0;
 	}
 
 } // audio

+ 3 - 5
src/modules/audio/wrap_Audio.h

@@ -22,9 +22,9 @@
 #define LOVE_AUDIO_WRAP_AUDIO_H
 
 // LOVE
+#include <common/config.h>
+#include <common/runtime.h>
 #include "Audio.h"
-#include "wrap_Sound.h"
-#include "wrap_Music.h"
 #include "wrap_Source.h"
 
 namespace love
@@ -32,9 +32,7 @@ namespace love
 namespace audio
 {
 	int w_getNumSources(lua_State * L);
-	int w_newSound(lua_State * L);
-	int w_newMusic(lua_State * L);
-	int w_newSource(lua_State * L);
+	int w_newSource1(lua_State * L);
 	int w_play(lua_State * L);
 	int w_stop(lua_State * L);
 	int w_pause(lua_State * L);

+ 0 - 42
src/modules/audio/wrap_Music.cpp

@@ -1,42 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Music.h"
-
-namespace love
-{
-namespace audio
-{
-	Music * luax_checkmusic(lua_State * L, int idx)
-	{
-		return luax_checktype<Music>(L, idx, "Music", AUDIO_MUSIC_T);
-	}
-
-	static const luaL_Reg functions[] = {
-		{ 0, 0 }
-	};
-
-	int luaopen_music(lua_State * L)
-	{
-		return luax_register_type(L, "Music", functions);
-	}
-
-} // audio
-} // love

+ 0 - 37
src/modules/audio/wrap_Music.h

@@ -1,37 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_WRAP_MUSIC_H
-#define LOVE_AUDIO_WRAP_MUSIC_H
-
-#include <common/runtime.h>
-#include "Music.h"
-
-namespace love
-{
-namespace audio
-{
-	Music * luax_checkmusic(lua_State * L, int idx);
-	int luaopen_music(lua_State * L);
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_WRAP_MUSIC_H

+ 0 - 42
src/modules/audio/wrap_Sound.cpp

@@ -1,42 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#include "wrap_Sound.h"
-
-namespace love
-{
-namespace audio
-{
-	Sound * luax_checksound(lua_State * L, int idx)
-	{
-		return luax_checktype<Sound>(L, idx, "Sound", AUDIO_SOUND_T);
-	}
-
-	static const luaL_Reg functions[] = {
-		{ 0, 0 }
-	};
-
-	int luaopen_sound(lua_State * L)
-	{
-		return luax_register_type(L, "Sound", functions);
-	}
-
-} // audio
-} // love

+ 0 - 37
src/modules/audio/wrap_Sound.h

@@ -1,37 +0,0 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-**/
-
-#ifndef LOVE_AUDIO_WRAP_SOUND_H
-#define LOVE_AUDIO_WRAP_SOUND_H
-
-#include <common/runtime.h>
-#include "Sound.h"
-
-namespace love
-{
-namespace audio
-{
-	Sound * luax_checksound(lua_State * L, int idx);
-	int luaopen_sound(lua_State * L);
-
-} // audio
-} // love
-
-#endif // LOVE_AUDIO_WRAP_SOUND_H

+ 8 - 0
src/modules/audio/wrap_Source.cpp

@@ -139,6 +139,13 @@ namespace audio
 		return 1;
 	}
 
+	int w_Source_isStopped(lua_State * L)
+	{
+		Source * t = luax_checksource(L, 1);
+		luax_pushboolean(L, t->isStopped());
+		return 1;
+	}
+
 	static const luaL_Reg functions[] = {
 		{ "setPitch", w_Source_setPitch },
 		{ "getPitch", w_Source_getPitch },
@@ -146,6 +153,7 @@ namespace audio
 		{ "getVolume", w_Source_getVolume },
 		{ "setLooping", w_Source_setLooping },
 		{ "isLooping", w_Source_isLooping },
+		{ "isStopped", w_Source_isStopped },
 		{ 0, 0 }
 	};
 

+ 1 - 0
src/modules/audio/wrap_Source.h

@@ -41,6 +41,7 @@ namespace audio
 	int w_Source_getDirection(lua_State * L);
 	int w_Source_setLooping(lua_State * L);
 	int w_Source_isLooping(lua_State * L);
+	int w_Source_isStopped(lua_State * L);
 	int luaopen_source(lua_State * L);
 
 } // audio

+ 2 - 2
src/modules/sound/Decoder.h

@@ -40,7 +40,7 @@ namespace sound
 		* Indicates how many bytes of raw data should be generated at each
 		* call to Decode.
 		**/
-		static const int DEFAULT_BUFFER_SIZE = 1024;
+		static const int DEFAULT_BUFFER_SIZE = 2048;
 
 		/**
 		* Indicates the quality of the sound. 
@@ -55,7 +55,7 @@ namespace sound
 		/**
 		* 16 bit audio is the default.
 		**/
-		static const int DEFAULT_T = 16;
+		static const int DEFAULT_BITS = 16;
 
 		/**
 		* Creates a deep of itself. The sound stream can (and should) be 

+ 5 - 1
src/modules/sound/lullaby/ModPlugDecoder.cpp

@@ -60,7 +60,11 @@ namespace lullaby
 	bool ModPlugDecoder::accepts(const std::string & ext)
 	{
 		static const std::string supported[] = {
-			"it", "xm", "mod", "wav", ""
+			"699", "abc", "amf", "ams", "dbm", "dmf",
+			"dsm", "far", "it", "j2b", "mdl", "med",
+			"mid", "mod", "mt2", "mtm", "okt", "pat",
+			"psm", "s3m", "stm", "ult", "umx", "wav",
+			"xm", ""
 		};
 
 		for(int i = 0; !(supported[i].empty()); i++)

+ 1 - 1
src/modules/sound/lullaby/ModPlugDecoder.h

@@ -44,7 +44,7 @@ namespace lullaby
 	public:
 
 		ModPlugDecoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
-		~ModPlugDecoder();
+		virtual ~ModPlugDecoder();
 
 		static bool accepts(const std::string & ext);
 

+ 72 - 33
src/modules/sound/lullaby/Mpg123Decoder.cpp

@@ -34,9 +34,12 @@ namespace lullaby
 	bool Mpg123Decoder::inited = false;
 
 	Mpg123Decoder::Mpg123Decoder(Data * data, const std::string & ext, int bufferSize, int sampleRate)
-		: Decoder(data, ext, bufferSize, sampleRate), handle(0), islooping(false)
+		: Decoder(data, ext, bufferSize, sampleRate), handle(0)
 	{
 
+		data_size = data->getSize();
+		data_offset = 0;
+
 		int ret;
 
 		if(!inited)
@@ -57,21 +60,11 @@ namespace lullaby
 		ret = mpg123_format(handle, sampleRate, MPG123_STEREO, MPG123_ENC_SIGNED_16);
 		if (ret != MPG123_OK)
 			throw love::Exception("Could not set output format.");
-		size_t numbytes = 0;
-		ret = mpg123_decode(handle, (unsigned char*)data->getData(), data->getSize(), NULL, 0, &numbytes);
-		
-		if(ret == MPG123_NEW_FORMAT)
-		{
-			long rate;
-			int channels;
-			int encoding;
-			mpg123_getformat(handle, &rate, &channels, &encoding);
-		}
-		else if(ret != 0)
-		{
-			throw love::Exception(mpg123_strerror(handle));
-		}
 
+		ret = feed(16384);
+
+		if (ret != MPG123_OK && ret != MPG123_DONE)
+			throw love::Exception("Could not feed!");
 	}
 
 	Mpg123Decoder::~Mpg123Decoder()
@@ -108,26 +101,51 @@ namespace lullaby
 
 	int Mpg123Decoder::decode()
 	{
-		size_t numbytes;
-		int r = mpg123_read(handle, (unsigned char*) buffer, bufferSize, &numbytes);
-	
-		if (r == MPG123_DONE || r != MPG123_OK)
+		int size = 0;
+		bool done = false;
+
+		while(size < bufferSize && !done && !eof)
 		{
-			if ( r == MPG123_NEED_MORE && islooping )
-			{
-				islooping = false;
-				size_t numbytes = 0;
-				mpg123_decode(handle, (unsigned char*) data->getData(), data->getSize(), (unsigned char*) buffer, bufferSize, &numbytes);
-			}
-			else
+			size_t numbytes = 0;
+
+			int r = mpg123_read(handle, (unsigned char*) buffer + size, bufferSize - size, &numbytes);
+
+			switch(r)
 			{
+			case MPG123_NEW_FORMAT:
+				continue;
+			case MPG123_NEED_MORE:
+				{
+					int v = feed(8192);
+
+					switch(v)
+					{
+					case MPG123_OK:
+						continue;
+					case MPG123_DONE:
+						if(numbytes == 0)
+							eof = true;
+						break;
+					default:
+						done = true;
+					}
+
+					continue;
+				}
+			case MPG123_OK:
+				size += numbytes;
+				continue;
+			case MPG123_DONE:
+				// Apparently, mpg123_read does not return MPG123_DONE, but 
+				// let's keep it here anyway.
 				eof = true;
-				numbytes = 0;
+			default:
+				done = true;
+				break;
 			}
 		}
 		
-
-		return numbytes;
+		return size;
 	}
 
 	bool Mpg123Decoder::seek(float s)
@@ -139,11 +157,16 @@ namespace lullaby
 
 	bool Mpg123Decoder::rewind()
 	{
-		if(mpg123_seek(handle, 0, SEEK_SET) >= 0)
-			return false;
-		islooping = true;
 		eof = false;
-		return true;
+		off_t offset;
+
+		if(mpg123_feedseek(handle, 0, SEEK_SET, &offset) >= 0)
+		{
+			data_offset = offset;
+			return true;
+		}
+		else
+			return false;
 	}
 
 	bool Mpg123Decoder::isSeekable()
@@ -160,7 +183,23 @@ namespace lullaby
 	{
 		return 16;
 	}
+
+	int Mpg123Decoder::feed(int bytes)
+	{
+		int remaining = data_size - data_offset;
+
+		if(remaining <= 0)
+			return MPG123_DONE;
+
+		int feed_bytes = remaining < bytes ? remaining : bytes;
 
+		int r = mpg123_feed(handle, (unsigned char*)data->getData() + data_offset, feed_bytes);
+
+		if(r == MPG123_OK || r == MPG123_DONE)
+			data_offset += feed_bytes;
+
+		return r;
+	}
 
 } // lullaby
 } // sound

+ 8 - 2
src/modules/sound/lullaby/Mpg123Decoder.h

@@ -43,13 +43,15 @@ namespace lullaby
 	private:
 
 		mpg123_handle * handle;
-		bool islooping;
 		static bool inited;
 
+		int data_offset;
+		int data_size;
+
 	public:
 
 		Mpg123Decoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
-		~Mpg123Decoder();
+		virtual ~Mpg123Decoder();
 		
 		static bool accepts(const std::string & ext);
 		static void quit();
@@ -62,6 +64,10 @@ namespace lullaby
 		int getChannels() const;
 		int getBits() const;
 
+	private:
+
+		int feed(int bytes);
+
 	}; // Decoder
 
 } // lullaby

+ 2 - 2
src/modules/sound/lullaby/Sound.cpp

@@ -55,9 +55,9 @@ namespace lullaby
 		// Find a suitable decoder here, and return it.
 		if(ModPlugDecoder::accepts(ext))
 			decoder = new ModPlugDecoder(data, ext, bufferSize, sampleRate);
-		else if (Mpg123Decoder::accepts(ext))
+		else if(Mpg123Decoder::accepts(ext))
 			decoder = new Mpg123Decoder(data, ext, bufferSize, sampleRate);
-		else if (VorbisDecoder::accepts(ext))
+		else if(VorbisDecoder::accepts(ext))
 			decoder = new VorbisDecoder(data, ext, bufferSize, sampleRate);
 		/*else if (FLACDecoder::accepts(ext))
 			decoder = new FLACDecoder(data, ext, bufferSize, sampleRate);*/

+ 10 - 31
src/modules/sound/lullaby/VorbisDecoder.cpp

@@ -182,42 +182,20 @@ namespace lullaby
 
 	int VorbisDecoder::decode()
 	{
-		int bits = this->getBits();
 		int size = 0;
-		int section;
-		int result;
-
-		if(bits == 16)
-			bits = 2;
-		else
-			bits = 1;
 
 		while(size < bufferSize)
 		{
-			result = ov_read(&handle, (char*) buffer + size, bufferSize - size, endian, bits, 1, &section);
+			int result = ov_read(&handle, (char*) buffer + size, bufferSize - size, endian, (getBits() == 16 ? 2 : 1), 1, 0);
 
-			if(result > 0)
-				size += result;
-			else if(result < 0)
-			{
-				switch(result)
-				{
-				case OV_EREAD:
-					throw love::Exception("Vorbis read: Read from media");
-				case OV_ENOTVORBIS:
-					throw love::Exception("Vorbis read: Not Vorbis data");
-				case OV_EVERSION:
-					throw love::Exception("Vorbis read: Vorbis version mismatch");
-				case OV_EBADHEADER:
-					throw love::Exception("Vorbis read: Invalid Vorbis header");
-				case OV_EFAULT:
-					throw love::Exception("Vorbis read: Internal logic fault (bug or heap/stack corruption)");
-				default:
-					throw love::Exception("Vorbis read: Unknown error");
-				}
-			}
-			else
+			if(result == OV_HOLE)
+				continue;
+			else if(result <= OV_EREAD)
+				return -1;
+			else if(result == 0)
 				break;
+			else if(result > 0)
+				size += result;
 		}
 
 		if(oggFile.dataSize - oggFile.dataRead == 0)
@@ -256,7 +234,8 @@ namespace lullaby
 	bool VorbisDecoder::rewind()
 	{
 		eof = false;
-		return this->seek(0);
+		ov_pcm_seek(&handle, 0);
+		return true;
 	}
 
 	bool VorbisDecoder::isSeekable()

+ 1 - 1
src/modules/sound/lullaby/VorbisDecoder.h

@@ -56,7 +56,7 @@ namespace lullaby
 	public:
 
 		VorbisDecoder(Data * data, const std::string & ext, int bufferSize, int sampleRate);
-		~VorbisDecoder();
+		virtual ~VorbisDecoder();
 		
 		static bool accepts(const std::string & ext);
 

+ 1 - 1
src/modules/sound/wrap_Sound.cpp

@@ -37,7 +37,7 @@ namespace sound
 		{
 			int samples = luaL_checkint(L, 1);
 			int sampleRate = luaL_optint(L, 2, Decoder::DEFAULT_SAMPLE_RATE);
-			int bits = luaL_optint(L, 3, Decoder::DEFAULT_T);
+			int bits = luaL_optint(L, 3, Decoder::DEFAULT_BITS);
 			int channels = luaL_optint(L, 4, Decoder::DEFAULT_CHANNELS);
 
 			try

+ 41 - 0
src/scripts/audio.lua

@@ -0,0 +1,41 @@
+--[[
+Copyright (c) 2006-2010 LOVE Development Team
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+--]]
+
+function love.audio.newSource(a, b)
+	if type(a) == "string" then
+		a = love.filesystem.newFile(a)
+	end
+	if type(a) == "userdata" then
+		if a:typeOf("File") then
+			a = love.sound.newDecoder(a)
+		end
+		
+		if a:typeOf("Decoder") then
+			if b == "static" then
+				a = love.sound.newSoundData(a)
+			end
+			return love.audio.newSource1(a)
+		end
+		if a:typeOf("SoundData") then
+			return love.audio.newSource1(a)
+		end
+	end
+	error("No matching overload")
+end

+ 93 - 0
src/scripts/audio.lua.h

@@ -0,0 +1,93 @@
+/**
+* Copyright (c) 2006-2010 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+namespace love
+{
+
+// [audio.lua]
+const unsigned char audio_lua[] = 
+{
+	0x1B,0x4C,0x75,0x61,0x51,0x00,0x01,0x04,0x04,0x04,0x08,0x00,0x0B,0x00,0x00,
+	0x00,0x40,0x61,0x75,0x64,0x69,0x6F,0x2E,0x6C,0x75,0x61,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x05,0x00,0x00,0x00,0x05,0x00,
+	0x00,0x00,0x06,0x40,0x40,0x00,0x64,0x00,0x00,0x00,0x09,0x40,0x00,0x81,0x1E,
+	0x00,0x80,0x00,0x03,0x00,0x00,0x00,0x04,0x05,0x00,0x00,0x00,0x6C,0x6F,0x76,
+	0x65,0x00,0x04,0x06,0x00,0x00,0x00,0x61,0x75,0x64,0x69,0x6F,0x00,0x04,0x0A,
+	0x00,0x00,0x00,0x6E,0x65,0x77,0x53,0x6F,0x75,0x72,0x63,0x65,0x00,0x01,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x00,
+	0x02,0x00,0x05,0x3D,0x00,0x00,0x00,0x85,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
+	0x9C,0x80,0x00,0x01,0x17,0x40,0x40,0x01,0x16,0x40,0x01,0x80,0x85,0x80,0x00,
+	0x00,0x86,0xC0,0x40,0x01,0x86,0x00,0x41,0x01,0xC0,0x00,0x00,0x00,0x9C,0x80,
+	0x00,0x01,0x00,0x00,0x00,0x01,0x85,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x9C,
+	0x80,0x00,0x01,0x17,0x40,0x41,0x01,0x16,0x00,0x0A,0x80,0x8B,0x80,0x41,0x00,
+	0x01,0xC1,0x01,0x00,0x9C,0x80,0x80,0x01,0x9A,0x00,0x00,0x00,0x16,0x40,0x01,
+	0x80,0x85,0x80,0x00,0x00,0x86,0x00,0x42,0x01,0x86,0x40,0x42,0x01,0xC0,0x00,
+	0x00,0x00,0x9C,0x80,0x00,0x01,0x00,0x00,0x00,0x01,0x8B,0x80,0x41,0x00,0x01,
+	0x81,0x02,0x00,0x9C,0x80,0x80,0x01,0x9A,0x00,0x00,0x00,0x16,0x40,0x03,0x80,
+	0x17,0xC0,0xC2,0x00,0x16,0x40,0x01,0x80,0x85,0x80,0x00,0x00,0x86,0x00,0x42,
+	0x01,0x86,0x00,0x43,0x01,0xC0,0x00,0x00,0x00,0x9C,0x80,0x00,0x01,0x00,0x00,
+	0x00,0x01,0x85,0x80,0x00,0x00,0x86,0x40,0x43,0x01,0x86,0x80,0x43,0x01,0xC0,
+	0x00,0x00,0x00,0x9D,0x00,0x00,0x01,0x9E,0x00,0x00,0x00,0x8B,0x80,0x41,0x00,
+	0x01,0xC1,0x03,0x00,0x9C,0x80,0x80,0x01,0x9A,0x00,0x00,0x00,0x16,0x40,0x01,
+	0x80,0x85,0x80,0x00,0x00,0x86,0x40,0x43,0x01,0x86,0x80,0x43,0x01,0xC0,0x00,
+	0x00,0x00,0x9D,0x00,0x00,0x01,0x9E,0x00,0x00,0x00,0x85,0x00,0x04,0x00,0xC1,
+	0x40,0x04,0x00,0x9C,0x40,0x00,0x01,0x1E,0x00,0x80,0x00,0x12,0x00,0x00,0x00,
+	0x04,0x05,0x00,0x00,0x00,0x74,0x79,0x70,0x65,0x00,0x04,0x07,0x00,0x00,0x00,
+	0x73,0x74,0x72,0x69,0x6E,0x67,0x00,0x04,0x05,0x00,0x00,0x00,0x6C,0x6F,0x76,
+	0x65,0x00,0x04,0x0B,0x00,0x00,0x00,0x66,0x69,0x6C,0x65,0x73,0x79,0x73,0x74,
+	0x65,0x6D,0x00,0x04,0x08,0x00,0x00,0x00,0x6E,0x65,0x77,0x46,0x69,0x6C,0x65,
+	0x00,0x04,0x09,0x00,0x00,0x00,0x75,0x73,0x65,0x72,0x64,0x61,0x74,0x61,0x00,
+	0x04,0x07,0x00,0x00,0x00,0x74,0x79,0x70,0x65,0x4F,0x66,0x00,0x04,0x05,0x00,
+	0x00,0x00,0x46,0x69,0x6C,0x65,0x00,0x04,0x06,0x00,0x00,0x00,0x73,0x6F,0x75,
+	0x6E,0x64,0x00,0x04,0x0B,0x00,0x00,0x00,0x6E,0x65,0x77,0x44,0x65,0x63,0x6F,
+	0x64,0x65,0x72,0x00,0x04,0x08,0x00,0x00,0x00,0x44,0x65,0x63,0x6F,0x64,0x65,
+	0x72,0x00,0x04,0x07,0x00,0x00,0x00,0x73,0x74,0x61,0x74,0x69,0x63,0x00,0x04,
+	0x0D,0x00,0x00,0x00,0x6E,0x65,0x77,0x53,0x6F,0x75,0x6E,0x64,0x44,0x61,0x74,
+	0x61,0x00,0x04,0x06,0x00,0x00,0x00,0x61,0x75,0x64,0x69,0x6F,0x00,0x04,0x0B,
+	0x00,0x00,0x00,0x6E,0x65,0x77,0x53,0x6F,0x75,0x72,0x63,0x65,0x31,0x00,0x04,
+	0x0A,0x00,0x00,0x00,0x53,0x6F,0x75,0x6E,0x64,0x44,0x61,0x74,0x61,0x00,0x04,
+	0x06,0x00,0x00,0x00,0x65,0x72,0x72,0x6F,0x72,0x00,0x04,0x15,0x00,0x00,0x00,
+	0x4E,0x6F,0x20,0x6D,0x61,0x74,0x63,0x68,0x69,0x6E,0x67,0x20,0x6F,0x76,0x65,
+	0x72,0x6C,0x6F,0x61,0x64,0x00,0x00,0x00,0x00,0x00,0x3D,0x00,0x00,0x00,0x16,
+	0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+	0x16,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x17,0x00,0x00,
+	0x00,0x17,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x19,0x00,
+	0x00,0x00,0x19,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x19,
+	0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,
+	0x1A,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x1B,0x00,0x00,
+	0x00,0x1B,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x1B,0x00,
+	0x00,0x00,0x1E,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1E,
+	0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,
+	0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,
+	0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,
+	0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,
+	0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+	0x24,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x25,0x00,0x00,
+	0x00,0x25,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x25,0x00,
+	0x00,0x00,0x28,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x29,
+	0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x61,0x00,0x00,0x00,
+	0x00,0x00,0x3C,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x00,
+	0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x15,0x00,
+	0x00,0x00,0x15,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x29,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+// [/audio.lua]
+
+} // love

+ 19 - 0
src/scripts/boot.lua

@@ -1,3 +1,22 @@
+--[[
+Copyright (c) 2006-2010 LOVE Development Team
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+--]]
 
 -- Make sure love table exists.
 if not love then love = {} end

+ 1 - 1
src/scripts/graphics.lua

@@ -1,5 +1,5 @@
 --[[
-Copyright (c) 2006-2009 LOVE Development Team
+Copyright (c) 2006-2010 LOVE Development Team
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages