瀏覽代碼

update SoundRenderer

mikymod 12 年之前
父節點
當前提交
328c197a0f
共有 2 個文件被更改,包括 148 次插入154 次删除
  1. 42 67
      engine/audio/SoundRenderer.h
  2. 106 87
      engine/audio/al/ALRenderer.cpp

+ 42 - 67
engine/audio/SoundRenderer.h

@@ -30,18 +30,20 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Allocator.h"
 #include "Types.h"
 
-#define	MAX_SOUNDS 64
+#define	MAX_SOUND_BUFFERS 64
+#define MAX_SOUND_SOURCES 64
 
 namespace crown
 {
-//-----------------------------------------------------------------------------
-typedef 	Id 		SoundId;
-
 //-----------------------------------------------------------------------------
 class SoundRendererImpl;
 class SoundResource;
 class Vector3;
 
+//-----------------------------------------------------------------------------
+typedef Id	SoundBufferId;
+typedef	Id	SoundSourceId;
+
 //-----------------------------------------------------------------------------
 class SoundRenderer
 {
@@ -60,99 +62,72 @@ public:
 
 	void					frame();
 
-	/// Returns number of sounds actually in use
-	uint32_t				num_sounds();
-
-	/// Sets listener parameters. @a position affects audibility of sounds, 
-	/// @a velocity affects doppler shift and @a orientation affects how a sound could be heard
 	void					set_listener(const Vector3& pos, const Vector3& vel, const Vector3& or_up, const Vector3& or_at) const;
 
-	/// Creates a sound of sound 
-	SoundId					create_sound(SoundResource* resource);
+	SoundBufferId			create_sound_buffer(void* data, size_t size, uint32_t sample_rate, uint32_t num_channels, uint16_t bits_ps);
 
-	/// Destroys a sound, specified by @a id, previously created
-	void					destroy_sound(SoundId id);
+	void					destroy_sound_buffer(SoundBufferId id);
 
-	/// Plays a sound, specified by sound @a sid and a buffer @a bid
-	void					play_sound(SoundId id);
+	SoundSourceId			create_sound_source();
 
-	/// Pauses a sound, specified by @a id
-	void					pause_sound(SoundId id);
+	void					destroy_sound_source(SoundSourceId id);
 
-	/// 
-	void					set_sound_loop(SoundId id, bool loop);
+	void					bind_buffer(SoundBufferId buffer, SoundSourceId source);
 
-	///	Sets sound's @a min_distance. From @a min_distance to @a max_distance, sound
-	/// scales from full volume to silence
-	void					set_sound_min_distance(SoundId id, const float min_distance);
+	void					unbind_buffer(SoundSourceId id);
 
-	///	Sets sound's @a max_distance. From @a min_distance to @a max_distance, sound
-	/// scales from full volume to silence
-	void					set_sound_max_distance(SoundId id, const float max_distance);
+	void					play_sound(SoundSourceId id);
 
-	/// Sets sound's @a position. It affects sound audibility
-	void					set_sound_position(SoundId id, const Vector3& pos);
+	void					pause_sound(SoundSourceId id);
 
-	/// Sets sound's @a velocity. It affects doppler shift
-	void					set_sound_velocity(SoundId id, const Vector3& vel);
+	void					set_sound_loop(SoundSourceId id, bool loop);
 
-	/// Sets sound's @a direction. It affects how a sound could be heard
-	void					set_sound_direction(SoundId id, const Vector3& dir);
+	void					set_sound_min_distance(SoundSourceId id, const float min_distance);
 
-	/// Sets sound's @a pitch.
-	void					set_sound_pitch(SoundId id, const float pitch);
+	void					set_sound_max_distance(SoundSourceId id, const float max_distance);
 
-	/// Sets sound's @a gain, that is measure sound's amplification
-	void					set_sound_gain(SoundId id, const float gain);
+	void					set_sound_position(SoundSourceId id, const Vector3& pos);
 
-	/// Sets sound's @a rolloff factor. Greater it is, greater sound's attenuation is
-	void					set_sound_rolloff(SoundId id, const float rolloff);
+	void					set_sound_velocity(SoundSourceId id, const Vector3& vel);
 
-	/// Returns minimum distance of @a id
-	float					sound_min_distance(SoundId id) const;
+	void					set_sound_direction(SoundSourceId id, const Vector3& dir);
 
-	/// Returns maximum distance of @a id
-	float					sound_max_distance(SoundId id) const;
-	
-	/// Returns position of @a id
-	Vector3					sound_position(SoundId id) const;
+	void					set_sound_pitch(SoundSourceId id, const float pitch);
 
-	/// Returns velocity of @a id
-	Vector3					sound_velocity(SoundId id) const;
+	void					set_sound_gain(SoundSourceId id, const float gain);
 
-	/// Returns direction of @a id
-	Vector3					sound_direction(SoundId id) const;
+	void					set_sound_rolloff(SoundSourceId id, const float rolloff);
 
-	/// Returns pitch of @a id
-	float					sound_pitch(SoundId id) const;
+	float					sound_min_distance(SoundSourceId id) const;
 
-	/// Returns gain of @a id
-	float					sound_gain(SoundId id) const;
+	float					sound_max_distance(SoundSourceId id) const;
+	
+	Vector3					sound_position(SoundSourceId id) const;
 
-	/// Returns rolloff factor of @a id
-	/// Rolloff: perceived volume decreases at a fixed rate as a sound sound moves away from the listener
-	float					sound_rolloff(SoundId id) const;
+	Vector3					sound_velocity(SoundSourceId id) const;
 
-	/// Returns number of queued buffers of @a id
-	int32_t					sound_queued_buffers(SoundId id) const;
+	Vector3					sound_direction(SoundSourceId id) const;
 
-	/// Returns number of processed buffers of @a id
-	int32_t					sound_processed_buffers(SoundId id) const;
+	float					sound_pitch(SoundSourceId id) const;
 
-	/// Is sound @a id playing?
-	bool					sound_playing(SoundId id);
+	float					sound_gain(SoundSourceId id) const;
 
-private:
+	float					sound_rolloff(SoundSourceId id) const;
 
-	Allocator& 				m_allocator;
+	int32_t					sound_queued_buffers(SoundSourceId id) const;
 
-	SoundRendererImpl*		m_impl;
+	int32_t					sound_processed_buffers(SoundSourceId id) const;
 
-	bool 					m_is_paused;
+	bool					sound_playing(SoundSourceId id);
+
+private:
 
-	IdTable<MAX_SOUNDS>		m_sounds_id_table;
+	Allocator& 					m_allocator;
+	SoundRendererImpl*			m_impl;
+	bool 						m_is_paused;
 
-	uint32_t				m_num_sounds;
+	IdTable<MAX_SOUND_BUFFERS>	m_buffers_id_table;
+	IdTable<MAX_SOUND_SOURCES>	m_sources_id_table;
 };
 
 } // namespace crown

