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;
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 )
88 if (__pAudioOutEvent.get() && __pAudioOutEventListener)
90 __pAudioOutEvent->RemoveListener(*__pAudioOutEventListener);
93 if ((__audioOutState == AUDIOOUT_STATE_INITIALIZED ) || __audioOutState == AUDIOOUT_STATE_UNPREPARED )
95 __pInstanceMutex->Acquire();
97 __pInstanceMutex->Release();
102 _AudioOutImpl::InitInstanceMutex(void)
104 result r = E_SUCCESS;
105 __pInstanceMutex.reset(new (std::nothrow) Tizen::Base::Runtime::Mutex);
106 SysTryReturn(NID_MEDIA, __pInstanceMutex.get() != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] no memory to create instance Mutex");
107 r = __pInstanceMutex->Create("FMEDIA_AUDIOOUT_N");
108 SysTryReturn(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Mutex::Create failed.");
109 __isInstanceMutexInitialized = true;
113 _AudioOutImpl::GetInstance(AudioOut* pAudioOut)
115 if (pAudioOut != null)
117 return pAudioOut->__pAudioOutImpl;
124 _AudioOutImpl::GetInstance(const AudioOut* pAudioOut)
126 if (pAudioOut != null)
128 return pAudioOut->__pAudioOutImpl;
135 _AudioOutImpl::Construct(const Tizen::Media::AudioOut* pAudioOut, Tizen::Media::IAudioOutEventListener& listener)
137 result r = E_SUCCESS;
138 __pAudioOut = const_cast <AudioOut*>(pAudioOut);
139 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
140 if (!__isInstanceMutexInitialized)
142 pthread_once(&onceBlock, InitInstanceMutex);
144 SysTryCatch(NID_MEDIA, __isInstanceMutexInitialized == true, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] memory allocation for Instance Mutex failed");
146 if (!maxInstanceCount)
148 r = MediaCapability::GetValue(AUDIOOUT_COUNT_MAX, maxInstanceCount);
149 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
150 SysTryCatch(NID_MEDIA, maxInstanceCount > 0, , r, "[%s] Propagating.", GetErrorMessage(r));
153 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);
155 //Setting up the Events
156 __pAudioOutEvent.reset(new (std::nothrow) _AudioOutEvent);
157 SysTryReturnResult(NID_MEDIA, __pAudioOutEvent.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
158 r = __pAudioOutEvent->Construct(__pAudioOut);
159 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
160 r = __pAudioOutEvent->AddListener(listener);
161 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
164 r = __bufferQueue.Construct();
165 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
167 __pBufferSync.reset( new (std::nothrow) Monitor);
168 SysTryCatch(NID_MEDIA, __pBufferSync.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
169 r = __pBufferSync->Construct();
170 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
173 __volume256 = (__volume << 8) / 100;
175 __pInstanceMutex->Acquire();
177 __pInstanceMutex->Release();
179 __audioOutState = AUDIOOUT_STATE_INITIALIZED;
189 _AudioOutImpl::GetMaxBufferSize(void)
191 result r = E_SUCCESS;
192 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
193 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
194 return audioOutMaximumBufferSize;
201 _AudioOutImpl::GetMinBufferSize(void)
203 result r = E_SUCCESS;
204 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
205 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
206 return audioOutMinimumBufferSize;
213 _AudioOutImpl::GetOptimizedChannelType(void)
215 return audioOutOptimalChannelType;
219 _AudioOutImpl::GetOptimizedSampleRate(void)
221 result r = E_SUCCESS;
223 return audioOutOptimalSampleRate;
227 _AudioOutImpl::GetOptimizedSampleType(void)
229 return audioOutOptimalSampleType;
233 _AudioOutImpl::GetState(void)
235 result r = E_SUCCESS;
237 SysLog(NID_MEDIA, "The current state of this instance is %d", __audioOutState);
238 return __audioOutState;
242 _AudioOutImpl::GetVolume(void) const
244 result r = E_SUCCESS;
245 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
246 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
254 _AudioOutImpl::SetVolume(int& volume)
256 result r = E_SUCCESS;
257 SysTryCatch(NID_MEDIA, __audioOutState < AUDIOOUT_STATE_UNPREPARED && __audioOutState >= AUDIOOUT_STATE_PREPARED,
258 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The state of this instance is in an invalid state.");
260 __volume256 = (__volume << 8) / 100;
267 _AudioOutImpl::Prepare(AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
269 result r = E_SUCCESS;
272 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
273 E_INVALID_STATE, "The state of this instance is in an invalid state.");
274 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
275 "Audio sample type is not valid.");
276 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
277 "Invalid argument is used. Audio channel type is not valid");
278 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
279 "Invalid argument is used. Audio sample rate is not valid.");
281 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), SOUND_TYPE_MEDIA, &__audioOutHandle);
282 r = MapExceptionToResult(ret);
283 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
285 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
286 r = MapExceptionToResult(ret);
287 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
288 "[%s] Failed to perform audio_out_set_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
290 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
291 if (ret == AUDIO_IO_ERROR_NONE)
293 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
297 r = MapExceptionToResult(ret);
298 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
301 __audioOutOptimalBufferSize = 1024;
302 __presentSampleType = audioSampleType;
303 __presentSampleRate = audioSampleRate;
305 __audioOutState = AUDIOOUT_STATE_PREPARED;
308 __audioOutHandle = null;
313 _AudioOutImpl::Prepare(AudioStreamType audioStreamType, AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
315 result r = E_SUCCESS;
318 SysTryReturnResult(NID_MEDIA, __audioOutState == AUDIOOUT_STATE_UNPREPARED || __audioOutState == AUDIOOUT_STATE_INITIALIZED,
319 E_INVALID_STATE, "The state of this instance is in an invalid state.");
320 SysTryReturnResult(NID_MEDIA, audioSampleType >= AUDIO_TYPE_PCM_U8 && audioSampleType < AUDIO_TYPE_PCM_S16_BE, E_UNSUPPORTED_FORMAT,
321 "Audio sample type is not valid.");
322 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
323 "Invalid argument is used. Audio channel type is not valid");
324 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
325 "Invalid argument is used. Audio sample rate is not valid.");
327 ret = audio_out_create(audioSampleRate, _AudioManagerConvert::ConvertChannelType(audioChannelType), _AudioManagerConvert::ConvertSampleType(audioSampleType), _AudioManagerConvert::ConvertAudioStreamType2SoundType(audioStreamType), &__audioOutHandle);
328 r = MapExceptionToResult(ret);
329 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_create operation with error code : 0x%x", GetErrorMessage(r), ret);
331 ret = audio_out_prepare(__audioOutHandle);
332 r = MapExceptionToResult(ret);
333 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_out_prepare operation with error code : 0x%x", GetErrorMessage(r), ret);
335 ret = audio_out_set_interrupted_cb(__audioOutHandle, AudioIoInterrupted, this);
336 r = MapExceptionToResult(ret);
337 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);
339 ret = audio_out_get_buffer_size(__audioOutHandle, &__audioOutOptimalBufferSize);
340 if (ret == AUDIO_IO_ERROR_NONE)
342 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioOutOptimalBufferSize);
346 r = MapExceptionToResult(ret);
347 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : %x", GetErrorMessage(r), ret);
350 __audioOutOptimalBufferSize = 1024;
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;
492 __pBufferSync->Enter();
493 if ( __bufferQueue.Peek(pBuffer) == E_UNDERFLOW)
496 __pBufferSync->Wait();
499 __pBufferSync->Exit();
502 __bufferQueue.Peek(pBuffer);
504 __pBufferSync->Exit();
506 SysTryCatch(NID_MEDIA, pBuffer, r = E_INVALID_ARG, E_INVALID_ARG,
507 "[E_INVALID_ARG] Invalid argument is used. The buffer to write is null.");
509 if ((__volume >= 0) && (__volume < 100))
516 buffer_size = pBuffer->GetLimit();
517 pData = (unsigned char*) pBuffer->GetPointer();
518 SysTryCatch(NID_MEDIA, pData, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. The data to write is null");
521 ret = audio_out_write(__audioOutHandle, (void*) pData, buffer_size);
522 if (ret != buffer_size)
524 SysLog(NID_MEDIA, "The size of actual written data is %d", ret);
531 __pBufferSync->Enter();
532 __bufferQueue.Dequeue(pBuffer);
533 __pBufferSync->Exit();
535 SendBufferEndReachedEvent();
547 _AudioOutImpl::AudioIoInterrupted(audio_io_interrupted_code_e code, void *pUserData)
549 SysTryReturn(NID_MEDIA, pUserData, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. The value of pUserData is null.");
550 _AudioOutImpl *pAudioOutImpl = (_AudioOutImpl *)pUserData;
554 case AUDIO_IO_INTERRUPTED_COMPLETED:
555 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_STOPPED)
557 if (!(pAudioOutImpl->__interruptFlag))
559 pAudioOutImpl->SendReleased();
561 pAudioOutImpl->__interruptFlag = false;
564 case AUDIO_IO_INTERRUPTED_BY_CALL:
565 pAudioOutImpl->__interruptFlag = true;
566 //Intentional Fall through
567 case AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG:
568 //Intentional Fall through
569 case AUDIO_IO_INTERRUPTED_BY_MEDIA:
570 //Intentional Fall through
571 case AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT:
572 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
574 pAudioOutImpl->SendAudioFocusChanged();
577 case AUDIO_IO_INTERRUPTED_BY_ALARM:
578 //Intentional Fall through
579 case AUDIO_IO_INTERRUPTED_BY_EMERGENCY:
580 if (pAudioOutImpl->__audioOutState == AUDIOOUT_STATE_PLAYING)
582 pAudioOutImpl->SendInterrupted();
586 SysLog(NID_MEDIA, "Interrupt code obtained is wrong - %d", code);
592 _AudioOutImpl::SendBufferEndReachedEvent(void)
594 result r = E_SUCCESS;
595 _AudioOutEventArg* pAudioOutEventArg = null;
596 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
597 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
599 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_DATA_END_REACHED);
600 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
601 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
604 delete pAudioOutEventArg;
609 _AudioOutImpl::SendInterrupted()
611 result r = E_SUCCESS;
612 _AudioOutEventArg* pAudioOutEventArg = null;
613 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
614 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
616 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_INTERRUPTED);
617 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
618 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
621 delete pAudioOutEventArg;
626 _AudioOutImpl::SendAudioFocusChanged()
628 result r = E_SUCCESS;
629 _AudioOutEventArg* pAudioOutEventArg = null;
630 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
631 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
633 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_AUDIO_FOCUS_CHANGED);
634 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
635 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
638 delete pAudioOutEventArg;
643 _AudioOutImpl::SendReleased()
645 result r = E_SUCCESS;
646 _AudioOutEventArg* pAudioOutEventArg = null;
647 pAudioOutEventArg = new (std::nothrow) _AudioOutEventArg;
648 SysTryReturnResult(NID_MEDIA, pAudioOutEventArg, E_OUT_OF_MEMORY, "Memory allocation failed.");
649 pAudioOutEventArg->SetEventType(_AUDIOOUT_EVENT_RELEASED);
650 r = __pAudioOutEvent->FireAsync(*pAudioOutEventArg);
651 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
654 delete pAudioOutEventArg;
659 _AudioOutImpl::ScaleDownVolume(unsigned char* pDataBuffer, int bytes)
661 switch (__presentSampleType)
663 case AUDIO_TYPE_PCM_U8:
665 unsigned char* pData = pDataBuffer;
666 int noOfSamples = bytes;
667 for (int i = 0; i < noOfSamples; i++)
669 int v = (((*pData - 128) * __volume256 + 128) >> 8) + 128;
670 *pData++ = av_clip_uint8(v);
675 case AUDIO_TYPE_PCM_S16_LE:
677 short* pData = (short*) pDataBuffer;
678 int noOfSamples = bytes >> 1;
679 for (int i = 0; i < noOfSamples; i++)
681 int v = ((*pData) * __volume256 + 128) >> 8;
682 *pData++ = av_clip_int16(v);
693 _AudioOutImpl::PreProcess(ByteBuffer* pBuffer)
695 unsigned char* pDataBuffer = null;
697 if (pBuffer->GetLimit() > 0)
699 pDataBuffer = (unsigned char*) pBuffer->GetPointer();
704 bytes = pBuffer->GetLimit();
710 if ((__volume256 < 256) && (__volume256 >= 0))
712 ScaleDownVolume(pDataBuffer, bytes);
717 _AudioOutImpl::MapExceptionToResult(int reason)
719 //All the fall through are intentional
723 case AUDIO_IO_ERROR_NONE:
727 case AUDIO_IO_ERROR_OUT_OF_MEMORY:
728 return E_OUT_OF_MEMORY;
731 case AUDIO_IO_ERROR_INVALID_PARAMETER:
732 return E_INVALID_ARG;
735 case AUDIO_IO_ERROR_INVALID_OPERATION:
736 return E_INVALID_OPERATION;
739 case AUDIO_IO_ERROR_DEVICE_NOT_OPENED:
740 return E_INVALID_STATE;
743 case AUDIO_IO_ERROR_INVALID_BUFFER:
744 return E_INVALID_ARG;
747 case AUDIO_IO_ERROR_DEVICE_NOT_CLOSED:
748 return E_INVALID_STATE;
751 case AUDIO_IO_ERROR_SOUND_POLICY:
752 return E_DEVICE_BUSY;