Commit c09515a1 authored by Byurrrer's avatar Byurrrer

Replaced FILE with IFile in audio codecs, fixed ogg coder

parent 26b7646b
......@@ -98,7 +98,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -114,7 +114,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -132,7 +132,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -152,7 +152,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OGGPLUGIN_EXPORTS;SX_LIB_NAME="OGG";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
......
......@@ -94,7 +94,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -110,7 +110,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -128,7 +128,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
......@@ -148,7 +148,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WAVPLUGIN_EXPORTS;SX_LIB_NAME="WAV";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
......
......@@ -3,44 +3,75 @@
//##########################################################################
size_t OggCallbackRead(void *ptr, size_t size, size_t nmemb, void *datasource)
size_t OggCallbackRead(void *pDataDest, size_t size, size_t nmemb, void *pDataFile)
{
FILE* f = (FILE*)datasource;
return fread(ptr, 1, size * nmemb, f);
IFile *pFile = (IFile*)pDataFile;
return pFile->readBin(pDataDest, size * nmemb);
}
int OggCallbackClose(void* datasource)
//**************************************************************************
int OggCallbackClose(void *pDataFile)
{
FILE* f = (FILE*)datasource;
fclose(f);
IFile *pFile = (IFile*)pDataFile;
//эту функци. вызывает ov_clear, но надо чтобы владалец обьекта сам закрывал файл
//mem_release(pFile);
return 0;
}
int OggCallbackSeek(void *datasource, ogg_int64_t offset, int whence)
//**************************************************************************
int OggCallbackSeek(void *pDataFile, ogg_int64_t offset, int whence)
{
FILE* f = (FILE*)datasource;
IFile *pFile = (IFile*)pDataFile;
switch (whence)
{
case SEEK_SET: return fseek(f, offset, SEEK_SET);
case SEEK_CUR: return fseek(f, offset, SEEK_CUR);
case SEEK_END: return fseek(f, offset, SEEK_END);
default: return -1;
case SEEK_SET:
{
if (offset < 0 || offset > pFile->getSize())
return 1;
pFile->setPos(offset);
return 0;
}
case SEEK_CUR:
{
size_t uPos = pFile->getPos() + offset;
if (uPos < 0 || uPos > pFile->getSize())
return 1;
pFile->setPos(uPos);
return 0;
}
case SEEK_END:
{
size_t uPos = pFile->getSize() + offset;
if (uPos < 0 || uPos > pFile->getSize())
return 1;
pFile->setPos(uPos);
return 0;
}
default:
return -1;
}
return 1;
}
long OggCallbackTell(void* datasource)
//**************************************************************************
long OggCallbackTell(void *pDataFile)
{
FILE* f = (FILE*)datasource;
return ftell(f);
IFile *pFile = (IFile*)pDataFile;
return pFile->getPos();
}
//##########################################################################
//##########################################################################
//##########################################################################
CAudioCodecOgg::CAudioCodecOgg()
CAudioCodecOgg::CAudioCodecOgg(IFileSystem *pFileSystem)
{
m_pFileSystem = pFileSystem;
m_oCB.close_func = OggCallbackClose;
m_oCB.read_func = OggCallbackRead;
m_oCB.seek_func = OggCallbackSeek;
......@@ -68,7 +99,7 @@ UINT XMETHODCALLTYPE CAudioCodecOgg::getExtCount() const
bool XMETHODCALLTYPE CAudioCodecOgg::open(const char *szFile, const char *szArg, IXAudioCodecTarget **ppTarget, bool forSave)
{
FILE *pFile = fopen(szFile, (forSave ? "wb" : "rb"));
IFile *pFile = m_pFileSystem->openFile(szFile, (forSave ? FILE_MODE_WRITE : FILE_MODE_READ));
if (!pFile || !ppTarget)
return false;
......@@ -126,11 +157,13 @@ CAudioCodecTargetOgg::~CAudioCodecTargetOgg()
ov_clear(m_pVoFile);
mem_delete(m_pVoFile);
}
mem_release(m_pFile);
}
//**************************************************************************
void CAudioCodecTargetOgg::init(FILE *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave)
void CAudioCodecTargetOgg::init(IFile *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave)
{
m_pFile = pFile;
m_pVoFile = pVoFile;
......@@ -287,20 +320,31 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw
iRetCode = ogg_stream_flush(&oOggStream, &oOggPage);
if(iRetCode == 0)
break;
fwrite(oOggPage.header, 1, oOggPage.header_len, m_pFile);
fwrite(oOggPage.body, 1, oOggPage.body_len, m_pFile);
m_pFile->writeBin(oOggPage.header, oOggPage.header_len);
m_pFile->writeBin(oOggPage.body, oOggPage.body_len);
}
//**************************************************
// инициализация семплов
//количество блоков семплов (количество каналов * байт на семпл)
int iCountBlocks = uSize/ (pOutDesc->u8BlockAlign);
//по сколько блоков записывать за один раз
int iPartBlocks = 1024;
//количество уже записанных блоков
int iCountReadedBlocks = 0;
/*в общем процесс записи сэмлов выглядит как показано в закомментированном коде ниже
но так делать не надо, потому что внутри vorbis_analysis_wrote выделяется память на стеке по общему количеству блоков
это может привести к переполнению стека
*/
/* получаем выделенный массив (по количеству каналов) массивов (по количеству семплов)
aaBuffer[iChannel][iSample]
*/
float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCountBlocks);
/*float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCountBlocks);
//заполняем выделенный float массив нормализованными данными [-1.0, 1.0]
for(int i = 0; i < iCountBlocks ; ++i)
......@@ -313,7 +357,33 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw
}
//сообщаем кодировщику что поступили данные для записи
vorbis_analysis_wrote(&oVoMainState, iCountBlocks);
vorbis_analysis_wrote(&oVoMainState, iCountBlocks);*/
//циклом (частями) передаем данные кодировщику
while (iCountReadedBlocks < iCountBlocks)
{
//количество уже прочитанных сэмплов
uint32_t uCountReadedSamples = (iCountReadedBlocks*pOutDesc->u8Channels);
//количество блоков для текущей итерации
int iCurrBlocks = iPartBlocks;
if (iCountBlocks - iCountReadedBlocks < iPartBlocks)
iCurrBlocks = iCountBlocks - iCountReadedBlocks;
float **aaBuffer = vorbis_analysis_buffer(&oVoMainState, iCurrBlocks);
for (int i = 0; i < iCurrBlocks; ++i)
{
for (int iChannels = 0; iChannels<pOutDesc->u8Channels; ++iChannels)
{
int16_t i16Sample = ((int16_t*)pData)[uCountReadedSamples + i];
aaBuffer[iChannels][i] = float(i16Sample) / 32768.f;
}
}
vorbis_analysis_wrote(&oVoMainState, iCurrBlocks);
iCountReadedBlocks += iCurrBlocks;
}
//**************************************************
......@@ -325,8 +395,10 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw
/*разбивка несжатых данных на блоки, если не удалось, тогда сообщаем что данных больше не будет
если не сообщить об этом, то не все данные будут записаны, не получится дойти до конца битового потока, потому что запись идет постраничная и последняя неполня страница не будет записана
*/
if(vorbis_analysis_blockout(&oVoMainState, &oVoDataBlock)!=1)
if (vorbis_analysis_blockout(&oVoMainState, &oVoDataBlock) != 1)
{
vorbis_analysis_wrote(&oVoMainState, 0);
}
//поиск режима кодирования и отправка блока на кодировку
vorbis_analysis(&oVoDataBlock, NULL);
......@@ -344,8 +416,9 @@ bool XMETHODCALLTYPE CAudioCodecTargetOgg::encode(IXBuffer *pBufferPCM, AudioRaw
int result=ogg_stream_pageout(&oOggStream, &oOggPage);
if(result==0)
break;
fwrite(oOggPage.header, 1, oOggPage.header_len, m_pFile);
fwrite(oOggPage.body, 1, oOggPage.body_len, m_pFile);
m_pFile->writeBin(oOggPage.header, oOggPage.header_len);
m_pFile->writeBin(oOggPage.body, oOggPage.body_len);
//если все записано (находимся в конце битового потока), сообщаем о завершении
if(ogg_page_eos(&oOggPage))
......
......@@ -15,16 +15,22 @@ See the license in LICENSE
#include <common/string.h>
#include <xcommon/IFileSystem.h>
#include <core/IFile.h>
//! количество байт на семпл
#define OGG_BYTES_PER_SAMPLE 2
//##########################################################################
class CAudioCodecOgg: public IXUnknownImplementation<IXAudioCodec>
{
public:
CAudioCodecOgg();
CAudioCodecOgg(IFileSystem *pFileSystem);
~CAudioCodecOgg(){}
XIMPLEMENT_VERSION(IXAUDIOCODEC_VERSION);
virtual const char* XMETHODCALLTYPE getFormat() const override;
virtual const char* XMETHODCALLTYPE getExt(UINT uIndex=0) const override;
virtual UINT XMETHODCALLTYPE getExtCount() const override;
......@@ -34,6 +40,7 @@ public:
protected:
ov_callbacks m_oCB;
Array<String> m_aExts;
IFileSystem *m_pFileSystem = NULL;
};
//##########################################################################
......@@ -52,9 +59,9 @@ protected:
friend CAudioCodecOgg;
void init(FILE *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave);
void init(IFile *pFile, OggVorbis_File *pVoFile, AudioRawDesc *pDesc, bool forSave);
FILE *m_pFile = NULL;
IFile *m_pFile = NULL;
OggVorbis_File *m_pVoFile;
AudioRawDesc m_oDesc;
bool m_forSave = false;
......
......@@ -20,6 +20,7 @@ class CAudioCodecOggPlugin: public IXUnknownImplementation<IXPlugin>
public:
void XMETHODCALLTYPE startup(IXCore *pCore) override
{
m_pCore = pCore;
}
void XMETHODCALLTYPE shutdown() override
......@@ -47,10 +48,13 @@ public:
{
if (guid == IXAUDIOCODEC_GUID)
{
return(new CAudioCodecOgg());
return(new CAudioCodecOgg(m_pCore->getFileSystem()));
}
return(NULL);
}
protected:
IXCore *m_pCore = NULL;
};
DECLARE_XPLUGIN(CAudioCodecOggPlugin);
......@@ -3,14 +3,15 @@
//##########################################################################
CAudioCodecWave::CAudioCodecWave()
CAudioCodecWave::CAudioCodecWave(IFileSystem *pFileSystem)
{
m_pFileSystem = pFileSystem;
m_aExts.push_back("wav");
}
bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg, IXAudioCodecTarget **ppTarget, bool forSave)
{
FILE *pFile = fopen(szFile, (forSave ? "wb" : "rb"));
IFile *pFile = m_pFileSystem->openFile(szFile, (forSave ? FILE_MODE_WRITE : FILE_MODE_READ));
if (!pFile || !ppTarget)
return false;
......@@ -20,10 +21,10 @@ bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg
if(!forSave)
{
uint32_t uCurrPos = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
fread(&oHeader, 1, sizeof(CWaveHeader), pFile);
fseek(pFile, 0, uCurrPos);
size_t uCurrPos = pFile->getPos();
pFile->setPos(0);
pFile->readBin(&oHeader, sizeof(CWaveHeader));
pFile->setPos(uCurrPos);
bool can =
memcmp(oHeader.aRiff, "RIFF", 4) == 0 &&
......@@ -33,7 +34,7 @@ bool XMETHODCALLTYPE CAudioCodecWave::open(const char *szFile, const char *szArg
if(!can)
{
fclose(pFile);
mem_release(pFile);
return false;
}
......@@ -87,12 +88,12 @@ UINT XMETHODCALLTYPE CAudioCodecWave::getExtCount() const
CAudioCodecTargetWave::~CAudioCodecTargetWave()
{
fclose(m_pFile);
mem_release(m_pFile);
}
//**************************************************************************
void CAudioCodecTargetWave::init(FILE *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave)
void CAudioCodecTargetWave::init(IFile *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave)
{
m_pFile = pFile;
......@@ -122,7 +123,7 @@ int64_t XMETHODCALLTYPE CAudioCodecTargetWave::getPos() const
if(!m_pFile || m_forSave)
return 0;
return ftell(m_pFile) - sizeof(CWaveHeader);
return m_pFile->getPos() - sizeof(CWaveHeader);
}
//**************************************************************************
......@@ -132,7 +133,7 @@ void XMETHODCALLTYPE CAudioCodecTargetWave::setPos(int64_t iPos)
if(!m_pFile || m_forSave)
return;
fseek(m_pFile, sizeof(CWaveHeader) + iPos, SEEK_SET);
m_pFile->setPos(sizeof(CWaveHeader) + iPos);
}
//**************************************************************************
......@@ -144,7 +145,7 @@ size_t XMETHODCALLTYPE CAudioCodecTargetWave::decode(int64_t iPos, uint64_t uLen
setPos(iPos);
size_t sizeRead = fread(*ppData, 1, uLen, m_pFile);
size_t sizeRead = m_pFile->readBin(*ppData, uLen);
return sizeRead;
}
......@@ -156,7 +157,7 @@ bool XMETHODCALLTYPE CAudioCodecTargetWave::encode(IXBuffer *pBufferPCM, AudioRa
if (!pBufferPCM || !pOutDesc)
return false;
fseek(m_pFile, 0, SEEK_SET);
m_pFile->setPos(0);
CWaveHeader oOutHeader;
oOutHeader.iSampleRate = pOutDesc->uSampleRate;
......@@ -173,8 +174,8 @@ bool XMETHODCALLTYPE CAudioCodecTargetWave::encode(IXBuffer *pBufferPCM, AudioRa
oOutHeader.i16FormatCode = (pOutDesc->fmtSample > AUDIO_SAMPLE_FMT_SINT32 ? WAVE_FORMAT_PCM_FLOAT : WAVE_FORMAT_PCM_INT);
oOutHeader.uFormatChunkSize = 16;
fwrite(&oOutHeader, sizeof(oOutHeader), 1, m_pFile);
fwrite(pBufferPCM->get(), 1, pBufferPCM->size(), m_pFile);
m_pFile->writeBin(&oOutHeader, sizeof(oOutHeader));
m_pFile->writeBin(pBufferPCM->get(), pBufferPCM->size());
return true;
}
......
......@@ -9,6 +9,8 @@ See the license in LICENSE
#include <xcommon/IXAudioCodec.h>
#include <common/string.h>
#include <xcommon/IFileSystem.h>
#include <core/IFile.h>
//##########################################################################
......@@ -40,7 +42,9 @@ struct CWaveHeader
class CAudioCodecWave: public IXUnknownImplementation<IXAudioCodec>
{
public:
CAudioCodecWave();
CAudioCodecWave(IFileSystem *pFileSystem);
XIMPLEMENT_VERSION(IXAUDIOCODEC_VERSION);
virtual const char* XMETHODCALLTYPE getFormat() const override;
virtual const char* XMETHODCALLTYPE getExt(UINT uIndex=0) const override;
......@@ -50,6 +54,7 @@ public:
protected:
Array<String> m_aExts;
IFileSystem *m_pFileSystem = NULL;
};
//##########################################################################
......@@ -68,9 +73,9 @@ protected:
friend CAudioCodecWave;
void init(FILE *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave);
void init(IFile *pFile, CWaveHeader *pHeader, AudioRawDesc *pDesc, bool forSave);
FILE *m_pFile = NULL;
IFile *m_pFile = NULL;
CWaveHeader m_oHeader;
AudioRawDesc m_oDesc;
bool m_forSave = false;
......
......@@ -14,6 +14,7 @@ class CAudioCodecWav: public IXUnknownImplementation<IXPlugin>
public:
void XMETHODCALLTYPE startup(IXCore *pCore) override
{
m_pCore = pCore;
}
void XMETHODCALLTYPE shutdown() override
......@@ -41,10 +42,13 @@ public:
{
if (guid == IXAUDIOCODEC_GUID)
{
return(new CAudioCodecWave());
return(new CAudioCodecWave(m_pCore->getFileSystem()));
}
return(NULL);
}
protected:
IXCore *m_pCore = NULL;
};
DECLARE_XPLUGIN(CAudioCodecWav);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment