axmol/CocosDenshion/bada/CCAudioOut.cpp

744 lines
16 KiB
C++
Raw Normal View History

/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
2011-10-14 18:33:14 +08:00
#include "CCAudioOut.h"
2011-10-14 17:57:44 +08:00
#include <stdio.h>
2011-10-18 09:45:04 +08:00
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <FSystem.h>
2011-10-14 17:57:44 +08:00
2011-10-29 14:47:13 +08:00
#define OGG_SUPPORT
2011-10-18 18:10:53 +08:00
#ifdef OGG_SUPPORT
2011-10-29 14:47:13 +08:00
#include "vorbis/vorbisfile.h"
2011-10-18 18:10:53 +08:00
#endif
2011-10-14 17:57:44 +08:00
using namespace Osp::Base;
using namespace Osp::Base::Collection;
using namespace Osp::Media;
2011-10-18 09:45:04 +08:00
using namespace Osp::Io;
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
namespace CocosDenshion {
#define PRE_BUFFERING_NUM 2
#define DEFAULT_VOLUME_LEVEL 5
2011-10-14 17:57:44 +08:00
2011-10-14 18:33:14 +08:00
typedef struct wave_tag
{
char ChunkID[5];
unsigned long int ChunkSize;
char Format[5];
char SubChunk1ID[5];
unsigned long int SubChunk1Size;
unsigned short int AudioFormat;
unsigned short int NumChannels;
unsigned long int SampleRate;
unsigned long int ByteRate;
unsigned short int BlockAlign;
unsigned short int BitsPerSample;
char SubChunk2ID[5];
unsigned long int SubChunk2Size;
}WAVE;
2011-10-18 09:45:04 +08:00
static void GetWaveHeadInfo(File* pFile, WAVE& outWavHead)
2011-10-14 18:33:14 +08:00
{
char szTmp[100] = {0};
int i = 0;
2011-10-18 09:45:04 +08:00
memset(&outWavHead, 0, sizeof(WAVE));
pFile->Read(outWavHead.ChunkID, 4);
pFile->Read(&(outWavHead.ChunkSize),4);
pFile->Read(outWavHead.Format, 4);
pFile->Read(outWavHead.SubChunk1ID, 4);
pFile->Read(&(outWavHead.SubChunk1Size), 4);
pFile->Read(&(outWavHead.AudioFormat), 2);
pFile->Read(&(outWavHead.NumChannels), 2);
pFile->Read(&(outWavHead.SampleRate), 4);
pFile->Read(&(outWavHead.ByteRate), 4);
pFile->Read(&(outWavHead.BlockAlign), 2);
pFile->Read(&(outWavHead.BitsPerSample), 2);
pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
pFile->Read(szTmp, 64);
2011-10-14 18:33:14 +08:00
for (i = 0; i <= 60; i++)
{
if (szTmp[i] == 'd' && szTmp[i+1] == 'a' && szTmp[i+2] == 't' && szTmp[i+3] == 'a')
{
break;
}
}
2011-10-18 09:45:04 +08:00
pFile->Seek(FILESEEKPOSITION_BEGIN, i);
pFile->Read(outWavHead.SubChunk2ID, 4);
pFile->Read(&(outWavHead.SubChunk2Size), 4);
}
2011-10-14 18:33:14 +08:00
2011-10-18 09:45:04 +08:00
int CCAudioOut::DecodeOgg(const char *infile)
{
2011-10-18 18:10:53 +08:00
#ifdef OGG_SUPPORT
2011-10-18 09:45:04 +08:00
FILE *in=NULL;
OggVorbis_File vf;
int bs = 0;
char buf[8192];
int buflen = 8192;
unsigned int written = 0;
int ret;
ogg_int64_t length = 0;
ogg_int64_t done = 0;
int size;
int seekable = 0;
int percent = 0;
2011-11-13 00:57:54 +08:00
//AppLog("enter, %s", infile);
2011-10-18 09:45:04 +08:00
in = fopen(infile, "rb");
if(!in) {
2011-11-13 00:57:54 +08:00
//AppLog("ERROR: Failed to open input file:\n");
2011-10-18 09:45:04 +08:00
return 1;
}
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
if(ov_open(in, &vf, NULL, 0) < 0) {
2011-11-13 00:57:54 +08:00
//AppLog("ERROR: Failed to open input as vorbis\n");
2011-10-18 09:45:04 +08:00
fclose(in);
// fclose(out);
return 1;
}
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
if(ov_seekable(&vf)) {
seekable = 1;
length = ov_pcm_total(&vf, 0);
size = 16/8 * ov_info(&vf, 0)->channels;
2011-10-18 09:45:04 +08:00
}
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
if (ov_info(&vf,0)->channels == 2)
{
__sampleChannelType = AUDIO_CHANNEL_TYPE_STEREO;
}
else
{
__sampleChannelType = AUDIO_CHANNEL_TYPE_MONO;
}
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
__sampleRate = ov_info(&vf,0)->rate;
__sampleBitdepth = AUDIO_TYPE_PCM_S16_LE;
2011-11-13 00:57:54 +08:00
//AppLog("enter");
while((ret = ov_read(&vf, buf, buflen, 0, 16/8, 1, &bs)) != 0) {
2011-10-18 09:45:04 +08:00
if(bs != 0) {
2011-11-13 00:57:54 +08:00
//AppLog("Only one logical bitstream currently supported\n");
2011-10-18 09:45:04 +08:00
break;
}
if(ret < 0) {
2011-11-13 00:57:54 +08:00
//AppLog("Warning: hole in data\n");
2011-10-18 09:45:04 +08:00
continue;
}
if (__pAllPcmBuffer == null)
{
__pAllPcmBuffer = (char*)malloc(ret);
}
else
{
__pAllPcmBuffer = (char*)realloc(__pAllPcmBuffer, written+ret);
}
memcpy(__pAllPcmBuffer+written, buf, ret);
written += ret;
if(seekable) {
2011-10-18 09:45:04 +08:00
done += ret/size;
if((double)done/(double)length * 200. > (double)percent) {
percent = (double)done/(double)length *200;
2011-11-13 00:57:54 +08:00
// //AppLog("[%5.1f%%]", (double)percent/2.);
2011-10-18 09:45:04 +08:00
}
}
}
__iAllPcmBufferSize = written;
// if(seekable && !quiet)
2011-11-13 00:57:54 +08:00
// //AppLog("\n");
2011-10-18 09:45:04 +08:00
// if(!raw)
// rewrite_header(out, written); /* We don't care if it fails, too late */
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
ov_clear(&vf);
fclose(in);
// fclose(out);
2011-10-18 18:10:53 +08:00
#endif
2011-11-13 00:57:54 +08:00
//AppLog("enter");
2011-10-18 09:45:04 +08:00
return 0;
2011-10-14 18:33:14 +08:00
}
2011-10-18 09:45:04 +08:00
CCAudioOut::CCAudioOut()
2011-10-14 17:57:44 +08:00
{
2011-11-13 00:57:54 +08:00
//AppLog("Enter");
2011-10-18 18:10:53 +08:00
__volumeLevel = -1;
2011-10-18 09:45:04 +08:00
__pAllPcmBuffer = null;
__iAllPcmBufferSize = 0;
__iAllPcmPos = 0;
__pAudioOut = null;
2011-10-18 09:45:04 +08:00
__iFileType = 0;
__pFile = null;
2011-10-18 18:10:53 +08:00
__bShortPcmBuffer = false;
__bBufferConstruted = false;
__checkInitFiniPair = false;
__iUsedBufferCount = 0;
__bLoop = false;
__bPause = false;
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
CCAudioOut::~CCAudioOut()
2011-10-14 17:57:44 +08:00
{
2011-11-13 00:57:54 +08:00
//AppLog("Enter");
2011-10-18 09:45:04 +08:00
Finalize();
if(__pAudioOut)
2011-10-14 17:57:44 +08:00
{
delete __pAudioOut;
__pAudioOut = null;
}
2011-10-18 09:45:04 +08:00
if (__pAllPcmBuffer)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
free(__pAllPcmBuffer);
__pAllPcmBuffer = null;
2011-10-14 17:57:44 +08:00
}
}
2011-10-18 09:45:04 +08:00
result CCAudioOut::Initialize(const char* pszFilePath)
2011-10-14 17:57:44 +08:00
{
2011-11-13 00:57:54 +08:00
//AppLog("Enter");
2011-10-18 09:45:04 +08:00
// This is called when AudioOut form is moving on the foreground.
result r = E_SUCCESS;
2011-10-18 18:10:53 +08:00
2011-10-18 09:45:04 +08:00
__pAllPcmBuffer = null;
__iAllPcmBufferSize = 0;
__iAllPcmPos = 0;
2011-10-18 18:10:53 +08:00
__iUsedBufferCount = 0;
2011-10-18 09:45:04 +08:00
if(__checkInitFiniPair == false)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
// Reset the configure variables
__finishChecker =0;
__bufWrittenCnt = PRE_BUFFERING_NUM;
__buffReadCnt = 0;
__buffWriteCnt = 0;
result r = E_FAILURE;
if (__pAudioOut == NULL)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
__pAudioOut = new AudioOut();
if (!__pAudioOut)
{
2011-11-13 00:57:54 +08:00
//AppLog("[E_OUT_OF_MEMORY] m_pAudio new failed\n");
2011-10-18 09:45:04 +08:00
return r;
}
r = __pAudioOut->Construct(*this);
if (IsFailed(r))
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.Construct failed");
2011-10-18 09:45:04 +08:00
return r;
}
2011-10-14 17:57:44 +08:00
}
else
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] __pAudioOut is already existed\n");
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
String strFile(pszFilePath);
if (strFile.EndsWith(".wav"))
{
__iFileType = 0;
// Construct File for feeding buffers
__pFile = new File();
if(!__pFile)
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] __pFile new failed\n");
2011-10-18 09:45:04 +08:00
return E_SYSTEM;
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
r = __pFile->Construct(pszFilePath, L"rb");
if (IsFailed(r)) {
2011-11-13 00:57:54 +08:00
//AppLog("[Error] __pFile.Construct failed : %d \n", r);
2011-10-18 09:45:04 +08:00
return r;
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
WAVE wavHead;
GetWaveHeadInfo(__pFile, wavHead);
2011-10-18 18:10:53 +08:00
__iAllPcmBufferSize = wavHead.SubChunk2Size;
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
if (wavHead.BitsPerSample == 8)
{
__sampleBitdepth = AUDIO_TYPE_PCM_U8;
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
}
else if (wavHead.BitsPerSample == 16)
{
__sampleBitdepth = AUDIO_TYPE_PCM_S16_LE;
}
else
{
__sampleBitdepth = AUDIO_TYPE_NONE;
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
if (wavHead.NumChannels == 1)
{
__sampleChannelType = AUDIO_CHANNEL_TYPE_MONO;
}
else if (wavHead.NumChannels == 2)
{
__sampleChannelType = AUDIO_CHANNEL_TYPE_STEREO;
}
else
{
__sampleChannelType = AUDIO_CHANNEL_TYPE_NONE;
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
__sampleRate = wavHead.SampleRate;
2011-10-18 18:10:53 +08:00
__pAllPcmBuffer = (char*)malloc(__iAllPcmBufferSize);
if (__pAllPcmBuffer != NULL)
{
__pFile->Read(__pAllPcmBuffer, __iAllPcmBufferSize);
}
else
{
2011-11-13 00:57:54 +08:00
//AppLog("not more memory...");
2011-10-18 18:10:53 +08:00
}
2011-10-18 09:45:04 +08:00
}
else if (strFile.EndsWith(".ogg"))
{
__iFileType = 1;
long long curTick, oldTick;
Osp::System::SystemTime::GetTicks(oldTick);
DecodeOgg(pszFilePath);
Osp::System::SystemTime::GetTicks(curTick);
2011-11-13 00:57:54 +08:00
//AppLog("decode ogg to pcm waste %ld", (long)(curTick-oldTick));
2011-10-18 09:45:04 +08:00
}
// Prepare AudioOut
r = __pAudioOut->Prepare( __sampleBitdepth, __sampleChannelType, __sampleRate );
if (IsFailed(r))
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.Prepare failed");
2011-10-18 09:45:04 +08:00
return r;
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
__bufferSize = __pAudioOut->GetMinBufferSize();
2011-11-13 00:57:54 +08:00
//AppLog("[Info] __bufferSize=%d (MaxBuf=%d Min Size %d)\n", __bufferSize, __pAudioOut->GetMaxBufferSize(),__pAudioOut->GetMinBufferSize());
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
// Reset Volume or keeping a volume level
__volumeLevel = __volumeLevel == -1 ? DEFAULT_VOLUME_LEVEL : __volumeLevel;
r = __pAudioOut->SetVolume(DEFAULT_VOLUME_LEVEL);
if (IsFailed(r))
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.SetVolume failed");
2011-10-18 09:45:04 +08:00
return r;
}
2011-10-14 17:57:44 +08:00
2011-10-18 18:10:53 +08:00
if (!__bBufferConstruted)
2011-10-18 09:45:04 +08:00
{
2011-10-18 18:10:53 +08:00
__bBufferConstruted = true;
r = __byteBuffer[0].Construct(__bufferSize);
if (E_SUCCESS != r)
{
2011-11-13 00:57:54 +08:00
//AppLog( "[Error] __byteBuffer[0].Construct failed..%d ",r);
2011-10-18 18:10:53 +08:00
return E_OUT_OF_MEMORY;
}
r = __byteBuffer[1].Construct(__bufferSize);
if (E_SUCCESS != r)
{
2011-11-13 00:57:54 +08:00
//AppLog( "[Error] __byteBuffer[1].Construct failed..%d ",r);
2011-10-18 18:10:53 +08:00
return E_OUT_OF_MEMORY;
}
r = __byteBuffer[2].Construct(__bufferSize);
if (E_SUCCESS != r)
{
2011-11-13 00:57:54 +08:00
//AppLog( "[Error] __byteBuffer[2].Construct failed..%d ",r);
2011-10-18 18:10:53 +08:00
return E_OUT_OF_MEMORY;
}
r = __byteBuffer[3].Construct(__bufferSize);
if (E_SUCCESS != r)
{
2011-11-13 00:57:54 +08:00
//AppLog( "[Error] __byteBuffer[3].Construct failed..%d ",r);
2011-10-18 18:10:53 +08:00
return E_OUT_OF_MEMORY;
}
2011-10-18 09:45:04 +08:00
}
2011-10-14 17:57:44 +08:00
2011-10-18 18:10:53 +08:00
if (__iAllPcmBufferSize <= __bufferSize * 4)
2011-10-18 09:45:04 +08:00
{
2011-10-18 18:10:53 +08:00
__bShortPcmBuffer = true;
2011-10-18 09:45:04 +08:00
}
2011-10-18 18:10:53 +08:00
else
2011-10-18 09:45:04 +08:00
{
2011-10-18 18:10:53 +08:00
__bShortPcmBuffer = false;
2011-10-18 09:45:04 +08:00
}
2011-10-18 18:10:53 +08:00
ReWriteBuffer();
2011-10-18 09:45:04 +08:00
__checkInitFiniPair = true;
}else{
2011-11-13 00:57:54 +08:00
//AppLog("[WANRNING] The application state is not proper");
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
return r;
}
result CCAudioOut::FeedBuffer (void)
{
2011-10-18 18:10:53 +08:00
result ret = E_FAILURE;
// if (__iFileType == 0)
// {
// /*
// * Read buffer from file
// */
// if(__pFile)
// {
// readSize = __pFile->Read((char *)__byteBuffer[__buffWriteCnt].GetPointer (), __bufferSize);
// if(readSize != 0)
// {
// __buffWriteCnt ++;
// if (4 == __buffWriteCnt)
// {
// __buffWriteCnt = 0;
// }
// }else
// {
// __finishChecker = PRE_BUFFERING_NUM;
// __buffWriteCnt = 0;
// }
// }
// }
// else if (__iFileType == 1)
2011-10-18 09:45:04 +08:00
{// ogg
int iRemainSize = __iAllPcmBufferSize - __iAllPcmPos;
if (iRemainSize < __bufferSize)
{
memcpy((void*)__byteBuffer[__buffWriteCnt].GetPointer (), __pAllPcmBuffer+__iAllPcmPos, iRemainSize);
__iAllPcmPos += iRemainSize;
}
else
{
memcpy((void*)__byteBuffer[__buffWriteCnt].GetPointer (), __pAllPcmBuffer+__iAllPcmPos, __bufferSize);
__iAllPcmPos += __bufferSize;
}
2011-10-14 17:57:44 +08:00
2011-10-19 17:15:21 +08:00
__iUsedBufferCount++;
2011-10-18 09:45:04 +08:00
if (__iAllPcmPos < __iAllPcmBufferSize)
{
__buffWriteCnt ++;
if (4 == __buffWriteCnt)
{
__buffWriteCnt = 0;
}
}
else
{
__finishChecker = PRE_BUFFERING_NUM;
__buffWriteCnt = 0;
__iAllPcmPos = 0;
2011-10-18 18:10:53 +08:00
ret = E_SUCCESS;
2011-10-18 09:45:04 +08:00
}
}
2011-10-14 17:57:44 +08:00
2011-10-18 09:45:04 +08:00
return ret;
2011-10-14 17:57:44 +08:00
}
2011-10-18 18:10:53 +08:00
result CCAudioOut::ReWriteBuffer(void)
{
int i = 0;
result r = E_FAILURE;
__iAllPcmPos = 0;
__iUsedBufferCount = 0;
if (__bShortPcmBuffer)
{
for (i=0; i<4; i++)
{
r = FeedBuffer();
if (!IsFailed(r)) // Feeding buffers(4)
{
break;
}
}
for (i = 0; i < __iUsedBufferCount; i++)
{
r = __pAudioOut->WriteBuffer(__byteBuffer[i]);
if (IsFailed(r))
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.WriteBuffer failed : %d\n", r);
2011-10-18 18:10:53 +08:00
return r;
}
}
}
else
{
for (i=0; i<4; i++)
{
FeedBuffer(); // Feeding buffers(4)
}
for (i = 0; i < 2; i++)
{
r = __pAudioOut->WriteBuffer(__byteBuffer[i]);
if (IsFailed(r))
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.WriteBuffer failed : %d\n", r);
2011-10-18 18:10:53 +08:00
return r;
}
}
}
return r;
}
2011-10-18 09:45:04 +08:00
void CCAudioOut::ReFeedBuffer(void)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
result r = E_SUCCESS;
for (int i=0; i<4; i++)
{
FeedBuffer(); // Feeding buffers(4)
}
r = __pAudioOut->WriteBuffer(__byteBuffer[0]);
if (IsFailed(r))
2011-10-14 17:57:44 +08:00
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.WriteBuffer failed : %d\n", r);
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
r = __pAudioOut->WriteBuffer(__byteBuffer[1]);
if (IsFailed(r))
2011-10-14 17:57:44 +08:00
{
2011-11-13 00:57:54 +08:00
//AppLog("[Error] m_AudioOut.WriteBuffer failed : %d\n", r);
2011-10-14 17:57:44 +08:00
}
}
result CCAudioOut::Play(bool bLoop/* = false*/)
2011-10-14 17:57:44 +08:00
{
2011-10-18 18:10:53 +08:00
result ret = E_FAILURE;
2011-10-18 09:45:04 +08:00
AudioOutState state = __pAudioOut->GetState();
2011-10-18 18:10:53 +08:00
if(state == AUDIOOUT_STATE_PREPARED || state == AUDIOOUT_STATE_STOPPED)
2011-10-18 09:45:04 +08:00
{
__bLoop = bLoop;
2011-10-18 09:45:04 +08:00
ret = __pAudioOut->Start();
if (IsFailed(ret))
{
AppLog("[Error] m_AudioOut.Start failed : %d\n", ret);
2011-10-18 09:45:04 +08:00
}
}
2011-10-18 18:10:53 +08:00
return ret;
2011-10-14 17:57:44 +08:00
}
2011-10-18 18:10:53 +08:00
result CCAudioOut::Stop(void)
2011-10-14 17:57:44 +08:00
{
AudioOutState state = __pAudioOut->GetState();
result r = E_SUCCESS;
__bPause = false;
if(state == AUDIOOUT_STATE_PLAYING)
{
r = __pAudioOut->Reset();
if(IsFailed(r))
{
AppLog("[Error] AudioOut Reset is failed");
}
ReWriteBuffer();
}
return r;
}
result CCAudioOut::Pause(void)
{
2011-10-18 18:10:53 +08:00
result ret = E_FAILURE;
2011-10-18 09:45:04 +08:00
if( __pAudioOut->GetState() == AUDIOOUT_STATE_PLAYING )
{
__bPause = true;
2011-10-18 09:45:04 +08:00
ret = __pAudioOut->Stop();
if (IsFailed(ret))
{
AppLog("[Error] m_AudioOut.Stop failed : %d\n", ret);
2011-10-18 09:45:04 +08:00
}
}
2011-10-18 18:10:53 +08:00
return ret;
}
result CCAudioOut::Resume(void)
2011-10-18 18:10:53 +08:00
{
result ret = E_FAILURE;
2011-10-18 18:10:53 +08:00
if(__bPause && __pAudioOut->GetState() == AUDIOOUT_STATE_STOPPED )
2011-10-18 09:45:04 +08:00
{
__bPause = false;
ret = __pAudioOut->Start();
if (IsFailed(ret))
2011-10-18 18:10:53 +08:00
{
AppLog("[Error] m_AudioOut.Stop failed : %d\n", ret);
2011-10-18 18:10:53 +08:00
}
2011-10-18 09:45:04 +08:00
}
2011-10-18 18:10:53 +08:00
return ret;
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
void CCAudioOut::OnAudioOutBufferEndReached(Osp::Media::AudioOut& src)
2011-10-14 17:57:44 +08:00
{
2011-10-18 18:10:53 +08:00
if (__bShortPcmBuffer)
2011-10-18 09:45:04 +08:00
{
2011-10-29 14:47:13 +08:00
__iUsedBufferCount--;
if (__iUsedBufferCount <= 0)
{
Stop();
if (__bLoop)
{
Play(__bLoop);
}
2011-10-29 14:47:13 +08:00
}
2011-10-18 18:10:53 +08:00
}
else
2011-10-14 17:57:44 +08:00
{
int ret = 0;
2011-11-13 00:57:54 +08:00
// //AppLog("thread name is %S", Thread::GetCurrentThread()->GetName().GetPointer());
//AppLog("__buffReadCnt = %d", __buffReadCnt);
2011-10-18 18:10:53 +08:00
__byteBuffer[__buffReadCnt++].Clear ();
if (4 == __buffReadCnt)
__buffReadCnt = 0;
2011-10-18 09:45:04 +08:00
if(__finishChecker == 0)
{
2011-10-18 18:10:53 +08:00
ret = src.WriteBuffer(__byteBuffer[__bufWrittenCnt++]);
if (4 == __bufWrittenCnt)
__bufWrittenCnt = 0;
FeedBuffer();
}
else
{
2011-11-13 00:57:54 +08:00
//AppLog("__finishChecker = %d", __finishChecker);
2011-10-18 18:10:53 +08:00
__finishChecker--;
if(__finishChecker == 0)
{
Stop();
2011-10-18 18:10:53 +08:00
__bufWrittenCnt = PRE_BUFFERING_NUM;
__buffReadCnt = 0;
__buffWriteCnt = 0;
if (__bLoop)
{
Play(__bLoop);
}
2011-10-18 18:10:53 +08:00
}
2011-10-18 09:45:04 +08:00
}
2011-10-14 17:57:44 +08:00
}
2011-10-18 18:10:53 +08:00
2011-10-14 17:57:44 +08:00
}
2011-10-18 09:45:04 +08:00
void CCAudioOut::OnAudioOutInterrupted(Osp::Media::AudioOut& src)
{
Pause();
2011-10-18 09:45:04 +08:00
}
void CCAudioOut::OnAudioOutReleased(Osp::Media::AudioOut& src)
{
Resume();
2011-10-18 09:45:04 +08:00
}
void CCAudioOut::Finalize(void)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
if(__checkInitFiniPair)
2011-10-14 17:57:44 +08:00
{
2011-10-18 09:45:04 +08:00
// Set OnAudioOutBufferEndReached stop.
__finishChecker = PRE_BUFFERING_NUM;
if(__pAudioOut)
{
AudioOutState state = __pAudioOut->GetState();
result r = E_SUCCESS;
if(state == AUDIOOUT_STATE_PLAYING)
{
r = __pAudioOut->Reset();
if(IsFailed(r))
{
AppLog("[Error] AudioOut Reset is failed");
2011-10-18 09:45:04 +08:00
}
}
state = __pAudioOut->GetState();
if(state == AUDIOOUT_STATE_PREPARED || state == AUDIOOUT_STATE_STOPPED)
{
r = __pAudioOut->Unprepare();
if(IsFailed(r))
{
AppLog("[Error] AudioOut UnPrepare is failed");
2011-10-18 09:45:04 +08:00
}
}
}
if(__pFile)
{
delete __pFile;
__pFile = null;
}
__checkInitFiniPair = false;
}else{
AppLog("[WANRNING] This application state is not proper");
2011-10-14 17:57:44 +08:00
}
}
2011-10-18 18:10:53 +08:00
void CCAudioOut::SetVolume(int volume)
{
if (__pAudioOut)
__pAudioOut->SetVolume(volume);
2011-10-14 17:57:44 +08:00
}
2011-10-18 18:10:53 +08:00
int CCAudioOut::GetVolume(void) const
{
int ret = 0;
if (__pAudioOut)
ret = __pAudioOut->GetVolume();
return ret;
}
Osp::Media::AudioOutState CCAudioOut::GetState(void) const
{
AudioOutState state = AUDIOOUT_STATE_ERROR;
if (__pAudioOut)
state = __pAudioOut->GetState();
return state;
}
}