Fix for SVACE defects
[platform/core/api/sound-pool.git] / src / stream.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file stream.c
19  * @brief This file include implementation of protected API
20  * for the sound streams(OpenAL sources) as part of SoundPool.
21  */
22
23 #include "internal/stream.h"
24 #include "internal/priority.h"
25
26 #include "internal/stream_cb_manager.h"
27
28 #define DEFAULT_STREAM_PRIORITY 255U
29 #define DEFAULT_STREAM_LOOP     1U
30 #define DEFAULT_STREAM_VOLUME   1.0f
31
32 static const char *__stringify_stream_state(sound_pool_stream_state_e state);
33 static void __al_source_state_cb(ALuint source, ALenum state, ALvoid *data);
34 static sound_pool_error_e __sound_pool_add_stream(sound_pool_t *pool, sound_stream_t *stream);
35 static sound_pool_error_e __sound_pool_remove_stream(sound_pool_t *pool, sound_stream_t *stream);
36
37 static const char *__stringify_stream_state(sound_pool_stream_state_e state)
38 {
39         switch (state) {
40         case SOUND_POOL_STREAM_STATE_NONE:
41                 return "SOUND_POOL_STREAM_STATE_NONE";
42         case SOUND_POOL_STREAM_STATE_PLAYING:
43                 return "SOUND_POOL_STREAM_STATE_PLAYING";
44         case SOUND_POOL_STREAM_STATE_PAUSED:
45                 return "SOUND_POOL_STREAM_STATE_PAUSED";
46         case SOUND_POOL_STREAM_STATE_SUSPENDED:
47                 return "SOUND_POOL_STREAM_STATE_SUSPENDED";
48         case SOUND_POOL_STREAM_STATE_STOPPED:
49                 return "SOUND_POOL_STREAM_STATE_STOPPED";
50         case SOUND_POOL_STREAM_STATE_FINISHED:
51                 return "SOUND_POOL_STREAM_STATE_FINISHED";
52         default:
53                 return "";
54         }
55 }
56
57 static void __al_source_state_cb(ALuint source, ALenum state, ALvoid *data)
58 {
59         SP_DEBUG_FENTER();
60
61         sound_stream_t *stream = (sound_stream_t *)data;
62         SP_RETM_IF(!stream, "Can't handle stream in OpenAL callback, it is NULL");
63         sound_pool_t *pool = stream->parent_source->parent_pool;
64         SP_RETM_IF(!pool, "Can't handle stream in OpenAL callback, stream's sound "
65                         "pool is NULL");
66
67         stream->state_previous = stream->state;
68
69         switch (state) {
70         case AL_INITIAL:
71                 stream->state = SOUND_POOL_STREAM_STATE_NONE;
72                 break;
73         case AL_PLAYING:
74                 stream->state = SOUND_POOL_STREAM_STATE_PLAYING;
75                 break;
76         case AL_PAUSED:
77                 if (pool->state == SOUND_POOL_STATE_INACTIVE)
78                         stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
79                 else if (pool->state == SOUND_POOL_STATE_ACTIVE)
80                         stream->state = SOUND_POOL_STREAM_STATE_PAUSED;
81                 break;
82         case AL_STOPPED:
83                 if (stream->stopped)
84                         stream->state = SOUND_POOL_STREAM_STATE_STOPPED;
85                 else
86                         stream->state = SOUND_POOL_STREAM_STATE_FINISHED;
87                 break;
88         default:
89                 SP_ERROR("Invalid OpenAl state value [%#04x]", state);
90                 return;
91         }
92
93         SP_INFO("Stream [%s:%d] state changed from [%s] to [%s]",
94                         stream->parent_source->tag_name, stream->id,
95                         __stringify_stream_state(stream->state_previous),
96                         __stringify_stream_state(stream->state));
97
98         SP_RETM_IF(_stream_cb_manager_register_event(pool->cbmgr, stream) !=
99                         SOUND_POOL_ERROR_NONE, "State changing event wasn't registered."
100                         "Callbacks will be not called");
101
102         SP_DEBUG_FLEAVE();
103 }
104
105 static sound_pool_error_e __sound_pool_add_stream(sound_pool_t *pool,
106                 sound_stream_t *stream)
107 {
108         SP_DEBUG_FENTER();
109         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
110         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
111         SP_RETVM_IF(!pool->streams, SOUND_POOL_ERROR_INVALID_OPERATION, "Sound "
112                         "pool to add the stream is corrupted: NULL streams hash table");
113         stream->id = ++(pool->max_stream_index);
114         SP_DEBUG("Id assigned to the stream is [%u]", stream->id);
115         SP_RETVM_IF(g_hash_table_contains(pool->streams, (gpointer)&stream->id),
116                         SOUND_POOL_ERROR_INVALID_PARAMETER,
117                         "Stream ID already exists in streams hash table.");
118         SP_RETVM_IF(stream->parent_source->parent_pool != pool,
119                         SOUND_POOL_ERROR_INVALID_OPERATION, "Sound stream can't be added "
120                         "to the pool different to the pool for which sound stream was created");
121
122         SP_RETVM_IF(!g_hash_table_insert(pool->streams, (gpointer)&stream->id, stream),
123                         SOUND_POOL_ERROR_INVALID_OPERATION, "Error occurred when adding "
124                         "the stream [%u] to the sound pool", stream->id);
125
126         sound_pool_error_e ret =
127                         _sound_stream_priority_add_stream(pool->mgr_priority, stream);
128         SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "Error occurred when adding "
129                         "the stream [%u] to the priority queue.", stream->id);
130
131         SP_DEBUG_FLEAVE();
132         return SOUND_POOL_ERROR_NONE;
133 }
134
135 static sound_pool_error_e __sound_pool_remove_stream(sound_pool_t *pool, sound_stream_t *stream)
136 {
137         SP_DEBUG_FENTER();
138         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
139         SP_INST_CHECK(pool->mgr_priority, SOUND_POOL_ERROR_INVALID_PARAMETER);
140         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
141         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
142
143         if (stream->parent_source->parent_pool == pool) {
144                 if (!g_hash_table_remove(pool->streams, &stream->id)
145                                 || SOUND_POOL_ERROR_NONE
146                                                 != _sound_stream_priority_remove_stream(pool->mgr_priority,
147                                                                 stream))
148                         SP_DEBUG("Id [%u] doesn't exist in streams hash table", stream->id);
149                 else
150                         SP_INFO("[%u] sound stream was removed from pool", stream->id);
151         } else {
152                 SP_DEBUG("Stream wasn't removed from sound pool as it isn't known by "
153                                 "the pool for which operation is performed");
154         }
155
156         SP_DEBUG_FLEAVE();
157         return SOUND_POOL_ERROR_NONE;
158 }
159
160 sound_pool_error_e _sound_stream_create(sound_source_t *src,
161                 sound_stream_t **stream)
162 {
163         SP_DEBUG_FENTER();
164         SP_RETVM_IF(!src, SOUND_POOL_ERROR_INVALID_PARAMETER,
165                         "Can't create sound stream in NULL sound source");
166         SP_RETVM_IF(!stream, SOUND_POOL_ERROR_INVALID_PARAMETER,
167                         "Can't create sound stream. Stream pointer is NULL");
168         SP_RETVM_IF(!src->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER,
169                         "Can't create sound stream. Source's pool is NULL");
170
171         SP_RETVM_IF(!alcMakeContextCurrent(src->parent_pool->al_context),
172                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
173
174         sound_stream_t *_stream = NULL;
175         SP_RETVM_IF(!(_stream = g_try_malloc0(sizeof(*_stream))),
176                         SOUND_POOL_ERROR_OUT_OF_MEMORY,
177                         "Memory alloc failure. Can't create sound stream");
178
179         _stream->parent_source = src;
180         _stream->priority = DEFAULT_STREAM_PRIORITY;
181         _stream->loop = DEFAULT_STREAM_LOOP;
182         _stream->volume = DEFAULT_STREAM_VOLUME;
183         _stream->state_previous = SOUND_POOL_STREAM_STATE_NONE;
184         _stream->state = SOUND_POOL_STREAM_STATE_NONE;
185         _stream->stopped = FALSE;
186         _stream->state_cb_info.callback = NULL;
187         _stream->state_cb_info.user_data = NULL;
188
189         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
190         alGenSources((ALsizei)1, &_stream->al_source);
191         if (alGetError() != AL_NO_ERROR) {
192                 ret = SOUND_POOL_ERROR_OUT_OF_MEMORY;
193                 GOTO_FAIL("OpenAL error occurred when trying to generate OpenAL Source",
194                                 cfail);
195         }
196
197         alSourcei(_stream->al_source, AL_BUFFER, src->al_buffer);
198         if (alGetError() != AL_NO_ERROR) {
199                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
200                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Buffer "
201                                 "to OpenAL Source", cfail);
202         }
203
204         alSourcep(_stream->al_source, AL_SOURCE_STATE_CALLBACK,
205                         (ALvoid *)__al_source_state_cb);
206         if (alGetError() != AL_NO_ERROR) {
207                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
208                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Callback "
209                                 "to OpenAL Source", cfail);
210         }
211
212         alSourcep(_stream->al_source, AL_SOURCE_STATE_CALLBACK_DATA, (ALvoid *)_stream);
213         if (alGetError() != AL_NO_ERROR) {
214                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
215                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Callback "
216                                 "Data to OpenAL Source", cfail);
217         }
218
219         ret = __sound_pool_add_stream(src->parent_pool, _stream);
220         if (ret != SOUND_POOL_ERROR_NONE)
221                 GOTO_FAIL("Error occurred when trying to add source to pool", cfail);
222
223         *stream = _stream;
224         SP_DEBUG_FLEAVE();
225         return ret;
226
227 cfail:
228         _sound_stream_destroy(_stream);
229         SP_DEBUG_FLEAVE();
230         return ret;
231 }
232
233 sound_pool_error_e _sound_stream_destroy(sound_stream_t *stream)
234 {
235         SP_DEBUG_FENTER();
236         SP_RETVM_IF(!stream, SOUND_POOL_ERROR_INVALID_PARAMETER,
237                         "Can't destroy NULL sound stream");
238         SP_RETVM_IF(!stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER,
239                         "Invalid parent source.");
240         SP_RETVM_IF(!stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER,
241                         "Empty parent pool pointer.");
242
243         if (stream->parent_source) {
244                 if (__sound_pool_remove_stream(stream->parent_source->parent_pool,
245                                 stream) != SOUND_POOL_ERROR_NONE)
246                         SP_DEBUG("Stream[%s] wasn't removed from sound pool. Continue destroying",
247                                         stream->parent_source->tag_name);
248                 if (alcMakeContextCurrent(stream->parent_source->parent_pool->al_context)) {
249                         alSourcei(stream->al_source, AL_BUFFER, 0);
250                         alDeleteSources(1, &stream->al_source);
251                         SP_DEBUG("Deleting OpenAL source with id [%u]", stream->al_source);
252                         if (alGetError() != AL_NO_ERROR)
253                                 SP_ERROR("OpenAL error while stream[%d] destroying.", stream->id);
254                 } else {
255                         SP_DEBUG("Can't set current context for deleting OpenAL source with id [%u]",
256                                         stream->al_source);
257                 }
258         }
259
260         SP_SAFE_GFREE(stream);
261
262         SP_DEBUG_FLEAVE();
263         return SOUND_POOL_ERROR_NONE;
264 }
265
266 sound_pool_error_e _sound_stream_play(sound_stream_t *stream)
267 {
268         SP_DEBUG_FENTER();
269         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
270         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
271         sound_pool_t *pool = stream->parent_source->parent_pool;
272         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
273         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
274         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
275                         stream->state != SOUND_POOL_STREAM_STATE_PAUSED &&
276                         stream->state != SOUND_POOL_STREAM_STATE_NONE,
277                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't play stream[%s] in [%s] "
278                         "state", stream->parent_source->tag_name, __stringify_stream_state(stream->state));
279         SP_RETVM_IF(stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED &&
280                         pool->state == SOUND_POOL_STATE_INACTIVE,
281                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't play suspended stream "
282                         "in inactive sound pool");
283
284         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
285                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
286
287         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
288                         stream->state == SOUND_POOL_STREAM_STATE_NONE) {
289                 stream->state_previous = stream->state;
290                 stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
291                 ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
292                 SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
293                                 "wasn't registered. Callbacks will be not called");
294                 SP_INFO("Don't play due to SoundPool is in inactive state.");
295         } else {
296                 alSourcePlay(stream->al_source);
297         }
298
299         SP_DEBUG_FLEAVE();
300         return ret;
301 }
302
303 sound_pool_error_e _sound_stream_pause(sound_stream_t *stream)
304 {
305         SP_DEBUG_FENTER();
306         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
307         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
308         sound_pool_t *pool = stream->parent_source->parent_pool;
309         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
310         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
311         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
312                         stream->state != SOUND_POOL_STREAM_STATE_PLAYING,
313                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't pause stream in [%s] "
314                         "state", __stringify_stream_state(stream->state));
315
316         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
317                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
318
319         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
320                         stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED) {
321                 stream->state_previous = stream->state;
322                 stream->state = SOUND_POOL_STREAM_STATE_PAUSED;
323                 ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
324                 SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
325                                 "wasn't registered. Callbacks will be not called");
326                 SP_INFO("Don't paused due to SoundPool is in inactive state.");
327         } else {
328                 alSourcePause(stream->al_source);
329         }
330
331         SP_DEBUG_FLEAVE();
332         return ret;
333 }
334
335 sound_pool_error_e _sound_stream_resume(sound_stream_t *stream)
336 {
337         SP_DEBUG_FENTER();
338         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
339         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
340         sound_pool_t *pool = stream->parent_source->parent_pool;
341         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
342         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
343         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PAUSED,
344                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't resume stream in [%s] "
345                         "state", __stringify_stream_state(stream->state));
346
347         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
348                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
349
350         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
351                         stream->state == SOUND_POOL_STREAM_STATE_PAUSED) {
352                 stream->state_previous = stream->state;
353                 stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
354                 ret = _stream_cb_manager_register_event(pool->cbmgr, stream);
355                 SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
356                                 "wasn't registered. Callbacks will be not called");
357                 SP_INFO("Don't resumed due to SoundPool is in inactive state.");
358         } else {
359                 alSourcePlay(stream->al_source);
360         }
361
362         SP_DEBUG_FLEAVE();
363         return ret;
364 }
365
366 sound_pool_error_e _sound_stream_stop(sound_stream_t *stream)
367 {
368         SP_DEBUG_FENTER();
369         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
370         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
371         sound_pool_t *pool = stream->parent_source->parent_pool;
372         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
373         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PLAYING &&
374                         stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
375                         stream->state != SOUND_POOL_STREAM_STATE_PAUSED,
376                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't stop stream in [%s] "
377                         "state", __stringify_stream_state(stream->state));
378
379         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
380                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
381
382         stream->stopped = TRUE;
383         alSourceStop(stream->al_source);
384
385         SP_DEBUG_FLEAVE();
386         return SOUND_POOL_ERROR_NONE;
387 }
388
389 sound_pool_error_e _sound_stream_set_loop(sound_stream_t *stream, unsigned loop)
390 {
391         SP_DEBUG_FENTER();
392         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
393         sound_pool_t *pool = stream->parent_source->parent_pool;
394         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
395         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
396                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
397
398         alSourcei(stream->al_source, AL_LOOP_COUNT, (ALint)loop);
399         stream->loop = loop;
400
401         SP_DEBUG_FLEAVE();
402         return SOUND_POOL_ERROR_NONE;
403 }
404
405 sound_pool_error_e _sound_stream_get_loop(sound_stream_t *stream, unsigned *loop)
406 {
407         SP_DEBUG_FENTER();
408         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
409         SP_INST_CHECK(loop, SOUND_POOL_ERROR_INVALID_PARAMETER);
410
411         *loop = stream->loop;
412
413         SP_DEBUG_FLEAVE();
414         return SOUND_POOL_ERROR_NONE;
415 }
416
417 sound_pool_error_e _sound_stream_set_volume(sound_stream_t *stream, float volume)
418 {
419         SP_DEBUG_FENTER();
420         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
421         SP_RETVM_IF((volume < 0.0f || volume > 1.0f),
422                         SOUND_POOL_ERROR_INVALID_PARAMETER,
423                         "Volume for sound stream should be in range 0.0..1.0.");
424         sound_pool_t *pool = stream->parent_source->parent_pool;
425         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
426         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
427                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
428
429         alSourcef(stream->al_source, AL_GAIN, volume);
430
431         stream->volume = volume;
432
433         SP_DEBUG_FLEAVE();
434         return SOUND_POOL_ERROR_NONE;
435 }
436
437 sound_pool_error_e _sound_stream_get_volume(sound_stream_t *stream, float *volume)
438 {
439         SP_DEBUG_FENTER();
440         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
441         SP_INST_CHECK(volume, SOUND_POOL_ERROR_INVALID_PARAMETER);
442
443         *volume = stream->volume;
444
445         SP_DEBUG_FLEAVE();
446         return SOUND_POOL_ERROR_NONE;
447 }
448
449 sound_pool_error_e _sound_stream_get_state(sound_stream_t *stream,
450                 sound_pool_stream_state_e *state)
451 {
452         SP_DEBUG_FENTER();
453         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
454         SP_INST_CHECK(state, SOUND_POOL_ERROR_INVALID_PARAMETER);
455
456         *state = stream->state;
457
458         SP_DEBUG_FLEAVE();
459         return SOUND_POOL_ERROR_NONE;
460 }
461
462 sound_pool_error_e _sound_stream_set_priority(sound_stream_t *stream,
463                 unsigned rank)
464 {
465         SP_DEBUG_FENTER();
466         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
467         SP_INST_CHECK(stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
468         SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority,
469                         SOUND_POOL_ERROR_INVALID_PARAMETER);
470         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
471
472         stream->priority = rank;
473         if (stream->parent_source->parent_pool->state == SOUND_POOL_STATE_INACTIVE) {
474                 if (stream->state == SOUND_POOL_STREAM_STATE_NONE) {
475                         stream->state_previous = stream->state;
476                         stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
477                         ret = _stream_cb_manager_register_event(stream->parent_source->parent_pool->cbmgr,
478                                         stream);
479                         SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event "
480                                         "wasn't registered. Callbacks will be not called");
481                 }
482                 SP_DEBUG("No need to update priority, Sound pool is INACTIVE.");
483                 return SOUND_POOL_ERROR_NONE;
484         }
485
486         _sound_stream_priority_update_playback(stream->parent_source->parent_pool->mgr_priority);
487
488         SP_DEBUG_FLEAVE();
489         return SOUND_POOL_ERROR_NONE;
490 }
491
492 sound_pool_error_e _sound_stream_get_priority(sound_stream_t *stream,
493                 unsigned *rank)
494 {
495         SP_DEBUG_FENTER();
496         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
497         SP_INST_CHECK(rank, SOUND_POOL_ERROR_INVALID_PARAMETER);
498
499         *rank = stream->priority;
500
501         SP_DEBUG_FLEAVE();
502         return SOUND_POOL_ERROR_NONE;
503 }
504
505 sound_pool_error_e _sound_stream_set_callback(sound_stream_t *stream,
506                 sound_pool_stream_state_change_cb callback, void *data)
507 {
508         SP_DEBUG_FENTER();
509         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
510         SP_INST_CHECK(callback, SOUND_POOL_ERROR_INVALID_PARAMETER);
511
512         stream->state_cb_info.callback = callback;
513         stream->state_cb_info.user_data = data;
514
515         SP_DEBUG_FLEAVE();
516         return SOUND_POOL_ERROR_NONE;
517 }
518
519 sound_pool_error_e _sound_stream_unset_callback(sound_stream_t *stream)
520 {
521         SP_DEBUG_FENTER();
522         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
523
524         stream->state_cb_info.callback = NULL;
525         stream->state_cb_info.user_data = NULL;
526
527         SP_DEBUG_FLEAVE();
528         return SOUND_POOL_ERROR_NONE;
529 }
530
531 sound_pool_error_e _sound_pool_get_stream_by_id(sound_pool_t *pool, unsigned id,
532                 sound_stream_t **stream)
533 {
534         SP_DEBUG_FENTER();
535         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
536         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
537
538         SP_RETVM_IF(!pool->streams, SOUND_POOL_ERROR_INVALID_OPERATION, "Corrupted "
539                         "sound pool. Sources hash table is NULL");
540
541         *stream = (sound_stream_t *)g_hash_table_lookup(pool->streams, &id);
542         SP_RETVM_IF(!(*stream), SOUND_POOL_ERROR_KEY_NOT_AVAILABLE, "Tag doesn't "
543                         "exist in sources hash table");
544
545         SP_DEBUG_FLEAVE();
546         return SOUND_POOL_ERROR_NONE;
547 }