+ 106 - 87
engine/audio/al/ALRenderer.cpp

@@ -102,19 +102,17 @@ private:
 	ALCdevice*				m_device;
 	ALCcontext*				m_context;
 
-	Sound 		 			m_sounds[MAX_SOUNDS];
+	SoundBuffer	 			m_buffers[MAX_SOUND_BUFFERS];
+	SoundSource				m_sources[MAX_SOUND_SOURCES];
 
 private:
 
 	friend class 			SoundRenderer;
 };
-//-----------------------------------------------------------------------------
-
 
 //-----------------------------------------------------------------------------
-SoundRenderer::SoundRenderer(Allocator& allocator) : 
-	m_allocator(allocator),
-	m_num_sounds(0)
+SoundRenderer::SoundRenderer(Allocator& allocator)
+	: m_allocator(allocator)
 {
 	m_impl = CE_NEW(m_allocator, SoundRendererImpl);
 }
@@ -143,210 +141,231 @@ void SoundRenderer::shutdown()
 //-----------------------------------------------------------------------------
 void SoundRenderer::frame()
 {
-	// TODO: needs additional works, but it's ok right now
-	for (uint32_t i = 0; i < m_num_sounds; i++)
-	{
-		if (m_impl->m_sounds[i].is_playing())
-		{
-			m_impl->m_sounds[i].update();
-		}
-	}
+
 }
 
 //-----------------------------------------------------------------------------
