Bläddra i källkod

audio on android works, additional work required btw

mikymod 12 år sedan
förälder
incheckning
d6cf790011

+ 3 - 11
engine/Device.cpp

@@ -221,7 +221,7 @@ void Device::init()
 	m_sound_renderer->init();
 	Log::d("SoundRenderer created.");
 
-	ResourceId id = m_resource_manager->load("sound", "sounds/untrue");
+	ResourceId id = m_resource_manager->load("sound", "sounds/mono1");
 	m_resource_manager->flush();
 
 	SoundResource* res = (SoundResource*)m_resource_manager->data(id);
@@ -231,7 +231,6 @@ void Device::init()
 
 	m_sound_renderer->play_sound(sound);
 
-
 	Log::i("Crown Engine initialized.");
 	Log::i("Initializing Game...");
 
@@ -285,7 +284,6 @@ void Device::shutdown()
 	{
 		m_sound_renderer->shutdown();
 
-		// FIXME: replace default_allocator with linear m_allocator
 		CE_DELETE(m_allocator, m_sound_renderer);
 	}
 
@@ -463,17 +461,12 @@ void Device::stop()
 void Device::pause()
 {
 	m_is_paused = true;
-
-	Log::d("Engine paused");
 }
 
 //-----------------------------------------------------------------------------
 void Device::unpause()
 {
 	m_is_paused = false;
-	m_is_really_paused = false;
-
-	Log::d("Engine unpaused");
 }
 
 //-----------------------------------------------------------------------------
@@ -524,12 +517,11 @@ void Device::frame(cb callback)
 		m_renderer->frame();
 
 		m_sound_renderer->frame();
-
 	}
 
-	m_frame_count++;
-
 	os_event_buffer()->clear();
+
+	m_frame_count++;
 }
 
 //-----------------------------------------------------------------------------

+ 4 - 9
engine/audio/al/ALRenderer.h

@@ -66,12 +66,7 @@ struct Sound
 {
 public:
 	//-----------------------------------------------------------------------------
-	Sound() : 
-		m_res(NULL), 
-		m_id(-1),	
-		m_looping(false)
-	{
-	}
+	Sound() : m_res(NULL), m_id(-1), m_looping(false) {}
 
 	//-----------------------------------------------------------------------------
 	void create(SoundResource* resource)
@@ -397,9 +392,9 @@ public:
 	ALuint			m_buffer[3];
 	ALuint 			m_format;
 
-	bool			m_playing;
-	bool			m_looping;
-	bool			m_streaming;
+	bool			m_playing :1;
+	bool			m_looping :1;
+	bool			m_streaming :1;
 
 	OggDecoder		m_decoder;
 };

+ 69 - 227
engine/audio/sles/SLESRenderer.cpp

@@ -40,24 +40,7 @@ namespace crown
 uint16_t* 	loop_data;
 size_t		loop_size;
 
-//-----------------------------------------------------------------------------
-void check_sles_errors(SLresult result)
-{
-	CE_ASSERT(result == SL_RESULT_SUCCESS, "SL_ERROR_CODE: %d", result);
-}
 
-//-----------------------------------------------------------------------------
-void source_callback(SLAndroidSimpleBufferQueueItf caller, void* source)
-{
-	(void)caller;
-
-	SoundSource* s = (SoundSource*)source;
-	
-	if (s->m_loop)
-	{	// FIXME FIXME FIXME
-		(*s->m_player_bufferqueue)->Enqueue(s->m_player_bufferqueue, loop_data, loop_size);
-	}
-}
 
 //-----------------------------------------------------------------------------
 class SoundRendererBackend
@@ -100,95 +83,14 @@ public:
 		}
 	}
 
