open source
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
@file JCAudioInterface.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
#ifndef __JCAudioInterface_H__
|
||||
#define __JCAudioInterface_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief JCAudioInterface
|
||||
* 纯接口类
|
||||
*/
|
||||
namespace laya
|
||||
{
|
||||
class JCAudioInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void onPlayEnd() = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCAudioInterface_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
@file JCAudioWavPlayer.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_4_22
|
||||
*/
|
||||
|
||||
#ifndef __JCAudioWavPlayer_H__
|
||||
#define __JCAudioWavPlayer_H__
|
||||
|
||||
//包含头文件
|
||||
#ifdef WIN32
|
||||
#include <xaudio2.h>
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#elif __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAl/alc.h>
|
||||
#elif ANDROID
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <thread>
|
||||
#include "../../util/JCCommonMethod.h"
|
||||
#include "JCWaveInfo.h"
|
||||
#include "JCAudioInterface.h"
|
||||
#include<unordered_map>
|
||||
#include <vector>
|
||||
namespace laya
|
||||
{
|
||||
class JCFileResManager;
|
||||
#define OPENAL_SOURCE_NUM 10
|
||||
|
||||
struct OpenALSourceInfo
|
||||
{
|
||||
ALuint m_nOpenALSouceID; //OpenAl的ID
|
||||
ALuint m_nBufferID; //bufferID
|
||||
ALfloat m_vSourcePos[3]; //源声音的位置
|
||||
ALfloat m_vSourceVel[3]; //源声音的速度
|
||||
bool m_bPlaying; //是否为播放状态
|
||||
JCAudioInterface* m_pAudio; //Audio 为了回调使用
|
||||
void operator=(const OpenALSourceInfo& other)
|
||||
{
|
||||
m_nOpenALSouceID = other.m_nOpenALSouceID;
|
||||
m_nBufferID = other.m_nBufferID;
|
||||
m_bPlaying = other.m_bPlaying;
|
||||
m_pAudio = other.m_pAudio;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_vSourcePos[i] = other.m_vSourcePos[i];
|
||||
m_vSourceVel[i] = other.m_vSourceVel[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class JCAudioWavPlayer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::unordered_map<std::string,JCWaveInfo*> MapWaveInfo;
|
||||
typedef MapWaveInfo::iterator MapWaveInfoIter;
|
||||
|
||||
public:
|
||||
|
||||
JCAudioWavPlayer(JCFileResManager* pFileResManager);
|
||||
|
||||
~JCAudioWavPlayer();
|
||||
|
||||
void Release();
|
||||
|
||||
public:
|
||||
|
||||
OpenALSourceInfo* playAudio( JCAudioInterface* p_pAudio,const std::string& p_sSrc,bool bIsOgg );
|
||||
|
||||
void delAudio(JCAudioInterface* p_pAudio);
|
||||
|
||||
OpenALSourceInfo* playAudioFromBuffer( JCAudioInterface* p_pAudio,const char* p_pBuffer,unsigned int p_nBufferSize,int p_nRate, int p_nBitsPerSample, int nChannels);
|
||||
|
||||
void setVolume(OpenALSourceInfo* pOpenALInfo,float p_nVolume );
|
||||
|
||||
void stop(OpenALSourceInfo* pOpenALInfo);
|
||||
|
||||
void setAllVolume(float p_nVolume);
|
||||
|
||||
void stopAll();
|
||||
|
||||
void checkWavePlayEnd();
|
||||
|
||||
void pause();
|
||||
|
||||
void resume();
|
||||
|
||||
public:
|
||||
|
||||
/** @brief 添加资源
|
||||
* @return
|
||||
*/
|
||||
JCWaveInfo* AddWaveInfo( const std::string& p_sUrl,unsigned char* p_pBuffer,int p_nSize,const char* p_sFilePath,void* p_pExternalMark,bool p_bIsOgg );
|
||||
|
||||
/** @brief 查找资源根据 ulid
|
||||
* @param[in] ulID
|
||||
* @return
|
||||
*/
|
||||
JCWaveInfo* FindWaveInfo( const std::string& p_sUrl );
|
||||
|
||||
/** @brief 清空所有
|
||||
*/
|
||||
bool ClearAllWaveInfo( void );
|
||||
|
||||
void autoGarbageCollection();
|
||||
|
||||
private:
|
||||
|
||||
void releaseOpenAL( OpenALSourceInfo* pOpenALInfo );
|
||||
|
||||
void createOpenALSource();
|
||||
|
||||
OpenALSourceInfo* getOpenALSource();
|
||||
|
||||
public:
|
||||
|
||||
static int s_nGarbageCollectionTime;
|
||||
|
||||
MapWaveInfo m_vWaveInfos; //wave的信息
|
||||
|
||||
public:
|
||||
|
||||
JCFileResManager* m_pFileResManager;
|
||||
ALCdevice* m_pDevice; // 打开默认音频设备
|
||||
ALCcontext* m_pContext; // context
|
||||
std::vector<OpenALSourceInfo*> m_pOpenALSource; // 播放声音用的
|
||||
int m_nCurrentIndex; // 记录上次的位置
|
||||
bool m_bStop;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__JCAudioWavPlayer_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -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--------------------------------
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
@file JCMp3Interface.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
#ifndef __JCMp3Interface_H__
|
||||
#define __JCMp3Interface_H__
|
||||
#include "JCAudioInterface.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief JCMp3Interface
|
||||
* 纯接口类
|
||||
*/
|
||||
namespace laya
|
||||
{
|
||||
class JCMp3Interface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio )=0;
|
||||
|
||||
virtual void delAudio( JCAudioInterface* p_pJSAudio )=0;
|
||||
|
||||
virtual void pause()=0;
|
||||
|
||||
virtual void stop()=0;
|
||||
|
||||
virtual void resume()=0;
|
||||
|
||||
virtual void setVolume( float p_nVolume )=0;
|
||||
|
||||
virtual void setMute(bool p_bMute)=0;
|
||||
|
||||
virtual void onPlayEnd()=0;
|
||||
|
||||
virtual void setCurrentTime(double nCurrentTime) = 0;
|
||||
|
||||
virtual double getCurrentTime() = 0;
|
||||
|
||||
virtual double getDuration() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCMp3Interface_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
@file JCOggParser.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
//包含头文件
|
||||
#include "JCOggParser.h"
|
||||
#include "../../util/Log.h"
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <vector>
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
#define READ_OGG_BUFFER_TEMP_SIZE 44100 //读取ogg的时候,临时缓冲区大小
|
||||
//------------------------------------------------------------------------------
|
||||
JCOggParser* JCOggParser::ms_pOggParser = NULL;
|
||||
//------------------------------------------------------------------------------
|
||||
JCOggParser::JCOggParser()
|
||||
{
|
||||
m_nBufferSize = READ_OGG_BUFFER_TEMP_SIZE;
|
||||
m_nCurBufferPos = 0;
|
||||
m_pBuffer = new char[m_nBufferSize];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCOggParser::~JCOggParser()
|
||||
{
|
||||
if( m_pBuffer != NULL )
|
||||
{
|
||||
delete[] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCOggParser* JCOggParser::GetInstance( void )
|
||||
{
|
||||
if( ms_pOggParser == NULL )
|
||||
{
|
||||
ms_pOggParser = new JCOggParser();
|
||||
}
|
||||
return ms_pOggParser;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void JCOggParser::DelInstance( void )
|
||||
{
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool JCOggParser::copyBuffer( char* p_pBuffer,int p_nSize )
|
||||
{
|
||||
if( p_pBuffer == NULL || p_nSize <=0 ) return false;
|
||||
if( m_nCurBufferPos + p_nSize > m_nBufferSize )
|
||||
{
|
||||
int nElargeSize = (p_nSize<=READ_OGG_BUFFER_TEMP_SIZE) ? READ_OGG_BUFFER_TEMP_SIZE : p_nSize;
|
||||
char* pNewBuffer = new char[m_nBufferSize + nElargeSize];
|
||||
memcpy( pNewBuffer,m_pBuffer,m_nBufferSize );
|
||||
m_nBufferSize += nElargeSize;
|
||||
delete m_pBuffer;
|
||||
m_pBuffer = pNewBuffer;
|
||||
}
|
||||
memcpy( m_pBuffer+m_nCurBufferPos,p_pBuffer,p_nSize );
|
||||
m_nCurBufferPos += p_nSize;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveInfo* JCOggParser::GetWaveInfo( const char* p_sFileName,unsigned char* p_sBuffer, int p_nBufferSize )
|
||||
{
|
||||
m_nCurBufferPos = 0;
|
||||
OggVorbis_File pOggStream;
|
||||
vorbis_info* pVorbisInfo = NULL;
|
||||
int nResult = -1;
|
||||
if( p_sBuffer != NULL && p_nBufferSize > 0 )
|
||||
{
|
||||
nResult = ov_open_callbacks( NULL, &pOggStream, (const char*)p_sBuffer, p_nBufferSize, OV_CALLBACKS_DEFAULT );
|
||||
}
|
||||
else if( p_sFileName != NULL )
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
fp = fopen( p_sFileName, "rb" );
|
||||
if( fp )
|
||||
{
|
||||
nResult = ov_open_callbacks( (void*)fp, &pOggStream, NULL, 0, OV_CALLBACKS_DEFAULT );
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
if( nResult >= 0 )
|
||||
{
|
||||
pVorbisInfo = ov_info( &pOggStream, -1 );
|
||||
char pBufferData[ READ_OGG_BUFFER_TEMP_SIZE ];//解码时候的缓冲区
|
||||
int nSize = 0;
|
||||
int nPortion = 0;
|
||||
int nResult1 = 0;
|
||||
while( true )
|
||||
{
|
||||
nResult1 = ov_read( &pOggStream, pBufferData, sizeof(pBufferData), 0, 2, 1, &nPortion );
|
||||
if( nResult1 > 0 )
|
||||
{
|
||||
nSize += nResult1;
|
||||
copyBuffer( pBufferData,nResult1 );
|
||||
}
|
||||
else if( nResult1 == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JCOggParser::GetWaveInfo error 1");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( nSize == 0)
|
||||
{
|
||||
LOGE("JCOggParser::GetWaveInfo error 2");
|
||||
return NULL;
|
||||
}
|
||||
JCWaveInfo* pWaveInfo = new JCWaveInfo();
|
||||
pWaveInfo->m_nRealDataSize = nSize;
|
||||
pWaveInfo->m_pData = new unsigned char[nSize];
|
||||
if( nSize == m_nCurBufferPos )
|
||||
{
|
||||
memcpy( pWaveInfo->m_pData,m_pBuffer,nSize*sizeof(char));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JCOggParser::GetWaveInfo error 3");
|
||||
return NULL;
|
||||
}
|
||||
pWaveInfo->m_kFmtBlock.wavFormat.dwSamplesPerSec = pVorbisInfo->rate;
|
||||
pWaveInfo->m_kFmtBlock.wavFormat.wChannels = pVorbisInfo->channels;
|
||||
//TODO 没有找到ogg的这个参数,似乎目前只支持16bit
|
||||
pWaveInfo->m_kFmtBlock.wavFormat.wBitsPerSample = 16;
|
||||
ov_clear(&pOggStream);
|
||||
return pWaveInfo;
|
||||
}
|
||||
LOGE("JCOggParser::GetWaveInfo error 0");
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
@file JCOggParser.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
#ifndef __JCOggParser_H__
|
||||
#define __JCOggParser_H__
|
||||
|
||||
#include "JCWaveInfo.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief 读取wav文件 目前只支持
|
||||
* 单声道
|
||||
* 16位
|
||||
* 采样级别 8000
|
||||
* 音频格式 PCM
|
||||
*/
|
||||
namespace laya
|
||||
{
|
||||
class JCOggParser
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCOggParser( void );
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCOggParser( void );
|
||||
|
||||
/*
|
||||
* getInstace()
|
||||
*/
|
||||
static JCOggParser* GetInstance( void );
|
||||
|
||||
|
||||
static void DelInstance( void );
|
||||
|
||||
/*
|
||||
* 从文件中读取wave数据
|
||||
*/
|
||||
JCWaveInfo* GetWaveInfo( const char* p_sFileName,unsigned char* p_sBuffer, int p_nBufferSize );
|
||||
|
||||
//拷贝buffer
|
||||
bool copyBuffer( char* p_sBuffer,int p_nSize );
|
||||
|
||||
protected:
|
||||
|
||||
static JCOggParser* ms_pOggParser; //静态的this指针
|
||||
|
||||
char* m_pBuffer; //临时的buffer
|
||||
|
||||
int m_nBufferSize; //buffer大小
|
||||
|
||||
int m_nCurBufferPos; //当前buffer的位置
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCOggParser_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
@file JCWaveInfo.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2012_11_17
|
||||
*/
|
||||
|
||||
#include "JCWaveInfo.h"
|
||||
#include "../../util/Log.h"
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveInfo::JCWaveInfo( void )
|
||||
{
|
||||
m_nTouchTime = 0;
|
||||
m_pExternalMark = NULL;
|
||||
m_pData = NULL;
|
||||
m_nCurPos = 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveInfo::~JCWaveInfo( void )
|
||||
{
|
||||
//赋值为NULL,就可以了,不需要删除
|
||||
if( m_pExternalMark != NULL )
|
||||
{
|
||||
m_pExternalMark = NULL;
|
||||
}
|
||||
if( m_pData != NULL )
|
||||
{
|
||||
delete[] m_pData;
|
||||
m_pData = NULL;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCWaveInfo::LoadData( const char* p_sFileName )
|
||||
{
|
||||
FILE *fp = fopen( p_sFileName,"rb" );
|
||||
if( fp == NULL )
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData Can't open file %s",p_sFileName );
|
||||
return false;
|
||||
}
|
||||
fseek( fp,0,SEEK_END );
|
||||
int nSize=ftell(fp);
|
||||
fseek(fp,0L,SEEK_SET);
|
||||
unsigned char* sBuffer = new unsigned char[nSize];
|
||||
fread( sBuffer,1,nSize,fp );
|
||||
fclose(fp);
|
||||
m_nCurPos = 0;
|
||||
LoadData( sBuffer,nSize );
|
||||
if (sBuffer)
|
||||
{
|
||||
delete[] sBuffer;
|
||||
sBuffer = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCWaveInfo::LoadData( unsigned char* p_sBuffer,int p_nBufferSize )
|
||||
{
|
||||
if( p_sBuffer == NULL )
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData buffer == null" );
|
||||
return false;
|
||||
}
|
||||
|
||||
//读取 RIFF 头
|
||||
{
|
||||
read( &m_kRiff, sizeof(RIFF_HEADER), p_sBuffer );
|
||||
if( memcmp( m_kRiff.szRiffID, "RIFF", 4 ) != 0 || memcmp( m_kRiff.szRiffFormat, "WAVE", 4 ) != 0 )
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData No a vaild wave file!\n");
|
||||
return false;
|
||||
}
|
||||
m_nCurPos += sizeof(RIFF_HEADER);
|
||||
}
|
||||
|
||||
//读取格式
|
||||
{
|
||||
read( &m_kFmtBlock.szFmtID, 4, p_sBuffer );
|
||||
m_nCurPos += 4;
|
||||
read( &m_kFmtBlock.dwFmtSize, 4, p_sBuffer );
|
||||
m_nCurPos += 4;
|
||||
|
||||
if( memcmp(m_kFmtBlock.szFmtID, "fmt ", 4) !=0 )
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData we only support follow format" );
|
||||
return false;
|
||||
}
|
||||
if( m_kFmtBlock.dwFmtSize != 18 && m_kFmtBlock.dwFmtSize != 16 )
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData we only support Format: linear PCM size = %d",m_kFmtBlock.dwFmtSize );
|
||||
return false;
|
||||
}
|
||||
if( m_kFmtBlock.dwFmtSize == 16 )
|
||||
{
|
||||
read(&m_kFmtBlock.wavFormat, 16, p_sBuffer );
|
||||
m_nCurPos += 16;
|
||||
}
|
||||
else if( m_kFmtBlock.dwFmtSize == 18 )
|
||||
{
|
||||
read(&m_kFmtBlock.wavFormat, 18, p_sBuffer );
|
||||
m_nCurPos += 18;
|
||||
}
|
||||
/*
|
||||
if( m_kFmtBlock.wavFormat.dwSamplesPerSec != 22050 )
|
||||
{
|
||||
LOGE("we only support Samples Rate: 22050 KHz" );
|
||||
return false;
|
||||
}
|
||||
if( m_kFmtBlock.wavFormat.wChannels != 0x1 )
|
||||
{
|
||||
LOGE("we only support one channel" );
|
||||
return false;
|
||||
}
|
||||
if( m_kFmtBlock.wavFormat.wBitsPerSample != 16 )
|
||||
{
|
||||
LOGE("we only support BitsPerSample: 16" );
|
||||
return false;
|
||||
}
|
||||
if( m_kFmtBlock.wavFormat.wFormatTag != 0x1 )
|
||||
{
|
||||
LOGE("we only support wFormatTag != 0x1" );
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
//读取无用信息 改到下面循环查找了
|
||||
{
|
||||
//试图读取fact
|
||||
read(&m_kFact, sizeof(FACT_BLOCK), p_sBuffer);
|
||||
if (memcmp(m_kFact.szFactID, "fact", 4) == 0)
|
||||
{
|
||||
m_nCurPos += sizeof(FACT_BLOCK);
|
||||
read(&m_vFackBlockBuffer, m_kFact.dwFactSize, p_sBuffer);
|
||||
m_nCurPos += m_kFact.dwFactSize;
|
||||
}
|
||||
//试图读取JUNK
|
||||
read(&m_kJunkBlock, sizeof(_JUNK_BLOCK), p_sBuffer);
|
||||
if (memcmp(m_kJunkBlock.szJUNK, "JUNK", 4) == 0)
|
||||
{
|
||||
m_nCurPos += sizeof(_JUNK_BLOCK) + m_kJunkBlock.dwJunkSize;
|
||||
}
|
||||
//试图读取FLLR
|
||||
read(&m_kJunkBlock, sizeof(_JUNK_BLOCK), p_sBuffer);
|
||||
if (memcmp(m_kJunkBlock.szJUNK, "FLLR", 4) == 0)
|
||||
{
|
||||
m_nCurPos += sizeof(_JUNK_BLOCK) + m_kJunkBlock.dwJunkSize;
|
||||
}
|
||||
}
|
||||
*/
|
||||
bool bResult = false;
|
||||
int nSize = p_nBufferSize - sizeof(DATA_BLOCK);
|
||||
while( m_nCurPos < nSize )
|
||||
{
|
||||
read( &m_kDataBlock, sizeof(DATA_BLOCK), p_sBuffer );
|
||||
if ( memcmp( m_kDataBlock.szDataID, "data", 4 ) == 0 )
|
||||
{
|
||||
m_kDataBlock.dwDataSize /= 2;
|
||||
m_nCurPos += sizeof(DATA_BLOCK);
|
||||
bResult = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nCurPos += sizeof(DATA_BLOCK) + m_kDataBlock.dwDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (bResult == false)
|
||||
{
|
||||
LOGE("JCWaveInfo::LoadData parse wav error");
|
||||
return false;
|
||||
}
|
||||
//拿出data数据
|
||||
m_nRealDataSize = m_kDataBlock.dwDataSize * 2;
|
||||
m_pData = new U8[m_nRealDataSize];
|
||||
for( unsigned int i =0; i< m_kDataBlock.dwDataSize; i++ )
|
||||
{
|
||||
U8 n1 = (U8) getC( p_sBuffer );
|
||||
m_nCurPos ++;
|
||||
U8 n2 = (U8) getC( p_sBuffer );
|
||||
m_nCurPos ++;
|
||||
|
||||
m_pData[i*2+0] = n1;
|
||||
m_pData[i*2+1] = n2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCWaveInfo::read( void* pRet, int p_nSize,unsigned char* p_sBuffer )
|
||||
{
|
||||
unsigned char* p = p_sBuffer + m_nCurPos;
|
||||
memcpy( pRet,(void*)(p),p_nSize );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned char JCWaveInfo::getC( unsigned char* p_sBuffer )
|
||||
{
|
||||
return p_sBuffer[m_nCurPos];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
@file JCWaveInfo.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
#ifndef __JCWaveInfo_H__
|
||||
#define __JCWaveInfo_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
|
||||
typedef unsigned char U8;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned int U32;
|
||||
typedef unsigned long U64;
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct _RIFF_HEADER
|
||||
{
|
||||
U8 szRiffID[4]; // 'R','I','F','F'
|
||||
U32 dwRiffSize;
|
||||
U8 szRiffFormat[4]; // 'W','A','V','E'
|
||||
}RIFF_HEADER;
|
||||
|
||||
typedef struct _WAVE_FORMAT
|
||||
{
|
||||
U16 wFormatTag;
|
||||
U16 wChannels;
|
||||
U32 dwSamplesPerSec;
|
||||
U32 dwAvgBytesPerSec;
|
||||
U16 wBlockAlign;
|
||||
U16 wBitsPerSample;
|
||||
U16 pack; //附加信息
|
||||
}WAVE_FORMAT;
|
||||
|
||||
typedef struct _FMT_BLOCK
|
||||
{
|
||||
U8 szFmtID[4]; // 'f','m','t',' '
|
||||
U32 dwFmtSize;
|
||||
WAVE_FORMAT wavFormat;
|
||||
}FMT_BLOCK;
|
||||
|
||||
typedef struct _FACT_BLOCK
|
||||
{
|
||||
U8 szFactID[4]; // 'f','a','c','t'
|
||||
U32 dwFactSize;
|
||||
}FACT_BLOCK;
|
||||
|
||||
typedef struct _JUNK_BLOCK
|
||||
{
|
||||
U8 szJUNK[4];
|
||||
U32 dwJunkSize;
|
||||
}JUNK_BLOCK;
|
||||
|
||||
typedef struct _DATA_BLOCK
|
||||
{
|
||||
U8 szDataID[4]; // 'd','a','t','a'
|
||||
U32 dwDataSize;
|
||||
}DATA_BLOCK;
|
||||
|
||||
#pragma pack(pop)
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class JCWaveInfo
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCWaveInfo( void );
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCWaveInfo( void );
|
||||
|
||||
|
||||
/** @brief 加载数据
|
||||
* @param[in] 文件名
|
||||
* @return true 代表读取成功 false代表失败
|
||||
*/
|
||||
bool LoadData( const char* p_sFileName );
|
||||
|
||||
|
||||
/** @brief 加载数据
|
||||
* @param[in] buffer数据
|
||||
* @param[in] 长度
|
||||
* @return true 代表读取成功 false代表失败
|
||||
*/
|
||||
bool LoadData( unsigned char* p_sBuffer,int p_nBufferSize );
|
||||
|
||||
private:
|
||||
|
||||
unsigned char getC( unsigned char* p_sBuffer );
|
||||
void read( void* pRet, int p_nSize, unsigned char* p_sBuffer );
|
||||
|
||||
public:
|
||||
|
||||
char m_vFackBlockBuffer[20]; //FackBlockBuffer
|
||||
|
||||
RIFF_HEADER m_kRiff; //数据头
|
||||
|
||||
FMT_BLOCK m_kFmtBlock; //fmt
|
||||
|
||||
DATA_BLOCK m_kDataBlock; //数据
|
||||
|
||||
U32 m_nRealDataSize; //数据长度
|
||||
|
||||
U8* m_pData; //数据
|
||||
|
||||
int m_nCurPos; //当前位置
|
||||
|
||||
void* m_pExternalMark; //外部标记,现在目的是为了存储JSAudio的指针,为了能够回调JS,或者想存储你想存储的数据
|
||||
|
||||
std::string m_sUrl; //url
|
||||
|
||||
double m_nTouchTime; //时间戳
|
||||
|
||||
//FACT_BLOCK m_kFact; //fact
|
||||
|
||||
//JUNK_BLOCK m_kJunkBlock; //JunkBlock
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCWaveInfo_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
@file JCWaveParser.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
|
||||
#include "JCWaveParser.h"
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveParser* JCWaveParser::m_sWaveParser = NULL;
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveParser::JCWaveParser()
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveParser::~JCWaveParser()
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveParser* JCWaveParser::GetInstance( void )
|
||||
{
|
||||
if( m_sWaveParser == NULL )
|
||||
{
|
||||
m_sWaveParser = new JCWaveParser();
|
||||
}
|
||||
return m_sWaveParser;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void JCWaveParser::DelInstance( void )
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveInfo* JCWaveParser::GetWaveInfoFromFile( const char* p_sFileName )
|
||||
{
|
||||
JCWaveInfo* pWaveInfo = new JCWaveInfo();
|
||||
bool bRet = pWaveInfo->LoadData( p_sFileName );
|
||||
if( bRet )
|
||||
{
|
||||
return pWaveInfo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCWaveInfo* JCWaveParser::GetWaveInfoFromBuffer( unsigned char* p_sBuffer, int p_nBufferSize )
|
||||
{
|
||||
JCWaveInfo* pWaveInfo = new JCWaveInfo();
|
||||
bool bRet = pWaveInfo->LoadData( p_sBuffer,p_nBufferSize );
|
||||
if( bRet )
|
||||
{
|
||||
return pWaveInfo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCWaveParser::TestWave( const char* p_sFileName,const char* p_sOutFileName )
|
||||
{
|
||||
JCWaveInfo* pInfo = GetWaveInfoFromFile( p_sFileName );
|
||||
if( pInfo )
|
||||
{
|
||||
FILE* fp = fopen( p_sOutFileName,"a+" );
|
||||
char sBuf[128];
|
||||
fputs( "{", fp );
|
||||
|
||||
for( unsigned int i = 0 ; i < pInfo->m_nRealDataSize; i++ )
|
||||
{
|
||||
memset( sBuf,0,128 );
|
||||
if( i == pInfo->m_nRealDataSize -1 )
|
||||
{
|
||||
sprintf( sBuf,"%d", pInfo->m_pData[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( sBuf,"%d,", pInfo->m_pData[i] );
|
||||
}
|
||||
fputs( sBuf,fp );
|
||||
}
|
||||
fputs( "};", fp );
|
||||
fclose( fp );
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
@file JCWaveParser.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_11_26
|
||||
*/
|
||||
#ifndef __JCWaveParser_H__
|
||||
#define __JCWaveParser_H__
|
||||
|
||||
#include "JCWaveInfo.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief 读取wav文件 目前只支持
|
||||
* 单声道
|
||||
* 16位
|
||||
* 采样级别 8000
|
||||
* 音频格式 PCM
|
||||
*/
|
||||
namespace laya
|
||||
{
|
||||
class JCWaveParser
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCWaveParser( void );
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCWaveParser( void );
|
||||
|
||||
/*
|
||||
* getInstace()
|
||||
*/
|
||||
static JCWaveParser* GetInstance( void );
|
||||
|
||||
|
||||
static void DelInstance( void );
|
||||
|
||||
/*
|
||||
* 从文件中读取wave数据
|
||||
*/
|
||||
JCWaveInfo* GetWaveInfoFromFile( const char* p_sFileName );
|
||||
|
||||
/*
|
||||
* 从数据中读取wave
|
||||
*/
|
||||
JCWaveInfo* GetWaveInfoFromBuffer( unsigned char* p_sBuffer, int p_nBufferSize );
|
||||
|
||||
|
||||
/**
|
||||
* @brief 测试用的
|
||||
*/
|
||||
void TestWave( const char* p_sFileName,const char* p_sOutFileName );
|
||||
|
||||
protected:
|
||||
|
||||
static JCWaveParser* m_sWaveParser; //静态的this指针
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCWaveParser_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
Reference in New Issue
Block a user