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 <FBaseSysLog.h>
19 #include "FMedia_AudioInImpl.h"
20 #include "FMedia_AudioInEvent.h"
21 #include "FMedia_AudioInEventArg.h"
22 #include "FMedia_AudioManagerConvert.h"
24 using namespace Tizen::Base;
25 using namespace Tizen::Base::Runtime;
26 using namespace Tizen::Base::Collection;
28 namespace Tizen { namespace Media
31 bool _AudioInImpl::__isConstructed = false;
32 int _AudioInImpl::__runFlag = false;
33 const int _AudioInImpl::_AUDIO_IN_OPTIMAL_SAMPLE_RATE = 44100;
34 const int _AudioInImpl::_AUDIO_IN_MINIMUM_BUFFER_SIZE = 1024;
35 const int _AudioInImpl::_AUDIO_IN_MAXIMUM_BUFFER_SIZE = 164112;
36 const AudioChannelType _AudioInImpl::_AUDIO_IN_OPTIMAL_CHANNEL_TYPE = AUDIO_CHANNEL_TYPE_STEREO;
37 const AudioSampleType _AudioInImpl::_AUDIO_IN_OPTIMAL_SAMPLE_TYPE = AUDIO_TYPE_PCM_S16_LE;
39 _AudioInImpl::_AudioInImpl(void)
40 : __audioInState(AUDIOIN_STATE_ERROR)
41 , __pAudioInEventListener(null)
42 , __audioInHandle(null)
43 , __audioInOptimalBufferSize(0)
44 , __interruptFlag(false)
48 _AudioInImpl::~_AudioInImpl(void)
51 __isConstructed = false;
53 if (__audioInState < AUDIOIN_STATE_UNPREPARED && __audioInState >= AUDIOIN_STATE_PREPARED)
55 if (__audioInState == AUDIOIN_STATE_RECORDING || __audioInState == AUDIOIN_STATE_STOPPED )
58 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
61 r = this->Unprepare();
62 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
65 if (__pAudioInEvent.get() && __pAudioInEventListener)
67 __pAudioInEvent->RemoveListener(*__pAudioInEventListener);
68 __pAudioInEventListener = null;
77 _AudioInImpl::GetInstance(AudioIn* pAudioIn)
81 return pAudioIn->__pAudioInImpl;
88 _AudioInImpl::GetInstance(const AudioIn* pAudioIn)
92 return pAudioIn->__pAudioInImpl;
99 _AudioInImpl::Construct(Tizen::Media::IAudioInEventListener& listener)
101 result r = E_SUCCESS;
103 SysTryReturnResult(NID_MEDIA, !__isConstructed, E_DEVICE_BUSY, "The input device is already in use");
104 __isConstructed = true;
106 //Setting up the Events
107 __pAudioInEvent.reset(new (std::nothrow) _AudioInEvent);
108 SysTryCatch(NID_MEDIA, __pAudioInEvent.get(), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
110 r = __pAudioInEvent->Construct();
111 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
113 r = __pAudioInEvent->AddListener(listener);
114 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
116 __pAudioInEventListener = &listener;
119 r = __bufferQueue.Construct();
120 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
123 __pBufferSync.reset(new (std::nothrow) Monitor);
124 SysTryCatch(NID_MEDIA, __pBufferSync.get(), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(r));
125 r = __pBufferSync->Construct();
126 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
128 __audioInState = AUDIOIN_STATE_INITIALIZED;
132 __isConstructed = false;
139 _AudioInImpl::GetMaxBufferSize(void)
141 result r = E_SUCCESS;
142 SysTryCatch(NID_MEDIA, __audioInState < AUDIOIN_STATE_UNPREPARED && __audioInState >= AUDIOIN_STATE_PREPARED, r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] AudioIn state is not proper.");
143 return _AUDIO_IN_MAXIMUM_BUFFER_SIZE;
151 _AudioInImpl::GetMinBufferSize(void)
153 result r = E_SUCCESS;
154 SysTryCatch(NID_MEDIA, __audioInState < AUDIOIN_STATE_UNPREPARED && __audioInState >= AUDIOIN_STATE_PREPARED, r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] AudioIn state is not proper.");
155 return _AUDIO_IN_MINIMUM_BUFFER_SIZE;
162 _AudioInImpl::GetOptimizedChannelType(void)
164 result r = E_SUCCESS;
166 return _AUDIO_IN_OPTIMAL_CHANNEL_TYPE;
171 _AudioInImpl::GetOptimizedSampleRate(void)
173 result r = E_SUCCESS;
175 return _AUDIO_IN_OPTIMAL_SAMPLE_RATE;
179 _AudioInImpl::GetOptimizedSampleType(void)
181 result r = E_SUCCESS;
183 return _AUDIO_IN_OPTIMAL_SAMPLE_TYPE;
187 _AudioInImpl::GetState(void)
189 result r = E_SUCCESS;
190 SysLog(NID_MEDIA, "The current state of AudioIn is %d", __audioInState);
192 return __audioInState;
196 _AudioInImpl::Prepare(AudioSampleType audioSampleType, AudioChannelType audioChannelType, int audioSampleRate)
198 result r = E_SUCCESS;
201 SysTryReturnResult(NID_MEDIA, __audioInState == AUDIOIN_STATE_UNPREPARED || __audioInState == AUDIOIN_STATE_INITIALIZED, E_INVALID_STATE, "AudioIn state is not proper.");
202 SysTryReturnResult(NID_MEDIA, audioSampleType == AUDIO_TYPE_PCM_U8 || audioSampleType == AUDIO_TYPE_PCM_S16_LE, E_INVALID_ARG,
203 "Invalid argument is used. Audio sample is type is not valid.");
204 SysTryReturnResult(NID_MEDIA, audioChannelType == AUDIO_CHANNEL_TYPE_MONO || audioChannelType == AUDIO_CHANNEL_TYPE_STEREO, E_INVALID_ARG,
205 "Invalid argument is used. Audio channel type is not valid");
206 SysTryReturnResult(NID_MEDIA, audioSampleRate >= 8000 && audioSampleRate <= 48000, E_INVALID_ARG,
207 "Invalid argument is used. Audio sample rate is not valid.");
209 ret = audio_in_create(audioSampleRate, _AudioManagerConvert::ConvertChannelTypeAudio(audioChannelType), _AudioManagerConvert::ConvertSampleTypeAudio(audioSampleType), &__audioInHandle);
210 r = MapExceptionToResult(ret);
211 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
212 "[%s] Failed to perform audio_in_create operation with error code : 0x%x", GetErrorMessage(r), ret);
214 ret = audio_in_set_interrupted_cb(__audioInHandle, AudioIoInterrupted, this);
215 r = MapExceptionToResult(ret);
216 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
217 "[%s] Failed to perform audio_in_set_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
219 ret = audio_in_get_buffer_size(__audioInHandle, &__audioInOptimalBufferSize);
220 if (ret == AUDIO_IO_ERROR_NONE)
222 SysLog(NID_MEDIA, "The optimal buffer size is %d", __audioInOptimalBufferSize);
226 r = MapExceptionToResult(ret);
227 SysLogException(NID_MEDIA, r, "[%s] Failed to perform audio_out_get_buffer_size operation with error code : 0x%x",GetErrorMessage(r), ret);
230 __audioInState = AUDIOIN_STATE_PREPARED;
234 __audioInHandle = null;
235 SysLog(NID_MEDIA, "This function is failed in %s with error code : %x. And the value of __audioInOptimalBufferSize is %x\n", __FUNCTION__, r, __audioInOptimalBufferSize);
240 _AudioInImpl::Reset(void)
242 result r = E_SUCCESS;
243 SysTryReturnResult(NID_MEDIA, __audioInState <AUDIOIN_STATE_UNPREPARED && __audioInState> AUDIOIN_STATE_PREPARED, E_INVALID_STATE,
244 "AudioIn state is in an invalid state. the current state is %d.", __audioInState);
245 if (__audioInState == AUDIOIN_STATE_RECORDING )
249 __bufferQueue.RemoveAll();
250 __audioInState = AUDIOIN_STATE_PREPARED;
255 _AudioInImpl::Unprepare(void)
257 result r = E_SUCCESS;
259 SysTryReturnResult(NID_MEDIA, __audioInState == AUDIOIN_STATE_PREPARED || __audioInState == AUDIOIN_STATE_STOPPED, E_INVALID_STATE,
260 "AudioIn state is in an invalid state. the current state is %d", __audioInState);
261 __bufferQueue.RemoveAll();
262 __audioInState = AUDIOIN_STATE_UNPREPARED;
266 ret = audio_in_unset_interrupted_cb(__audioInHandle);
267 r = MapExceptionToResult(ret);
268 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
269 "[%s] Failed to perform audio_in_unset_interrupted_cb operation with error code : 0x%x", GetErrorMessage(r), ret);
271 ret = audio_in_destroy(__audioInHandle);
272 r = MapExceptionToResult(ret);
273 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
274 "[%s] Failed to perform audio_in_destroy operation with error code : 0x%x", GetErrorMessage(r), ret);
276 __audioInHandle = null;
279 __audioInState = AUDIOIN_STATE_INITIALIZED;
284 _AudioInImpl::Start(void)
286 result r = E_SUCCESS;
287 int ret = AUDIO_IO_ERROR_NONE;
288 SysTryReturnResult(NID_MEDIA, __audioInState == AUDIOIN_STATE_PREPARED || __audioInState == AUDIOIN_STATE_STOPPED, E_INVALID_STATE,
289 "AudioIn state is in an invalid state");
290 SysTryCatch(NID_MEDIA, __bufferQueue.GetCount() > 0, r = E_SYSTEM, E_SYSTEM,
291 "[E_SYSTEM] A system error has been occurred. There is no buffers queued.");
293 ret = audio_in_prepare(__audioInHandle);
294 r = MapExceptionToResult(ret);
295 SysTryReturnResult(NID_MEDIA, r != E_DEVICE_BUSY, E_DEVICE_BUSY, "AudioIn cannot Start, higher priority task at work.");
296 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Failed to perform audio_in_prepare operation with error code : %x", GetErrorMessage(r), ret);
298 __pWorkerThread.reset(new (std::nothrow) Thread);
299 SysTryCatch(NID_MEDIA, __pWorkerThread.get(), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
301 r = __pWorkerThread->Construct(*this);
302 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = E_SYSTEM, r, "[%s] Propagating.", GetErrorMessage(r));
305 r = __pWorkerThread->Start();
306 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = E_SYSTEM, r, "[%s] Propagating.", GetErrorMessage(r));
308 __audioInState = AUDIOIN_STATE_RECORDING;
313 ret = audio_in_unprepare(__audioInHandle);
314 SysTryLog(NID_MEDIA, ret == AUDIO_IO_ERROR_NONE, "Failed to perform audio_in_unprepare operation with error code : %x", ret);
317 __audioInState = AUDIOIN_STATE_ERROR;
322 _AudioInImpl::Stop(void)
324 result r = E_SUCCESS;
325 SysTryReturnResult(NID_MEDIA, __audioInState == AUDIOIN_STATE_RECORDING, E_INVALID_STATE,
326 "The state of AudioIn is in an invalied state. the current state is %d", __audioInState);
329 if (__pWorkerThread.get())
331 r = __pBufferSync->Enter();
332 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
333 r = __pBufferSync->Notify();
334 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
335 r = __pBufferSync->Exit();
336 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
337 r = __pWorkerThread->Join();
338 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
342 SysLog(NID_MEDIA, "There is no thread to stop.");
345 __audioInState = AUDIOIN_STATE_STOPPED;
350 _AudioInImpl::AddBuffer(const Tizen::Base::ByteBuffer* pByteBuffer)
352 result r = E_SUCCESS;
354 TryReturn(__audioInState >= AUDIOIN_STATE_PREPARED && __audioInState < AUDIOIN_STATE_UNPREPARED, E_INVALID_STATE, "AudioIn state is not proper.");
355 SysTryReturnResult(NID_MEDIA, __audioInState >= AUDIOIN_STATE_PREPARED && __audioInState < AUDIOIN_STATE_UNPREPARED, E_INVALID_STATE, "AudioIn state is not proper.");
356 SysTryReturnResult(NID_MEDIA, (pByteBuffer->GetCapacity() >= _AUDIO_IN_MINIMUM_BUFFER_SIZE), E_INVALID_ARG,
357 "Invalid argument is used. The size of buffer is too small, the current size is %d. The size of buffer should be between %d and %d",
358 pByteBuffer->GetCapacity(), _AUDIO_IN_MINIMUM_BUFFER_SIZE, _AUDIO_IN_MAXIMUM_BUFFER_SIZE);
359 SysTryReturnResult(NID_MEDIA, _AUDIO_IN_MAXIMUM_BUFFER_SIZE >= pByteBuffer->GetCapacity(), E_OVERFLOW,
360 "Invalid argument is used. The size of buffer is too big, the current size is %d. The size of buffer should be between %d and %d", pByteBuffer->GetCapacity(), _AUDIO_IN_MINIMUM_BUFFER_SIZE, _AUDIO_IN_MAXIMUM_BUFFER_SIZE);
362 r = __pBufferSync->Enter();
363 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
365 r = __bufferQueue.Enqueue((const ByteBuffer*) (pByteBuffer));
366 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
368 r = __pBufferSync->Notify();
369 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
371 r = __pBufferSync->Exit();
372 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
377 _AudioInImpl::Run(void)
379 ByteBuffer* pBuffer = null;
381 unsigned char* pData = null;
382 unsigned char* pInitialPointer = null;
384 result r = E_SUCCESS;
388 r = __pBufferSync->Enter();
389 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
390 if (__bufferQueue.Peek((const Tizen::Base::ByteBuffer * &)pBuffer) == E_UNDERFLOW)
393 __pBufferSync->Wait();
396 r = __pBufferSync->Exit();
397 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
398 ret = audio_in_unprepare(__audioInHandle);
399 SysTryLog(NID_MEDIA, ret == AUDIO_IO_ERROR_NONE, "Failed to perform audio_in_unprepare operation with error code : %x", ret);
402 r = __bufferQueue.Peek((const Tizen::Base::ByteBuffer * &)pBuffer);
403 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
405 r = __pBufferSync->Exit();
406 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
408 buffer_size = pBuffer->GetCapacity();
409 pData = (unsigned char*) pBuffer->GetPointer();
410 SysTryCatch(NID_MEDIA, pData != null, r = E_INVALID_ARG, r, "Invalid argument is used. Data to read is null.");
414 ret = audio_in_read(__audioInHandle, (void*) pData, buffer_size);
415 if (ret != buffer_size)
417 SysLog(NID_MEDIA, "The size of data read is smaller than buffer size");
421 __pBufferSync->Enter();
422 r = __bufferQueue.Dequeue((const Tizen::Base::ByteBuffer * &)pBuffer);
423 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
425 r = __pBufferSync->Exit();
426 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
428 pInitialPointer = (unsigned char*) pBuffer->GetPointer();
431 pBuffer->SetPosition(pData - pInitialPointer);
433 SendBufferEndReachedEvent(pBuffer);
437 ret = audio_in_unprepare(__audioInHandle);
438 SysTryLog(NID_MEDIA, ret == AUDIO_IO_ERROR_NONE, "Failed to perform audio_in_unprepare operation with error code : %x", ret);
439 SysLog(NID_MEDIA, "AudioIn thread is terminated.");
442 ret = audio_in_unprepare(__audioInHandle);
443 SysTryLog(NID_MEDIA, ret == AUDIO_IO_ERROR_NONE, "Failed to perform audio_in_unprepare operation with error code : %x", ret);
448 _AudioInImpl::AudioIoInterrupted(audio_io_interrupted_code_e code, void *pUserData)
450 SysTryReturn(NID_MEDIA, pUserData, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. pUserData is null.");
451 _AudioInImpl *pAudioInImpl = (_AudioInImpl *)pUserData;
455 case AUDIO_IO_INTERRUPTED_COMPLETED:
456 if (pAudioInImpl->__audioInState == AUDIOIN_STATE_STOPPED)
458 if (!(pAudioInImpl->__interruptFlag))
460 pAudioInImpl->SendReleased();
462 pAudioInImpl->__interruptFlag = false;
465 case AUDIO_IO_INTERRUPTED_BY_CALL:
466 pAudioInImpl->__interruptFlag = true;
467 //Intentional Fall through
468 case AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG:
469 //Intentional Fall through
470 case AUDIO_IO_INTERRUPTED_BY_MEDIA:
471 //Intentional Fall through
472 case AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT:
473 //Intentional Fall through
474 if (pAudioInImpl->__audioInState == AUDIOIN_STATE_RECORDING)
476 pAudioInImpl->SendAudioFocusChanged();
479 case AUDIO_IO_INTERRUPTED_BY_ALARM:
480 //Intentional Fall through
481 case AUDIO_IO_INTERRUPTED_BY_EMERGENCY:
482 if (pAudioInImpl->__audioInState == AUDIOIN_STATE_RECORDING)
484 pAudioInImpl->SendInterrupted();
488 SysLog(NID_MEDIA, "Interrupt code obtained is wrong, the code is %d", code);
494 _AudioInImpl::SendBufferEndReachedEvent(Tizen::Base::ByteBuffer* pBuffer)
496 _AudioInEventArg* pAudioInEventArg = null;
498 pAudioInEventArg = new (std::nothrow) _AudioInEventArg;
499 TryReturn(pAudioInEventArg, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
501 pAudioInEventArg->SetData(pBuffer);
503 pAudioInEventArg->SetEventType(_AUDIOIN_EVENT_RECORDED_DATA);
505 __pAudioInEvent->FireAsync(*pAudioInEventArg);
511 _AudioInImpl::SendInterrupted(void)
513 result r = E_SUCCESS;
514 _AudioInEventArg* pAudioInEventArg = null;
515 pAudioInEventArg = new (std::nothrow) _AudioInEventArg;
516 SysTryReturnResult(NID_MEDIA, pAudioInEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
518 pAudioInEventArg->SetEventType(_AUDIOIN_EVENT_INTERRUPTED);
519 r = __pAudioInEvent->FireAsync(*pAudioInEventArg);
520 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
523 delete pAudioInEventArg;
528 _AudioInImpl::SendAudioFocusChanged(void)
530 result r = E_SUCCESS;
531 _AudioInEventArg* pAudioInEventArg = null;
532 pAudioInEventArg = new (std::nothrow) _AudioInEventArg;
533 SysTryReturnResult(NID_MEDIA, pAudioInEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
535 pAudioInEventArg->SetEventType(_AUDIOIN_EVENT_AUDIO_FOCUS_CHANGED);
536 r = __pAudioInEvent->FireAsync(*pAudioInEventArg);
537 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
540 delete pAudioInEventArg;
545 _AudioInImpl::SendReleased(void)
547 result r = E_SUCCESS;
548 _AudioInEventArg* pAudioInEventArg = null;
549 pAudioInEventArg = new (std::nothrow) _AudioInEventArg;
550 SysTryReturnResult(NID_MEDIA, pAudioInEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
551 pAudioInEventArg->SetEventType(_AUDIOIN_EVENT_RELEASED);
552 r = __pAudioInEvent->FireAsync(*pAudioInEventArg);
553 SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
556 delete pAudioInEventArg;
561 _AudioInImpl::MapExceptionToResult(int reason)
563 //All the fall through are intentional
567 case AUDIO_IO_ERROR_NONE:
571 case AUDIO_IO_ERROR_OUT_OF_MEMORY:
572 return E_OUT_OF_MEMORY;
575 case AUDIO_IO_ERROR_INVALID_PARAMETER:
576 return E_INVALID_ARG;
579 case AUDIO_IO_ERROR_INVALID_OPERATION:
580 return E_INVALID_OPERATION;
583 case AUDIO_IO_ERROR_DEVICE_NOT_OPENED:
584 return E_INVALID_STATE;
587 case AUDIO_IO_ERROR_INVALID_BUFFER:
588 return E_INVALID_ARG;
591 case AUDIO_IO_ERROR_DEVICE_NOT_CLOSED:
592 return E_INVALID_STATE;
595 case AUDIO_IO_ERROR_SOUND_POLICY:
596 return E_DEVICE_BUSY;