-uint32_t SoundRenderer::num_sounds()
+void SoundRenderer::set_listener(const Vector3& pos, const Vector3& vel, const Vector3& or_up, const Vector3& or_at) const
 {
-	return m_num_sounds;
+	m_impl->set_listener(pos, vel, or_up, or_at);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_listener(const Vector3& pos, const Vector3& vel, const Vector3& or_up, const Vector3& or_at) const
+SoundBufferId SoundRenderer::create_sound_buffer(void* data, size_t size, uint32_t sample_rate, uint32_t num_channels, uint16_t bits_ps)
 {
-	m_impl->set_listener(pos, vel, or_up, or_at);
+	SoundBufferId id = m_buffers_id_table.create();
+
+	m_impl->m_buffers[id.index].create(sample_rate, num_channels, bits_ps);
+	m_impl->m_buffers[id.index].update(data, size);
+
+	return id;
 }
 
 //-----------------------------------------------------------------------------
-SoundId SoundRenderer::create_sound(SoundResource* resource)
+void SoundRenderer::destroy_sound_buffer(SoundBufferId id)
 {
-	SoundId id = m_sounds_id_table.create();
+	CE_ASSERT(m_buffers_id_table.has(id), "SoundBuffer does not exists");
 
-	m_impl->m_sounds[id.index].create(resource);
+	m_impl->m_buffers[id.index].destroy();
 
-	m_num_sounds++;
+	m_buffers_id_table.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+SoundSourceId SoundRenderer::create_sound_source()
+{
+	SoundSourceId id = m_sources_id_table.create();
+
+	m_impl->m_sources[id.index].create();
 
 	return id;
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::destroy_sound(SoundId id)
+void SoundRenderer::destroy_sound_source(SoundSourceId id)
+{
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
+
+	m_impl->m_sources[id.index].destroy();
+
+	m_sources_id_table.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+void SoundRenderer::bind_buffer(SoundBufferId buffer, SoundSourceId source)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_buffers_id_table.has(buffer), "SoundBuffer does not exists");
+	CE_ASSERT(m_sources_id_table.has(source), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].destroy();
+	m_impl->m_sources[source.index].bind_buffer(m_impl->m_buffers[buffer.index].m_id);
+}
 
-	m_sounds_id_table.destroy(id);
+//-----------------------------------------------------------------------------
+void SoundRenderer::unbind_buffer(SoundSourceId id)
+{
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_num_sounds--;
+	m_impl->m_sources[id.index].unbind_buffer();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::play_sound(SoundId id)
+void SoundRenderer::play_sound(SoundSourceId id)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].play();
+	m_impl->m_sources[id.index].play();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::pause_sound(SoundId id)
+void SoundRenderer::pause_sound(SoundSourceId id)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].pause();
+	m_impl->m_sources[id.index].pause();
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_loop(SoundId id, bool loop)
+void SoundRenderer::set_sound_loop(SoundSourceId id, bool loop)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].loop(loop);
+	m_impl->m_sources[id.index].loop(loop);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_min_distance(SoundId id, const float min_distance)
+void SoundRenderer::set_sound_min_distance(SoundSourceId id, const float min_distance)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_min_distance(min_distance);
+	m_impl->m_sources[id.index].set_min_distance(min_distance);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_max_distance(SoundId id, const float max_distance)
+void SoundRenderer::set_sound_max_distance(SoundSourceId id, const float max_distance)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_max_distance(max_distance);
+	m_impl->m_sources[id.index].set_max_distance(max_distance);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_position(SoundId id, const Vector3& pos)
+void SoundRenderer::set_sound_position(SoundSourceId id, const Vector3& pos)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_position(pos);
+	m_impl->m_sources[id.index].set_position(pos);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_velocity(SoundId id, const Vector3& vel)
+void SoundRenderer::set_sound_velocity(SoundSourceId id, const Vector3& vel)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_velocity(vel);
+	m_impl->m_sources[id.index].set_velocity(vel);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_direction(SoundId id, const Vector3& dir)
+void SoundRenderer::set_sound_direction(SoundSourceId id, const Vector3& dir)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_direction(dir);
+	m_impl->m_sources[id.index].set_direction(dir);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_pitch(SoundId id, const float pitch)
+void SoundRenderer::set_sound_pitch(SoundSourceId id, const float pitch)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_pitch(pitch);
+	m_impl->m_sources[id.index].set_pitch(pitch);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_gain(SoundId id, const float gain)
+void SoundRenderer::set_sound_gain(SoundSourceId id, const float gain)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_gain(gain);
+	m_impl->m_sources[id.index].set_gain(gain);
 }
 
 //-----------------------------------------------------------------------------
