Commits

Bart van Strien  committed df63b64

Add love.audio.sdl on new branch 'sdlaudio'.

Adds a dependency on SDL_mixer, can be loaded and chosen. No compile-time selection yet though.
And it doesn't fully work yet either.

  • Participants
  • Parent commits ed28d72
  • Branches sdlaudio

Comments (0)

Files changed (9)

File configure.in

 AC_PROG_CXX
 AC_SEARCH_LIBS([sqrt], [m], [], AC_MSG_ERROR([Can't LÖVE without C math library]))
 AC_SEARCH_LIBS([SDL_Init], [SDL], [], AC_MSG_ERROR([Can't LÖVE without SDL]))
+AC_SEARCH_LIBS([Mix_OpenAudio], [SDL_mixer], [], AC_MSG_ERROR([Can't LÖVE without SDL_mixer]))
 AC_SEARCH_LIBS([glLoadIdentity], [GL], [], AC_MSG_ERROR([Can't LÖVE without OpenGL]))
 #AC_SEARCH_LIBS([gluOrtho2D], [GLU], [], AC_MSG_ERROR([Can't LÖVE without OpenGL Utility Library]))
 AC_SEARCH_LIBS([alSourcePlay], [openal], [], AC_MSG_ERROR([Can't LÖVE without OpenAL]))

File src/love.cpp

 
 // Modules
 #include <audio/openal/wrap_Audio.h>
+#include <audio/sdl/wrap_Audio.h>
 #include <audio/null/wrap_Audio.h>
 #include <event/sdl/wrap_Event.h>
 #include <filesystem/physfs/wrap_Filesystem.h>
 
 static const luaL_Reg modules[] = {
 	{ "love.audio.openal", love::audio::openal::luaopen_love_audio_openal },
+	{ "love.audio.sdl", love::audio::sdl::luaopen_love_audio_sdl },
 	{ "love.audio.null", love::audio::null::luaopen_love_audio_null },
 	{ "love.event.sdl", love::event::sdl::luaopen_love_event_sdl },
 	{ "love.filesystem.physfs", love::filesystem::physfs::luaopen_love_filesystem_physfs },

File src/modules/audio/openal/wrap_Audio.cpp

 			// Try OpenAL first.
 			try
 			{
-				instance = new love::audio::openal::Audio();
+				instance = new Audio();
 			}
 			catch(love::Exception & e)
 			{

File src/modules/audio/sdl/Audio.cpp

+/**
+* 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.
+**/
+
+#include "Audio.h"
+
+namespace love
+{
+namespace audio
+{
+namespace sdl
+{
+	Audio::Audio()
+	{
+		Mix_OpenAudio(love::sound::Decoder::DEFAULT_SAMPLE_RATE, AUDIO_S16SYS, love::sound::Decoder::DEFAULT_CHANNELS, love::sound::Decoder::DEFAULT_BUFFER_SIZE);
+	}
+
+	Audio::~Audio()
+	{
+		Mix_CloseAudio();
+	}
+
+	const char * Audio::getName() const
+	{
+		return "love.audio.sdl";
+	}
+
+	love::audio::Source * Audio::newSource(love::sound::Decoder * decoder)
+	{
+		return new Source(decoder);
+	}
+
+	love::audio::Source * Audio::newSource(love::sound::SoundData *sounddata)
+	{
+		return new Source(sounddata);
+	}
+
+	int Audio::getNumSources() const
+	{
+		return 0;
+	}
+
+	int Audio::getMaxSources() const
+	{
+		return 0;
+	}
+
+	void Audio::play(love::audio::Source * source)
+	{
+		source->play();
+	}
+
+	void Audio::play()
+	{
+	}
+
+	void Audio::stop(love::audio::Source * source)
+	{
+		source->stop();
+	}
+
+	void Audio::stop()
+	{
+	}
+
+	void Audio::pause(love::audio::Source * source)
+	{
+		source->pause();
+	}
+
+	void Audio::pause()
+	{
+	}
+
+	void Audio::resume(love::audio::Source * source)
+	{
+		source->resume();
+	}
+
+	void Audio::resume()
+	{
+	}
+
+	void Audio::rewind(love::audio::Source * source)
+	{
+		source->rewind();
+	}
+
+	void Audio::rewind()
+	{
+	}
+
+	void Audio::setVolume(float volume)
+	{
+		this->volume = volume;
+	}
+
+	float Audio::getVolume() const
+	{
+		return volume;
+	}
+
+	void Audio::getPosition(float *) const
+	{
+	}
+
+	void Audio::setPosition(float *)
+	{
+	}
+
+	void Audio::getOrientation(float *) const
+	{
+	}
+
+	void Audio::setOrientation(float *)
+	{
+	}
+
+	void Audio::getVelocity(float *) const
+	{
+	}
+
+	void Audio::setVelocity(float *)
+	{
+	}
+
+	void Audio::record()
+	{
+	}
+
+	love::sound::SoundData * Audio::getRecordedData()
+	{
+		return NULL;
+	}
+
+	love::sound::SoundData * Audio::stopRecording(bool)
+	{
+		return NULL;
+	}
+
+	bool Audio::canRecord()
+	{
+		return false;
+	}
+
+} // sdl
+} // audio
+} // love

File src/modules/audio/sdl/Audio.h

+/**
+* 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.
+**/
+
+#ifndef LOVE_AUDIO_SDL_AUDIO_H
+#define LOVE_AUDIO_SDL_AUDIO_H
+
+// LOVE
+#include <audio/Audio.h>
+
+// SDL
+#include <SDL_mixer.h>
+
+#include "Source.h"
+
+namespace love
+{
+namespace audio
+{
+namespace sdl
+{
+	class Audio : public love::audio::Audio
+	{
+	private:
+		float volume;
+	public:
+
+		Audio();
+		virtual ~Audio();
+
+		// Implements Module.
+		const char * getName() const;
+
+		// Implements Audio.
+		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();
+		void stop(love::audio::Source * source);
+		void stop();
+		void pause(love::audio::Source * source);
+		void pause();
+		void resume(love::audio::Source * source);
+		void resume();
+		void rewind(love::audio::Source * source);
+		void rewind();
+		void setVolume(float volume);
+		float getVolume() const;
+
+		void getPosition(float * v) const;
+		void setPosition(float * v);
+		void getOrientation(float * v) const;
+		void setOrientation(float * v);
+		void getVelocity(float * v) const;
+		void setVelocity(float * v);
+
+		void record();
+		love::sound::SoundData * getRecordedData();
+		love::sound::SoundData * stopRecording(bool returnData);
+		bool canRecord();
+
+	}; // Audio
+
+} // sdl
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_SDL_AUDIO_H

File src/modules/audio/sdl/Source.cpp

+/**
+* 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.
+**/
+
+#include "Source.h"
+
+#include <iostream>
+
+namespace love
+{
+namespace audio
+{
+namespace sdl
+{
+	void Source::music_callback(void *udata, Uint8 * stream, int len)
+	{
+		Source *thisS = (Source*) udata;
+		for (int i = 0; i < len;)
+		{
+			int numbytes = thisS->decoder->getSize()-thisS->bufferpos;
+			numbytes = len > numbytes ? numbytes : len;
+			memcpy(stream+i, ((char*) thisS->decoder->getBuffer())+thisS->bufferpos, numbytes);
+			thisS->bufferpos += numbytes;
+			i += numbytes;
+			if (thisS->bufferpos == thisS->decoder->getSize())
+			{
+				thisS->decoder->decode();
+				thisS->bufferpos = 0;
+				if (thisS->isFinished())
+				{
+					if (thisS->isLooping())
+						Mix_HookMusic(music_callback, udata);
+					else
+						Mix_HookMusic(NULL, NULL);
+				}
+			}
+		}
+	}
+
+	Source::Source(love::sound::Decoder * decoder)
+		: love::audio::Source(Source::TYPE_STREAM), looping(false), decoder(decoder), bufferpos(0)
+	{
+		decoder->retain();
+	}
+
+	Source::Source(love::sound::SoundData * sounddata)
+	: love::audio::Source(Source::TYPE_STATIC), looping(false), sounddata(sounddata), bufferpos(0)
+	{
+		sounddata->retain();
+		snd = Mix_QuickLoad_RAW((Uint8*) sounddata->getData(), (Uint32) sounddata->getSize());
+	}
+
+	Source::~Source()
+	{
+		if (isStatic())
+			sounddata->release();
+		else
+			decoder->release();
+	}
+
+	love::audio::Source * Source::copy()
+	{
+		this->retain();
+		return this;
+	}
+
+	void Source::play()
+	{
+		if (isStatic())
+			sndchannel = Mix_PlayChannel(-1, snd, isLooping() ? -1 : 0);
+		else
+			Mix_HookMusic(music_callback, this);
+	}
+
+	void Source::stop()
+	{
+		if (isStatic())
+			Mix_HaltChannel(sndchannel);
+		else
+			Mix_HookMusic(NULL, NULL);
+	}
+
+	void Source::pause()
+	{
+		if (isStatic())
+			Mix_Pause(sndchannel);
+		else
+			Mix_PauseMusic();
+	}
+
+	void Source::resume()
+	{
+		if (isStatic())
+			Mix_Resume(sndchannel);
+		else
+			Mix_ResumeMusic();
+	}
+
+	void Source::rewind()
+	{
+		if (!isStatic())
+			Mix_RewindMusic();
+	}
+
+	bool Source::isStopped() const
+	{
+		if (isStatic())
+			return !Mix_Playing(sndchannel);
+		else
+			return decoder->isFinished();
+	}
+
+	bool Source::isFinished() const
+	{
+		if (isStatic())
+			return isStopped() && !Mix_Paused(sndchannel);
+		else
+			return decoder->isFinished();
+		return true;
+	}
+	
+	bool Source::isPaused() const
+	{
+		if (isStatic())
+			return Mix_Paused(sndchannel);
+		else
+			return Mix_PausedMusic();
+		return true;
+	}
+
+	void Source::update()
+	{
+	}
+
+	void Source::setPitch(float pitch)
+	{
+		this->pitch = pitch;
+	}
+
+	float Source::getPitch() const
+	{
+		return pitch;
+	}
+
+	void Source::setVolume(float volume)
+	{
+		this->volume = volume;
+	}
+
+	float Source::getVolume() const
+	{
+		return volume;
+	}
+
+	void Source::setPosition(float *)
+	{
+	}
+
+	void Source::getPosition(float *) const
+	{
+	}
+
+	void Source::setVelocity(float *)
+	{
+	}
+
+	void Source::getVelocity(float *) const
+	{
+	}
+
+	void Source::setDirection(float *)
+	{
+	}
+
+	void Source::getDirection(float *) const
+	{
+	}
+
+	void Source::setLooping(bool looping)
+	{
+		this->looping = looping;
+	}
+
+	bool Source::isLooping() const
+	{
+		return looping;
+	}
+
+	bool Source::isStatic() const
+	{
+		return (type == TYPE_STATIC);
+	}
+	
+	void Source::seek(float offset, Source::Unit unit)
+	{
+		switch (unit) {
+			case Source::UNIT_SAMPLES:
+				/* stub */
+				break;
+			case Source::UNIT_SECONDS:	
+			default:
+				Mix_RewindMusic();
+				Mix_SetMusicPosition(offset);
+				break;
+			}
+	}
+	
+	float Source::tell(Source::Unit unit) const
+	{
+		float offset = 0;
+		switch (unit) {
+			case Source::UNIT_SAMPLES:
+				/* stub */
+				break;
+			case Source::UNIT_SECONDS:
+			default:
+				/* stub */
+				break;
+		}
+		return offset;
+	}
+
+} // sdl
+} // audio
+} // love

File src/modules/audio/sdl/Source.h

+/**
+* 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.
+**/
+
+#ifndef LOVE_AUDIO_SDL_SOURCE_H
+#define LOVE_AUDIO_SDL_SOURCE_H
+
+// LOVE
+#include <common/Object.h>
+#include <audio/Source.h>
+#include <sound/Decoder.h>
+#include <sound/SoundData.h>
+
+// SDL
+#include <SDL_mixer.h>
+
+namespace love
+{
+namespace audio
+{
+namespace sdl
+{
+	class Source : public love::audio::Source
+	{
+	private:
+
+		float pitch;
+		float volume;
+		bool looping;
+
+		static void music_callback(void *udata, Uint8 * stream, int len);
+
+		Mix_Chunk *snd;
+		int sndchannel;
+
+		love::sound::Decoder * decoder;
+		love::sound::SoundData * sounddata;
+
+		int bufferpos;
+
+	public:
+		Source(love::sound::SoundData * sounddata);
+		Source(love::sound::Decoder * decoder);
+		virtual ~Source();
+
+		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 bool isPaused() 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;
+		bool isStatic() const;
+		virtual void seek(float offset, Unit unit);
+		virtual float tell(Unit unit) const;
+
+	}; // Source
+
+} // sdl
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_SDL_SOURCE_H

File src/modules/audio/sdl/wrap_Audio.cpp

+/**
+* Copyright (c) 2006-2011 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 <iostream>
+
+// LOVE
+#include "wrap_Audio.h"
+
+#include "Audio.h"
+#include "audio/null/Audio.h"
+
+#include <scripts/audio.lua.h>
+
+#include <common/runtime.h>
+
+namespace love
+{
+namespace audio
+{
+	extern Audio * instance;
+namespace sdl
+{
+	// List of functions to wrap.
+	static const luaL_Reg functions[] = {
+		{ "getNumSources", w_getNumSources },
+		{ "newSource1", w_newSource1 },
+		{ "play", w_play },
+		{ "stop", w_stop },
+		{ "pause", w_pause },
+		{ "resume", w_resume },
+		{ "rewind", w_rewind },
+		{ "setVolume", w_setVolume },
+		{ "getVolume", w_getVolume },
+		{ "setPosition", w_setPosition },
+		{ "getPosition", w_getPosition },
+		{ "setOrientation", w_setOrientation },
+		{ "getOrientation", w_getOrientation },
+		{ "setVelocity", w_setVelocity },
+		{ "getVelocity", w_getVelocity },
+		{ 0, 0 }
+	};
+
+	static const lua_CFunction types[] = {
+		luaopen_source,
+		0
+	};
+
+	int luaopen_love_audio_sdl(lua_State * L)
+	{
+		if(instance == 0)
+		{
+			// Try SDL first.
+			try
+			{
+				instance = new Audio();
+			}
+			catch(love::Exception & e)
+			{
+				std::cout << e.what() << std::endl;
+			}
+		}
+		else
+			instance->retain();
+
+		if(instance == 0)
+		{
+			// Fall back to nullaudio.
+			try
+			{
+				instance = new love::audio::null::Audio();
+			}
+			catch(love::Exception & e)
+			{
+				std::cout << e.what() << std::endl;
+			}
+		}
+
+		if(instance == 0)
+			return luaL_error(L, "Could not open any audio module.");
+
+		WrappedModule w;
+		w.module = instance;
+		w.name = "audio";
+		w.flags = MODULE_T;
+		w.functions = functions;
+		w.types = types;
+
+		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;
+	}
+	
+} // sdl
+} // audio
+} // love

File src/modules/audio/sdl/wrap_Audio.h

+/**
+* Copyright (c) 2006-2011 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_SDL_WRAP_AUDIO_H
+#define LOVE_AUDIO_SDL_WRAP_AUDIO_H
+
+// LOVE
+#include "audio/wrap_Audio.h"
+
+namespace love
+{
+namespace audio
+{
+namespace sdl
+{
+	extern "C" LOVE_EXPORT int luaopen_love_audio_sdl(lua_State * L);
+
+} // sdl
+} // audio
+} // love
+
+#endif // LOVE_AUDIO_SDL_WRAP_AUDIO_H