Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
204 lines
3.9 KiB
C++
204 lines
3.9 KiB
C++
|
|
#include "OggFile.h"
|
|
#include "SoundGlobal.h"
|
|
|
|
#include "vorbis/codec.h"
|
|
#include "vorbis/vorbisfile.h"
|
|
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|