open source

This commit is contained in:
lvfulong
2020-11-11 16:17:13 +08:00
parent 4d989f3ecb
commit bc4ca748de
2441 changed files with 623057 additions and 2 deletions
@@ -0,0 +1,417 @@
/**
@file JCAudioWavPlayer.cpp
@brief
@author James
@version 1.0
@date 2014_4_22
*/
#include "JCAudioWavPlayer.h"
#include "../../util/JCCommonMethod.h"
#include "../../util/Log.h"
#include "JCWaveParser.h"
#include "JCOggParser.h"
#include "../JCFileResManager.h"
//------------------------------------------------------------------------------
namespace laya
{
int JCAudioWavPlayer::s_nGarbageCollectionTime = 30000; //30Ãë
//------------------------------------------------------------------------------
JCAudioWavPlayer::JCAudioWavPlayer(JCFileResManager* pFileResManager)
{
m_pFileResManager = pFileResManager;
m_pOpenALSource.reserve(128);
m_nCurrentIndex = 0;
m_bStop=false;
m_pDevice = alcOpenDevice(NULL);
m_pContext = alcCreateContext( m_pDevice, NULL );
alcMakeContextCurrent( m_pContext );
createOpenALSource();
}
void JCAudioWavPlayer::createOpenALSource()
{
int m_nALCount = m_pOpenALSource.size();
m_pOpenALSource.resize(m_nALCount + OPENAL_SOURCE_NUM);
ALuint pOpenALBuffer[OPENAL_SOURCE_NUM];
alGenBuffers(OPENAL_SOURCE_NUM, pOpenALBuffer);
ALuint pOpenALSouceID[OPENAL_SOURCE_NUM];
alGenSources(OPENAL_SOURCE_NUM, pOpenALSouceID);
for (int i = 0; i < OPENAL_SOURCE_NUM; i++)
{
m_pOpenALSource[m_nALCount + i] = new OpenALSourceInfo;
m_pOpenALSource[m_nALCount + i]->m_nOpenALSouceID = pOpenALSouceID[i];
m_pOpenALSource[m_nALCount + i]->m_nBufferID = 0;
for (int j = 0; j < 3; j++)
{
m_pOpenALSource[m_nALCount + i]->m_vSourcePos[j] = 0;
m_pOpenALSource[m_nALCount + i]->m_vSourceVel[j] = 0;
}
m_pOpenALSource[m_nALCount + i]->m_bPlaying = false;
m_pOpenALSource[m_nALCount + i]->m_pAudio = NULL;
}
LOGI("createOpenALSource current num=%d",m_pOpenALSource.size());
}
//------------------------------------------------------------------------------
JCAudioWavPlayer::~JCAudioWavPlayer()
{
Release();
}
//------------------------------------------------------------------------------
OpenALSourceInfo* JCAudioWavPlayer::getOpenALSource()
{
int m_nALCount = m_pOpenALSource.size();
bool bFind = false;
OpenALSourceInfo* pInfo = NULL;
for( int i = 0; i < m_nALCount; i++ )
{
int n = (m_nCurrentIndex + i) % m_nALCount;
pInfo= m_pOpenALSource[n];
if( pInfo->m_bPlaying == false )
{
m_nCurrentIndex = n + 1;
bFind = true;
break;
}
}
if (bFind==false)
{
int nLastCount = m_nALCount;
createOpenALSource();
pInfo = m_pOpenALSource[nLastCount];
m_nCurrentIndex = nLastCount;
}
return pInfo;
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::checkWavePlayEnd()
{
int m_nALCount = m_pOpenALSource.size();
ALint nState = 0;
for ( int i = 0; i < m_nALCount; i++)
{
if( m_pOpenALSource[i]->m_bPlaying == true )
{
alGetSourcei(m_pOpenALSource[i]->m_nOpenALSouceID, AL_SOURCE_STATE, &nState );
if ( nState == AL_STOPPED )
{
releaseOpenAL(m_pOpenALSource[i]);
m_pOpenALSource[i]->m_bPlaying = false;
if(m_pOpenALSource[i]->m_pAudio != NULL )
{
m_pOpenALSource[i]->m_pAudio->onPlayEnd();
m_pOpenALSource[i]->m_pAudio = NULL;
}
}
}
}
}
//------------------------------------------------------------------------------
OpenALSourceInfo* JCAudioWavPlayer::playAudio( JCAudioInterface* p_pAudio,const std::string& p_sSrc, bool bIsOgg)
{
JCWaveInfo* pInfo = NULL;
MapWaveInfoIter iter = m_vWaveInfos.find( p_sSrc );
if( iter != m_vWaveInfos.end() )
{
pInfo = iter->second;
}
else
{
JCFileRes* pRes = m_pFileResManager->getRes(p_sSrc.c_str());
JCBuffer kBuffer;
if (pRes && pRes->loadFromCache(kBuffer, false))
{
pInfo = AddWaveInfo(p_sSrc, (unsigned char*)kBuffer.m_pPtr, kBuffer.m_nLen, NULL, p_pAudio, bIsOgg);
}
else
{
LOGE("JCAudioWavPlayer::playAudio load res error");
}
}
if (pInfo != NULL)
{
pInfo->m_nTouchTime = tmGetCurms();
WAVE_FORMAT* pFormat = &(pInfo->m_kFmtBlock.wavFormat);
return playAudioFromBuffer(p_pAudio, (char*)(pInfo->m_pData), pInfo->m_nRealDataSize, pFormat->dwSamplesPerSec, pFormat->wBitsPerSample, pFormat->wChannels);
}
return NULL;
}
void JCAudioWavPlayer::delAudio(JCAudioInterface* p_pAudio)
{
int m_nALCount = m_pOpenALSource.size();
for ( int i = 0; i < m_nALCount; i++){
if( m_pOpenALSource[i]->m_pAudio==p_pAudio){
m_pOpenALSource[i]->m_pAudio = NULL;
}
}
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::releaseOpenAL( OpenALSourceInfo* pOpenALInfo )
{
#ifdef __APPLE__
// some specific OpenAL implement defects existed on iOS platform
// refer to: https://github.com/cocos2d/cocos2d-x/issues/18597
ALint sourceState;
ALint bufferProcessed = 0;
alGetSourcei(pOpenALInfo->m_nOpenALSouceID, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_PLAYING)
{
alGetSourcei(pOpenALInfo->m_nOpenALSouceID, AL_BUFFERS_PROCESSED, &bufferProcessed);
while (bufferProcessed < 1/*QUEUEBUFFER_NUM*/)
{
LOGI("JCAudioWavPlayer::releaseOpenAL wait buffer");
std::this_thread::sleep_for(std::chrono::milliseconds(2));
alGetSourcei(pOpenALInfo->m_nOpenALSouceID, AL_BUFFERS_PROCESSED, &bufferProcessed);
}
alSourceUnqueueBuffers(pOpenALInfo->m_nOpenALSouceID, /*QUEUEBUFFER_NUM*/1, &pOpenALInfo->m_nBufferID);
}
#else
alSourceUnqueueBuffers( pOpenALInfo->m_nOpenALSouceID, 1, &(pOpenALInfo->m_nBufferID) );
#endif
alSourcei(pOpenALInfo->m_nOpenALSouceID, AL_BUFFER, 0);
if (pOpenALInfo->m_nBufferID != 0 && alIsBuffer(pOpenALInfo->m_nBufferID))
{
alDeleteBuffers(1, &pOpenALInfo->m_nBufferID);
pOpenALInfo->m_nBufferID = 0;
}
}
//------------------------------------------------------------------------------
OpenALSourceInfo* JCAudioWavPlayer::playAudioFromBuffer( JCAudioInterface* p_pAudio,const char* p_pBuffer,unsigned int p_nBufferSize,
int p_nRate,int nBitsPerSample, int nChannels)
{
OpenALSourceInfo* pOpenALInfo = getOpenALSource();
alSourceStop( pOpenALInfo->m_nOpenALSouceID );
releaseOpenAL( pOpenALInfo );
alSourcef ( pOpenALInfo->m_nOpenALSouceID, AL_PITCH, 1.0 );
alSourcef ( pOpenALInfo->m_nOpenALSouceID, AL_GAIN, 1.0 );
alSourcei ( pOpenALInfo->m_nOpenALSouceID, AL_LOOPING, 0 );
//ÏÈÆÁ±Î
//alSourcefv( pOpenALInfo->m_nOpenALSouceID, AL_VELOCITY, pOpenALInfo->m_vSourceVel );
//alSourcefv( pOpenALInfo->m_nOpenALSouceID, AL_POSITION, pOpenALInfo->m_vSourcePos );
//bind buffer
ALuint nBufferID = 0;
alGenBuffers( 1,&nBufferID );
int nFormat = AL_FORMAT_MONO16;
switch (nChannels)
{
case 1:
switch (nBitsPerSample)
{
case 8:
nFormat = AL_FORMAT_MONO8;
break;
case 16:
nFormat = AL_FORMAT_MONO16;
break;
default:
LOGE("JCAudioWavPlayer::playAudioFromBuffer sound bitsPerSample error,only support 8 or 16");
nFormat = AL_FORMAT_MONO16;
break;
}
break;
case 2:
switch (nBitsPerSample)
{
case 8:
nFormat = AL_FORMAT_STEREO8;
break;
case 16:
nFormat = AL_FORMAT_STEREO16;
break;
default:
LOGE("JCAudioWavPlayer::playAudioFromBuffer sound bitsPerSample error,only support 8 or 16");
nFormat = AL_FORMAT_STEREO16;
break;
}
break;
default:
LOGE("JCAudioWavPlayer::playAudioFromBuffer sound channel error");
switch (nBitsPerSample)
{
case 8:
nFormat = AL_FORMAT_MONO8;
break;
case 16:
nFormat = AL_FORMAT_MONO16;
break;
default:
LOGE("JCAudioWavPlayer::playAudioFromBuffer sound bitsPerSample error,only support 8 or 16");
nFormat = AL_FORMAT_MONO16;
break;
}
break;
}
alBufferData(nBufferID, nFormat, p_pBuffer, p_nBufferSize, p_nRate);
alSourceQueueBuffers( pOpenALInfo->m_nOpenALSouceID, 1, &nBufferID );
pOpenALInfo->m_nBufferID = nBufferID;
//play
alSourcePlay( pOpenALInfo->m_nOpenALSouceID );
//±£ÁôÐÅÏ¢
pOpenALInfo->m_pAudio = p_pAudio;
pOpenALInfo->m_bPlaying = true;
return pOpenALInfo;
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::stopAll()
{
int m_nALCount = m_pOpenALSource.size();
for (int i = 0; i < m_nALCount; i++)
{
if( m_pOpenALSource[i]->m_bPlaying == true )
{
alSourceStop(m_pOpenALSource[i]->m_nOpenALSouceID );
releaseOpenAL(m_pOpenALSource[i]);
m_pOpenALSource[i]->m_bPlaying = false;
}
}
}
void JCAudioWavPlayer::pause()
{
int m_nALCount = m_pOpenALSource.size();
for (int i = 0; i < m_nALCount; i++)
{
alSourcePause(m_pOpenALSource[i]->m_nOpenALSouceID);
}
}
void JCAudioWavPlayer::resume()
{
int m_nALCount = m_pOpenALSource.size();
for (int i = 0; i < m_nALCount; i++)
{
alSourcePlay(m_pOpenALSource[i]->m_nOpenALSouceID);
}
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::setAllVolume( float p_nVolume )
{
int m_nALCount = m_pOpenALSource.size();
for ( int i = 0; i < m_nALCount; i++ )
{
alSourcef ( m_pOpenALSource[i]->m_nOpenALSouceID, AL_GAIN, p_nVolume);
}
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::stop(OpenALSourceInfo* pOpenALInfo)
{
if (pOpenALInfo->m_bPlaying == true)
{
alSourceStop(pOpenALInfo->m_nOpenALSouceID);
releaseOpenAL(pOpenALInfo);
pOpenALInfo->m_bPlaying = false;
pOpenALInfo->m_pAudio = NULL;
}
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::setVolume(OpenALSourceInfo* pOpenALInfo,float p_nVolume)
{
alSourcef(pOpenALInfo->m_nOpenALSouceID, AL_GAIN, p_nVolume);
}
//------------------------------------------------------------------------------
void JCAudioWavPlayer::Release()
{
for (int i = 0; i < m_pOpenALSource.size(); i++)
{
if (m_pOpenALSource[i]->m_nBufferID != 0 && alIsBuffer(m_pOpenALSource[i]->m_nBufferID))
{
alDeleteBuffers(1, &m_pOpenALSource[i]->m_nBufferID);
m_pOpenALSource[i]->m_nBufferID = 0;
}
if (m_pOpenALSource[i]->m_nOpenALSouceID != 0 && alIsSource(m_pOpenALSource[i]->m_nOpenALSouceID))
{
alDeleteSources(1, &m_pOpenALSource[i]->m_nOpenALSouceID);
m_pOpenALSource[i]->m_nOpenALSouceID = 0;
}
delete m_pOpenALSource[i];
}
if (m_pContext != NULL)
{
alcDestroyContext( m_pContext );
m_pContext=NULL;
}
if ( m_pDevice !=NULL )
{
alcCloseDevice(m_pDevice);
m_pDevice=NULL;
}
m_bStop=true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
JCWaveInfo* JCAudioWavPlayer::AddWaveInfo( const std::string& p_sUrl,unsigned char* p_pBuffer,int p_nSize,const char* p_sFilePath,void* p_pExternalMark,bool p_bIsOgg )
{
JCWaveInfo* pInfo = FindWaveInfo( p_sUrl );
if( pInfo == NULL )
{
if( p_bIsOgg == false )
{
pInfo = JCWaveParser::GetInstance()->GetWaveInfoFromBuffer( p_pBuffer,p_nSize );
}
else
{
pInfo = JCOggParser::GetInstance()->GetWaveInfo( p_sFilePath,p_pBuffer,p_nSize );
}
if( pInfo != NULL )
{
pInfo->m_sUrl = p_sUrl;
pInfo->m_nTouchTime = tmGetCurms();
pInfo->m_pExternalMark = p_pExternalMark;
m_vWaveInfos[ p_sUrl ] = pInfo;
}
else
{
LOGE( "JCAudioWavPlayer::AddWaveInfo wave paser err" );
}
}
return pInfo;
}
void JCAudioWavPlayer::autoGarbageCollection()
{
if (m_vWaveInfos.size() <= 0)return;
double nCurrentTime = tmGetCurms();
for (MapWaveInfoIter iter = m_vWaveInfos.begin(); iter != m_vWaveInfos.end();)
{
JCWaveInfo* pInfo = iter->second;
if (pInfo && (nCurrentTime - pInfo->m_nTouchTime > s_nGarbageCollectionTime ) )
{
delete pInfo;
pInfo = NULL;
iter = m_vWaveInfos.erase(iter);
}
else
{
iter++;
}
}
}
//------------------------------------------------------------------------------
JCWaveInfo* JCAudioWavPlayer::FindWaveInfo( const std::string& p_sUrl )
{
MapWaveInfoIter iter = m_vWaveInfos.find( p_sUrl );
if( iter != m_vWaveInfos.end() )
{
return iter->second;
}
return NULL;
}
//------------------------------------------------------------------------------
bool JCAudioWavPlayer::ClearAllWaveInfo( void )
{
for( MapWaveInfoIter iter = m_vWaveInfos.begin(); iter != m_vWaveInfos.end(); iter++ )
{
JCWaveInfo* pInfo = NULL;
pInfo = iter->second;
if( pInfo != NULL )
{
delete pInfo;
pInfo = NULL;
}
}
m_vWaveInfos.clear();
return true;
}
//------------------------------------------------------------------------------
}
//-----------------------------END FILE--------------------------------