d2bb663e2d2d48478113d00a2cb4ebd15983a422
[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, sound_stream_t *stream)
106 {
107         SP_DEBUG_FENTER();
108         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
109         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
110         SP_RETVM_IF(!pool->streams, SOUND_POOL_ERROR_INVALID_OPERATION, "Sound "
111                         "pool to add the stream is corrupted: NULL streams hash table");
112         stream->id = ++(pool->max_stream_index);
113         SP_DEBUG("Id assigned to the stream is [%u]", stream->id);
114         SP_RETVM_IF(g_hash_table_contains(pool->streams, (gpointer)&stream->id),
115                         SOUND_POOL_ERROR_INVALID_PARAMETER,
116                         "Stream ID already exists in streams hash table.");
117         SP_RETVM_IF(stream->parent_source->parent_pool != pool,
118                         SOUND_POOL_ERROR_INVALID_OPERATION, "Sound stream can't be added "
119                         "to the pool different to the pool for which sound stream was created");
120
121         SP_RETVM_IF(!g_hash_table_insert(pool->streams, (gpointer)&stream->id, stream),
122                         SOUND_POOL_ERROR_INVALID_OPERATION, "Error occurred when adding "
123                         "the stream [%u] to the sound pool", stream->id);
124
125         sound_pool_error_e ret = _sound_stream_priority_add_stream(pool->mgr_priority, stream);
126         SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "Error occurred when adding "
127                         "the stream [%u] to the priority queue.", stream->id);
128
129         SP_DEBUG_FLEAVE();
130         return SOUND_POOL_ERROR_NONE;
131 }
132
133 static sound_pool_error_e __sound_pool_remove_stream(sound_pool_t *pool, sound_stream_t *stream)
134 {
135         SP_DEBUG_FENTER();
136         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
137         SP_INST_CHECK(pool->mgr_priority, SOUND_POOL_ERROR_INVALID_PARAMETER);
138         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
139         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
140
141         if (stream->parent_source->parent_pool == pool) {
142                 if (!g_hash_table_remove(pool->streams, &stream->id)
143                                 || SOUND_POOL_ERROR_NONE
144                                                 != _sound_stream_priority_remove_stream(pool->mgr_priority,
145                                                                 stream))
146                         SP_DEBUG("Id [%u] doesn't exist in streams hash table", stream->id);
147                 else
148                         SP_INFO("[%u] sound stream was removed from pool", stream->id);
149         } else {
150                 SP_DEBUG("Stream wasn't removed from sound pool as it isn't known by "
151                                 "the pool for which operation is performed");
152         }
153
154         SP_DEBUG_FLEAVE();
155         return SOUND_POOL_ERROR_NONE;
156 }
157
158 sound_pool_error_e _sound_stream_create(sound_source_t *src,
159                 sound_stream_t **stream)
160 {
161         SP_DEBUG_FENTER();
162         SP_RETVM_IF(!src, SOUND_POOL_ERROR_INVALID_PARAMETER,
163                         "Can't create sound stream in NULL sound source");
164         SP_RETVM_IF(!stream, SOUND_POOL_ERROR_INVALID_PARAMETER,
165                         "Can't create sound stream. Stream pointer is NULL");
166         SP_RETVM_IF(!src->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER,
167                         "Can't create sound stream. Source's pool is NULL");
168
169         SP_RETVM_IF(!alcMakeContextCurrent(src->parent_pool->al_context),
170                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
171
172         sound_stream_t *_stream = NULL;
173         SP_RETVM_IF(!(_stream = g_try_malloc0(sizeof(*_stream))),
174                         SOUND_POOL_ERROR_OUT_OF_MEMORY,
175                         "Memory alloc failure. Can't create sound stream");
176
177         _stream->parent_source = src;
178         _stream->priority = DEFAULT_STREAM_PRIORITY;
179         _stream->loop = DEFAULT_STREAM_LOOP;
180         _stream->volume = DEFAULT_STREAM_VOLUME;
181         _stream->state_previous = SOUND_POOL_STREAM_STATE_NONE;
182         _stream->state = SOUND_POOL_STREAM_STATE_NONE;
183         _stream->stopped = FALSE;
184         _stream->state_cb_info.callback = NULL;
185         _stream->state_cb_info.user_data = NULL;
186
187         sound_pool_error_e ret = SOUND_POOL_ERROR_NONE;
188         alGenSources((ALsizei)1, &_stream->al_source);
189         if (alGetError() != AL_NO_ERROR) {
190                 ret = SOUND_POOL_ERROR_OUT_OF_MEMORY;
191                 GOTO_FAIL("OpenAL error occurred when trying to generate OpenAL Source",
192                                 cfail);
193         }
194
195         alSourcei(_stream->al_source, AL_BUFFER, src->al_buffer);
196         if (alGetError() != AL_NO_ERROR) {
197                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
198                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Buffer "
199                                 "to OpenAL Source", cfail);
200         }
201
202         alSourcep(_stream->al_source, AL_SOURCE_STATE_CALLBACK,
203                         (ALvoid *)__al_source_state_cb);
204         if (alGetError() != AL_NO_ERROR) {
205                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
206                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Callback "
207                                 "to OpenAL Source", cfail);
208         }
209
210         alSourcep(_stream->al_source, AL_SOURCE_STATE_CALLBACK_DATA, (ALvoid *)_stream);
211         if (alGetError() != AL_NO_ERROR) {
212                 ret = SOUND_POOL_ERROR_INVALID_OPERATION;
213                 GOTO_FAIL("OpenAL error occurred when trying to assign OpenAL Callback "
214                                 "Data to OpenAL Source", cfail);
215         }
216
217         ret = __sound_pool_add_stream(src->parent_pool, _stream);
218         if (ret != SOUND_POOL_ERROR_NONE)
219                 GOTO_FAIL("Error occurred when trying to add source to pool", cfail);
220
221         *stream = _stream;
222         SP_DEBUG_FLEAVE();
223         return ret;
224
225 cfail:
226         _sound_stream_destroy(_stream);
227         SP_DEBUG_FLEAVE();
228         return ret;
229 }
230
231 sound_pool_error_e _sound_stream_destroy(sound_stream_t *stream)
232 {
233         SP_DEBUG_FENTER();
234         SP_RETVM_IF(!stream, SOUND_POOL_ERROR_INVALID_PARAMETER,
235                         "Can't destroy NULL sound stream");
236         SP_RETVM_IF(!stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER,
237                         "Empty parent pool pointer.");
238
239         if (stream->parent_source) {
240                 if (__sound_pool_remove_stream(stream->parent_source->parent_pool,
241                                 stream) != SOUND_POOL_ERROR_NONE)
242                         SP_DEBUG("Stream[%s] wasn't removed from sound pool. Continue destroying",
243                                         stream->parent_source->tag_name);
244                 if (alcMakeContextCurrent(stream->parent_source->parent_pool->al_context)) {
245                         alSourcei(stream->al_source, AL_BUFFER, 0);
246                         alDeleteSources(1, &stream->al_source);
247                         SP_DEBUG("Deleting OpenAL source with id [%u]", stream->al_source);
248                 } else {
249                         SP_DEBUG("Can't set current context for deleting OpenAL source with id [%u]",
250                                         stream->al_source);
251                 }
252         }
253
254         SP_SAFE_GFREE(stream);
255
256         SP_DEBUG_FLEAVE();
257         return SOUND_POOL_ERROR_NONE;
258 }
259
260 sound_pool_error_e _sound_stream_play(sound_stream_t *stream)
261 {
262         SP_DEBUG_FENTER();
263         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
264         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
265         sound_pool_t *pool = stream->parent_source->parent_pool;
266         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
267         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
268                         stream->state != SOUND_POOL_STREAM_STATE_PAUSED &&
269                         stream->state != SOUND_POOL_STREAM_STATE_NONE,
270                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't play stream[%s] in [%s] "
271                         "state", stream->parent_source->tag_name, __stringify_stream_state(stream->state));
272         SP_RETVM_IF(stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED &&
273                         pool->state == SOUND_POOL_STATE_INACTIVE,
274                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't play suspended stream "
275                         "in inactive sound pool");
276
277         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
278                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
279
280         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
281                         stream->state == SOUND_POOL_STREAM_STATE_NONE) {
282                 stream->state_previous = stream->state;
283                 stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
284                 if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
285                                 SOUND_POOL_ERROR_NONE)
286                         SP_DEBUG("State changing event wasn't registered."
287                                         "Callbacks will be not called");
288                 SP_DEBUG("Don't play due to SoundPool is in inactive state.");
289         } else {
290                 alSourcePlay(stream->al_source);
291         }
292
293         SP_DEBUG_FLEAVE();
294         return SOUND_POOL_ERROR_NONE;
295 }
296
297 sound_pool_error_e _sound_stream_pause(sound_stream_t *stream)
298 {
299         SP_DEBUG_FENTER();
300         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
301         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
302         sound_pool_t *pool = stream->parent_source->parent_pool;
303         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
304         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
305                         stream->state != SOUND_POOL_STREAM_STATE_PLAYING,
306                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't pause stream in [%s] "
307                         "state", __stringify_stream_state(stream->state));
308
309         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
310                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
311
312         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
313                         stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED) {
314                 stream->state_previous = stream->state;
315                 stream->state = SOUND_POOL_STREAM_STATE_PAUSED;
316                 if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
317                                 SOUND_POOL_ERROR_NONE)
318                         SP_DEBUG("State changing event wasn't registered."
319                                         "Callbacks will be not called");
320                 SP_DEBUG("Don't paused due to SoundPool is in inactive state.");
321         } else {
322                 alSourcePause(stream->al_source);
323         }
324
325         SP_DEBUG_FLEAVE();
326         return SOUND_POOL_ERROR_NONE;
327 }
328
329 sound_pool_error_e _sound_stream_resume(sound_stream_t *stream)
330 {
331         SP_DEBUG_FENTER();
332         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
333         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
334         sound_pool_t *pool = stream->parent_source->parent_pool;
335         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
336         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PAUSED,
337                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't resume stream in [%s] "
338                         "state", __stringify_stream_state(stream->state));
339
340         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
341                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
342
343         if (pool->state == SOUND_POOL_STATE_INACTIVE &&
344                         stream->state == SOUND_POOL_STREAM_STATE_PAUSED)
345         {
346                 stream->state_previous = stream->state;
347                 stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
348                 if (_stream_cb_manager_register_event(pool->cbmgr, stream) !=
349                                 SOUND_POOL_ERROR_NONE)
350                         SP_DEBUG("State changing event wasn't registered."
351                                         "Callbacks will be not called");
352                 SP_DEBUG("Don't resumed due to SoundPool is in inactive state.");
353         } else {
354                 alSourcePlay(stream->al_source);
355         }
356
357         SP_DEBUG_FLEAVE();
358         return SOUND_POOL_ERROR_NONE;
359 }
360
361 sound_pool_error_e _sound_stream_stop(sound_stream_t *stream)
362 {
363         SP_DEBUG_FENTER();
364         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
365         SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER);
366         sound_pool_t *pool = stream->parent_source->parent_pool;
367         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
368         SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PLAYING &&
369                         stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED &&
370                         stream->state != SOUND_POOL_STREAM_STATE_PAUSED,
371                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't stop stream in [%s] "
372                         "state", __stringify_stream_state(stream->state));
373
374         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
375                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
376
377         stream->stopped = TRUE;
378         alSourceStop(stream->al_source);
379
380         SP_DEBUG_FLEAVE();
381         return SOUND_POOL_ERROR_NONE;
382 }
383
384 sound_pool_error_e _sound_stream_set_loop(sound_stream_t *stream, unsigned loop)
385 {
386         SP_DEBUG_FENTER();
387         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
388         sound_pool_t *pool = stream->parent_source->parent_pool;
389         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
390         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
391                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
392
393         alSourcei(stream->al_source, AL_LOOP_COUNT, (ALint)loop);
394         stream->loop = loop;
395
396         SP_DEBUG_FLEAVE();
397         return SOUND_POOL_ERROR_NONE;
398 }
399
400 sound_pool_error_e _sound_stream_get_loop(sound_stream_t *stream, unsigned *loop)
401 {
402         SP_DEBUG_FENTER();
403         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
404         SP_INST_CHECK(loop, SOUND_POOL_ERROR_INVALID_PARAMETER);
405
406         *loop = stream->loop;
407
408         SP_DEBUG_FLEAVE();
409         return SOUND_POOL_ERROR_NONE;
410 }
411
412 sound_pool_error_e _sound_stream_set_volume(sound_stream_t *stream, float volume)
413 {
414         SP_DEBUG_FENTER();
415         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
416         SP_RETVM_IF((volume < 0.0f || volume > 1.0f),
417                         SOUND_POOL_ERROR_INVALID_PARAMETER,
418                         "Volume for sound stream should be in range 0.0..1.0.");
419         sound_pool_t *pool = stream->parent_source->parent_pool;
420         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
421         SP_RETVM_IF(!alcMakeContextCurrent(pool->al_context),
422                         SOUND_POOL_ERROR_INVALID_OPERATION, "Can't set current context.");
423
424         alSourcef(stream->al_source, AL_GAIN, volume);
425
426         stream->volume = volume;
427
428         SP_DEBUG_FLEAVE();
429         return SOUND_POOL_ERROR_NONE;
430 }
431
432 sound_pool_error_e _sound_stream_get_volume(sound_stream_t *stream, float *volume)
433 {
434         SP_DEBUG_FENTER();
435         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
436         SP_INST_CHECK(volume, SOUND_POOL_ERROR_INVALID_PARAMETER);
437
438         *volume = stream->volume;
439
440         SP_DEBUG_FLEAVE();
441         return SOUND_POOL_ERROR_NONE;
442 }
443
444 sound_pool_error_e _sound_stream_get_state(sound_stream_t *stream,
445                 sound_pool_stream_state_e *state)
446 {
447         SP_DEBUG_FENTER();
448         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
449         SP_INST_CHECK(state, SOUND_POOL_ERROR_INVALID_PARAMETER);
450
451         *state = stream->state;
452
453         SP_DEBUG_FLEAVE();
454         return SOUND_POOL_ERROR_NONE;
455 }
456
457 sound_pool_error_e _sound_stream_set_priority(sound_stream_t *stream, unsigned rank)
458 {
459         SP_DEBUG_FENTER();
460         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
461         SP_INST_CHECK(stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
462         SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority, SOUND_POOL_ERROR_INVALID_PARAMETER);
463
464         stream->priority = rank;
465         if (stream->parent_source->parent_pool->state == SOUND_POOL_STATE_INACTIVE) {
466                 if (stream->state == SOUND_POOL_STREAM_STATE_NONE) {
467                         stream->state_previous = stream->state;
468                         stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED;
469                         if (_stream_cb_manager_register_event(
470                                         stream->parent_source->parent_pool->cbmgr, stream)
471                                         != SOUND_POOL_ERROR_NONE)
472                                 SP_DEBUG(
473                                                 "State changing event wasn't registered." "Callbacks"
474                                                 " will be not called");
475                 }
476                 SP_DEBUG("No need to update priority, Sound pool is INACTIVE.");
477                 return SOUND_POOL_ERROR_NONE;
478         }
479
480         _sound_stream_priority_update_playback(stream->parent_source->parent_pool->mgr_priority);
481
482         SP_DEBUG_FLEAVE();
483         return SOUND_POOL_ERROR_NONE;
484 }
485
486 sound_pool_error_e _sound_stream_get_priority(sound_stream_t *stream, unsigned *rank)
487 {
488         SP_DEBUG_FENTER();
489         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
490         SP_INST_CHECK(rank, SOUND_POOL_ERROR_INVALID_PARAMETER);
491
492         *rank = stream->priority;
493
494         SP_DEBUG_FLEAVE();
495         return SOUND_POOL_ERROR_NONE;
496 }
497
498 sound_pool_error_e _sound_stream_set_callback(sound_stream_t *stream,
499                 sound_pool_stream_state_change_cb callback, void *data)
500 {
501         SP_DEBUG_FENTER();
502         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
503         SP_INST_CHECK(callback, SOUND_POOL_ERROR_INVALID_PARAMETER);
504
505         stream->state_cb_info.callback = callback;
506         stream->state_cb_info.user_data = data;
507
508         SP_DEBUG_FLEAVE();
509         return SOUND_POOL_ERROR_NONE;
510 }
511
512 sound_pool_error_e _sound_stream_unset_callback(sound_stream_t *stream)
513 {
514         SP_DEBUG_FENTER();
515         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
516
517         stream->state_cb_info.callback = NULL;
518         stream->state_cb_info.user_data = NULL;
519
520         SP_DEBUG_FLEAVE();
521         return SOUND_POOL_ERROR_NONE;
522 }
523
524 sound_pool_error_e _sound_pool_get_stream_by_id(sound_pool_t *pool, unsigned id,
525                 sound_stream_t **stream)
526 {
527         SP_DEBUG_FENTER();
528         SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER);
529         SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER);
530
531         SP_RETVM_IF(!pool->streams, SOUND_POOL_ERROR_INVALID_OPERATION, "Corrupted "
532                         "sound pool. Sources hash table is NULL");
533
534         *stream = (sound_stream_t *)g_hash_table_lookup(pool->streams, &id);
535         SP_RETVM_IF(!(*stream), SOUND_POOL_ERROR_KEY_NOT_AVAILABLE, "Tag doesn't "
536                         "exist in sources hash table");
537
538         SP_DEBUG_FLEAVE();
539         return SOUND_POOL_ERROR_NONE;
540 }