return SOUND_POOL_ERROR_NONE;
}
+/*
+ * Checks selected stream for availability of playing. It depends
+ * on its position in priority queue and current state of other streams.
+ * The queue is analyzed downwards to lower priorities skipping all paused
+ * streams until first suspended stream is found.
+*/
sound_pool_error_e _sound_stream_priority_check(stream_priority_manager_t *mgr,
sound_stream_t *stream, gboolean *out)
{
SP_INST_CHECK(mgr->pool->sources, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_INST_CHECK(g_hash_table_lookup(mgr->pool->sources,
stream->parent_source->tag_name), SOUND_POOL_ERROR_KEY_NOT_AVAILABLE);
+ SP_RETVM_IF(NULL == mgr->priority_queue, SOUND_POOL_ERROR_INVALID_PARAMETER,
+ "Can't perform checking stream [%s] due to priority queue is NULL.",
+ stream->parent_source->tag_name);
*out = FALSE;
- int position = g_list_index(mgr->priority_queue, (gconstpointer)stream);
- SP_RETVM_IF(-1 == position, SOUND_POOL_ERROR_INVALID_PARAMETER,
- "Can't find stream in priority queue[%s]", stream->parent_source->tag_name);
+ sound_stream_t *ref_stream = (sound_stream_t*)(mgr->priority_queue->data);
+ gboolean flag_target_priority = FALSE;
+ gboolean flag_terminator = FALSE;
+ unsigned rank = ref_stream->priority;
+
+ if (rank == stream->priority) {
+ *out = TRUE;
+ } else {
+ GList *iter = mgr->priority_queue;
+ for (; iter != NULL && !flag_terminator; iter = iter->next) {
+ sound_stream_t *str = (sound_stream_t *)iter->data;
+ if ((ref_stream->priority > str->priority)) {
+ if (flag_target_priority) {
+ flag_terminator = TRUE;
+ continue;
+ }
+ rank = ref_stream->priority;
+ ref_stream = str;
+ }
+
+ if (SOUND_POOL_STREAM_STATE_PLAYING == str->state ||
+ SOUND_POOL_STREAM_STATE_SUSPENDED == str->state) {
+ rank = str->priority;
+ flag_target_priority = TRUE;
+ }
+ }
- *out = TRUE;
+ if (rank == stream->priority)
+ *out = TRUE;
+ }
SP_DEBUG_FLEAVE();
return SOUND_POOL_ERROR_NONE;
gboolean can_run = FALSE;
if (mgr->pool->state == SOUND_POOL_STATE_INACTIVE) {
- SP_INFO("No need to update priority, Sound pool is INACTIVE.");
+ SP_INFO("No need to update streams state based on priority, "
+ "because of Sound pool is INACTIVE.");
return;
}
GList *iter = mgr->priority_queue;
for (; iter != NULL; iter = iter->next) {
sound_stream_t *stream = (sound_stream_t *)iter->data;
+
if (SOUND_POOL_ERROR_NONE != _sound_stream_priority_check(mgr, stream,
&can_run))
continue;
if (TRUE == can_run) {
- if (SOUND_POOL_STREAM_STATE_PLAYING != stream->state)
+ if (SOUND_POOL_STREAM_STATE_PLAYING != stream->state &&
+ SOUND_POOL_STREAM_STATE_PAUSED != stream->state)
_sound_stream_play(stream);
- } else {
- if (SOUND_POOL_STREAM_STATE_PLAYING == stream->state)
- _sound_stream_pause(stream);
+ } else if (SOUND_POOL_STREAM_STATE_PLAYING == stream->state) {
+ _sound_stream_pause(stream);
stream->state_previous = stream->state;
stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
if (_stream_cb_manager_register_event(mgr->pool->cbmgr, stream) !=
sound_pool_t *_pool = (sound_pool_t *)pool;
sound_source_t *_source = NULL;
+ sound_pool_error_e ret_destroy = SOUND_POOL_ERROR_NONE;
sound_pool_error_e ret = _sound_pool_get_source_by_tag(_pool, tag, &_source);
SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
"getting sound source [%s] from the sound pool", tag);
"Error while creating sound source instance.");
ret = _sound_stream_set_loop(_stream, loop);
- SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
- "setting sound stream loop parameter", tag);
+ if (ret != SOUND_POOL_ERROR_NONE)
+ GOTO_FAIL("Error occurred when setting sound stream loop parameter", cfail);
ret = _sound_stream_set_volume(_stream, volume);
- SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
- "setting sound stream volume parameter", tag);
+ if (ret != SOUND_POOL_ERROR_NONE)
+ GOTO_FAIL("Error occurred when setting sound stream volume " "parameter",
+ cfail);
if (callback) {
ret = _sound_stream_set_callback(_stream, callback, data);
- SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
- "setting sound stream callback", tag);
+ if (ret != SOUND_POOL_ERROR_NONE)
+ GOTO_FAIL("Error occurred when setting sound stream callback", cfail);
}
ret = _sound_stream_set_priority(_stream, priority);
- SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
- "setting sound stream priority parameter", tag);
+ if (ret != SOUND_POOL_ERROR_NONE)
+ GOTO_FAIL("Error occurred when setting sound stream priority "
+ "parameter", cfail);
*id = _stream->id;
SP_DEBUG_FLEAVE();
return ret;
+
+cfail:
+ ret_destroy = _sound_stream_destroy(_stream);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret_destroy, ret_destroy,
+ "Error occurred during removal of uncompleted sound stream.");
+ SP_DEBUG_FLEAVE();
+ return ret;
}
sound_pool_error_e sound_pool_stream_pause(sound_pool_h pool, unsigned id)
SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
"pausing sound stream [%u]", id);
+ _sound_stream_priority_update_playback(_pool->mgr_priority);
+
SP_DEBUG_FLEAVE();
return ret;
}
SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when "
"resuming sound stream [%u]", id);
+ _sound_stream_priority_update_playback(_pool->mgr_priority);
+
SP_DEBUG_FLEAVE();
return ret;
}
sound_pool_state_e old_state = pool->state;
pool->state = SOUND_POOL_STATE_ACTIVE;
+ _sound_stream_priority_update_playback(pool->mgr_priority);
+
/* Generate array of all AlSources in pool */
GPtrArray *streams = NULL;
if (g_hash_table_size(pool->streams) > 0) {
SOUND_POOL_ERROR_OUT_OF_MEMORY,
"Memory alloc failure. Can't create sound _src");
+ sound_pool_error_e ret_destroy = SOUND_POOL_ERROR_NONE;
sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
alGenBuffers(1, &_src->al_buffer);
if (alGetError() != AL_NO_ERROR) {
return ret;
cfail:
- ret = _sound_source_destroy(_src);
- SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "Error occurred during removal "
- "of sound source[%s].", tag);
+ ret_destroy = _sound_source_destroy(_src);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret_destroy, ret_destroy,
+ "Error occurred during removal of sound source[%s].", tag);
SP_DEBUG_FLEAVE();
return ret;
}
alSourcei(stream->al_source, AL_BUFFER, 0);
alDeleteSources(1, &stream->al_source);
SP_DEBUG("Deleting OpenAL source with id [%u]", stream->al_source);
+ if (alGetError() != AL_NO_ERROR)
+ SP_ERROR("OpenAL error while stream[%d] destroying.", stream->id);
} else {
SP_DEBUG("Can't set current context for deleting OpenAL source with id [%u]",
stream->al_source);
SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
sound_pool_t *pool = stream->parent_source->parent_pool;
+ sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
stream->state != SOUND_POOL_STREAM_STATE_PAUSED &&
stream->state == SOUND_POOL_STREAM_STATE_NONE) {
stream->state_previous = stream->state;
stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
- if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
- SOUND_POOL_ERROR_NONE)
- SP_DEBUG("State changing event wasn't registered."
- "Callbacks will be not called");
- SP_DEBUG("Don't play due to SoundPool is in inactive state.");
+ ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
+ "wasn't registered. Callbacks will be not called");
+ SP_INFO("Don't play due to SoundPool is in inactive state.");
} else {
alSourcePlay(stream->al_source);
}
SP_DEBUG_FLEAVE();
- return SOUND_POOL_ERROR_NONE;
+ return ret;
}
sound_pool_error_e _sound_stream_pause(sound_stream_t *stream)
SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
sound_pool_t *pool = stream->parent_source->parent_pool;
+ sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
stream->state != SOUND_POOL_STREAM_STATE_PLAYING,
stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED) {
stream->state_previous = stream->state;
stream->state = SOUND_POOL_STREAM_STATE_PAUSED;
- if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
- SOUND_POOL_ERROR_NONE)
- SP_DEBUG("State changing event wasn't registered."
- "Callbacks will be not called");
- SP_DEBUG("Don't paused due to SoundPool is in inactive state.");
+ ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
+ "wasn't registered. Callbacks will be not called");
+ SP_INFO("Don't paused due to SoundPool is in inactive state.");
} else {
alSourcePause(stream->al_source);
}
SP_DEBUG_FLEAVE();
- return SOUND_POOL_ERROR_NONE;
+ return ret;
}
sound_pool_error_e _sound_stream_resume(sound_stream_t *stream)
SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
sound_pool_t *pool = stream->parent_source->parent_pool;
+ sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PAUSED,
SOUND_POOL_ERROR_INVALID_OPERATION, "Can't resume stream in [%s] "
{
stream->state_previous = stream->state;
stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
- if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
- SOUND_POOL_ERROR_NONE)
- SP_DEBUG("State changing event wasn't registered."
- "Callbacks will be not called");
- SP_DEBUG("Don't resumed due to SoundPool is in inactive state.");
+ ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
+ "wasn't registered. Callbacks will be not called");
+ SP_INFO("Don't resumed due to SoundPool is in inactive state.");
} else {
alSourcePlay(stream->al_source);
}
SP_DEBUG_FLEAVE();
- return SOUND_POOL_ERROR_NONE;
+ return ret;
}
sound_pool_error_e _sound_stream_stop(sound_stream_t *stream)
SP_DEBUG_FENTER();
SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
SP_INST_CHECK(stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
- SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority, SOUND_POOL_ERROR_INVALID_PARAMETER);
+ SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority,
+ SOUND_POOL_ERROR_INVALID_PARAMETER);
+ sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
stream->priority = rank;
if (stream->parent_source->parent_pool->state == SOUND_POOL_STATE_INACTIVE) {
if (stream->state == SOUND_POOL_STREAM_STATE_NONE) {
stream->state_previous = stream->state;
stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
- if (_stream_cb_manager_register_event(
- stream->parent_source->parent_pool->cbmgr, stream)
- != SOUND_POOL_ERROR_NONE)
- SP_DEBUG(
- "State changing event wasn't registered." "Callbacks"
- " will be not called");
+ ret = _stream_cb_manager_register_event( stream->parent_source->parent_pool->cbmgr,
+ stream);
+ SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
+ "wasn't registered. Callbacks will be not called");
}
SP_DEBUG("No need to update priority, Sound pool is INACTIVE.");
return SOUND_POOL_ERROR_NONE;