-void SoundRenderer::set_sound_rolloff(SoundId id, const float rolloff)
+void SoundRenderer::set_sound_rolloff(SoundSourceId id, const float rolloff)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	m_impl->m_sounds[id.index].set_rolloff(rolloff);
+	m_impl->m_sources[id.index].set_rolloff(rolloff);
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::sound_min_distance(SoundId id) const
+float SoundRenderer::sound_min_distance(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].min_distance();
+	return m_impl->m_sources[id.index].min_distance();
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::sound_max_distance(SoundId id) const
+float SoundRenderer::sound_max_distance(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].max_distance();
+	return m_impl->m_sources[id.index].max_distance();
 }
 
 //-----------------------------------------------------------------------------
-Vector3 SoundRenderer::sound_position(SoundId id) const
+Vector3 SoundRenderer::sound_position(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].position();
+	return m_impl->m_sources[id.index].position();
 }
 
 //-----------------------------------------------------------------------------
-Vector3 SoundRenderer::sound_velocity(SoundId id) const
+Vector3 SoundRenderer::sound_velocity(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].velocity();
+	return m_impl->m_sources[id.index].velocity();
 }
 
 //-----------------------------------------------------------------------------
-Vector3 SoundRenderer::sound_direction(SoundId id) const
+Vector3 SoundRenderer::sound_direction(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].direction();
+	return m_impl->m_sources[id.index].direction();
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::sound_pitch(SoundId id) const
+float SoundRenderer::sound_pitch(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].pitch();
+	return m_impl->m_sources[id.index].pitch();
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::sound_gain(SoundId id) const
+float SoundRenderer::sound_gain(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].gain();
+	return m_impl->m_sources[id.index].gain();
 }
 
 //-----------------------------------------------------------------------------
-float SoundRenderer::sound_rolloff(SoundId id) const
+float SoundRenderer::sound_rolloff(SoundSourceId id) const
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].rolloff();
+	return m_impl->m_sources[id.index].rolloff();
 }
 
 //-----------------------------------------------------------------------------
-bool SoundRenderer::sound_playing(SoundId id)
+bool SoundRenderer::sound_playing(SoundSourceId id)
 {
-	CE_ASSERT(m_sounds_id_table.has(id), "Sound does not exists");
+	CE_ASSERT(m_sources_id_table.has(id), "SoundSource does not exists");
 
-	return m_impl->m_sounds[id.index].is_playing();
+	return m_impl->m_sources[id.index].is_playing();
 }
 
 } // namespace crown