-	//-----------------------------------------------------------------------------
-	void create_source(SoundSource& s)
-	{
-		SLresult result;
-
-		int32_t speakers = SL_SPEAKER_FRONT_CENTER;
-
-		// Configures buffer queue
-	    SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
-
-		// Configures audio format
-	    SLDataFormat_PCM format_pcm;
-		format_pcm.formatType = SL_DATAFORMAT_PCM;
-		format_pcm.numChannels = 1;	// Mono
-		format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
-		format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
-		format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
-		format_pcm.channelMask = speakers;
-		format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
-
-	    // Configures audio source
-	    SLDataSource audio_source;
-	    audio_source.pLocator = &buffer_queue;
-	    audio_source.pFormat = &format_pcm;
-
-		// Configures audio output mix
-	 	SLDataLocator_OutputMix out_mix;
-	 	out_mix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
-	 	out_mix.outputMix = m_out_mix_obj;
-
-	 	// Configures audio sink
-	    SLDataSink audio_sink;
-	 	audio_sink.pLocator = &out_mix;
-	 	audio_sink.pFormat = NULL;
-
-		// Creates sound player
-		const SLInterfaceID ids[] = {SL_IID_PLAY, SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
-		const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
-
-		result = (*m_engine)->CreateAudioPlayer(m_engine, &s.m_player_obj, &audio_source, &audio_sink, 3, ids, reqs);
-		check_sles_errors(result);
-
-		result = (*s.m_player_obj)->Realize(s.m_player_obj, SL_BOOLEAN_FALSE);
-		check_sles_errors(result);
-
-		// Gets interfaces
-		result = (*s.m_player_obj)->GetInterface(s.m_player_obj, SL_IID_PLAY, &s.m_player_play);
-		check_sles_errors(result);
-
-		result = (*s.m_player_obj)->GetInterface(s.m_player_obj, SL_IID_BUFFERQUEUE, &s.m_player_bufferqueue);
-		check_sles_errors(result);
-
-		result = (*s.m_player_obj)->GetInterface(s.m_player_obj, SL_IID_VOLUME, &s.m_player_volume);
-		check_sles_errors(result);
-
-		(*s.m_player_bufferqueue)->RegisterCallback(s.m_player_bufferqueue, source_callback, &s);
-	}
-
-	//-----------------------------------------------------------------------------
-	void destroy_source(SoundSource& s)
-	{
-		if (s.m_player_obj)
-		{
-			SLuint32 state;
-			(*s.m_player_obj)->GetState(s.m_player_obj, &state);
-
-			if (state == SL_OBJECT_STATE_REALIZED)
-			{
-				(*s.m_player_bufferqueue)->Clear(s.m_player_bufferqueue);
-				(*s.m_player_obj)->AbortAsyncOperation(s.m_player_obj);
-				(*s.m_player_obj)->Destroy(s.m_player_obj);
-
-	  			s.m_player_obj = NULL;
-	  			s.m_player_play = NULL;
-	  			s.m_player_bufferqueue = NULL;
-	  			s.m_player_volume = NULL;
-			}
-		}
-	}
-
-private:
+public:
 
 	SLObjectItf						m_engine_obj;
 	SLEngineItf						m_engine;
 
 	SLObjectItf 					m_out_mix_obj;
 
-	SoundBuffer 					m_buffers[MAX_SOUND_BUFFERS];
-	SoundSource 					m_sources[MAX_SOUND_SOURCES];
+	Sound 							m_sounds[MAX_SOUNDS];
 
 private:
 
@@ -197,11 +99,9 @@ private:
 
 //-----------------------------------------------------------------------------
 SoundRenderer::SoundRenderer(Allocator& allocator) :
-	m_allocator(allocator),
-	m_buffers_id_table(default_allocator(), MAX_SOUND_BUFFERS),
-	m_sources_id_table(default_allocator(), MAX_SOUND_SOURCES)	
+	m_allocator(allocator)
 {
-	m_backend = CE_NEW(default_allocator(), SoundRendererBackend);
+	m_backend = CE_NEW(m_allocator, SoundRendererBackend);
 }
 
 //-----------------------------------------------------------------------------
@@ -209,7 +109,7 @@ SoundRenderer::~SoundRenderer()
 {
 	if (m_backend)
 	{
-		CE_DELETE(default_allocator(), m_backend);
+		CE_DELETE(m_allocator, m_backend);
 	}
 }
 
@@ -226,269 +126,211 @@ void SoundRenderer::shutdown()
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_listener(const Vec3& pos, const Vec3& vel, const Vec3& or_up, const Vec3& or_at) const
+void SoundRenderer::frame()
 {
-	Log::w("Stub");
-
-	(void)pos;
-	(void)vel;
-	(void)or_up;
-	(void)or_at;
+	// TODO: needs additional works, but it's ok right now
+	for (uint32_t i = 0; i < m_num_sounds; i++)
+	{
+		if (m_backend->m_sounds[i].is_playing())
+		{
+			m_backend->m_sounds[i].update();
+		}
+	}
 }
 
 //-----------------------------------------------------------------------------
-SoundBufferId SoundRenderer::create_buffer(const void* data, const uint32_t size, const uint32_t sample_rate, const uint32_t channels, const uint32_t bits)
+uint32_t SoundRenderer::num_sounds()
 {
-	SoundBufferId id = m_buffers_id_table.create();
-
-	m_backend->m_buffers[id.index].create(data, size, sample_rate, channels, bits);
-
-	return id;
+	return m_num_sounds;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::destroy_buffer(SoundBufferId id)
+SoundId SoundRenderer::create_sound(SoundResource* resource)
 {
-	CE_ASSERT(m_buffers_id_table.has(id), "SoundBuffer does not exist");
+	SoundId id = m_sounds_id_table.create();
+
+	m_backend->m_sounds[id.index].create(m_backend->m_engine, m_backend->m_out_mix_obj, resource);
 
-	m_backend->m_buffers[id.index].destroy();
+	m_num_sounds++;
 
-	m_buffers_id_table.destroy(id);
+	return id;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::bind_buffer_to_source(SoundBufferId bid, SoundSourceId sid)
+void SoundRenderer::destroy_sound(SoundId id)
 {
-	CE_ASSERT(m_buffers_id_table.has(bid), "SoundBuffer does not exist");
-	CE_ASSERT(m_sources_id_table.has(sid), "SoundSource does not exist");
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
 
-	SoundBuffer& b = m_backend->m_buffers[bid.index];
-	SoundSource& s = m_backend->m_sources[sid.index];
+	m_backend->m_sounds[id.index].destroy();
 
-	int32_t result = (*s.m_player_bufferqueue)->Enqueue(s.m_player_bufferqueue, b.m_data, b.m_size);
-	check_sles_errors(result);
+	m_sounds_id_table.destroy(id);
 
-	if (s.m_loop)
-	{
-		loop_data = b.m_data;
-		loop_size = b.m_size;
-	}
+	m_num_sounds--;
 }
 
 //-----------------------------------------------------------------------------
-SoundSourceId SoundRenderer::create_source(bool loop)
+void SoundRenderer::play_sound(SoundId id)
 {
-	SoundSourceId id = m_sources_id_table.create();
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
 
-	SoundSource& sl_source = m_backend->m_sources[id.index];
-
-	m_backend->create_source(sl_source);
-
-	sl_source.m_loop = loop;
-
-	return id;
+	m_backend->m_sounds[id.index].play();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::play_source(SoundSourceId id)
+void SoundRenderer::pause_sound(SoundId id)
 {
-	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exist");
-
-	SoundSource& s = m_backend->m_sources[id.index];
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
 
-	SLresult result = (*s.m_player_play)->SetPlayState(s.m_player_play, SL_PLAYSTATE_PLAYING);
-
-	check_sles_errors(result);
+	m_backend->m_sounds[id.index].pause();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::pause_source(SoundSourceId id)
+void SoundRenderer::set_sound_loop(SoundId id, bool loop)
 {
-	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exist");
-
-	SoundSource& s = m_backend->m_sources[id.index];
-
-	SLresult result = (*s.m_player_play)->SetPlayState(s.m_player_play, SL_PLAYSTATE_PAUSED);
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
 
-	check_sles_errors(result);
+	m_backend->m_sounds[id.index].loop(loop);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::destroy_source(SoundSourceId id)
+bool SoundRenderer::sound_playing(SoundId id)
 {
-	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exist");
-
-	SoundSource& s = m_backend->m_sources[id.index];
-
-	m_backend->destroy_source(s);
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exist");
 
-	m_sources_id_table.destroy(id);
+	return m_backend->m_sounds[id.index].is_playing();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_min_distance(SoundSourceId id,  const float min_distance)
+void SoundRenderer::set_listener(const Vec3& /*pos*/, const Vec3& /*vel*/, const Vec3& /*or_up*/, const Vec3& /*or_at*/) const
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)min_distance;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_max_distance(SoundSourceId id,  const float max_distance)
+void SoundRenderer::set_sound_min_distance(SoundId /*id*/,  const float /*min_distance*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)max_distance;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_position(SoundSourceId id, const Vec3& pos)
+void SoundRenderer::set_sound_max_distance(SoundId /*id*/,  const float /*max_distance*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)pos;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_velocity(SoundSourceId id, const Vec3& vel)
+void SoundRenderer::set_sound_position(SoundId /*id*/, const Vec3& /*pos*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)vel;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_direction(SoundSourceId id, const Vec3& dir)
+void SoundRenderer::set_sound_velocity(SoundId /*id*/, const Vec3& /*vel*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)dir;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_pitch(SoundSourceId id, const float pitch)
+void SoundRenderer::set_sound_direction(SoundId /*id*/, const Vec3& /*dir*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)pitch;	
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_gain(SoundSourceId id, const float gain)
+void SoundRenderer::set_sound_pitch(SoundId /*id*/, const float /*pitch*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)gain;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_source_rolloff(SoundSourceId id, const float rolloff)
+void SoundRenderer::set_sound_gain(SoundId /*id*/, const float /*gain*/)
 {
 	Log::w("Stub");
-
-	(void)id;
-	(void)rolloff;
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::source_min_distance(SoundSourceId id) const
+void SoundRenderer::set_sound_rolloff(SoundId /*id*/, const float /*rolloff*/)
 {
 	Log::w("Stub");
+}
 
-	(void)id;
+//-----------------------------------------------------------------------------
+float SoundRenderer::sound_min_distance(SoundId /*id*/) const
+{
+	Log::w("Stub");
 
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::source_max_distance(SoundSourceId id) const
+float SoundRenderer::sound_max_distance(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-Vec3 SoundRenderer::source_position(SoundSourceId id) const
+Vec3 SoundRenderer::sound_position(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return Vec3::ZERO;
 }
 
 //-----------------------------------------------------------------------------
-Vec3 SoundRenderer::source_velocity(SoundSourceId id) const
+Vec3 SoundRenderer::sound_velocity(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return Vec3::ZERO;
 }
 
 //-----------------------------------------------------------------------------
-Vec3 SoundRenderer::source_direction(SoundSourceId id) const
+Vec3 SoundRenderer::sound_direction(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return Vec3::ZERO;
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::source_pitch(SoundSourceId id) const
+float SoundRenderer::sound_pitch(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::source_gain(SoundSourceId id) const
+float SoundRenderer::sound_gain(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::source_rolloff(SoundSourceId id) const
+float SoundRenderer::sound_rolloff(SoundId /*id*/) const
 {
 	Log::w("Stub");
 
-	(void)id;
-
 	return 0;
 }
 
 //-----------------------------------------------------------------------------
-bool SoundRenderer::source_playing(SoundSourceId id)
+int32_t SoundRenderer::sound_queued_buffers(SoundId id) const
 {
-	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exist");
-
-	SoundSource& s = m_backend->m_sources[id.index];
+	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exist");
 
-    SLuint32 state;
+	return m_backend->m_sounds[id.index].queued_buffers();
+}
 
-    (*s.m_player_play)->GetPlayState(s.m_player_play, &state);
+//-----------------------------------------------------------------------------
+int32_t SoundRenderer::sound_processed_buffers(SoundId id) const
+{
+	Log::w("Stub");
+}
 
-    return state == SL_PLAYSTATE_PLAYING;
-}	
 
 } // namespace crown

+ 386 - 34
engine/audio/sles/SLESRenderer.h

@@ -26,62 +26,414 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include "Assert.h"
-#include "Types.h"
+#include "SoundResource.h"
+#include "OggDecoder.h"
+#include "Vec3.h"
+#include "Log.h"
 
 namespace crown
 {
 
+static const char* sles_error_to_string(SLresult result)
+{
+	switch (result)
+	{
+	case SL_RESULT_SUCCESS: return "SL_RESULT_SUCCESS";
+	case SL_RESULT_PARAMETER_INVALID: return "SL_RESULT_PARAMETER_INVALID";
+	case SL_RESULT_MEMORY_FAILURE: return "SL_RESULT_MEMORY_FAILURE";
+	case SL_RESULT_FEATURE_UNSUPPORTED: return "SL_RESULT_FEATURE_UNSUPPORTED";
+	case SL_RESULT_RESOURCE_ERROR: return "SL_RESULT_RESOURCE_ERROR";
+	case SL_RESULT_IO_ERROR: return "SL_RESULT_IO_ERROR";
+	case SL_RESULT_PRECONDITIONS_VIOLATED: return "SL_RESULT_PRECONDITIONS_VIOLATED";
+	case SL_RESULT_CONTENT_CORRUPTED: return "SL_RESULT_CONTENT_CORRUPTED";
+	case SL_RESULT_CONTENT_UNSUPPORTED: return "SL_RESULT_CONTENT_UNSUPPORTED";
+	case SL_RESULT_CONTENT_NOT_FOUND: return "SL_RESULT_CONTENT_NOT_FOUND";
+	case SL_RESULT_PERMISSION_DENIED: return "SL_RESULT_PERMISSION_DENIED";
+	case SL_RESULT_BUFFER_INSUFFICIENT: return "SL_RESULT_BUFFER_INSUFFICIENT";
+	default: return "SL_RESULT_UNKNOWN";
+
+	}
+}
 
 //-----------------------------------------------------------------------------
-struct SoundBuffer
+void check_sles_errors(SLresult result)
 {
+	CE_ASSERT(result == SL_RESULT_SUCCESS, "SL_ERROR_CODE: %s", sles_error_to_string(result));
+}
 
-	void create(const void* data, const uint32_t size, const uint32_t sample_rate, const uint32_t channels, const uint32_t bits)
-	{
-		CE_ASSERT_NOT_NULL(data);
-		CE_ASSERT(size > 0, "Size must be > 0");
-
-		m_data = (uint16_t*)data;
-		m_size = size;
-		m_sample_rate = sample_rate;
-		m_channels = channels;
-		m_bits_per_sample = bits;
-	}
+//-----------------------------------------------------------------------------
+struct Sound
+{
+					Sound();
 
-	void update(const void* data, const uint32_t size)
-	{
-		CE_ASSERT_NOT_NULL(data);
-		CE_ASSERT(size > 0, "Size must be > 0");
+	void 			create(SLEngineItf engine, SLObjectItf out_mix_obj, SoundResource* resource);
+	void 			update();
+	void 			destroy();
+	void 			play();
+	void 			pause();
+	void 			loop(bool loop);
+	void 			set_min_distance(const float min_distance);
+	void 			set_max_distance( const float max_distance);
+	void 			set_position(const Vec3& pos);
+	void 			set_velocity(const Vec3& vel);
+	void 			set_direction(const Vec3& dir);
+	void 			set_pitch(const float pitch);
+	void 			set_gain(const float gain);
+	void 			set_rolloff(const float rolloff);
+	float 			min_distance() const;
+	float 			max_distance() const;
+	Vec3 			position() const;
+	Vec3 			velocity() const;
+	Vec3 			direction() const;
+	float 			pitch() const;
+	float 			gain() const;
+	float 			rolloff() const;
+	bool 			is_playing() const;
+	int32_t 		queued_buffers();
+	int32_t 		processed_buffers();
 
-		m_data = (uint16_t*)data;
-		m_size = size;
-	}
+	static void 	buffer_callback(SLAndroidSimpleBufferQueueItf caller, void* sound);
 
-	void destroy()
-	{
+private:
 
-	}
+	void create_stream();
+
+	void update_stream();
 
 public:
 
+	SoundResource*					m_res;
+
+	SLEngineItf						m_engine;
+	SLObjectItf 					m_out_mix_obj;
+	SLObjectItf 					m_player_obj;
+	SLPlayItf 						m_player_play;
+	SLAndroidSimpleBufferQueueItf 	m_player_bufferqueue;
+	SLSeekItf 						m_player_seek;
+	SLVolumeItf						m_player_volume;
+
+	uint32_t						m_processed_buffers;
+	
 	uint16_t* 						m_data;
 	size_t	  						m_size;
 	uint32_t  						m_sample_rate;
 	uint32_t  						m_channels;
-	uint32_t  						m_bits_per_sample;
+	uint32_t  						m_bits;
+
+	bool							m_playing  :1;
+	bool							m_looping :1;
+	bool							m_streaming :1;
+
+	OggDecoder						m_decoder;
 };
 
 //-----------------------------------------------------------------------------
-struct SoundSource
+inline void Sound::buffer_callback(SLAndroidSimpleBufferQueueItf caller, void* sound)
 {
-  	SLObjectItf 					m_player_obj;
-  	SLPlayItf 						m_player_play;
-  	SLAndroidSimpleBufferQueueItf 	m_player_bufferqueue;
-  	SLSeekItf 						m_player_seek;
-  	SLVolumeItf						m_player_volume;
+	Sound* s = (Sound*)sound;
 
-  	bool							m_loop;
-};
+	s->m_processed_buffers++;
+
+	if (s->m_streaming)
+	{
+		if (s->m_decoder.stream())
+		{
+			(*s->m_player_bufferqueue)->Enqueue(s->m_player_bufferqueue, s->m_decoder.data(), s->m_decoder.size());
+		}
+		else if (s->m_looping)
+		{
+			s->m_decoder.rewind();
+			s->m_decoder.stream();
+			(*s->m_player_bufferqueue)->Enqueue(s->m_player_bufferqueue, s->m_decoder.data(), s->m_decoder.size());	
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+inline Sound::Sound() : 
+	m_res(NULL),
+
+	m_processed_buffers(0),
+	m_data(NULL),
+	m_size(0),
+	m_sample_rate(0),
+	m_channels(0),
+	m_bits(0),
+
+	m_playing(false),
+	m_looping(false),
+	m_streaming(false)
+{
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::create(SLEngineItf engine, SLObjectItf out_mix_obj, SoundResource* resource)
+{
+	CE_ASSERT_NOT_NULL(resource);
+
+	m_engine = engine;
+	m_out_mix_obj = out_mix_obj;
+
+	m_res = resource;
+
+	SLresult result;
+
+	int32_t speakers = SL_SPEAKER_FRONT_CENTER;
+
+	// Configures buffer queue
+	SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
+
+	// Configures audio format
+	SLDataFormat_PCM format_pcm;
+	format_pcm.formatType = SL_DATAFORMAT_PCM;
+	format_pcm.numChannels = 1;	// Mono
+	format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
+	format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
+	format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
+	format_pcm.channelMask = speakers;
+	format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+
+	// Configures audio source
+	SLDataSource audio_source;
+	audio_source.pLocator = &buffer_queue;
+	audio_source.pFormat = &format_pcm;
+
+	// Configures audio output mix
+	SLDataLocator_OutputMix out_mix;
+	out_mix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
+	out_mix.outputMix = m_out_mix_obj;
+
+	// Configures audio sink
+	SLDataSink audio_sink;
+	audio_sink.pLocator = &out_mix;
+	audio_sink.pFormat = NULL;
+
+	// Creates sound player
+	const SLInterfaceID ids[] = {SL_IID_PLAY, SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
+	const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+
+	result = (*m_engine)->CreateAudioPlayer(m_engine, &m_player_obj, &audio_source, &audio_sink, 3, ids, reqs);
+	check_sles_errors(result);
+
+	result = (*m_player_obj)->Realize(m_player_obj, SL_BOOLEAN_FALSE);
+	check_sles_errors(result);
+
+	// Gets interfaces
+	result = (*m_player_obj)->GetInterface(m_player_obj, SL_IID_PLAY, &m_player_play);
+	check_sles_errors(result);
+
+	result = (*m_player_obj)->GetInterface(m_player_obj, SL_IID_BUFFERQUEUE, &m_player_bufferqueue);
+	check_sles_errors(result);
+
+	result = (*m_player_obj)->GetInterface(m_player_obj, SL_IID_VOLUME, &m_player_volume);
+	check_sles_errors(result);
+
+	(*m_player_bufferqueue)->RegisterCallback(m_player_bufferqueue, Sound::buffer_callback, this);
+
+	// Manage simple sound or stream
+	m_streaming = m_res->sound_type() == ST_OGG;
+
+	if (m_streaming)
+	{
+		m_decoder.init((char*)m_res->data(), m_res->size());
+
+		m_decoder.stream();
+		(*m_player_bufferqueue)->Enqueue(m_player_bufferqueue, m_decoder.data(), m_decoder.size());
+	}
+	else
+	{
+		(*m_player_bufferqueue)->Enqueue(m_player_bufferqueue, m_res->data(), m_res->size());
+	}
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::update()
+{
+	// not needed right now
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::destroy()
+{
+	if (m_player_obj)
+	{
+		SLuint32 state;
+		(*m_player_obj)->GetState(m_player_obj, &state);
+
+		if (state == SL_OBJECT_STATE_REALIZED)
+		{
+			(*m_player_bufferqueue)->Clear(m_player_bufferqueue);
+			(*m_player_obj)->AbortAsyncOperation(m_player_obj);
+			(*m_player_obj)->Destroy(m_player_obj);
+
+			m_player_obj = NULL;
+			m_player_play = NULL;
+			m_player_bufferqueue = NULL;
+			m_player_volume = NULL;
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::play()
+{
+	SLresult result = (*m_player_play)->SetPlayState(m_player_play, SL_PLAYSTATE_PLAYING);
+	check_sles_errors(result);
+
+	m_playing = true;
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::pause()
+{
+	SLresult result = (*m_player_play)->SetPlayState(m_player_play, SL_PLAYSTATE_PAUSED);
+	check_sles_errors(result);
+
+	m_playing = false;
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::loop(bool loop)
+{
+	m_looping = true;
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_min_distance(const float min_distance)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_max_distance( const float max_distance)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_position(const Vec3& pos)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_velocity(const Vec3& vel)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_direction(const Vec3& dir)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_pitch(const float pitch)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_gain(const float gain)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline void Sound::set_rolloff(const float rolloff)
+{
+	Log::w("stub");
+}
+
+//-----------------------------------------------------------------------------
+inline float Sound::min_distance() const
+{
+	Log::w("stub");
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+inline float Sound::max_distance() const
+{
+	Log::w("stub");
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+inline Vec3 Sound::position() const
+{
+	Log::w("stub");
+
+	return Vec3::ZERO;
+}
+
+//-----------------------------------------------------------------------------
+inline Vec3 Sound::velocity() const
+{
+	Log::w("stub");
+
+	return Vec3::ZERO;
+}
+
+//-----------------------------------------------------------------------------
+inline Vec3 Sound::direction() const
+{
+	Log::w("stub");
+
+	return Vec3::ZERO;
+}
+
+//-----------------------------------------------------------------------------
+inline float Sound::pitch() const
+{
+	Log::w("stub");
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+inline float Sound::gain() const
+{
+	Log::w("stub");
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+inline float Sound::rolloff() const
+{
+	Log::w("stub");
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+inline bool Sound::is_playing() const
+{
+	SLuint32 state;
+
+	(*m_player_play)->GetPlayState(m_player_play, &state);
+
+	return state == SL_PLAYSTATE_PLAYING;
+}
+
+//-----------------------------------------------------------------------------
+inline int32_t Sound::queued_buffers()
+{
+	SLAndroidSimpleBufferQueueState state;
+
+	(*m_player_bufferqueue)->GetState(m_player_bufferqueue, &state);
+
+	return state.count;
+}
+
+//-----------------------------------------------------------------------------
+inline int32_t Sound::processed_buffers()
+{
+	return m_processed_buffers;
+}
 
-} // namespace crown
+}// namespace crown

+ 0 - 3
engine/os/android/AndroidDevice.cpp

@@ -27,7 +27,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <jni.h>
 #include "Device.h"
 #include "Renderer.h"
-#include "Log.h"
 
 namespace crown
 {
@@ -104,14 +103,12 @@ extern "C" JNIEXPORT void JNICALL Java_crown_android_CrownLib_frame(JNIEnv* /*en
 extern "C" JNIEXPORT void JNICALL Java_crown_android_CrownLib_initRenderer(JNIEnv* /*env*/, jobject /*obj*/)
 {
 	device()->renderer()->init();
-	Log::i("Renderer initialized");
 }
 
 //-----------------------------------------------------------------------------
 extern "C" JNIEXPORT void JNICALL Java_crown_android_CrownLib_shutdownRenderer(JNIEnv* /*env*/, jobject /*obj*/)
 {
 	device()->renderer()->shutdown();
-	Log::i("Renderer shutdowned");
 }
 
 } // namespace crown