mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
Fix line endings and tabs
This commit is contained in:
@ -1,35 +1,35 @@
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
include_directories(${DirectX_INCLUDE_DIR})
|
||||
include_directories(${Ogg_INCLUDE_DIR})
|
||||
include_directories(${Vorbis_INCLUDE_DIR})
|
||||
|
||||
set(plAudioCore_SOURCES
|
||||
plAudioFileReader.cpp
|
||||
plBufferedFileReader.cpp
|
||||
plFastWavReader.cpp
|
||||
plOGGCodec.cpp
|
||||
plSoundBuffer.cpp
|
||||
plSoundDeswizzler.cpp
|
||||
plWavFile.cpp
|
||||
)
|
||||
|
||||
set(plAudioCore_HEADERS
|
||||
plAudioCore.h
|
||||
plAudioCoreCreatable.h
|
||||
plAudioFileReader.h
|
||||
plBufferedFileReader.h
|
||||
plFastWavReader.h
|
||||
plOGGCodec.h
|
||||
plSoundBuffer.h
|
||||
plSoundDeswizzler.h
|
||||
plWavFile.h
|
||||
)
|
||||
|
||||
add_library(plAudioCore STATIC ${plAudioCore_SOURCES} ${plAudioCore_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plAudioCore_SOURCES})
|
||||
source_group("Header Files" FILES ${plAudioCore_HEADERS})
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
include_directories(${DirectX_INCLUDE_DIR})
|
||||
include_directories(${Ogg_INCLUDE_DIR})
|
||||
include_directories(${Vorbis_INCLUDE_DIR})
|
||||
|
||||
set(plAudioCore_SOURCES
|
||||
plAudioFileReader.cpp
|
||||
plBufferedFileReader.cpp
|
||||
plFastWavReader.cpp
|
||||
plOGGCodec.cpp
|
||||
plSoundBuffer.cpp
|
||||
plSoundDeswizzler.cpp
|
||||
plWavFile.cpp
|
||||
)
|
||||
|
||||
set(plAudioCore_HEADERS
|
||||
plAudioCore.h
|
||||
plAudioCoreCreatable.h
|
||||
plAudioFileReader.h
|
||||
plBufferedFileReader.h
|
||||
plFastWavReader.h
|
||||
plOGGCodec.h
|
||||
plSoundBuffer.h
|
||||
plSoundDeswizzler.h
|
||||
plWavFile.h
|
||||
)
|
||||
|
||||
add_library(plAudioCore STATIC ${plAudioCore_SOURCES} ${plAudioCore_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plAudioCore_SOURCES})
|
||||
source_group("Header Files" FILES ${plAudioCore_HEADERS})
|
||||
|
@ -1,68 +1,68 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioCore - Core, common stuff that all of the audio system needs //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plAudioCore_h
|
||||
#define _plAudioCore_h
|
||||
|
||||
//// plWAVHeader Class ///////////////////////////////////////////////////////
|
||||
// Just a small info class about WAV sound
|
||||
|
||||
class plWAVHeader
|
||||
{
|
||||
public:
|
||||
UInt16 fFormatTag;
|
||||
UInt16 fNumChannels;
|
||||
UInt32 fNumSamplesPerSec;
|
||||
UInt32 fAvgBytesPerSec;
|
||||
UInt16 fBlockAlign;
|
||||
UInt16 fBitsPerSample;
|
||||
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
};
|
||||
|
||||
//// plAudioCore Konstants ///////////////////////////////////////////////////
|
||||
|
||||
namespace plAudioCore
|
||||
{
|
||||
enum ChannelSelect
|
||||
{
|
||||
kAll = 0,
|
||||
kLeft,
|
||||
kRight
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //_plAudioCore_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioCore - Core, common stuff that all of the audio system needs //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plAudioCore_h
|
||||
#define _plAudioCore_h
|
||||
|
||||
//// plWAVHeader Class ///////////////////////////////////////////////////////
|
||||
// Just a small info class about WAV sound
|
||||
|
||||
class plWAVHeader
|
||||
{
|
||||
public:
|
||||
UInt16 fFormatTag;
|
||||
UInt16 fNumChannels;
|
||||
UInt32 fNumSamplesPerSec;
|
||||
UInt32 fAvgBytesPerSec;
|
||||
UInt16 fBlockAlign;
|
||||
UInt16 fBitsPerSample;
|
||||
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
};
|
||||
|
||||
//// plAudioCore Konstants ///////////////////////////////////////////////////
|
||||
|
||||
namespace plAudioCore
|
||||
{
|
||||
enum ChannelSelect
|
||||
{
|
||||
kAll = 0,
|
||||
kLeft,
|
||||
kRight
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //_plAudioCore_h
|
||||
|
@ -1,36 +1,36 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plAudioCoreCreatable_inc
|
||||
#define plAudioCoreCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
#include "plSoundBuffer.h"
|
||||
|
||||
REGISTER_CREATABLE( plSoundBuffer );
|
||||
|
||||
#endif // plAudioCoreCreatable_inc
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plAudioCoreCreatable_inc
|
||||
#define plAudioCoreCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
#include "plSoundBuffer.h"
|
||||
|
||||
REGISTER_CREATABLE( plSoundBuffer );
|
||||
|
||||
#endif // plAudioCoreCreatable_inc
|
||||
|
@ -1,169 +1,169 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioFileReader //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 3.5.2001 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <string.h>
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plAudioFileReader.h"
|
||||
#include "plAudioCore.h"
|
||||
//#include "hsTimer.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plFile/hsFiles.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "plUnifiedTime/plUnifiedTime.h"
|
||||
#include "plBufferedFileReader.h"
|
||||
#include "plFastWavReader.h"
|
||||
#include "plOGGCodec.h"
|
||||
#include "plWavFile.h"
|
||||
|
||||
#define kCacheDirName "streamingCache"
|
||||
|
||||
static void hsStrUpper(char *s)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
int len = hsStrlen(s);
|
||||
for (int i = 0; i < len; i++)
|
||||
s[i] = toupper(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
plAudioFileReader* plAudioFileReader::CreateReader(const char* path, plAudioCore::ChannelSelect whichChan, StreamType type)
|
||||
{
|
||||
const char* ext = plFileUtils::GetFileExt(path);
|
||||
|
||||
if (type == kStreamWAV)
|
||||
{
|
||||
bool isWav = (stricmp(ext, "wav") == 0);
|
||||
// We want to stream a wav off disk, but this is a compressed file.
|
||||
// Get the uncompressed path. Ignore the requested channel, since it
|
||||
// will have already been split into two files if that is necessary.
|
||||
if (!isWav)
|
||||
{
|
||||
char cachedPath[256];
|
||||
IGetCachedPath(path, cachedPath, whichChan);
|
||||
plAudioFileReader *r = TRACKED_NEW plFastWAV(cachedPath, plAudioCore::kAll);
|
||||
return r;
|
||||
}
|
||||
|
||||
plAudioFileReader *r = TRACKED_NEW plFastWAV(path, whichChan);
|
||||
return r;
|
||||
}
|
||||
else if (type == kStreamRAM)
|
||||
return TRACKED_NEW plBufferedFileReader(path, whichChan);
|
||||
else if (type == kStreamNative)
|
||||
return TRACKED_NEW plOGGCodec(path, whichChan);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
plAudioFileReader* plAudioFileReader::CreateWriter(const char* path, plWAVHeader& header)
|
||||
{
|
||||
const char* ext = plFileUtils::GetFileExt(path);
|
||||
|
||||
plAudioFileReader* writer = TRACKED_NEW CWaveFile(path, plAudioCore::kAll);
|
||||
writer->OpenForWriting(path, header);
|
||||
return writer;
|
||||
}
|
||||
|
||||
void plAudioFileReader::IGetCachedPath(const char* path, char* cachedPath, plAudioCore::ChannelSelect whichChan)
|
||||
{
|
||||
// Get the file's path and add our streaming cache folder to it
|
||||
strcpy(cachedPath, path);
|
||||
plFileUtils::StripFile(cachedPath);
|
||||
strcat(cachedPath, kCacheDirName"\\");
|
||||
|
||||
// Create the directory first
|
||||
plFileUtils::CreateDir(cachedPath);
|
||||
|
||||
// Get the path to the cached version of the file, without the extension
|
||||
const char* fileName = plFileUtils::GetFileName(path);
|
||||
const char* fileExt = plFileUtils::GetFileExt(fileName);
|
||||
strncat(cachedPath, fileName, fileExt-fileName-1);
|
||||
|
||||
if (whichChan == plAudioCore::kLeft)
|
||||
strcat(cachedPath, "-Left.wav");
|
||||
else if (whichChan == plAudioCore::kRight)
|
||||
strcat(cachedPath, "-Right.wav");
|
||||
else if (whichChan == plAudioCore::kAll)
|
||||
strcat(cachedPath, ".wav");
|
||||
}
|
||||
|
||||
void plAudioFileReader::ICacheFile(const char* path, bool noOverwrite, plAudioCore::ChannelSelect whichChan)
|
||||
{
|
||||
char cachedPath[256];
|
||||
IGetCachedPath(path, cachedPath, whichChan);
|
||||
if (!noOverwrite || !plFileUtils::FileExists(cachedPath))
|
||||
{
|
||||
plAudioFileReader* reader = plAudioFileReader::CreateReader(path, whichChan, kStreamNative);
|
||||
if (!reader || !reader->IsValid())
|
||||
{
|
||||
delete reader;
|
||||
return;
|
||||
}
|
||||
plAudioFileReader* writer = CreateWriter(cachedPath, reader->GetHeader());
|
||||
if (!writer || !writer->IsValid())
|
||||
{
|
||||
delete reader;
|
||||
delete writer;
|
||||
return;
|
||||
}
|
||||
|
||||
UInt8 buffer[4096];
|
||||
UInt32 numLeft;
|
||||
while ((numLeft = reader->NumBytesLeft()) > 0)
|
||||
{
|
||||
UInt32 toRead = (numLeft < sizeof(buffer)) ? numLeft : sizeof(buffer);
|
||||
reader->Read(toRead, buffer);
|
||||
writer->Write(toRead, buffer);
|
||||
}
|
||||
writer->Close();
|
||||
|
||||
delete writer;
|
||||
delete reader;
|
||||
}
|
||||
}
|
||||
|
||||
void plAudioFileReader::CacheFile(const char* path, bool splitChannels, bool noOverwrite)
|
||||
{
|
||||
if (splitChannels)
|
||||
{
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kLeft);
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kAll);
|
||||
}
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioFileReader //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 3.5.2001 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <string.h>
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plAudioFileReader.h"
|
||||
#include "plAudioCore.h"
|
||||
//#include "hsTimer.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plFile/hsFiles.h"
|
||||
#include "plFile/plFileUtils.h"
|
||||
#include "plUnifiedTime/plUnifiedTime.h"
|
||||
#include "plBufferedFileReader.h"
|
||||
#include "plFastWavReader.h"
|
||||
#include "plOGGCodec.h"
|
||||
#include "plWavFile.h"
|
||||
|
||||
#define kCacheDirName "streamingCache"
|
||||
|
||||
static void hsStrUpper(char *s)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
int len = hsStrlen(s);
|
||||
for (int i = 0; i < len; i++)
|
||||
s[i] = toupper(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
plAudioFileReader* plAudioFileReader::CreateReader(const char* path, plAudioCore::ChannelSelect whichChan, StreamType type)
|
||||
{
|
||||
const char* ext = plFileUtils::GetFileExt(path);
|
||||
|
||||
if (type == kStreamWAV)
|
||||
{
|
||||
bool isWav = (stricmp(ext, "wav") == 0);
|
||||
// We want to stream a wav off disk, but this is a compressed file.
|
||||
// Get the uncompressed path. Ignore the requested channel, since it
|
||||
// will have already been split into two files if that is necessary.
|
||||
if (!isWav)
|
||||
{
|
||||
char cachedPath[256];
|
||||
IGetCachedPath(path, cachedPath, whichChan);
|
||||
plAudioFileReader *r = TRACKED_NEW plFastWAV(cachedPath, plAudioCore::kAll);
|
||||
return r;
|
||||
}
|
||||
|
||||
plAudioFileReader *r = TRACKED_NEW plFastWAV(path, whichChan);
|
||||
return r;
|
||||
}
|
||||
else if (type == kStreamRAM)
|
||||
return TRACKED_NEW plBufferedFileReader(path, whichChan);
|
||||
else if (type == kStreamNative)
|
||||
return TRACKED_NEW plOGGCodec(path, whichChan);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
plAudioFileReader* plAudioFileReader::CreateWriter(const char* path, plWAVHeader& header)
|
||||
{
|
||||
const char* ext = plFileUtils::GetFileExt(path);
|
||||
|
||||
plAudioFileReader* writer = TRACKED_NEW CWaveFile(path, plAudioCore::kAll);
|
||||
writer->OpenForWriting(path, header);
|
||||
return writer;
|
||||
}
|
||||
|
||||
void plAudioFileReader::IGetCachedPath(const char* path, char* cachedPath, plAudioCore::ChannelSelect whichChan)
|
||||
{
|
||||
// Get the file's path and add our streaming cache folder to it
|
||||
strcpy(cachedPath, path);
|
||||
plFileUtils::StripFile(cachedPath);
|
||||
strcat(cachedPath, kCacheDirName"\\");
|
||||
|
||||
// Create the directory first
|
||||
plFileUtils::CreateDir(cachedPath);
|
||||
|
||||
// Get the path to the cached version of the file, without the extension
|
||||
const char* fileName = plFileUtils::GetFileName(path);
|
||||
const char* fileExt = plFileUtils::GetFileExt(fileName);
|
||||
strncat(cachedPath, fileName, fileExt-fileName-1);
|
||||
|
||||
if (whichChan == plAudioCore::kLeft)
|
||||
strcat(cachedPath, "-Left.wav");
|
||||
else if (whichChan == plAudioCore::kRight)
|
||||
strcat(cachedPath, "-Right.wav");
|
||||
else if (whichChan == plAudioCore::kAll)
|
||||
strcat(cachedPath, ".wav");
|
||||
}
|
||||
|
||||
void plAudioFileReader::ICacheFile(const char* path, bool noOverwrite, plAudioCore::ChannelSelect whichChan)
|
||||
{
|
||||
char cachedPath[256];
|
||||
IGetCachedPath(path, cachedPath, whichChan);
|
||||
if (!noOverwrite || !plFileUtils::FileExists(cachedPath))
|
||||
{
|
||||
plAudioFileReader* reader = plAudioFileReader::CreateReader(path, whichChan, kStreamNative);
|
||||
if (!reader || !reader->IsValid())
|
||||
{
|
||||
delete reader;
|
||||
return;
|
||||
}
|
||||
plAudioFileReader* writer = CreateWriter(cachedPath, reader->GetHeader());
|
||||
if (!writer || !writer->IsValid())
|
||||
{
|
||||
delete reader;
|
||||
delete writer;
|
||||
return;
|
||||
}
|
||||
|
||||
UInt8 buffer[4096];
|
||||
UInt32 numLeft;
|
||||
while ((numLeft = reader->NumBytesLeft()) > 0)
|
||||
{
|
||||
UInt32 toRead = (numLeft < sizeof(buffer)) ? numLeft : sizeof(buffer);
|
||||
reader->Read(toRead, buffer);
|
||||
writer->Write(toRead, buffer);
|
||||
}
|
||||
writer->Close();
|
||||
|
||||
delete writer;
|
||||
delete reader;
|
||||
}
|
||||
}
|
||||
|
||||
void plAudioFileReader::CacheFile(const char* path, bool splitChannels, bool noOverwrite)
|
||||
{
|
||||
if (splitChannels)
|
||||
{
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kLeft);
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ICacheFile(path, noOverwrite, plAudioCore::kAll);
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +1,83 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioFileReader - Microsoft's way of making our lives difficult when //
|
||||
// reading in .WMA files. Hacking Winamp's plugins is //
|
||||
// probably easier... //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plAudioFileReader_h
|
||||
#define _plAudioFileReader_h
|
||||
|
||||
#include "plAudioCore.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plUnifiedTime;
|
||||
class plWAVHeader;
|
||||
class plAudioFileReader
|
||||
{
|
||||
public:
|
||||
virtual ~plAudioFileReader() {}
|
||||
virtual plWAVHeader &GetHeader( void ) = 0;
|
||||
|
||||
enum StreamType
|
||||
{
|
||||
kStreamRAM, // Stream from a WAV loaded into RAM
|
||||
kStreamWAV, // Stream from a WAV on disk
|
||||
kStreamNative, // Stream from the native type (ie, an Ogg on disk)
|
||||
};
|
||||
|
||||
virtual void Open(){}
|
||||
virtual void Close( void ) = 0;
|
||||
|
||||
virtual UInt32 GetDataSize( void ) = 0;
|
||||
virtual float GetLengthInSecs( void ) = 0;
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes ) = 0;
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer ) = 0;
|
||||
virtual UInt32 NumBytesLeft( void ) = 0;
|
||||
|
||||
virtual hsBool OpenForWriting( const char *path, plWAVHeader &header ) { return false; }
|
||||
virtual UInt32 Write( UInt32 bytes, void *buffer ) { return 0; }
|
||||
|
||||
virtual hsBool IsValid( void ) = 0;
|
||||
|
||||
static plAudioFileReader* CreateReader(const char* path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll, StreamType type = kStreamWAV);
|
||||
static plAudioFileReader* CreateWriter(const char* path, plWAVHeader& header);
|
||||
|
||||
// Decompresses a compressed file to the cache directory
|
||||
static void CacheFile(const char* path, bool splitChannels=false, bool noOverwrite=false);
|
||||
|
||||
protected:
|
||||
static void IGetCachedPath(const char* path, char* cachedPath, plAudioCore::ChannelSelect whichChan);
|
||||
static void ICacheFile(const char* path, bool noOverwrite, plAudioCore::ChannelSelect whichChan);
|
||||
};
|
||||
|
||||
#endif //_plAudioFileReader_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plAudioFileReader - Microsoft's way of making our lives difficult when //
|
||||
// reading in .WMA files. Hacking Winamp's plugins is //
|
||||
// probably easier... //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plAudioFileReader_h
|
||||
#define _plAudioFileReader_h
|
||||
|
||||
#include "plAudioCore.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plUnifiedTime;
|
||||
class plWAVHeader;
|
||||
class plAudioFileReader
|
||||
{
|
||||
public:
|
||||
virtual ~plAudioFileReader() {}
|
||||
virtual plWAVHeader &GetHeader( void ) = 0;
|
||||
|
||||
enum StreamType
|
||||
{
|
||||
kStreamRAM, // Stream from a WAV loaded into RAM
|
||||
kStreamWAV, // Stream from a WAV on disk
|
||||
kStreamNative, // Stream from the native type (ie, an Ogg on disk)
|
||||
};
|
||||
|
||||
virtual void Open(){}
|
||||
virtual void Close( void ) = 0;
|
||||
|
||||
virtual UInt32 GetDataSize( void ) = 0;
|
||||
virtual float GetLengthInSecs( void ) = 0;
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes ) = 0;
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer ) = 0;
|
||||
virtual UInt32 NumBytesLeft( void ) = 0;
|
||||
|
||||
virtual hsBool OpenForWriting( const char *path, plWAVHeader &header ) { return false; }
|
||||
virtual UInt32 Write( UInt32 bytes, void *buffer ) { return 0; }
|
||||
|
||||
virtual hsBool IsValid( void ) = 0;
|
||||
|
||||
static plAudioFileReader* CreateReader(const char* path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll, StreamType type = kStreamWAV);
|
||||
static plAudioFileReader* CreateWriter(const char* path, plWAVHeader& header);
|
||||
|
||||
// Decompresses a compressed file to the cache directory
|
||||
static void CacheFile(const char* path, bool splitChannels=false, bool noOverwrite=false);
|
||||
|
||||
protected:
|
||||
static void IGetCachedPath(const char* path, char* cachedPath, plAudioCore::ChannelSelect whichChan);
|
||||
static void ICacheFile(const char* path, bool noOverwrite, plAudioCore::ChannelSelect whichChan);
|
||||
};
|
||||
|
||||
#endif //_plAudioFileReader_h
|
||||
|
@ -1,166 +1,166 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plBufferedFileReader - Reads in a given file into a RAM buffer, then //
|
||||
// "reads" from that buffer as requested. Useless //
|
||||
// for normal sounds, but perfect for streaming //
|
||||
// from RAM. //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 11.1.2002 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plBufferedFileReader.h"
|
||||
//#include "plProfile.h"
|
||||
|
||||
|
||||
//plProfile_CreateMemCounter( "BufferedRAM", "Sound", SndBufferedMem );
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plBufferedFileReader::plBufferedFileReader( const char *path, plAudioCore::ChannelSelect whichChan )
|
||||
{
|
||||
// Init some stuff
|
||||
fBufferSize = 0;
|
||||
fBuffer = nil;
|
||||
fCursor = 0;
|
||||
|
||||
hsAssert( path != nil, "Invalid path specified in plBufferedFileReader" );
|
||||
|
||||
// Ask plAudioFileReader for another reader to get this file
|
||||
// Note: have this reader do the chanSelect for us
|
||||
plAudioFileReader *reader = plAudioFileReader::CreateReader( path, whichChan );
|
||||
if( reader == nil || !reader->IsValid() )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to open file to read in to RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
fHeader = reader->GetHeader();
|
||||
|
||||
fBufferSize = reader->GetDataSize();
|
||||
fBuffer = TRACKED_NEW UInt8[ fBufferSize ];
|
||||
//plProfile_NewMem( SndBufferedMem, fBufferSize );
|
||||
if( fBuffer == nil )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to allocate RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !reader->Read( fBufferSize, fBuffer ) )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to read file into RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
// All done!
|
||||
delete reader;
|
||||
}
|
||||
|
||||
plBufferedFileReader::~plBufferedFileReader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void plBufferedFileReader::Close( void )
|
||||
{
|
||||
//plProfile_DelMem( SndBufferedMem, fBufferSize );
|
||||
|
||||
DEL(fBuffer);;
|
||||
fBuffer = nil;
|
||||
fBufferSize = 0;
|
||||
fCursor = 0;
|
||||
}
|
||||
|
||||
void plBufferedFileReader::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plBufferedFileReader::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid RAM buffer" );
|
||||
|
||||
return fHeader;
|
||||
}
|
||||
|
||||
float plBufferedFileReader::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid RAM buffer" );
|
||||
|
||||
return (float)fBufferSize / (float)fHeader.fAvgBytesPerSec;
|
||||
}
|
||||
|
||||
hsBool plBufferedFileReader::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "SetPosition() called on an invalid RAM buffer" );
|
||||
|
||||
if( numBytes > fBufferSize )
|
||||
{
|
||||
hsAssert( false, "Invalid position in SetPosition()" );
|
||||
return false;
|
||||
}
|
||||
|
||||
fCursor = numBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plBufferedFileReader::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "Read() called on an invalid RAM buffer" );
|
||||
|
||||
|
||||
hsBool valid = true;
|
||||
|
||||
if( fCursor + numBytes > fBufferSize )
|
||||
{
|
||||
numBytes = fBufferSize - fCursor;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
memcpy( buffer, fBuffer + fCursor, numBytes );
|
||||
fCursor += numBytes;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
UInt32 plBufferedFileReader::NumBytesLeft( void )
|
||||
{
|
||||
hsAssert( IsValid(), "NumBytesLeft() called on an invalid RAM buffer" );
|
||||
|
||||
return fBufferSize - fCursor;
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plBufferedFileReader - Reads in a given file into a RAM buffer, then //
|
||||
// "reads" from that buffer as requested. Useless //
|
||||
// for normal sounds, but perfect for streaming //
|
||||
// from RAM. //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 11.1.2002 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plBufferedFileReader.h"
|
||||
//#include "plProfile.h"
|
||||
|
||||
|
||||
//plProfile_CreateMemCounter( "BufferedRAM", "Sound", SndBufferedMem );
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plBufferedFileReader::plBufferedFileReader( const char *path, plAudioCore::ChannelSelect whichChan )
|
||||
{
|
||||
// Init some stuff
|
||||
fBufferSize = 0;
|
||||
fBuffer = nil;
|
||||
fCursor = 0;
|
||||
|
||||
hsAssert( path != nil, "Invalid path specified in plBufferedFileReader" );
|
||||
|
||||
// Ask plAudioFileReader for another reader to get this file
|
||||
// Note: have this reader do the chanSelect for us
|
||||
plAudioFileReader *reader = plAudioFileReader::CreateReader( path, whichChan );
|
||||
if( reader == nil || !reader->IsValid() )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to open file to read in to RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
fHeader = reader->GetHeader();
|
||||
|
||||
fBufferSize = reader->GetDataSize();
|
||||
fBuffer = TRACKED_NEW UInt8[ fBufferSize ];
|
||||
//plProfile_NewMem( SndBufferedMem, fBufferSize );
|
||||
if( fBuffer == nil )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to allocate RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !reader->Read( fBufferSize, fBuffer ) )
|
||||
{
|
||||
delete reader;
|
||||
IError( "Unable to read file into RAM buffer" );
|
||||
return;
|
||||
}
|
||||
|
||||
// All done!
|
||||
delete reader;
|
||||
}
|
||||
|
||||
plBufferedFileReader::~plBufferedFileReader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void plBufferedFileReader::Close( void )
|
||||
{
|
||||
//plProfile_DelMem( SndBufferedMem, fBufferSize );
|
||||
|
||||
DEL(fBuffer);;
|
||||
fBuffer = nil;
|
||||
fBufferSize = 0;
|
||||
fCursor = 0;
|
||||
}
|
||||
|
||||
void plBufferedFileReader::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plBufferedFileReader::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid RAM buffer" );
|
||||
|
||||
return fHeader;
|
||||
}
|
||||
|
||||
float plBufferedFileReader::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid RAM buffer" );
|
||||
|
||||
return (float)fBufferSize / (float)fHeader.fAvgBytesPerSec;
|
||||
}
|
||||
|
||||
hsBool plBufferedFileReader::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "SetPosition() called on an invalid RAM buffer" );
|
||||
|
||||
if( numBytes > fBufferSize )
|
||||
{
|
||||
hsAssert( false, "Invalid position in SetPosition()" );
|
||||
return false;
|
||||
}
|
||||
|
||||
fCursor = numBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plBufferedFileReader::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "Read() called on an invalid RAM buffer" );
|
||||
|
||||
|
||||
hsBool valid = true;
|
||||
|
||||
if( fCursor + numBytes > fBufferSize )
|
||||
{
|
||||
numBytes = fBufferSize - fCursor;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
memcpy( buffer, fBuffer + fCursor, numBytes );
|
||||
fCursor += numBytes;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
UInt32 plBufferedFileReader::NumBytesLeft( void )
|
||||
{
|
||||
hsAssert( IsValid(), "NumBytesLeft() called on an invalid RAM buffer" );
|
||||
|
||||
return fBufferSize - fCursor;
|
||||
}
|
||||
|
@ -1,66 +1,66 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plBufferedFileReader - Reads in a given file into a RAM buffer, then //
|
||||
// "reads" from that buffer as requested. Useless //
|
||||
// for normal sounds, but perfect for streaming //
|
||||
// from RAM. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plBufferedFileReader_h
|
||||
#define _plBufferedFileReader_h
|
||||
|
||||
#include "plAudioCore/plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plBufferedFileReader : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
plBufferedFileReader( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plBufferedFileReader();
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
virtual void Close( void );
|
||||
virtual UInt32 GetDataSize( void ) { return fBufferSize; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
virtual hsBool IsValid( void ) { return ( fBuffer != nil ) ? true : false; }
|
||||
|
||||
protected:
|
||||
UInt32 fBufferSize;
|
||||
UInt8 *fBuffer;
|
||||
plWAVHeader fHeader;
|
||||
UInt32 fCursor;
|
||||
void IError( const char *msg );
|
||||
};
|
||||
|
||||
#endif //_plBufferedFileReader_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plBufferedFileReader - Reads in a given file into a RAM buffer, then //
|
||||
// "reads" from that buffer as requested. Useless //
|
||||
// for normal sounds, but perfect for streaming //
|
||||
// from RAM. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plBufferedFileReader_h
|
||||
#define _plBufferedFileReader_h
|
||||
|
||||
#include "plAudioCore/plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plBufferedFileReader : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
plBufferedFileReader( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plBufferedFileReader();
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
virtual void Close( void );
|
||||
virtual UInt32 GetDataSize( void ) { return fBufferSize; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
virtual hsBool IsValid( void ) { return ( fBuffer != nil ) ? true : false; }
|
||||
|
||||
protected:
|
||||
UInt32 fBufferSize;
|
||||
UInt8 *fBuffer;
|
||||
plWAVHeader fHeader;
|
||||
UInt32 fCursor;
|
||||
void IError( const char *msg );
|
||||
};
|
||||
|
||||
#endif //_plBufferedFileReader_h
|
||||
|
@ -1,334 +1,334 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFastWavReader - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 11.5.2001 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plFastWavReader.h"
|
||||
|
||||
|
||||
//// Local Helpers ///////////////////////////////////////////////////////////
|
||||
|
||||
class plRIFFChunk
|
||||
{
|
||||
public:
|
||||
char fID[ 4 ];
|
||||
UInt32 fSize;
|
||||
|
||||
void Read( FILE *fp )
|
||||
{
|
||||
fread( fID, 1, 4, fp );
|
||||
fread( &fSize, sizeof( UInt32 ), 1, fp );
|
||||
}
|
||||
|
||||
bool IsA( const char *type )
|
||||
{
|
||||
return ( memcmp( fID, type, 4 ) == 0 ) ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
class plRIFFHeader
|
||||
{
|
||||
protected:
|
||||
plRIFFChunk fChunk;
|
||||
bool fValid;
|
||||
char fFormat[ 4 ];
|
||||
|
||||
public:
|
||||
plRIFFHeader( FILE *fp )
|
||||
{
|
||||
fValid = false;
|
||||
fChunk.Read( fp );
|
||||
if( fChunk.IsA( "RIFF" ) )
|
||||
{
|
||||
if( fread( &fFormat, 1, 4, fp ) == 4 )
|
||||
{
|
||||
fValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid( void )
|
||||
{
|
||||
return fValid;
|
||||
}
|
||||
|
||||
bool IsA( const char *type )
|
||||
{
|
||||
return ( memcmp( fFormat, type, 4 ) == 0 ) ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plFastWAV::plFastWAV( const char *path, plAudioCore::ChannelSelect whichChan ) : fFileHandle( nil )
|
||||
{
|
||||
hsAssert( path != nil, "Invalid path specified in plFastWAV reader" );
|
||||
|
||||
strncpy( fFilename, path, sizeof( fFilename ) );
|
||||
fWhichChannel = whichChan;
|
||||
|
||||
fFileHandle = fopen( path, "rb" );
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
/// Read in our header and calc our start position
|
||||
plRIFFHeader riffHdr( fFileHandle );
|
||||
|
||||
if( !riffHdr.IsValid() )
|
||||
{
|
||||
IError( "Invalid RIFF file header in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !riffHdr.IsA( "WAVE" ) )
|
||||
{
|
||||
IError( "Invalid RIFF file type in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
fChunkStart = ftell( fFileHandle );
|
||||
|
||||
// Seek and read the "fmt " header
|
||||
plRIFFChunk chunk;
|
||||
if( !ISeekToChunk( "fmt ", &chunk ) )
|
||||
{
|
||||
IError( "Unable to find fmt chunk in WAV file" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( fread( &fHeader, 1, sizeof( plWAVHeader ), fFileHandle ) != sizeof( plWAVHeader ) )
|
||||
{
|
||||
IError( "Invalid WAV file header in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check format
|
||||
if( fHeader.fFormatTag != kPCMFormatTag )
|
||||
{
|
||||
IError( "Invalid format in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Seek to and get the position of the data chunk
|
||||
if( !ISeekToChunk( "data", &chunk ) )
|
||||
{
|
||||
IError( "Unable to find data chunk in WAV file" );
|
||||
return;
|
||||
}
|
||||
fDataStartPos = ftell( fFileHandle );
|
||||
fDataSize = chunk.fSize;
|
||||
|
||||
// HACKY FIX FOR BAD WAV FILES
|
||||
fDataSize -= ( fDataSize & ( fHeader.fBlockAlign - 1 ) );
|
||||
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
fChannelAdjust = 2;
|
||||
fChannelOffset = ( fWhichChannel == plAudioCore::kLeft ) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fChannelAdjust = 1;
|
||||
fChannelOffset = 0;
|
||||
}
|
||||
|
||||
fFakeHeader = fHeader;
|
||||
fFakeHeader.fAvgBytesPerSec /= fChannelAdjust;
|
||||
fFakeHeader.fNumChannels /= (UInt16)fChannelAdjust;
|
||||
fFakeHeader.fBlockAlign /= (UInt16)fChannelAdjust;
|
||||
|
||||
SetPosition( 0 );
|
||||
// fCurrDataPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
plFastWAV::~plFastWAV()
|
||||
{
|
||||
if( fFileHandle != nil )
|
||||
fclose( fFileHandle );
|
||||
}
|
||||
|
||||
bool plFastWAV::ISeekToChunk( const char *type, plRIFFChunk *c )
|
||||
{
|
||||
plRIFFChunk chunk;
|
||||
|
||||
|
||||
// Start from chunk start and search through all the, well, chunks :)
|
||||
fseek( fFileHandle, fChunkStart, SEEK_SET );
|
||||
while( !feof( fFileHandle ) )
|
||||
{
|
||||
chunk.Read( fFileHandle );
|
||||
if( chunk.IsA( type ) )
|
||||
{
|
||||
*c = chunk;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Seek past this one
|
||||
fseek( fFileHandle, chunk.fSize, SEEK_CUR );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plFastWAV::Open()
|
||||
{
|
||||
if(fFileHandle)
|
||||
return;
|
||||
|
||||
fFileHandle = fopen( fFilename, "rb" );
|
||||
if(!fFileHandle)
|
||||
return;
|
||||
|
||||
fCurrDataPos = 0;
|
||||
|
||||
fseek( fFileHandle, fDataStartPos, SEEK_SET );
|
||||
}
|
||||
|
||||
void plFastWAV::Close( void )
|
||||
{
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
fclose( fFileHandle );
|
||||
fFileHandle = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plFastWAV::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plFastWAV::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
return fFakeHeader;
|
||||
}
|
||||
|
||||
float plFastWAV::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid WAV file" );
|
||||
|
||||
return (float)( fDataSize / fChannelAdjust ) / (float)fHeader.fAvgBytesPerSec;
|
||||
}
|
||||
|
||||
hsBool plFastWAV::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
|
||||
fCurrDataPos = numBytes * fChannelAdjust + ( fChannelOffset * fHeader.fBlockAlign / fChannelAdjust );
|
||||
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while seeking WAV file" );
|
||||
|
||||
return ( fseek( fFileHandle, fDataStartPos + fCurrDataPos, SEEK_SET ) == 0 ) ? true : false;
|
||||
}
|
||||
|
||||
hsBool plFastWAV::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
size_t numRead, sampleSize = fHeader.fBlockAlign / fChannelAdjust;
|
||||
static UInt8 trashBuffer[ 32 ];
|
||||
|
||||
UInt32 numBytesFull = numBytes;
|
||||
if( fCurrDataPos + ( numBytes * fChannelAdjust ) > fDataSize )
|
||||
numBytesFull -= sampleSize;
|
||||
|
||||
for( numRead = 0; numRead < numBytesFull; numRead += sampleSize )
|
||||
{
|
||||
size_t thisRead = fread( buffer, 1, sampleSize, fFileHandle );
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
// fseek( fFileHandle, sampleSize * ( fChannelAdjust - 1 ), SEEK_CUR );
|
||||
thisRead = fread( trashBuffer, 1, sampleSize, fFileHandle );
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
buffer = (void *)( (UInt8 *)buffer + sampleSize );
|
||||
fCurrDataPos += sampleSize * fChannelAdjust;
|
||||
}
|
||||
|
||||
if( numRead < numBytes )
|
||||
{
|
||||
if( numBytes - numRead > sampleSize )
|
||||
{
|
||||
hsAssert( false, "Invalid logic in plFastWAV::Read()" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Must not have enough room left, so no more skipping
|
||||
size_t thisRead = fread( buffer, 1, sampleSize, fFileHandle );
|
||||
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
buffer = (void *)( (UInt8 *)buffer + sampleSize );
|
||||
fCurrDataPos += sampleSize;
|
||||
}
|
||||
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while reading WAV file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t numRead = fread( buffer, 1, numBytes, fFileHandle );
|
||||
|
||||
fCurrDataPos += numRead;
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while reading WAV file" );
|
||||
|
||||
if( numRead < numBytes )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 plFastWAV::NumBytesLeft( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid current position while reading WAV file" );
|
||||
|
||||
return ( fDataSize - fCurrDataPos ) / fChannelAdjust;
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFastWavReader - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 11.5.2001 - Created by mcn. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plFastWavReader.h"
|
||||
|
||||
|
||||
//// Local Helpers ///////////////////////////////////////////////////////////
|
||||
|
||||
class plRIFFChunk
|
||||
{
|
||||
public:
|
||||
char fID[ 4 ];
|
||||
UInt32 fSize;
|
||||
|
||||
void Read( FILE *fp )
|
||||
{
|
||||
fread( fID, 1, 4, fp );
|
||||
fread( &fSize, sizeof( UInt32 ), 1, fp );
|
||||
}
|
||||
|
||||
bool IsA( const char *type )
|
||||
{
|
||||
return ( memcmp( fID, type, 4 ) == 0 ) ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
class plRIFFHeader
|
||||
{
|
||||
protected:
|
||||
plRIFFChunk fChunk;
|
||||
bool fValid;
|
||||
char fFormat[ 4 ];
|
||||
|
||||
public:
|
||||
plRIFFHeader( FILE *fp )
|
||||
{
|
||||
fValid = false;
|
||||
fChunk.Read( fp );
|
||||
if( fChunk.IsA( "RIFF" ) )
|
||||
{
|
||||
if( fread( &fFormat, 1, 4, fp ) == 4 )
|
||||
{
|
||||
fValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid( void )
|
||||
{
|
||||
return fValid;
|
||||
}
|
||||
|
||||
bool IsA( const char *type )
|
||||
{
|
||||
return ( memcmp( fFormat, type, 4 ) == 0 ) ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plFastWAV::plFastWAV( const char *path, plAudioCore::ChannelSelect whichChan ) : fFileHandle( nil )
|
||||
{
|
||||
hsAssert( path != nil, "Invalid path specified in plFastWAV reader" );
|
||||
|
||||
strncpy( fFilename, path, sizeof( fFilename ) );
|
||||
fWhichChannel = whichChan;
|
||||
|
||||
fFileHandle = fopen( path, "rb" );
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
/// Read in our header and calc our start position
|
||||
plRIFFHeader riffHdr( fFileHandle );
|
||||
|
||||
if( !riffHdr.IsValid() )
|
||||
{
|
||||
IError( "Invalid RIFF file header in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !riffHdr.IsA( "WAVE" ) )
|
||||
{
|
||||
IError( "Invalid RIFF file type in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
fChunkStart = ftell( fFileHandle );
|
||||
|
||||
// Seek and read the "fmt " header
|
||||
plRIFFChunk chunk;
|
||||
if( !ISeekToChunk( "fmt ", &chunk ) )
|
||||
{
|
||||
IError( "Unable to find fmt chunk in WAV file" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( fread( &fHeader, 1, sizeof( plWAVHeader ), fFileHandle ) != sizeof( plWAVHeader ) )
|
||||
{
|
||||
IError( "Invalid WAV file header in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check format
|
||||
if( fHeader.fFormatTag != kPCMFormatTag )
|
||||
{
|
||||
IError( "Invalid format in plFastWAV" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Seek to and get the position of the data chunk
|
||||
if( !ISeekToChunk( "data", &chunk ) )
|
||||
{
|
||||
IError( "Unable to find data chunk in WAV file" );
|
||||
return;
|
||||
}
|
||||
fDataStartPos = ftell( fFileHandle );
|
||||
fDataSize = chunk.fSize;
|
||||
|
||||
// HACKY FIX FOR BAD WAV FILES
|
||||
fDataSize -= ( fDataSize & ( fHeader.fBlockAlign - 1 ) );
|
||||
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
fChannelAdjust = 2;
|
||||
fChannelOffset = ( fWhichChannel == plAudioCore::kLeft ) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fChannelAdjust = 1;
|
||||
fChannelOffset = 0;
|
||||
}
|
||||
|
||||
fFakeHeader = fHeader;
|
||||
fFakeHeader.fAvgBytesPerSec /= fChannelAdjust;
|
||||
fFakeHeader.fNumChannels /= (UInt16)fChannelAdjust;
|
||||
fFakeHeader.fBlockAlign /= (UInt16)fChannelAdjust;
|
||||
|
||||
SetPosition( 0 );
|
||||
// fCurrDataPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
plFastWAV::~plFastWAV()
|
||||
{
|
||||
if( fFileHandle != nil )
|
||||
fclose( fFileHandle );
|
||||
}
|
||||
|
||||
bool plFastWAV::ISeekToChunk( const char *type, plRIFFChunk *c )
|
||||
{
|
||||
plRIFFChunk chunk;
|
||||
|
||||
|
||||
// Start from chunk start and search through all the, well, chunks :)
|
||||
fseek( fFileHandle, fChunkStart, SEEK_SET );
|
||||
while( !feof( fFileHandle ) )
|
||||
{
|
||||
chunk.Read( fFileHandle );
|
||||
if( chunk.IsA( type ) )
|
||||
{
|
||||
*c = chunk;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Seek past this one
|
||||
fseek( fFileHandle, chunk.fSize, SEEK_CUR );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plFastWAV::Open()
|
||||
{
|
||||
if(fFileHandle)
|
||||
return;
|
||||
|
||||
fFileHandle = fopen( fFilename, "rb" );
|
||||
if(!fFileHandle)
|
||||
return;
|
||||
|
||||
fCurrDataPos = 0;
|
||||
|
||||
fseek( fFileHandle, fDataStartPos, SEEK_SET );
|
||||
}
|
||||
|
||||
void plFastWAV::Close( void )
|
||||
{
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
fclose( fFileHandle );
|
||||
fFileHandle = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plFastWAV::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plFastWAV::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
return fFakeHeader;
|
||||
}
|
||||
|
||||
float plFastWAV::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid WAV file" );
|
||||
|
||||
return (float)( fDataSize / fChannelAdjust ) / (float)fHeader.fAvgBytesPerSec;
|
||||
}
|
||||
|
||||
hsBool plFastWAV::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
|
||||
fCurrDataPos = numBytes * fChannelAdjust + ( fChannelOffset * fHeader.fBlockAlign / fChannelAdjust );
|
||||
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while seeking WAV file" );
|
||||
|
||||
return ( fseek( fFileHandle, fDataStartPos + fCurrDataPos, SEEK_SET ) == 0 ) ? true : false;
|
||||
}
|
||||
|
||||
hsBool plFastWAV::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
|
||||
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
size_t numRead, sampleSize = fHeader.fBlockAlign / fChannelAdjust;
|
||||
static UInt8 trashBuffer[ 32 ];
|
||||
|
||||
UInt32 numBytesFull = numBytes;
|
||||
if( fCurrDataPos + ( numBytes * fChannelAdjust ) > fDataSize )
|
||||
numBytesFull -= sampleSize;
|
||||
|
||||
for( numRead = 0; numRead < numBytesFull; numRead += sampleSize )
|
||||
{
|
||||
size_t thisRead = fread( buffer, 1, sampleSize, fFileHandle );
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
// fseek( fFileHandle, sampleSize * ( fChannelAdjust - 1 ), SEEK_CUR );
|
||||
thisRead = fread( trashBuffer, 1, sampleSize, fFileHandle );
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
buffer = (void *)( (UInt8 *)buffer + sampleSize );
|
||||
fCurrDataPos += sampleSize * fChannelAdjust;
|
||||
}
|
||||
|
||||
if( numRead < numBytes )
|
||||
{
|
||||
if( numBytes - numRead > sampleSize )
|
||||
{
|
||||
hsAssert( false, "Invalid logic in plFastWAV::Read()" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Must not have enough room left, so no more skipping
|
||||
size_t thisRead = fread( buffer, 1, sampleSize, fFileHandle );
|
||||
|
||||
if( thisRead != sampleSize )
|
||||
return false;
|
||||
|
||||
buffer = (void *)( (UInt8 *)buffer + sampleSize );
|
||||
fCurrDataPos += sampleSize;
|
||||
}
|
||||
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while reading WAV file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t numRead = fread( buffer, 1, numBytes, fFileHandle );
|
||||
|
||||
fCurrDataPos += numRead;
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid new position while reading WAV file" );
|
||||
|
||||
if( numRead < numBytes )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 plFastWAV::NumBytesLeft( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid WAV file" );
|
||||
hsAssert( fCurrDataPos <= fDataSize, "Invalid current position while reading WAV file" );
|
||||
|
||||
return ( fDataSize - fCurrDataPos ) / fChannelAdjust;
|
||||
}
|
||||
|
@ -1,82 +1,82 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFastWavReader - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plFastWavReader_h
|
||||
#define _plFastWavReader_h
|
||||
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plRIFFChunk;
|
||||
|
||||
class plFastWAV : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
plFastWAV( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plFastWAV();
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
|
||||
virtual void Open();
|
||||
virtual void Close( void );
|
||||
|
||||
virtual UInt32 GetDataSize( void ) { return fDataSize / fChannelAdjust; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
|
||||
virtual hsBool IsValid( void ) { return ( fFileHandle != nil ) ? true : false; }
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
|
||||
char fFilename[ 512 ];
|
||||
FILE * fFileHandle;
|
||||
plWAVHeader fHeader, fFakeHeader;
|
||||
UInt32 fDataStartPos, fCurrDataPos, fDataSize;
|
||||
UInt32 fChunkStart;
|
||||
plAudioCore::ChannelSelect fWhichChannel;
|
||||
UInt32 fChannelAdjust, fChannelOffset;
|
||||
|
||||
void IError( const char *msg );
|
||||
bool ISeekToChunk( const char *type, plRIFFChunk *c );
|
||||
};
|
||||
|
||||
#endif //_plFastWavReader_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFastWavReader - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plFastWavReader_h
|
||||
#define _plFastWavReader_h
|
||||
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plRIFFChunk;
|
||||
|
||||
class plFastWAV : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
plFastWAV( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plFastWAV();
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
|
||||
virtual void Open();
|
||||
virtual void Close( void );
|
||||
|
||||
virtual UInt32 GetDataSize( void ) { return fDataSize / fChannelAdjust; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
|
||||
virtual hsBool IsValid( void ) { return ( fFileHandle != nil ) ? true : false; }
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
|
||||
char fFilename[ 512 ];
|
||||
FILE * fFileHandle;
|
||||
plWAVHeader fHeader, fFakeHeader;
|
||||
UInt32 fDataStartPos, fCurrDataPos, fDataSize;
|
||||
UInt32 fChunkStart;
|
||||
plAudioCore::ChannelSelect fWhichChannel;
|
||||
UInt32 fChannelAdjust, fChannelOffset;
|
||||
|
||||
void IError( const char *msg );
|
||||
bool ISeekToChunk( const char *type, plRIFFChunk *c );
|
||||
};
|
||||
|
||||
#endif //_plFastWavReader_h
|
||||
|
@ -1,342 +1,342 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plOGGCodec - Plasma codec support for the OGG/Vorbis file format. //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.7.2003 - Created by mcn. If only life were really this simple... //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plOGGCodec.h"
|
||||
|
||||
#include "hsTimer.h"
|
||||
#include "pnNetCommon/plNetApp.h"
|
||||
|
||||
plOGGCodec::DecodeFormat plOGGCodec::fDecodeFormat = plOGGCodec::k16bitSigned;
|
||||
UInt8 plOGGCodec::fDecodeFlags = 0;
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plOGGCodec::plOGGCodec( const char *path, plAudioCore::ChannelSelect whichChan ) : fFileHandle( nil )
|
||||
{
|
||||
fOggFile = nil;
|
||||
IOpen( path, whichChan );
|
||||
fCurHeaderPos = 0;
|
||||
fHeadBuf = nil;
|
||||
}
|
||||
|
||||
void plOGGCodec::BuildActualWaveHeader()
|
||||
{
|
||||
// Build an actual WAVE header for this ogg
|
||||
int fmtSize = 16;
|
||||
short fmt = 1;
|
||||
int factsize = 4;
|
||||
int factdata = 0;
|
||||
int size = fDataSize+48; // size of data with header except for first four bytes
|
||||
|
||||
fHeadBuf = (UInt8 *) ALLOC(56);
|
||||
memcpy(fHeadBuf, "RIFF", 4);
|
||||
memcpy(fHeadBuf+4, &size, 4);
|
||||
memcpy(fHeadBuf+8, "WAVE", 4);
|
||||
memcpy(fHeadBuf+12, "fmt ", 4);
|
||||
memcpy(fHeadBuf+16, &fmtSize, 4);
|
||||
memcpy(fHeadBuf+20, &fmt, 2); /* format */
|
||||
memcpy(fHeadBuf+22, &fHeader.fNumChannels, 2);
|
||||
memcpy(fHeadBuf+24, &fHeader.fNumSamplesPerSec, 4);
|
||||
memcpy(fHeadBuf+28, &fHeader.fAvgBytesPerSec, 4);
|
||||
memcpy(fHeadBuf+32, &fHeader.fBlockAlign, 4);
|
||||
memcpy(fHeadBuf+34, &fHeader.fBitsPerSample, 2);
|
||||
memcpy(fHeadBuf+36, "fact", 4);
|
||||
memcpy(fHeadBuf+40, &factsize, 4);
|
||||
memcpy(fHeadBuf+44, &factdata, 4);
|
||||
memcpy(fHeadBuf+48, "data", 4);
|
||||
memcpy(fHeadBuf+52, &fDataSize, 4);
|
||||
}
|
||||
|
||||
bool plOGGCodec::ReadFromHeader(int numBytes, void *data)
|
||||
{
|
||||
if(fCurHeaderPos < 56)
|
||||
{
|
||||
memcpy(data, fHeadBuf+fCurHeaderPos, numBytes);
|
||||
fCurHeaderPos += numBytes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void plOGGCodec::IOpen( const char *path, plAudioCore::ChannelSelect whichChan )
|
||||
{
|
||||
hsAssert( path != nil, "Invalid path specified in plOGGCodec reader" );
|
||||
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Open %s, t=%f, start", path, hsTimer::GetSeconds());
|
||||
|
||||
strncpy( fFilename, path, sizeof( fFilename ) );
|
||||
fWhichChannel = whichChan;
|
||||
|
||||
/// Open the file as a plain binary stream
|
||||
fFileHandle = fopen( path, "rb" );
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
/// Create the OGG data struct
|
||||
fOggFile = TRACKED_NEW OggVorbis_File;
|
||||
|
||||
/// Open the OGG decompressor
|
||||
if( ov_open( fFileHandle, fOggFile, NULL, 0 ) < 0 )
|
||||
{
|
||||
IError( "Unable to open OGG source file" );
|
||||
return;
|
||||
}
|
||||
|
||||
/// Construct some header info from the ogg info
|
||||
vorbis_info *vInfo = ov_info( fOggFile, -1 );
|
||||
|
||||
fHeader.fFormatTag = 1;
|
||||
fHeader.fNumChannels = vInfo->channels;
|
||||
fHeader.fNumSamplesPerSec = vInfo->rate;
|
||||
|
||||
// Funny thing about the bits per sample: we get to CHOOSE. Go figure!
|
||||
fHeader.fBitsPerSample = ( fDecodeFormat == k8bitUnsigned ) ? 8 : 16;
|
||||
|
||||
// Why WAV files hold this info when it can be calculated is beyond me...
|
||||
fHeader.fBlockAlign = ( fHeader.fBitsPerSample * fHeader.fNumChannels ) >> 3;
|
||||
fHeader.fAvgBytesPerSec = fHeader.fNumSamplesPerSec * fHeader.fBlockAlign;
|
||||
|
||||
|
||||
/// The size in bytes of our PCM data stream
|
||||
/// Note: OGG sometimes seems to be off by 1 sample, which causes our reads to suck
|
||||
/// because we end up waiting for 1 more sample than we actually have. So, on the
|
||||
/// assumption that OGG is just slightly wrong sometimes, we just subtract 1 sample
|
||||
/// from what it tells us. As Brice put it, who's going to miss 1/40,000'ths of a second?
|
||||
fDataSize = (UInt32)(( ov_pcm_total( fOggFile, -1 ) - 1 ) * fHeader.fBlockAlign);
|
||||
|
||||
/// Channel select
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
fChannelAdjust = 2;
|
||||
fChannelOffset = ( fWhichChannel == plAudioCore::kLeft ) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fChannelAdjust = 1;
|
||||
fChannelOffset = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Construct our fake header for channel adjustment
|
||||
fFakeHeader = fHeader;
|
||||
fFakeHeader.fAvgBytesPerSec /= fChannelAdjust;
|
||||
fFakeHeader.fNumChannels /= (UInt16)fChannelAdjust;
|
||||
fFakeHeader.fBlockAlign /= (UInt16)fChannelAdjust;
|
||||
|
||||
SetPosition( 0 );
|
||||
}
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Open %s, t=%f, end", path, hsTimer::GetSeconds());
|
||||
}
|
||||
|
||||
plOGGCodec::~plOGGCodec()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void plOGGCodec::Close( void )
|
||||
{
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Close, t=%f, start", hsTimer::GetSeconds());
|
||||
FREE(fHeadBuf);
|
||||
fHeadBuf = nil;
|
||||
if( fOggFile != nil )
|
||||
{
|
||||
ov_clear( fOggFile );
|
||||
DEL(fOggFile);
|
||||
fOggFile = nil;
|
||||
}
|
||||
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
fclose( fFileHandle );
|
||||
fFileHandle = nil;
|
||||
}
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Close, t=%f, end", hsTimer::GetSeconds());
|
||||
}
|
||||
|
||||
void plOGGCodec::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plOGGCodec::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
|
||||
return fFakeHeader;
|
||||
}
|
||||
|
||||
float plOGGCodec::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid OGG file" );
|
||||
|
||||
// Just query ogg directly...starting to see how cool ogg is yet?
|
||||
return (float)ov_time_total( fOggFile, -1 );
|
||||
}
|
||||
|
||||
hsBool plOGGCodec::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
|
||||
|
||||
if( !ov_seekable( fOggFile ) )
|
||||
{
|
||||
hsAssert( false, "Trying to set position on an unseekable OGG stream!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// The numBytes position is in uncompressed space and should be sample-aligned anyway,
|
||||
// so this should be just fine here.
|
||||
ogg_int64_t newSample = ( numBytes / (fFakeHeader.fBlockAlign * fChannelAdjust) );
|
||||
|
||||
// Now please note how freaking easy it is here to do accurate or fast seeking...
|
||||
// Also note that if we're doing our channel extraction, we MUST do it the accurate way
|
||||
if( ( fDecodeFlags & kFastSeeking ) && fChannelAdjust == 1 )
|
||||
{
|
||||
if( ov_pcm_seek_page( fOggFile, newSample ) != 0 )
|
||||
{
|
||||
IError( "Unable to seek OGG stream" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ov_pcm_seek( fOggFile, newSample ) != 0 )
|
||||
{
|
||||
IError( "Unable to seek OGG stream" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plOGGCodec::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Read, t=%f, start", hsTimer::GetSeconds());
|
||||
|
||||
int bytesPerSample = ( fDecodeFormat == k16bitSigned ) ? 2 : 1;
|
||||
int isSigned = ( fDecodeFormat == k16bitSigned ) ? 1 : 0;
|
||||
int currSection;
|
||||
|
||||
if( fWhichChannel == plAudioCore::kAll )
|
||||
{
|
||||
// Easy, just a straight read
|
||||
char *uBuffer = (char *)buffer;
|
||||
|
||||
while( numBytes > 0 )
|
||||
{
|
||||
// Supposedly we should pay attention to currSection in case of bitrate changes,
|
||||
// but hopefully we'll never have those....
|
||||
|
||||
long bytesRead = ov_read( fOggFile, uBuffer, numBytes, 0, bytesPerSample, isSigned, &currSection );
|
||||
|
||||
// Since our job is so simple, do some extra error checking
|
||||
if( bytesRead == OV_HOLE )
|
||||
{
|
||||
IError( "Unable to read from OGG file: missing data" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead == OV_EBADLINK )
|
||||
{
|
||||
IError( "Unable to read from OGG file: corrupt link" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead == 0 )
|
||||
{
|
||||
IError( "Unable to finish reading from OGG file: end of stream" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead < 0 )
|
||||
{
|
||||
IError( "Unable to read from OGG file: unknown error" );
|
||||
return false;
|
||||
}
|
||||
|
||||
numBytes -= bytesRead;
|
||||
uBuffer += bytesRead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Read in 4k chunks and extract
|
||||
static char trashBuffer[ 4096 ];
|
||||
|
||||
long toRead, i, thisRead, sampleSize = fFakeHeader.fBlockAlign;
|
||||
|
||||
for( ; numBytes > 0; )
|
||||
{
|
||||
/// Read 4k worth of samples
|
||||
toRead = ( sizeof( trashBuffer ) < numBytes * fChannelAdjust ) ? sizeof( trashBuffer ) : numBytes * fChannelAdjust;
|
||||
|
||||
|
||||
thisRead = ov_read( fOggFile, (char *)trashBuffer, toRead, 0, bytesPerSample, isSigned, &currSection );
|
||||
if( thisRead < 0 )
|
||||
return false;
|
||||
|
||||
/// Copy every other sample out
|
||||
int sampleOffset = (fChannelOffset == 1) ? sampleSize : 0;
|
||||
for (i = 0; i < thisRead; i += sampleSize * 2)
|
||||
{
|
||||
memcpy(buffer, &trashBuffer[i + sampleOffset], sampleSize);
|
||||
buffer = (void*)((UInt8*)buffer + sampleSize);
|
||||
|
||||
numBytes -= sampleSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Read, t=%f, end", hsTimer::GetSeconds());
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 plOGGCodec::NumBytesLeft( void )
|
||||
{
|
||||
if(!IsValid())
|
||||
{
|
||||
hsAssert( false, "GetHeader() called on an invalid OGG file" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (UInt32)(( fDataSize - ( ov_pcm_tell( fOggFile ) * fHeader.fBlockAlign ) ) / fChannelAdjust);
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plOGGCodec - Plasma codec support for the OGG/Vorbis file format. //
|
||||
// //
|
||||
//// Notes ///////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.7.2003 - Created by mcn. If only life were really this simple... //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plOGGCodec.h"
|
||||
|
||||
#include "hsTimer.h"
|
||||
#include "pnNetCommon/plNetApp.h"
|
||||
|
||||
plOGGCodec::DecodeFormat plOGGCodec::fDecodeFormat = plOGGCodec::k16bitSigned;
|
||||
UInt8 plOGGCodec::fDecodeFlags = 0;
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plOGGCodec::plOGGCodec( const char *path, plAudioCore::ChannelSelect whichChan ) : fFileHandle( nil )
|
||||
{
|
||||
fOggFile = nil;
|
||||
IOpen( path, whichChan );
|
||||
fCurHeaderPos = 0;
|
||||
fHeadBuf = nil;
|
||||
}
|
||||
|
||||
void plOGGCodec::BuildActualWaveHeader()
|
||||
{
|
||||
// Build an actual WAVE header for this ogg
|
||||
int fmtSize = 16;
|
||||
short fmt = 1;
|
||||
int factsize = 4;
|
||||
int factdata = 0;
|
||||
int size = fDataSize+48; // size of data with header except for first four bytes
|
||||
|
||||
fHeadBuf = (UInt8 *) ALLOC(56);
|
||||
memcpy(fHeadBuf, "RIFF", 4);
|
||||
memcpy(fHeadBuf+4, &size, 4);
|
||||
memcpy(fHeadBuf+8, "WAVE", 4);
|
||||
memcpy(fHeadBuf+12, "fmt ", 4);
|
||||
memcpy(fHeadBuf+16, &fmtSize, 4);
|
||||
memcpy(fHeadBuf+20, &fmt, 2); /* format */
|
||||
memcpy(fHeadBuf+22, &fHeader.fNumChannels, 2);
|
||||
memcpy(fHeadBuf+24, &fHeader.fNumSamplesPerSec, 4);
|
||||
memcpy(fHeadBuf+28, &fHeader.fAvgBytesPerSec, 4);
|
||||
memcpy(fHeadBuf+32, &fHeader.fBlockAlign, 4);
|
||||
memcpy(fHeadBuf+34, &fHeader.fBitsPerSample, 2);
|
||||
memcpy(fHeadBuf+36, "fact", 4);
|
||||
memcpy(fHeadBuf+40, &factsize, 4);
|
||||
memcpy(fHeadBuf+44, &factdata, 4);
|
||||
memcpy(fHeadBuf+48, "data", 4);
|
||||
memcpy(fHeadBuf+52, &fDataSize, 4);
|
||||
}
|
||||
|
||||
bool plOGGCodec::ReadFromHeader(int numBytes, void *data)
|
||||
{
|
||||
if(fCurHeaderPos < 56)
|
||||
{
|
||||
memcpy(data, fHeadBuf+fCurHeaderPos, numBytes);
|
||||
fCurHeaderPos += numBytes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void plOGGCodec::IOpen( const char *path, plAudioCore::ChannelSelect whichChan )
|
||||
{
|
||||
hsAssert( path != nil, "Invalid path specified in plOGGCodec reader" );
|
||||
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Open %s, t=%f, start", path, hsTimer::GetSeconds());
|
||||
|
||||
strncpy( fFilename, path, sizeof( fFilename ) );
|
||||
fWhichChannel = whichChan;
|
||||
|
||||
/// Open the file as a plain binary stream
|
||||
fFileHandle = fopen( path, "rb" );
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
/// Create the OGG data struct
|
||||
fOggFile = TRACKED_NEW OggVorbis_File;
|
||||
|
||||
/// Open the OGG decompressor
|
||||
if( ov_open( fFileHandle, fOggFile, NULL, 0 ) < 0 )
|
||||
{
|
||||
IError( "Unable to open OGG source file" );
|
||||
return;
|
||||
}
|
||||
|
||||
/// Construct some header info from the ogg info
|
||||
vorbis_info *vInfo = ov_info( fOggFile, -1 );
|
||||
|
||||
fHeader.fFormatTag = 1;
|
||||
fHeader.fNumChannels = vInfo->channels;
|
||||
fHeader.fNumSamplesPerSec = vInfo->rate;
|
||||
|
||||
// Funny thing about the bits per sample: we get to CHOOSE. Go figure!
|
||||
fHeader.fBitsPerSample = ( fDecodeFormat == k8bitUnsigned ) ? 8 : 16;
|
||||
|
||||
// Why WAV files hold this info when it can be calculated is beyond me...
|
||||
fHeader.fBlockAlign = ( fHeader.fBitsPerSample * fHeader.fNumChannels ) >> 3;
|
||||
fHeader.fAvgBytesPerSec = fHeader.fNumSamplesPerSec * fHeader.fBlockAlign;
|
||||
|
||||
|
||||
/// The size in bytes of our PCM data stream
|
||||
/// Note: OGG sometimes seems to be off by 1 sample, which causes our reads to suck
|
||||
/// because we end up waiting for 1 more sample than we actually have. So, on the
|
||||
/// assumption that OGG is just slightly wrong sometimes, we just subtract 1 sample
|
||||
/// from what it tells us. As Brice put it, who's going to miss 1/40,000'ths of a second?
|
||||
fDataSize = (UInt32)(( ov_pcm_total( fOggFile, -1 ) - 1 ) * fHeader.fBlockAlign);
|
||||
|
||||
/// Channel select
|
||||
if( fWhichChannel != plAudioCore::kAll )
|
||||
{
|
||||
fChannelAdjust = 2;
|
||||
fChannelOffset = ( fWhichChannel == plAudioCore::kLeft ) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fChannelAdjust = 1;
|
||||
fChannelOffset = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Construct our fake header for channel adjustment
|
||||
fFakeHeader = fHeader;
|
||||
fFakeHeader.fAvgBytesPerSec /= fChannelAdjust;
|
||||
fFakeHeader.fNumChannels /= (UInt16)fChannelAdjust;
|
||||
fFakeHeader.fBlockAlign /= (UInt16)fChannelAdjust;
|
||||
|
||||
SetPosition( 0 );
|
||||
}
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Open %s, t=%f, end", path, hsTimer::GetSeconds());
|
||||
}
|
||||
|
||||
plOGGCodec::~plOGGCodec()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void plOGGCodec::Close( void )
|
||||
{
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Close, t=%f, start", hsTimer::GetSeconds());
|
||||
FREE(fHeadBuf);
|
||||
fHeadBuf = nil;
|
||||
if( fOggFile != nil )
|
||||
{
|
||||
ov_clear( fOggFile );
|
||||
DEL(fOggFile);
|
||||
fOggFile = nil;
|
||||
}
|
||||
|
||||
if( fFileHandle != nil )
|
||||
{
|
||||
fclose( fFileHandle );
|
||||
fFileHandle = nil;
|
||||
}
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Close, t=%f, end", hsTimer::GetSeconds());
|
||||
}
|
||||
|
||||
void plOGGCodec::IError( const char *msg )
|
||||
{
|
||||
hsAssert( false, msg );
|
||||
Close();
|
||||
}
|
||||
|
||||
plWAVHeader &plOGGCodec::GetHeader( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
|
||||
return fFakeHeader;
|
||||
}
|
||||
|
||||
float plOGGCodec::GetLengthInSecs( void )
|
||||
{
|
||||
hsAssert( IsValid(), "GetLengthInSecs() called on an invalid OGG file" );
|
||||
|
||||
// Just query ogg directly...starting to see how cool ogg is yet?
|
||||
return (float)ov_time_total( fOggFile, -1 );
|
||||
}
|
||||
|
||||
hsBool plOGGCodec::SetPosition( UInt32 numBytes )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
|
||||
|
||||
if( !ov_seekable( fOggFile ) )
|
||||
{
|
||||
hsAssert( false, "Trying to set position on an unseekable OGG stream!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// The numBytes position is in uncompressed space and should be sample-aligned anyway,
|
||||
// so this should be just fine here.
|
||||
ogg_int64_t newSample = ( numBytes / (fFakeHeader.fBlockAlign * fChannelAdjust) );
|
||||
|
||||
// Now please note how freaking easy it is here to do accurate or fast seeking...
|
||||
// Also note that if we're doing our channel extraction, we MUST do it the accurate way
|
||||
if( ( fDecodeFlags & kFastSeeking ) && fChannelAdjust == 1 )
|
||||
{
|
||||
if( ov_pcm_seek_page( fOggFile, newSample ) != 0 )
|
||||
{
|
||||
IError( "Unable to seek OGG stream" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ov_pcm_seek( fOggFile, newSample ) != 0 )
|
||||
{
|
||||
IError( "Unable to seek OGG stream" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plOGGCodec::Read( UInt32 numBytes, void *buffer )
|
||||
{
|
||||
hsAssert( IsValid(), "GetHeader() called on an invalid OGG file" );
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Read, t=%f, start", hsTimer::GetSeconds());
|
||||
|
||||
int bytesPerSample = ( fDecodeFormat == k16bitSigned ) ? 2 : 1;
|
||||
int isSigned = ( fDecodeFormat == k16bitSigned ) ? 1 : 0;
|
||||
int currSection;
|
||||
|
||||
if( fWhichChannel == plAudioCore::kAll )
|
||||
{
|
||||
// Easy, just a straight read
|
||||
char *uBuffer = (char *)buffer;
|
||||
|
||||
while( numBytes > 0 )
|
||||
{
|
||||
// Supposedly we should pay attention to currSection in case of bitrate changes,
|
||||
// but hopefully we'll never have those....
|
||||
|
||||
long bytesRead = ov_read( fOggFile, uBuffer, numBytes, 0, bytesPerSample, isSigned, &currSection );
|
||||
|
||||
// Since our job is so simple, do some extra error checking
|
||||
if( bytesRead == OV_HOLE )
|
||||
{
|
||||
IError( "Unable to read from OGG file: missing data" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead == OV_EBADLINK )
|
||||
{
|
||||
IError( "Unable to read from OGG file: corrupt link" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead == 0 )
|
||||
{
|
||||
IError( "Unable to finish reading from OGG file: end of stream" );
|
||||
return false;
|
||||
}
|
||||
else if( bytesRead < 0 )
|
||||
{
|
||||
IError( "Unable to read from OGG file: unknown error" );
|
||||
return false;
|
||||
}
|
||||
|
||||
numBytes -= bytesRead;
|
||||
uBuffer += bytesRead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Read in 4k chunks and extract
|
||||
static char trashBuffer[ 4096 ];
|
||||
|
||||
long toRead, i, thisRead, sampleSize = fFakeHeader.fBlockAlign;
|
||||
|
||||
for( ; numBytes > 0; )
|
||||
{
|
||||
/// Read 4k worth of samples
|
||||
toRead = ( sizeof( trashBuffer ) < numBytes * fChannelAdjust ) ? sizeof( trashBuffer ) : numBytes * fChannelAdjust;
|
||||
|
||||
|
||||
thisRead = ov_read( fOggFile, (char *)trashBuffer, toRead, 0, bytesPerSample, isSigned, &currSection );
|
||||
if( thisRead < 0 )
|
||||
return false;
|
||||
|
||||
/// Copy every other sample out
|
||||
int sampleOffset = (fChannelOffset == 1) ? sampleSize : 0;
|
||||
for (i = 0; i < thisRead; i += sampleSize * 2)
|
||||
{
|
||||
memcpy(buffer, &trashBuffer[i + sampleOffset], sampleSize);
|
||||
buffer = (void*)((UInt8*)buffer + sampleSize);
|
||||
|
||||
numBytes -= sampleSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// plNetClientApp::StaticDebugMsg("Ogg Read, t=%f, end", hsTimer::GetSeconds());
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 plOGGCodec::NumBytesLeft( void )
|
||||
{
|
||||
if(!IsValid())
|
||||
{
|
||||
hsAssert( false, "GetHeader() called on an invalid OGG file" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (UInt32)(( fDataSize - ( ov_pcm_tell( fOggFile ) * fHeader.fBlockAlign ) ) / fChannelAdjust);
|
||||
}
|
||||
|
@ -1,106 +1,106 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plOGGCodec - Plasma codec support for the OGG/Vorbis file format. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plOGGCodec_h
|
||||
#define _plOGGCodec_h
|
||||
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
struct OggVorbis_File;
|
||||
|
||||
class plOGGCodec : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
|
||||
plOGGCodec( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plOGGCodec();
|
||||
|
||||
enum DecodeFormat
|
||||
{
|
||||
k8bitUnsigned,
|
||||
k16bitSigned
|
||||
};
|
||||
|
||||
enum DecodeFlags
|
||||
{
|
||||
kFastSeeking = 0x01
|
||||
};
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
|
||||
virtual void Close( void );
|
||||
|
||||
virtual UInt32 GetDataSize( void ) { return fDataSize / fChannelAdjust; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
|
||||
virtual hsBool IsValid( void ) { return ( fOggFile != nil ) ? true : false; }
|
||||
|
||||
static void SetDecodeFormat( DecodeFormat f ) { fDecodeFormat = f; }
|
||||
static void SetDecodeFlag( UInt8 flag, hsBool on ) { if( on ) fDecodeFlags |= flag; else fDecodeFlags &= ~flag; }
|
||||
static UInt8 GetDecodeFlags( void ) { return fDecodeFlags; }
|
||||
void ResetWaveHeaderRef() { fCurHeaderPos = 0; }
|
||||
void BuildActualWaveHeader();
|
||||
bool ReadFromHeader(int numBytes, void *data); // read from Actual wave header
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
|
||||
char fFilename[ 512 ];
|
||||
FILE *fFileHandle;
|
||||
OggVorbis_File *fOggFile;
|
||||
|
||||
plWAVHeader fHeader, fFakeHeader;
|
||||
UInt32 fDataStartPos, fCurrDataPos, fDataSize;
|
||||
|
||||
plAudioCore::ChannelSelect fWhichChannel;
|
||||
UInt32 fChannelAdjust, fChannelOffset;
|
||||
|
||||
static DecodeFormat fDecodeFormat;
|
||||
static UInt8 fDecodeFlags;
|
||||
UInt8 * fHeadBuf;
|
||||
int fCurHeaderPos;
|
||||
|
||||
void IError( const char *msg );
|
||||
void IOpen( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
};
|
||||
|
||||
#endif //_plOGGCodec_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plOGGCodec - Plasma codec support for the OGG/Vorbis file format. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plOGGCodec_h
|
||||
#define _plOGGCodec_h
|
||||
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
struct OggVorbis_File;
|
||||
|
||||
class plOGGCodec : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
|
||||
plOGGCodec( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
virtual ~plOGGCodec();
|
||||
|
||||
enum DecodeFormat
|
||||
{
|
||||
k8bitUnsigned,
|
||||
k16bitSigned
|
||||
};
|
||||
|
||||
enum DecodeFlags
|
||||
{
|
||||
kFastSeeking = 0x01
|
||||
};
|
||||
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
|
||||
virtual void Close( void );
|
||||
|
||||
virtual UInt32 GetDataSize( void ) { return fDataSize / fChannelAdjust; }
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
|
||||
virtual hsBool IsValid( void ) { return ( fOggFile != nil ) ? true : false; }
|
||||
|
||||
static void SetDecodeFormat( DecodeFormat f ) { fDecodeFormat = f; }
|
||||
static void SetDecodeFlag( UInt8 flag, hsBool on ) { if( on ) fDecodeFlags |= flag; else fDecodeFlags &= ~flag; }
|
||||
static UInt8 GetDecodeFlags( void ) { return fDecodeFlags; }
|
||||
void ResetWaveHeaderRef() { fCurHeaderPos = 0; }
|
||||
void BuildActualWaveHeader();
|
||||
bool ReadFromHeader(int numBytes, void *data); // read from Actual wave header
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
kPCMFormatTag = 1
|
||||
};
|
||||
|
||||
char fFilename[ 512 ];
|
||||
FILE *fFileHandle;
|
||||
OggVorbis_File *fOggFile;
|
||||
|
||||
plWAVHeader fHeader, fFakeHeader;
|
||||
UInt32 fDataStartPos, fCurrDataPos, fDataSize;
|
||||
|
||||
plAudioCore::ChannelSelect fWhichChannel;
|
||||
UInt32 fChannelAdjust, fChannelOffset;
|
||||
|
||||
static DecodeFormat fDecodeFormat;
|
||||
static UInt8 fDecodeFlags;
|
||||
UInt8 * fHeadBuf;
|
||||
int fCurHeaderPos;
|
||||
|
||||
void IError( const char *msg );
|
||||
void IOpen( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
|
||||
};
|
||||
|
||||
#endif //_plOGGCodec_h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,146 +1,146 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundBuffer - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
// Now loads data asynchronously. When fLoading is true //
|
||||
// do not touch any data in the soundbuffer //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plSoundBuffer_h
|
||||
#define _plSoundBuffer_h
|
||||
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
#include "plAudioCore.h"
|
||||
#include "plAudioFileReader.h"
|
||||
#include "pnUtils/pnUtils.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plUnifiedTime;
|
||||
class plAudioFileReader;
|
||||
class plSoundBuffer : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
plSoundBuffer();
|
||||
plSoundBuffer( const char *fileName, UInt32 flags = 0 );
|
||||
~plSoundBuffer();
|
||||
|
||||
CLASSNAME_REGISTER( plSoundBuffer );
|
||||
GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject );
|
||||
|
||||
LINK(plSoundBuffer) link;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
kIsExternal = 0x0001,
|
||||
kAlwaysExternal = 0x0002,
|
||||
kOnlyLeftChannel = 0x0004,
|
||||
kOnlyRightChannel = 0x0008,
|
||||
kStreamCompressed = 0x0010,
|
||||
};
|
||||
|
||||
enum ELoadReturnVal
|
||||
{
|
||||
kSuccess,
|
||||
kError,
|
||||
kPending,
|
||||
};
|
||||
|
||||
void RoundDataPos( UInt32 &pos );
|
||||
|
||||
virtual void Read( hsStream *s, hsResMgr *mgr );
|
||||
virtual void Write( hsStream *s, hsResMgr *mgr );
|
||||
|
||||
plWAVHeader &GetHeader( void ) { return fHeader; }
|
||||
UInt32 GetDataLength( void ) const { return fDataLength; }
|
||||
void SetDataLength(unsigned length) { fDataLength = length; }
|
||||
void *GetData( void ) const { return fData; }
|
||||
const char *GetFileName( void ) const { return fFileName; }
|
||||
hsBool IsValid( void ) const { return fValid; }
|
||||
hsScalar GetDataLengthInSecs( void ) const;
|
||||
|
||||
void SetFileName( const char *name );
|
||||
hsBool HasFlag( UInt32 flag ) { return ( fFlags & flag ) ? true : false; }
|
||||
void SetFlag( UInt32 flag, hsBool yes = true ) { if( yes ) fFlags |= flag; else fFlags &= ~flag; }
|
||||
|
||||
// Must be called until return value is kSuccess. starts an asynchronous load first time called. returns kSuccess when finished.
|
||||
ELoadReturnVal AsyncLoad( plAudioFileReader::StreamType type, unsigned length = 0 );
|
||||
void UnLoad( );
|
||||
|
||||
plAudioCore::ChannelSelect GetReaderSelect( void ) const;
|
||||
|
||||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
plAudioFileReader * GetAudioReader(); // transfers ownership to caller
|
||||
void SetAudioReader(plAudioFileReader *reader);
|
||||
void SetLoaded(bool loaded);
|
||||
|
||||
plAudioFileReader::StreamType GetAudioReaderType() { return fStreamType; }
|
||||
unsigned GetAsyncLoadLength() { return fAsyncLoadLength ? fAsyncLoadLength : fDataLength; }
|
||||
|
||||
// for plugins only
|
||||
void SetInternalData( plWAVHeader &header, UInt32 length, UInt8 *data );
|
||||
ELoadReturnVal EnsureInternal( );
|
||||
void SetError() { fError = true; }
|
||||
|
||||
protected:
|
||||
|
||||
// plSoundBuffers can be two ways--they can either have a filename and no
|
||||
// data, in which case they reference a file in the sfx folder, or they
|
||||
// can store the data directly
|
||||
|
||||
void IInitBuffer();
|
||||
|
||||
hsBool IGrabHeaderInfo( void );
|
||||
void IAddBuffers( void *base, void *toAdd, UInt32 lengthInBytes, UInt8 bitsPerSample );
|
||||
void IGetFullPath( char *destStr );
|
||||
|
||||
UInt32 fFlags;
|
||||
hsBool fValid;
|
||||
UInt32 fDataRead;
|
||||
char *fFileName;
|
||||
|
||||
bool fLoaded;
|
||||
bool fLoading;
|
||||
bool fError;
|
||||
|
||||
plAudioFileReader * fReader;
|
||||
UInt8 * fData;
|
||||
plWAVHeader fHeader;
|
||||
UInt32 fDataLength;
|
||||
UInt32 fAsyncLoadLength;
|
||||
plAudioFileReader::StreamType fStreamType;
|
||||
|
||||
// for plugins only
|
||||
plAudioFileReader *IGetReader( hsBool fullpath );
|
||||
};
|
||||
|
||||
#endif //_plSoundBuffer_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundBuffer - Quick, dirty, and highly optimized class for reading //
|
||||
// in the samples of a WAV file when you're in a hurry. //
|
||||
// ONLY WORKS WITH PCM (i.e. uncompressed) DATA //
|
||||
// //
|
||||
// Now loads data asynchronously. When fLoading is true //
|
||||
// do not touch any data in the soundbuffer //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plSoundBuffer_h
|
||||
#define _plSoundBuffer_h
|
||||
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
#include "plAudioCore.h"
|
||||
#include "plAudioFileReader.h"
|
||||
#include "pnUtils/pnUtils.h"
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plUnifiedTime;
|
||||
class plAudioFileReader;
|
||||
class plSoundBuffer : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
plSoundBuffer();
|
||||
plSoundBuffer( const char *fileName, UInt32 flags = 0 );
|
||||
~plSoundBuffer();
|
||||
|
||||
CLASSNAME_REGISTER( plSoundBuffer );
|
||||
GETINTERFACE_ANY( plSoundBuffer, hsKeyedObject );
|
||||
|
||||
LINK(plSoundBuffer) link;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
kIsExternal = 0x0001,
|
||||
kAlwaysExternal = 0x0002,
|
||||
kOnlyLeftChannel = 0x0004,
|
||||
kOnlyRightChannel = 0x0008,
|
||||
kStreamCompressed = 0x0010,
|
||||
};
|
||||
|
||||
enum ELoadReturnVal
|
||||
{
|
||||
kSuccess,
|
||||
kError,
|
||||
kPending,
|
||||
};
|
||||
|
||||
void RoundDataPos( UInt32 &pos );
|
||||
|
||||
virtual void Read( hsStream *s, hsResMgr *mgr );
|
||||
virtual void Write( hsStream *s, hsResMgr *mgr );
|
||||
|
||||
plWAVHeader &GetHeader( void ) { return fHeader; }
|
||||
UInt32 GetDataLength( void ) const { return fDataLength; }
|
||||
void SetDataLength(unsigned length) { fDataLength = length; }
|
||||
void *GetData( void ) const { return fData; }
|
||||
const char *GetFileName( void ) const { return fFileName; }
|
||||
hsBool IsValid( void ) const { return fValid; }
|
||||
hsScalar GetDataLengthInSecs( void ) const;
|
||||
|
||||
void SetFileName( const char *name );
|
||||
hsBool HasFlag( UInt32 flag ) { return ( fFlags & flag ) ? true : false; }
|
||||
void SetFlag( UInt32 flag, hsBool yes = true ) { if( yes ) fFlags |= flag; else fFlags &= ~flag; }
|
||||
|
||||
// Must be called until return value is kSuccess. starts an asynchronous load first time called. returns kSuccess when finished.
|
||||
ELoadReturnVal AsyncLoad( plAudioFileReader::StreamType type, unsigned length = 0 );
|
||||
void UnLoad( );
|
||||
|
||||
plAudioCore::ChannelSelect GetReaderSelect( void ) const;
|
||||
|
||||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
plAudioFileReader * GetAudioReader(); // transfers ownership to caller
|
||||
void SetAudioReader(plAudioFileReader *reader);
|
||||
void SetLoaded(bool loaded);
|
||||
|
||||
plAudioFileReader::StreamType GetAudioReaderType() { return fStreamType; }
|
||||
unsigned GetAsyncLoadLength() { return fAsyncLoadLength ? fAsyncLoadLength : fDataLength; }
|
||||
|
||||
// for plugins only
|
||||
void SetInternalData( plWAVHeader &header, UInt32 length, UInt8 *data );
|
||||
ELoadReturnVal EnsureInternal( );
|
||||
void SetError() { fError = true; }
|
||||
|
||||
protected:
|
||||
|
||||
// plSoundBuffers can be two ways--they can either have a filename and no
|
||||
// data, in which case they reference a file in the sfx folder, or they
|
||||
// can store the data directly
|
||||
|
||||
void IInitBuffer();
|
||||
|
||||
hsBool IGrabHeaderInfo( void );
|
||||
void IAddBuffers( void *base, void *toAdd, UInt32 lengthInBytes, UInt8 bitsPerSample );
|
||||
void IGetFullPath( char *destStr );
|
||||
|
||||
UInt32 fFlags;
|
||||
hsBool fValid;
|
||||
UInt32 fDataRead;
|
||||
char *fFileName;
|
||||
|
||||
bool fLoaded;
|
||||
bool fLoading;
|
||||
bool fError;
|
||||
|
||||
plAudioFileReader * fReader;
|
||||
UInt8 * fData;
|
||||
plWAVHeader fHeader;
|
||||
UInt32 fDataLength;
|
||||
UInt32 fAsyncLoadLength;
|
||||
plAudioFileReader::StreamType fStreamType;
|
||||
|
||||
// for plugins only
|
||||
plAudioFileReader *IGetReader( hsBool fullpath );
|
||||
};
|
||||
|
||||
#endif //_plSoundBuffer_h
|
||||
|
@ -1,81 +1,81 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundDeswizzler - Quick helper class to extract a single channel of //
|
||||
// data from stereo (or more)-channel data. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plSoundDeswizzler.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
plSoundDeswizzler::plSoundDeswizzler( void *srcPtr, UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize )
|
||||
{
|
||||
fNumSamples = srcLength / sampleSize;
|
||||
fSampleSize = sampleSize;
|
||||
fStride = fSampleSize * numChannels;
|
||||
fData = (UInt8 *)srcPtr;
|
||||
fOwnsData = false;
|
||||
}
|
||||
|
||||
plSoundDeswizzler::plSoundDeswizzler( UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize )
|
||||
{
|
||||
fNumSamples = srcLength / sampleSize;
|
||||
fSampleSize = sampleSize;
|
||||
fStride = fSampleSize * numChannels;
|
||||
fData = TRACKED_NEW UInt8[ srcLength ];
|
||||
fOwnsData = true;
|
||||
}
|
||||
|
||||
plSoundDeswizzler::~plSoundDeswizzler()
|
||||
{
|
||||
if( fOwnsData )
|
||||
delete [] fData;
|
||||
}
|
||||
|
||||
void plSoundDeswizzler::Extract( UInt8 channelSelect, void *dest, UInt32 numBytesToProcess )
|
||||
{
|
||||
UInt8 *srcPtr = fData + channelSelect * fSampleSize;
|
||||
UInt8 *destPtr = (UInt8 *)dest;
|
||||
UInt32 i;
|
||||
|
||||
|
||||
if( numBytesToProcess == 0 )
|
||||
numBytesToProcess = fNumSamples;
|
||||
else
|
||||
numBytesToProcess /= fStride;
|
||||
|
||||
// Extract!
|
||||
for( i = 0; i < numBytesToProcess; i++ )
|
||||
{
|
||||
memcpy( destPtr, srcPtr, fSampleSize );
|
||||
destPtr += fSampleSize;
|
||||
srcPtr += fStride;
|
||||
}
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundDeswizzler - Quick helper class to extract a single channel of //
|
||||
// data from stereo (or more)-channel data. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plSoundDeswizzler.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
plSoundDeswizzler::plSoundDeswizzler( void *srcPtr, UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize )
|
||||
{
|
||||
fNumSamples = srcLength / sampleSize;
|
||||
fSampleSize = sampleSize;
|
||||
fStride = fSampleSize * numChannels;
|
||||
fData = (UInt8 *)srcPtr;
|
||||
fOwnsData = false;
|
||||
}
|
||||
|
||||
plSoundDeswizzler::plSoundDeswizzler( UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize )
|
||||
{
|
||||
fNumSamples = srcLength / sampleSize;
|
||||
fSampleSize = sampleSize;
|
||||
fStride = fSampleSize * numChannels;
|
||||
fData = TRACKED_NEW UInt8[ srcLength ];
|
||||
fOwnsData = true;
|
||||
}
|
||||
|
||||
plSoundDeswizzler::~plSoundDeswizzler()
|
||||
{
|
||||
if( fOwnsData )
|
||||
delete [] fData;
|
||||
}
|
||||
|
||||
void plSoundDeswizzler::Extract( UInt8 channelSelect, void *dest, UInt32 numBytesToProcess )
|
||||
{
|
||||
UInt8 *srcPtr = fData + channelSelect * fSampleSize;
|
||||
UInt8 *destPtr = (UInt8 *)dest;
|
||||
UInt32 i;
|
||||
|
||||
|
||||
if( numBytesToProcess == 0 )
|
||||
numBytesToProcess = fNumSamples;
|
||||
else
|
||||
numBytesToProcess /= fStride;
|
||||
|
||||
// Extract!
|
||||
for( i = 0; i < numBytesToProcess; i++ )
|
||||
{
|
||||
memcpy( destPtr, srcPtr, fSampleSize );
|
||||
destPtr += fSampleSize;
|
||||
srcPtr += fStride;
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundDeswizzler - Quick helper class to extract a single channel of //
|
||||
// data from stereo (or more)-channel data. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plSoundDeswizzler_h
|
||||
#define _plSoundDeswizzler_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plSoundDeswizzler
|
||||
{
|
||||
public:
|
||||
plSoundDeswizzler( void *srcPtr, UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize );
|
||||
plSoundDeswizzler( UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize );
|
||||
~plSoundDeswizzler();
|
||||
|
||||
void *GetSourceBuffer( void ) const { return fData; }
|
||||
void Extract( UInt8 channelSelect, void *destPtr, UInt32 numBytesToProcess = 0 );
|
||||
|
||||
protected:
|
||||
UInt8 *fData;
|
||||
UInt32 fNumSamples, fSampleSize, fStride;
|
||||
hsBool fOwnsData;
|
||||
};
|
||||
|
||||
#endif //_plSoundDeswizzler_h
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plSoundDeswizzler - Quick helper class to extract a single channel of //
|
||||
// data from stereo (or more)-channel data. //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plSoundDeswizzler_h
|
||||
#define _plSoundDeswizzler_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plSoundDeswizzler
|
||||
{
|
||||
public:
|
||||
plSoundDeswizzler( void *srcPtr, UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize );
|
||||
plSoundDeswizzler( UInt32 srcLength, UInt8 numChannels, UInt32 sampleSize );
|
||||
~plSoundDeswizzler();
|
||||
|
||||
void *GetSourceBuffer( void ) const { return fData; }
|
||||
void Extract( UInt8 channelSelect, void *destPtr, UInt32 numBytesToProcess = 0 );
|
||||
|
||||
protected:
|
||||
UInt8 *fData;
|
||||
UInt32 fNumSamples, fSampleSize, fStride;
|
||||
hsBool fOwnsData;
|
||||
};
|
||||
|
||||
#endif //_plSoundDeswizzler_h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +1,114 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plWavFile_H
|
||||
#define plWavFile_H
|
||||
|
||||
#define WAVEFILE_READ 1
|
||||
#define WAVEFILE_WRITE 2
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsWindows.h"
|
||||
#include "hsStlUtils.h"
|
||||
#include <mmsystem.h>
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
struct plSoundMarker
|
||||
{
|
||||
char *fName;
|
||||
double fOffset; // in Secs
|
||||
|
||||
plSoundMarker () { fName = NULL;fOffset = 0.0; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CWaveFile
|
||||
// Desc: Encapsulates reading or writing sound data to or from a wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class CWaveFile : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
CWaveFile();
|
||||
~CWaveFile();
|
||||
|
||||
HRESULT Open(const char *strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
|
||||
HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
|
||||
HRESULT AdvanceWithoutRead( DWORD dwSizeToRead, DWORD* pdwSizeRead );
|
||||
HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );
|
||||
|
||||
DWORD GetSize();
|
||||
HRESULT ResetFile();
|
||||
WAVEFORMATEX* GetFormat() { return m_pwfx; };
|
||||
|
||||
DWORD GetNumMarkers() { return fMarkers.size() ; };
|
||||
plSoundMarker *GetSoundMarker(int i) { return fMarkers[i]; }
|
||||
|
||||
|
||||
// Overloads for plAudioFileReader
|
||||
CWaveFile( const char *path, plAudioCore::ChannelSelect whichChan );
|
||||
virtual hsBool OpenForWriting( const char *path, plWAVHeader &header );
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
virtual void Close( void );
|
||||
virtual UInt32 GetDataSize( void );
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
virtual UInt32 Write( UInt32 bytes, void *buffer );
|
||||
|
||||
virtual hsBool IsValid( void );
|
||||
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
|
||||
HMMIO m_hmmio; // MM I/O handle for the WAVE
|
||||
MMCKINFO m_ck; // Multimedia RIFF chunk
|
||||
MMCKINFO m_ckRiff; // Use in opening a WAVE file
|
||||
DWORD m_dwSize; // The size of the wave file
|
||||
MMIOINFO m_mmioinfoOut;
|
||||
DWORD m_dwFlags;
|
||||
BOOL m_bIsReadingFromMemory;
|
||||
BYTE* m_pbData;
|
||||
BYTE* m_pbDataCur;
|
||||
ULONG m_ulDataSize;
|
||||
|
||||
plWAVHeader fHeader;
|
||||
|
||||
std::vector<plSoundMarker*> fMarkers;
|
||||
double fSecsPerSample;
|
||||
|
||||
protected:
|
||||
HRESULT ReadMMIO();
|
||||
HRESULT WriteMMIO( WAVEFORMATEX *pwfxDest );
|
||||
HRESULT IClose();
|
||||
};
|
||||
|
||||
#endif // plWavFile_H
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plWavFile_H
|
||||
#define plWavFile_H
|
||||
|
||||
#define WAVEFILE_READ 1
|
||||
#define WAVEFILE_WRITE 2
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsWindows.h"
|
||||
#include "hsStlUtils.h"
|
||||
#include <mmsystem.h>
|
||||
#include "plAudioFileReader.h"
|
||||
|
||||
|
||||
struct plSoundMarker
|
||||
{
|
||||
char *fName;
|
||||
double fOffset; // in Secs
|
||||
|
||||
plSoundMarker () { fName = NULL;fOffset = 0.0; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CWaveFile
|
||||
// Desc: Encapsulates reading or writing sound data to or from a wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class CWaveFile : public plAudioFileReader
|
||||
{
|
||||
public:
|
||||
CWaveFile();
|
||||
~CWaveFile();
|
||||
|
||||
HRESULT Open(const char *strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags );
|
||||
|
||||
HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
|
||||
HRESULT AdvanceWithoutRead( DWORD dwSizeToRead, DWORD* pdwSizeRead );
|
||||
HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );
|
||||
|
||||
DWORD GetSize();
|
||||
HRESULT ResetFile();
|
||||
WAVEFORMATEX* GetFormat() { return m_pwfx; };
|
||||
|
||||
DWORD GetNumMarkers() { return fMarkers.size() ; };
|
||||
plSoundMarker *GetSoundMarker(int i) { return fMarkers[i]; }
|
||||
|
||||
|
||||
// Overloads for plAudioFileReader
|
||||
CWaveFile( const char *path, plAudioCore::ChannelSelect whichChan );
|
||||
virtual hsBool OpenForWriting( const char *path, plWAVHeader &header );
|
||||
virtual plWAVHeader &GetHeader( void );
|
||||
virtual void Close( void );
|
||||
virtual UInt32 GetDataSize( void );
|
||||
virtual float GetLengthInSecs( void );
|
||||
|
||||
virtual hsBool SetPosition( UInt32 numBytes );
|
||||
virtual hsBool Read( UInt32 numBytes, void *buffer );
|
||||
virtual UInt32 NumBytesLeft( void );
|
||||
virtual UInt32 Write( UInt32 bytes, void *buffer );
|
||||
|
||||
virtual hsBool IsValid( void );
|
||||
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
|
||||
HMMIO m_hmmio; // MM I/O handle for the WAVE
|
||||
MMCKINFO m_ck; // Multimedia RIFF chunk
|
||||
MMCKINFO m_ckRiff; // Use in opening a WAVE file
|
||||
DWORD m_dwSize; // The size of the wave file
|
||||
MMIOINFO m_mmioinfoOut;
|
||||
DWORD m_dwFlags;
|
||||
BOOL m_bIsReadingFromMemory;
|
||||
BYTE* m_pbData;
|
||||
BYTE* m_pbDataCur;
|
||||
ULONG m_ulDataSize;
|
||||
|
||||
plWAVHeader fHeader;
|
||||
|
||||
std::vector<plSoundMarker*> fMarkers;
|
||||
double fSecsPerSample;
|
||||
|
||||
protected:
|
||||
HRESULT ReadMMIO();
|
||||
HRESULT WriteMMIO( WAVEFORMATEX *pwfxDest );
|
||||
HRESULT IClose();
|
||||
};
|
||||
|
||||
#endif // plWavFile_H
|
||||
|
Reference in New Issue
Block a user