#include "OggFile.h" #include "SoundGlobal.h" #include "vorbis/codec.h" #include "vorbis/vorbisfile.h" #include #pragma comment(lib, "vorbisfile_static.lib" ) #pragma comment(lib, "ogg_static.lib" ) #pragma comment(lib, "vorbis_static.lib" ) ///////////////////////////////////////////////////////////////////////////////////////// // COGGFile::COGGFile() : m_fp( 0 ), m_pVF( NULL ) , m_pszFilename( NULL ) , m_dwAvgBytesPerSec( 44100 ) { } COGGFile::COGGFile( const char * szFilename ) : m_fp( 0 ), m_pVF( NULL ) , m_pszFilename( NULL ) { Create( szFilename ); } COGGFile::~COGGFile() { Destroy(); delete m_pVF; } void COGGFile::Create( const char * szFilename ) { if( m_pszFilename ) delete [] m_pszFilename; if( m_pVF != NULL ) Destroy(); m_pVF = new OggVorbis_File; m_pszFilename = new char[ strlen( szFilename ) + 1 ]; strcpy( m_pszFilename, szFilename ); m_fp = fopen( szFilename, "rb" ); if( m_fp == NULL ) SNDError( "Cannot open OGG File : %s", szFilename ); int r = ov_open( m_fp, m_pVF, NULL, 0 ); if( r < 0 ) { switch( r ) { case OV_EREAD : SNDError( "OGG Error : OV_EREAD : %s", szFilename ); break; case OV_ENOTVORBIS : SNDError( "OGG Error : OV_ENOTVORVIS : %s", szFilename ); break; case OV_EVERSION : SNDError( "OGG Error : OV_EVERSION : %s", szFilename ); break; case OV_EBADHEADER : SNDError( "OGG Error : OV_EBADHEADER : %s", szFilename ); break; case OV_EFAULT : SNDError( "OGG Error : OV_EFAULT : %s", szFilename ); break; } } m_dwAvgBytesPerSec = GetBitsPerSample() / 8 * GetChannelCount() * GetSamplePerSec(); } void COGGFile::Destroy() { delete [] m_pszFilename; m_pszFilename = NULL; if( m_pVF ) { ov_clear( m_pVF ); delete m_pVF; m_pVF = NULL; } if( m_fp ) fclose( m_fp ); } WORD COGGFile::GetBitsPerSample() { return 16; } DWORD COGGFile::GetSamplePerSec() { vorbis_info * vi = ov_info( m_pVF, -1 ); return vi->rate; } WORD COGGFile::GetChannelCount() { vorbis_info * vi = ov_info( m_pVF, -1 ); return vi->channels; } DWORD COGGFile::GetSize() { ogg_int64_t pcmtotal = ov_pcm_total( m_pVF, -1 ); if( pcmtotal > 0xffffffff ) SNDError( "pcm »çÀÌÁî°¡ 4¹ÙÀÌÆ® º¯¼öÀÇ ÃÖ´ëÄ¡¸¦ ³Ñ¾ú½À´Ï´Ù. (at COGGFile::GetSize)" ); DWORD size = DWORD(pcmtotal & 0xffffffff); return size; } void COGGFile::Reset() { int r = ov_raw_seek( m_pVF, 0 ); if( r != 0 ) SNDError( "ov_raw_seek Failed!! ErrorCode : 0x%x", r ); } size_t COGGFile::Read( void * pBuf, size_t readSize ) { int current_section; size_t BufferWritten = 0, nActualBytesWritten = 0; DWORD readOnce; while( BufferWritten < readSize ) { if( readSize - BufferWritten < 4096 ) readOnce = readSize - BufferWritten; else readOnce = 4096; nActualBytesWritten = ov_read( m_pVF, ((char*)pBuf) + BufferWritten, readOnce, 0, 2, 1, ¤t_section ); if( nActualBytesWritten <= 0 ) break; BufferWritten += nActualBytesWritten; } if( BufferWritten > readSize ) { SNDError( "COGGFile::Read ¿¡¼­ ¹öÆÛ Å©±âº¸´Ù ´õ ¸¹ÀÌ Data¸¦ º¹»ç Çß½À´Ï´Ù." ); } return BufferWritten; } size_t COGGFile::ReadWhole( void * pBuf ) { return Read( pBuf, 0xffffffff ); } DWORD COGGFile::SeekWaveData( DWORD offset, eSeekPos seekPos ) { double offsetTime = double( offset ) / double( m_dwAvgBytesPerSec ); int r = 0; if( seekPos == seek_begin ) { r = ov_time_seek( m_pVF, offsetTime ); } else if( seekPos == seek_current ) { double currentTime = ov_time_tell( m_pVF ); r = ov_time_seek( m_pVF, currentTime + offsetTime ); } else { double totalTime = ov_time_total( m_pVF, -1 ); r = ov_time_seek( m_pVF, totalTime + offsetTime ); } double newTime = ov_time_tell( m_pVF ); return DWORD( newTime * m_dwAvgBytesPerSec ); } double COGGFile::GetTotalTime() { return ov_time_total( m_pVF, -1 ); } const char * COGGFile::GetFilename() { return m_pszFilename; } /////////////////////////////////////////////////////////////////////////////////////////