2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 #include <FMediaCapability.h>
19 #include <FBaseSysLog.h>
20 #include "FMedia_AudioOutEvent.h"
21 #include "FMedia_AudioOutImpl.h"
22 #include "FMedia_AudioOutEventArg.h"
23 #include "FMedia_AudioManagerConvert.h"
26 #define attribute_deprecated
29 #define __STDC_CONSTANT_MACROS
39 #include <libswscale/swscale.h>
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Runtime;
44 using namespace Tizen::Base::Collection;
46 namespace Tizen { namespace Media
49 int _AudioOutImpl::instanceCount = 0;
50 int _AudioOutImpl::maxInstanceCount = 0;
51 AudioChannelType _AudioOutImpl::audioOutOptimalChannelType = AUDIO_CHANNEL_TYPE_STEREO;
52 AudioSampleType _AudioOutImpl::audioOutOptimalSampleType = AUDIO_TYPE_PCM_S16_LE;
53 int _AudioOutImpl::audioOutOptimalSampleRate = 44100;
54 int _AudioOutImpl::audioOutMinimumBufferSize = 2048;
55 int _AudioOutImpl::audioOutMaximumBufferSize = 164112;
56 std::unique_ptr<Tizen::Base::Runtime::Mutex> _AudioOutImpl::__pInstanceMutex;
57 bool _AudioOutImpl::__isInstanceMutexInitialized = false;
59 _AudioOutImpl::_AudioOutImpl(void)
61 , __pAudioOutEventListener(null)
62 , __audioOutState(AUDIOOUT_STATE_ERROR)
65 , __presentSampleType(AUDIO_TYPE_NONE)
66 , __presentSampleRate(0)
67 , __audioOutHandle(null)
68 , __audioOutOptimalBufferSize(0)
70 , __interruptFlag(false)
75 _AudioOutImpl::~_AudioOutImpl(void)
77 if (__audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED)
79 if (__audioOutState == AUDIOOUT_STATE_PLAYING )
88 if ((__audioOutState == AUDIOOUT_STATE_INITIALIZED ) || __audioOutState == AUDIOOUT_STATE_UNPREPARED )
90 __pInstanceMutex->Acquire();
92 __pInstanceMutex->Release();
97 _AudioOutImpl::InitInstanceMutex(void)
100 __pInstanceMutex.reset(new (std::nothrow) Tizen::Base::Runtime::Mutex);
101 SysTryReturn(NID_MEDIA, __pInstanceMutex.get() != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] no memory to create instance Mutex");
102 r = __pInstanceMutex->Create("FMEDIA_AUDIOOUT_N");
103 SysTryReturn(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Mutex::Create failed.");
104 __isInstanceMutexInitialized = true;
108 _AudioOutImpl::GetInstance(AudioOut* pAudioOut)
110 if (pAudioOut != null)
112 return pAudioOut->__pAudioOutImpl;
119 _AudioOutImpl::GetInstance(const AudioOut* pAudioOut)
121 if (pAudioOut != null)
123 return pAudioOut->__pAudioOutImpl;
130 _AudioOutImpl::Construct(const Tizen::Media::AudioOut* pAudioOut, Tizen::Media::IAudioOutEventListener& listener)
132 result r = E_SUCCESS;
133 __pAudioOut = const_cast <AudioOut*>(pAudioOut);
134 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
135 if (!__isInstanceMutexInitialized)
137 pthread_once(&onceBlock, InitInstanceMutex);
139 SysTryCatch(NID_MEDIA, __isInstanceMutexInitialized == true, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] memory allocation for Instance Mutex failed");
141 if (!maxInstanceCount)
143 r = MediaCapability::GetValue(AUDIOOUT_COUNT_MAX, maxInstanceCount);
144 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
145 SysTryCatch(NID_MEDIA, maxInstanceCount > 0, , r, "[%s] Propagating.", GetErrorMessage(r));
148 SysTryCatch(NID_MEDIA, instanceCount < maxInstanceCount, r = E_RESOURCE_UNAVAILABLE, E_RESOURCE_UNAVAILABLE, "[E_RESOURCE_UNAVAILABLE] The number of instances exceeds the available number of instances. The current number of instance is %d", instanceCount);
150 //Setting up the Events
151 __pAudioOutEvent.reset(new (std::nothrow) _AudioOutEvent);
152 SysTryReturnResult(NID_MEDIA, __pAudioOutEvent.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
153 r = __pAudioOutEvent->Construct(__pAudioOut);
154 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
155 r = __pAudioOutEvent->AddListener(listener);
156 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
159 r = __bufferQueue.Construct();
160 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
162 __pBufferSync.reset( new (std::nothrow) Monitor);
163 SysTryCatch(NID_MEDIA, __pBufferSync.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
164 r = __pBufferSync->Construct();
165 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
168 __volume256 = (__volume << 8) / 100;
170 __pInstanceMutex->Acquire();
172 __pInstanceMutex->Release();
174 __audioOutState = AUDIOOUT_STATE_INITIALIZED;
184 _AudioOutImpl::GetMaxBufferSize(void)
186 result r = E_SUCCESS;
187 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
188 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
189 return audioOutMaximumBufferSize;
196 _AudioOutImpl::GetMinBufferSize(void)
198 result r = E_SUCCESS;
199 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
200 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
201 return audioOutMinimumBufferSize;
208 _AudioOutImpl::GetOptimizedChannelType(void)
210 return audioOutOptimalChannelType;
214 _AudioOutImpl::GetOptimizedSampleRate(void)
216 result r = E_SUCCESS;
218 return audioOutOptimalSampleRate;
222 _AudioOutImpl::GetOptimizedSampleType(void)
224 return audioOutOptimalSampleType;
228 _AudioOutImpl::GetState(void)
230 result r = E_SUCCESS;
232 SysLog(NID_MEDIA, "The current state of this instance is %d", __audioOutState);
233 return __audioOutState;
237 _AudioOutImpl::GetVolume(void) const
239 result r = E_SUCCESS;
240 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
241 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
249 _AudioOutImpl::SetVolume(int& volume)
251 result r = E_SUCCESS;
252 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
253 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
255 __volume256 = (__volume << 8) / 100;
262 _AudioOutImpl::Prepare(AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
264 result r = E_SUCCESS;
267 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
268 E_INVALID_STATE, "The state of this instance is in an invalid state.");
269 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
270 "Audio sample type is not valid.");
271 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
272 "Invalid argument is used. Audio channel type is not valid");
273 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
274 "Invalid argument is used. Audio sample rate is not valid.");
276 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), SOUND_TYPE_MEDIA, &__audioOutHandle);
277 r = MapExceptionToResult(ret);
278 SysTryCatch(NID_MEDIA, r != E_INVALID_STATE, , r, "[%s] The device has moved to invalid state as it has run out of system resources: 0x%x", GetErrorMessage(r), ret);
279 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
281 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
282 r = MapExceptionToResult(ret);
283 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
284 "[%s] Failed to perform audio_out_set_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
286 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
287 if (ret == AUDIO_IO_ERROR_NONE)
289 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
293 r = MapExceptionToResult(ret);
294 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
296 // this is done to get better Stop time
297 __audioOutOptimalBufferSize = 1024;
298 __pFeedBuffer.reset(new (std::nothrow) ByteBuffer);
299 __pFeedBuffer->Construct(__audioOutOptimalBufferSize);
300 __presentSampleType = audioSampleType;
301 __presentSampleRate = audioSampleRate;
303 __audioOutState = AUDIOOUT_STATE_PREPARED;
306 __audioOutHandle = null;
311 _AudioOutImpl::Prepare(AudioStreamType audioStreamType, AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
313 result r = E_SUCCESS;
316 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
317 E_INVALID_STATE, "The state of this instance is in an invalid state.");
318 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
319 "Audio sample type is not valid.");
320 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
321 "Invalid argument is used. Audio channel type is not valid");
322 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
323 "Invalid argument is used. Audio sample rate is not valid.");
325 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), _AudioManagerConvert::ConvertAudioStreamType2SoundType(audioStreamType), &__audioOutHandle);
326 r = MapExceptionToResult(ret);
327 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
329 ret = audio_out_prepare(__audioOutHandle);
330 r = MapExceptionToResult(ret);
331 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_prepare operation with error code : 0x%x", GetErrorMessage(r), ret);
333 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
334 r = MapExceptionToResult(ret);
335 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_set_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
337 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
338 if (ret == AUDIO_IO_ERROR_NONE)
340 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
344 r = MapExceptionToResult(ret);
345 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
348 __audioOutOptimalBufferSize = 1024;
349 __pFeedBuffer.reset(new (std::nothrow) ByteBuffer);
350 __pFeedBuffer->Construct(__audioOutOptimalBufferSize);
351 __presentSampleType = audioSampleType;
352 __presentSampleRate = audioSampleRate;
354 __audioOutState = AUDIOOUT_STATE_PREPARED;
357 __audioOutHandle = null;
362 _AudioOutImpl::Reset(void)
364 result r = E_SUCCESS;
365 SysTryReturnResult(NID_MEDIA, __audioOutState <AUDIOOUT_STATE_UNPREPARED && __audioOutState> AUDIOOUT_STATE_PREPARED, E_INVALID_STATE,
366 "The state of this instance is in an invalid state. the current state is %d.", __audioOutState);
367 if (__audioOutState == AUDIOOUT_STATE_PLAYING )
371 __bufferQueue.RemoveAll();
372 __audioOutState = AUDIOOUT_STATE_PREPARED;
377 _AudioOutImpl::UnPrepare(void)
379 result r = E_SUCCESS;
382 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PREPARED || __audioOutState == AUDIOOUT_STATE_STOPPED, E_INVALID_STATE,
383 "The state of this instance is in an invalid state. the current state is %d", __audioOutState);
384 __bufferQueue.RemoveAll();
386 ret = audio_out_unprepare(__audioOutHandle);
387 r = MapExceptionToResult(ret);
388 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_prepare operation with error code : %x", GetErrorMessage(r), ret);
390 SysTryCatch(NID_MEDIA, __audioOutHandle, r = E_SYSTEM, E_SYSTEM, "__audioout Handle is NULL");
392 ret = audio_out_unset_interrupted_cb(__audioOutHandle);
393 r = MapExceptionToResult(ret);
394 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_unset_interrupted_cb operation with error code : %x", GetErrorMessage(r), ret);
396 ret = audio_out_destroy(__audioOutHandle);
397 r = MapExceptionToResult(ret);
398 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_destroy operation with error code : %d", GetErrorMessage(r), ret);
399 __audioOutHandle = null;
401 __audioOutState = AUDIOOUT_STATE_UNPREPARED;
408 _AudioOutImpl::Start(void)
410 result r = E_SUCCESS;
412 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PREPARED || __audioOutState == AUDIOOUT_STATE_STOPPED, E_INVALID_STATE,
413 "The state of this instance is in an invalid state.");
415 ret = audio_out_prepare(__audioOutHandle);
416 r = MapExceptionToResult(ret);
417 SysTryReturnResult(NID_MEDIA, r != E_DEVICE_BUSY, E_DEVICE_BUSY, "AudioOut cannot Start, higher priority task at work.");
418 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
419 "[%s] Failed to perform audio_out_prepare operation with error code : 0x%x", GetErrorMessage(r), ret);
422 __pWorkerThread.reset(new (std::nothrow) Thread);
423 SysTryReturnResult(NID_MEDIA, __pWorkerThread.get() != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
424 r = __pWorkerThread->Construct(*this);
425 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
426 r = __pWorkerThread->Start();
427 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
428 __audioOutState = AUDIOOUT_STATE_PLAYING;
436 _AudioOutImpl::Stop(void)
438 result r = E_SUCCESS;
439 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PLAYING, E_INVALID_STATE,
440 "The state of this instance is in an invalid state. The current state is %d", __audioOutState);
441 if (__pWorkerThread.get())
444 __pBufferSync->Notify();
445 r = __pWorkerThread->Join();
446 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
450 SysLog(NID_MEDIA, "Thread is null.");
452 __audioOutState = AUDIOOUT_STATE_STOPPED;
457 _AudioOutImpl::WriteBuffer(const Tizen::Base::ByteBuffer& userData)
459 result r = E_SUCCESS;
460 int size = userData.GetLimit();
461 SysTryReturnResult(NID_MEDIA, __audioOutState >= AUDIOOUT_STATE_PREPARED && __audioOutState < AUDIOOUT_STATE_UNPREPARED, E_INVALID_STATE,
462 "The state of this instance is in an invalid state.");
463 SysTryReturnResult(NID_MEDIA, (size >= audioOutMinimumBufferSize), E_INVALID_ARG,
464 "Invalid argument is used. The size of buffer is too small, the current size of buffer is %d. It should be between %d and %d",
465 audioOutMinimumBufferSize, size, audioOutMaximumBufferSize);
466 SysTryReturnResult(NID_MEDIA, audioOutMaximumBufferSize >= size, E_OVERFLOW, "The size of buffer size is too big, the current size is %d. It should be between %d and %d", audioOutMinimumBufferSize, size, audioOutMaximumBufferSize);
468 __pBufferSync->Enter();
469 r = __bufferQueue.Enqueue(&const_cast <ByteBuffer&>(userData));
470 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
471 __pBufferSync->Notify();
472 __pBufferSync->Exit();
475 __pBufferSync->Exit();
480 _AudioOutImpl::Run(void)
482 ByteBuffer* pBuffer = null;
484 unsigned char* pData = NULL;
485 result r = E_SUCCESS;
487 bool isSuccesful = true;
494 __pBufferSync->Enter();
495 if ( __bufferQueue.Peek(pBuffer) == E_UNDERFLOW)
498 __pBufferSync->Wait();
501 __pBufferSync->Exit();
504 __bufferQueue.Peek(pBuffer);
506 __pBufferSync->Exit();
508 SysTryCatch(NID_MEDIA, pBuffer, r = E_INVALID_ARG, E_INVALID_ARG,
509 "[E_INVALID_ARG] Invalid argument is used. The buffer to write is null.");
513 buffer_size = pBuffer->GetLimit();
514 pData = (unsigned char*) pBuffer->GetPointer();
515 SysTryCatch(NID_MEDIA, pData, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. The data to write is null");
517 while (!__stop && buffer_size)
519 if (buffer_size > __audioOutOptimalBufferSize)
521 feedSize = __audioOutOptimalBufferSize;
522 buffer_size = buffer_size - __audioOutOptimalBufferSize;
523 SysLog(NID_MEDIA, "index - %d buffer_size - %d", index, feedSize);
527 feedSize = buffer_size;
529 SysLog(NID_MEDIA, "index - %d buffer_size - %d", index, feedSize);
531 if ((__volume >= 0) && (__volume < 100))
533 PreProcess(pBuffer, index, feedSize);
534 ret = audio_out_write(__audioOutHandle, (void*) __pFeedBuffer->GetPointer(), feedSize);
538 pData = pData + index;
539 ret = audio_out_write(__audioOutHandle, (void*) pData, feedSize);
543 SysLog(NID_MEDIA, "The size of actual written data is %d", ret);
545 index = index + feedSize;
547 if (buffer_size == 0)
552 __pBufferSync->Enter();
553 __bufferQueue.Dequeue(pBuffer);
554 __pBufferSync->Exit();
556 SendBufferEndReachedEvent();
566 _AudioOutImpl::AudioIoInterrupted(audio_io_interrupted_code_e code, void *pUserData)
568 SysTryReturn(NID_MEDIA, pUserData, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. The value of pUserData is null.");
569 _AudioOutImpl *pAudioOutImpl = (_AudioOutImpl *)pUserData;
573 case AUDIO_IO_INTERRUPTED_COMPLETED:
574 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_STOPPED)
576 if (!(pAudioOutImpl->__interruptFlag))
578 pAudioOutImpl->SendReleased();
580 pAudioOutImpl->__interruptFlag = false;
583 case AUDIO_IO_INTERRUPTED_BY_CALL:
584 pAudioOutImpl->__interruptFlag = true;
585 //Intentional Fall through
586 case AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG:
587 //Intentional Fall through
588 case AUDIO_IO_INTERRUPTED_BY_MEDIA:
589 //Intentional Fall through
590 case AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT:
591 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
593 pAudioOutImpl->SendAudioFocusChanged();
596 case AUDIO_IO_INTERRUPTED_BY_ALARM:
597 //Intentional Fall through
598 case AUDIO_IO_INTERRUPTED_BY_EMERGENCY:
599 //Intentional Fall through
600 case AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA:
601 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
603 pAudioOutImpl->SendInterrupted();
607 SysLog(NID_MEDIA, "Interrupt code obtained is wrong - %d", code);
613 _AudioOutImpl::SendBufferEndReachedEvent(void)
615 result r = E_SUCCESS;
616 _AudioOutEventArg* pAudioOutEventArg = null;
617 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
618 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
620 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_DATA_END_REACHED);
621 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
622 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
625 delete pAudioOutEventArg;
630 _AudioOutImpl::SendInterrupted()
632 result r = E_SUCCESS;
633 _AudioOutEventArg* pAudioOutEventArg = null;
634 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
635 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
637 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_INTERRUPTED);
638 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
639 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
642 delete pAudioOutEventArg;
647 _AudioOutImpl::SendAudioFocusChanged()
649 result r = E_SUCCESS;
650 _AudioOutEventArg* pAudioOutEventArg = null;
651 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
652 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
654 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_AUDIO_FOCUS_CHANGED);
655 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
656 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
659 delete pAudioOutEventArg;
664 _AudioOutImpl::SendReleased()
666 result r = E_SUCCESS;
667 _AudioOutEventArg* pAudioOutEventArg = null;
668 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
669 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
670 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_RELEASED);
671 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
672 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
675 delete pAudioOutEventArg;
680 _AudioOutImpl::ScaleDownVolume(unsigned char* pDataBuffer, int bytes)
682 switch (__presentSampleType)
684 case AUDIO_TYPE_PCM_U8:
686 unsigned char* pOutput = __pFeedBuffer->GetPointer();
687 unsigned char* pData = pDataBuffer;
688 int noOfSamples = bytes;
689 for (int i = 0; i < noOfSamples; i++)
691 int v = (((*pData++ - 128) * __volume256 + 128) >> 8) + 128;
692 *pOutput++ = av_clip_uint8(v);
697 case AUDIO_TYPE_PCM_S16_LE:
699 short* pData = (short*) pDataBuffer;
700 short* pOutput = (short*) __pFeedBuffer->GetPointer();
701 int noOfSamples = bytes >> 1;
702 for (int i = 0; i < noOfSamples; i++)
704 int v = ((*pData++) * __volume256 + 128) >> 8;
705 *pOutput++ = av_clip_int16(v);
716 _AudioOutImpl::PreProcess(ByteBuffer* pBuffer, int index, int size)
718 unsigned char* pDataBuffer = null;
719 if (pBuffer->GetLimit() > 0)
721 pDataBuffer = (unsigned char*) pBuffer->GetPointer();
726 pDataBuffer = pDataBuffer + index;
732 if ((__volume256 < 256) && (__volume256 >= 0))
734 ScaleDownVolume(pDataBuffer, size);
739 _AudioOutImpl::MapExceptionToResult(int reason)
741 //All the fall through are intentional
745 case AUDIO_IO_ERROR_NONE:
749 case AUDIO_IO_ERROR_OUT_OF_MEMORY:
750 return E_OUT_OF_MEMORY;
753 case AUDIO_IO_ERROR_INVALID_PARAMETER:
754 return E_INVALID_ARG;
757 case AUDIO_IO_ERROR_INVALID_OPERATION:
758 return E_INVALID_OPERATION;
761 case AUDIO_IO_ERROR_DEVICE_NOT_OPENED:
762 return E_INVALID_STATE;
765 case AUDIO_IO_ERROR_INVALID_BUFFER:
766 return E_INVALID_ARG;
769 case AUDIO_IO_ERROR_DEVICE_NOT_CLOSED:
770 return E_INVALID_STATE;
773 case AUDIO_IO_ERROR_SOUND_POLICY:
774 return E_DEVICE_BUSY;