|
|
@@ -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
|