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 <libavutil/common.h>
40 #include <libswscale/swscale.h>
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Runtime;
45 using namespace Tizen::Base::Collection;
47 namespace Tizen { namespace Media
50 int _AudioOutImpl::instanceCount = 0;
51 int _AudioOutImpl::maxInstanceCount = 0;
52 AudioChannelType _AudioOutImpl::audioOutOptimalChannelType = AUDIO_CHANNEL_TYPE_STEREO;
53 AudioSampleType _AudioOutImpl::audioOutOptimalSampleType = AUDIO_TYPE_PCM_S16_LE;
54 int _AudioOutImpl::audioOutOptimalSampleRate = 44100;
55 int _AudioOutImpl::audioOutMinimumBufferSize = 2048;
56 int _AudioOutImpl::audioOutMaximumBufferSize = 164112;
57 std::unique_ptr<Tizen::Base::Runtime::Mutex> _AudioOutImpl::__pInstanceMutex;
58 bool _AudioOutImpl::__isInstanceMutexInitialized = false;
60 _AudioOutImpl::_AudioOutImpl(void)
62 , __pAudioOutEventListener(null)
63 , __audioOutState(AUDIOOUT_STATE_ERROR)
66 , __presentSampleType(AUDIO_TYPE_NONE)
67 , __presentSampleRate(0)
68 , __audioOutHandle(null)
69 , __audioOutOptimalBufferSize(0)
71 , __interruptFlag(false)
76 _AudioOutImpl::~_AudioOutImpl(void)
78 if (__audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED)
80 if (__audioOutState == AUDIOOUT_STATE_PLAYING )
89 if ((__audioOutState == AUDIOOUT_STATE_INITIALIZED ) || __audioOutState == AUDIOOUT_STATE_UNPREPARED )
91 __pInstanceMutex->Acquire();
93 __pInstanceMutex->Release();
98 _AudioOutImpl::InitInstanceMutex(void)
100 result r = E_SUCCESS;
101 __pInstanceMutex.reset(new (std::nothrow) Tizen::Base::Runtime::Mutex);
102 SysTryReturn(NID_MEDIA, __pInstanceMutex.get() != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] no memory to create instance Mutex");
103 r = __pInstanceMutex->Create("FMEDIA_AUDIOOUT_N");
104 SysTryReturn(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Mutex::Create failed.");
105 __isInstanceMutexInitialized = true;
109 _AudioOutImpl::GetInstance(AudioOut* pAudioOut)
111 if (pAudioOut != null)
113 return pAudioOut->__pAudioOutImpl;
120 _AudioOutImpl::GetInstance(const AudioOut* pAudioOut)
122 if (pAudioOut != null)
124 return pAudioOut->__pAudioOutImpl;
131 _AudioOutImpl::Construct(const Tizen::Media::AudioOut* pAudioOut, Tizen::Media::IAudioOutEventListener& listener)
133 result r = E_SUCCESS;
134 __pAudioOut = const_cast <AudioOut*>(pAudioOut);
135 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
136 if (!__isInstanceMutexInitialized)
138 pthread_once(&onceBlock, InitInstanceMutex);
140 SysTryCatch(NID_MEDIA, __isInstanceMutexInitialized == true, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] memory allocation for Instance Mutex failed");
142 if (!maxInstanceCount)
144 r = MediaCapability::GetValue(AUDIOOUT_COUNT_MAX, maxInstanceCount);
145 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
146 SysTryCatch(NID_MEDIA, maxInstanceCount > 0, , r, "[%s] Propagating.", GetErrorMessage(r));
149 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);
151 //Setting up the Events
152 __pAudioOutEvent.reset(new (std::nothrow) _AudioOutEvent);
153 SysTryReturnResult(NID_MEDIA, __pAudioOutEvent.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
154 r = __pAudioOutEvent->Construct(__pAudioOut);
155 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
156 r = __pAudioOutEvent->AddListener(listener);
157 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
160 r = __bufferQueue.Construct();
161 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
163 __pBufferSync.reset( new (std::nothrow) Monitor);
164 SysTryCatch(NID_MEDIA, __pBufferSync.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
165 r = __pBufferSync->Construct();
166 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
169 __volume256 = (__volume << 8) / 100;
171 __pInstanceMutex->Acquire();
173 __pInstanceMutex->Release();
175 __audioOutState = AUDIOOUT_STATE_INITIALIZED;
185 _AudioOutImpl::GetMaxBufferSize(void)
187 result r = E_SUCCESS;
188 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
189 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
190 return audioOutMaximumBufferSize;
197 _AudioOutImpl::GetMinBufferSize(void)
199 result r = E_SUCCESS;
200 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
201 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
202 return audioOutMinimumBufferSize;
209 _AudioOutImpl::GetOptimizedChannelType(void)
211 return audioOutOptimalChannelType;
215 _AudioOutImpl::GetOptimizedSampleRate(void)
217 result r = E_SUCCESS;
219 return audioOutOptimalSampleRate;
223 _AudioOutImpl::GetOptimizedSampleType(void)
225 return audioOutOptimalSampleType;
229 _AudioOutImpl::GetState(void)
231 result r = E_SUCCESS;
233 SysLog(NID_MEDIA, "The current state of this instance is %d", __audioOutState);
234 return __audioOutState;
238 _AudioOutImpl::GetVolume(void) const
240 result r = E_SUCCESS;
241 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
242 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
250 _AudioOutImpl::SetVolume(int& volume)
252 result r = E_SUCCESS;
253 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
254 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
256 __volume256 = (__volume << 8) / 100;
263 _AudioOutImpl::Prepare(AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
265 result r = E_SUCCESS;
268 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
269 E_INVALID_STATE, "The state of this instance is in an invalid state.");
270 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
271 "Audio sample type is not valid.");
272 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
273 "Invalid argument is used. Audio channel type is not valid");
274 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
275 "Invalid argument is used. Audio sample rate is not valid.");
277 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), SOUND_TYPE_MEDIA, &__audioOutHandle);
278 r = MapExceptionToResult(ret);
279 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);
280 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
282 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
283 r = MapExceptionToResult(ret);
284 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
285 "[%s] Failed to perform audio_out_set_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
287 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
288 if (ret == AUDIO_IO_ERROR_NONE)
290 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
294 r = MapExceptionToResult(ret);
295 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
297 // this is done to get better Stop time
298 __audioOutOptimalBufferSize = 1024;
299 __pFeedBuffer.reset(new (std::nothrow) ByteBuffer);
300 __pFeedBuffer->Construct(__audioOutOptimalBufferSize);
301 __presentSampleType = audioSampleType;
302 __presentSampleRate = audioSampleRate;
304 __audioOutState = AUDIOOUT_STATE_PREPARED;
307 __audioOutHandle = null;
312 _AudioOutImpl::Prepare(AudioStreamType audioStreamType, AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
314 result r = E_SUCCESS;
317 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
318 E_INVALID_STATE, "The state of this instance is in an invalid state.");
319 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
320 "Audio sample type is not valid.");
321 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
322 "Invalid argument is used. Audio channel type is not valid");
323 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
324 "Invalid argument is used. Audio sample rate is not valid.");
326 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), _AudioManagerConvert::ConvertAudioStreamType2SoundType(audioStreamType), &__audioOutHandle);
327 r = MapExceptionToResult(ret);
328 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
330 ret = audio_out_prepare(__audioOutHandle);
331 r = MapExceptionToResult(ret);
332 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_prepare operation with error code : 0x%x", GetErrorMessage(r), ret);
334 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
335 r = MapExceptionToResult(ret);
336 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);
338 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
339 if (ret == AUDIO_IO_ERROR_NONE)
341 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
345 r = MapExceptionToResult(ret);
346 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
349 __audioOutOptimalBufferSize = 1024;
350 __pFeedBuffer.reset(new (std::nothrow) ByteBuffer);
351 __pFeedBuffer->Construct(__audioOutOptimalBufferSize);
352 __presentSampleType = audioSampleType;
353 __presentSampleRate = audioSampleRate;
355 __audioOutState = AUDIOOUT_STATE_PREPARED;
358 __audioOutHandle = null;
363 _AudioOutImpl::Reset(void)
365 result r = E_SUCCESS;
366 SysTryReturnResult(NID_MEDIA, __audioOutState <AUDIOOUT_STATE_UNPREPARED && __audioOutState> AUDIOOUT_STATE_PREPARED, E_INVALID_STATE,
367 "The state of this instance is in an invalid state. the current state is %d.", __audioOutState);
368 if (__audioOutState == AUDIOOUT_STATE_PLAYING )
372 __bufferQueue.RemoveAll();
373 __audioOutState = AUDIOOUT_STATE_PREPARED;
378 _AudioOutImpl::UnPrepare(void)
380 result r = E_SUCCESS;
383 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PREPARED || __audioOutState == AUDIOOUT_STATE_STOPPED, E_INVALID_STATE,
384 "The state of this instance is in an invalid state. the current state is %d", __audioOutState);
385 __bufferQueue.RemoveAll();
387 ret = audio_out_unprepare(__audioOutHandle);
388 r = MapExceptionToResult(ret);
389 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_prepare operation with error code : %x", GetErrorMessage(r), ret);
391 SysTryCatch(NID_MEDIA, __audioOutHandle, r = E_SYSTEM, E_SYSTEM, "__audioout Handle is NULL");
393 ret = audio_out_unset_interrupted_cb(__audioOutHandle);
394 r = MapExceptionToResult(ret);
395 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_unset_interrupted_cb operation with error code : %x", GetErrorMessage(r), ret);
397 ret = audio_out_destroy(__audioOutHandle);
398 r = MapExceptionToResult(ret);
399 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_destroy operation with error code : %d", GetErrorMessage(r), ret);
400 __audioOutHandle = null;
402 __audioOutState = AUDIOOUT_STATE_UNPREPARED;
409 _AudioOutImpl::Start(void)
411 result r = E_SUCCESS;
413 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PREPARED || __audioOutState == AUDIOOUT_STATE_STOPPED, E_INVALID_STATE,
414 "The state of this instance is in an invalid state.");
416 ret = audio_out_prepare(__audioOutHandle);
417 r = MapExceptionToResult(ret);
418 SysTryReturnResult(NID_MEDIA, r != E_DEVICE_BUSY, E_DEVICE_BUSY, "AudioOut cannot Start, higher priority task at work.");
419 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
420 "[%s] Failed to perform audio_out_prepare operation with error code : 0x%x", GetErrorMessage(r), ret);
423 __pWorkerThread.reset(new (std::nothrow) Thread);
424 SysTryReturnResult(NID_MEDIA, __pWorkerThread.get() != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
425 r = __pWorkerThread->Construct(*this);
426 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
427 r = __pWorkerThread->Start();
428 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
429 __audioOutState = AUDIOOUT_STATE_PLAYING;
437 _AudioOutImpl::Stop(void)
439 result r = E_SUCCESS;
440 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_PLAYING, E_INVALID_STATE,
441 "The state of this instance is in an invalid state. The current state is %d", __audioOutState);
442 if (__pWorkerThread.get())
445 __pBufferSync->Notify();
446 r = __pWorkerThread->Join();
447 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
451 SysLog(NID_MEDIA, "Thread is null.");
453 __audioOutState = AUDIOOUT_STATE_STOPPED;
458 _AudioOutImpl::WriteBuffer(const Tizen::Base::ByteBuffer& userData)
460 result r = E_SUCCESS;
461 int size = userData.GetLimit();
462 SysTryReturnResult(NID_MEDIA, __audioOutState >= AUDIOOUT_STATE_PREPARED && __audioOutState < AUDIOOUT_STATE_UNPREPARED, E_INVALID_STATE,
463 "The state of this instance is in an invalid state.");
464 SysTryReturnResult(NID_MEDIA, (size >= audioOutMinimumBufferSize), E_INVALID_ARG,
465 "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",
466 audioOutMinimumBufferSize, size, audioOutMaximumBufferSize);
467 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);
469 __pBufferSync->Enter();
470 r = __bufferQueue.Enqueue(&const_cast <ByteBuffer&>(userData));
471 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
472 __pBufferSync->Notify();
473 __pBufferSync->Exit();
476 __pBufferSync->Exit();
481 _AudioOutImpl::Run(void)
483 ByteBuffer* pBuffer = null;
485 unsigned char* pData = NULL;
486 result r = E_SUCCESS;
488 bool isSuccesful = true;
495 __pBufferSync->Enter();
496 if ( __bufferQueue.Peek(pBuffer) == E_UNDERFLOW)
499 __pBufferSync->Wait();
502 __pBufferSync->Exit();
505 __bufferQueue.Peek(pBuffer);
507 __pBufferSync->Exit();
509 SysTryCatch(NID_MEDIA, pBuffer, r = E_INVALID_ARG, E_INVALID_ARG,
510 "[E_INVALID_ARG] Invalid argument is used. The buffer to write is null.");
514 buffer_size = pBuffer->GetLimit();
515 pData = (unsigned char*) pBuffer->GetPointer();
516 SysTryCatch(NID_MEDIA, pData, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. The data to write is null");
518 while (!__stop && buffer_size)
520 if (buffer_size > __audioOutOptimalBufferSize)
522 feedSize = __audioOutOptimalBufferSize;
523 buffer_size = buffer_size - __audioOutOptimalBufferSize;
524 SysLog(NID_MEDIA, "index - %d buffer_size - %d", index, feedSize);
528 feedSize = buffer_size;
530 SysLog(NID_MEDIA, "index - %d buffer_size - %d", index, feedSize);
532 if ((__volume >= 0) && (__volume < 100))
534 PreProcess(pBuffer, index, feedSize);
535 ret = audio_out_write(__audioOutHandle, (void*) __pFeedBuffer->GetPointer(), feedSize);
539 pData = pData + index;
540 ret = audio_out_write(__audioOutHandle, (void*) pData, feedSize);
544 SysLog(NID_MEDIA, "The size of actual written data is %d", ret);
546 index = index + feedSize;
548 if (buffer_size == 0)
553 __pBufferSync->Enter();
554 __bufferQueue.Dequeue(pBuffer);
555 __pBufferSync->Exit();
557 SendBufferEndReachedEvent();
567 _AudioOutImpl::AudioIoInterrupted(audio_io_interrupted_code_e code, void *pUserData)
569 SysTryReturn(NID_MEDIA, pUserData, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. The value of pUserData is null.");
570 _AudioOutImpl *pAudioOutImpl = (_AudioOutImpl *)pUserData;
574 case AUDIO_IO_INTERRUPTED_COMPLETED:
575 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_STOPPED)
577 if (!(pAudioOutImpl->__interruptFlag))
579 pAudioOutImpl->SendReleased();
581 pAudioOutImpl->__interruptFlag = false;
584 case AUDIO_IO_INTERRUPTED_BY_CALL:
585 pAudioOutImpl->__interruptFlag = true;
586 //Intentional Fall through
587 case AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG:
588 //Intentional Fall through
589 case AUDIO_IO_INTERRUPTED_BY_MEDIA:
590 //Intentional Fall through
591 case AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT:
592 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
594 pAudioOutImpl->SendAudioFocusChanged();
597 case AUDIO_IO_INTERRUPTED_BY_ALARM:
598 //Intentional Fall through
599 case AUDIO_IO_INTERRUPTED_BY_EMERGENCY:
600 //Intentional Fall through
601 case AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA:
602 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
604 pAudioOutImpl->SendInterrupted();
608 SysLog(NID_MEDIA, "Interrupt code obtained is wrong - %d", code);
614 _AudioOutImpl::SendBufferEndReachedEvent(void)
616 result r = E_SUCCESS;
617 _AudioOutEventArg* pAudioOutEventArg = null;
618 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
619 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
621 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_DATA_END_REACHED);
622 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
623 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
626 delete pAudioOutEventArg;
631 _AudioOutImpl::SendInterrupted()
633 result r = E_SUCCESS;
634 _AudioOutEventArg* pAudioOutEventArg = null;
635 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
636 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
638 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_INTERRUPTED);
639 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
640 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
643 delete pAudioOutEventArg;
648 _AudioOutImpl::SendAudioFocusChanged()
650 result r = E_SUCCESS;
651 _AudioOutEventArg* pAudioOutEventArg = null;
652 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
653 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
655 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_AUDIO_FOCUS_CHANGED);
656 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
657 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
660 delete pAudioOutEventArg;
665 _AudioOutImpl::SendReleased()
667 result r = E_SUCCESS;
668 _AudioOutEventArg* pAudioOutEventArg = null;
669 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
670 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
671 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_RELEASED);
672 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
673 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
676 delete pAudioOutEventArg;
681 _AudioOutImpl::ScaleDownVolume(unsigned char* pDataBuffer, int bytes)
683 switch (__presentSampleType)
685 case AUDIO_TYPE_PCM_U8:
687 unsigned char* pOutput = __pFeedBuffer->GetPointer();
688 unsigned char* pData = pDataBuffer;
689 int noOfSamples = bytes;
690 for (int i = 0; i < noOfSamples; i++)
692 int v = (((*pData++ - 128) * __volume256 + 128) >> 8) + 128;
693 *pOutput++ = av_clip_uint8(v);
698 case AUDIO_TYPE_PCM_S16_LE:
700 short* pData = (short*) pDataBuffer;
701 short* pOutput = (short*) __pFeedBuffer->GetPointer();
702 int noOfSamples = bytes >> 1;
703 for (int i = 0; i < noOfSamples; i++)
705 int v = ((*pData++) * __volume256 + 128) >> 8;
706 *pOutput++ = av_clip_int16(v);
717 _AudioOutImpl::PreProcess(ByteBuffer* pBuffer, int index, int size)
719 unsigned char* pDataBuffer = null;
720 if (pBuffer->GetLimit() > 0)
722 pDataBuffer = (unsigned char*) pBuffer->GetPointer();
727 pDataBuffer = pDataBuffer + index;
733 if ((__volume256 < 256) && (__volume256 >= 0))
735 ScaleDownVolume(pDataBuffer, size);
740 _AudioOutImpl::MapExceptionToResult(int reason)
742 //All the fall through are intentional
746 case AUDIO_IO_ERROR_NONE:
750 case AUDIO_IO_ERROR_OUT_OF_MEMORY:
751 return E_OUT_OF_MEMORY;
754 case AUDIO_IO_ERROR_INVALID_PARAMETER:
755 return E_INVALID_ARG;
758 case AUDIO_IO_ERROR_INVALID_OPERATION:
759 return E_INVALID_OPERATION;
762 case AUDIO_IO_ERROR_DEVICE_NOT_OPENED:
763 return E_INVALID_STATE;
766 case AUDIO_IO_ERROR_INVALID_BUFFER:
767 return E_INVALID_ARG;
770 case AUDIO_IO_ERROR_DEVICE_NOT_CLOSED:
771 return E_INVALID_STATE;
774 case AUDIO_IO_ERROR_SOUND_POLICY:
775 return E_DEVICE_BUSY;