mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
CWE Directory Reorganization
Rearrange directory structure of CWE to be loosely equivalent to the H'uru Plasma repository. Part 1: Movement of directories and files.
This commit is contained in:
84
Sources/Plasma/PubUtilLib/plAudioCore/plAudioCore.h
Normal file
84
Sources/Plasma/PubUtilLib/plAudioCore/plAudioCore.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
52
Sources/Plasma/PubUtilLib/plAudioCore/plAudioCoreCreatable.h
Normal file
52
Sources/Plasma/PubUtilLib/plAudioCore/plAudioCoreCreatable.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
185
Sources/Plasma/PubUtilLib/plAudioCore/plAudioFileReader.cpp
Normal file
185
Sources/Plasma/PubUtilLib/plAudioCore/plAudioFileReader.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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 "../plAudio/plOGGCodec.h"
|
||||
#include "../plAudio/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);
|
||||
}
|
||||
}
|
99
Sources/Plasma/PubUtilLib/plAudioCore/plAudioFileReader.h
Normal file
99
Sources/Plasma/PubUtilLib/plAudioCore/plAudioFileReader.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
182
Sources/Plasma/PubUtilLib/plAudioCore/plBufferedFileReader.cpp
Normal file
182
Sources/Plasma/PubUtilLib/plAudioCore/plBufferedFileReader.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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;
|
||||
}
|
82
Sources/Plasma/PubUtilLib/plAudioCore/plBufferedFileReader.h
Normal file
82
Sources/Plasma/PubUtilLib/plAudioCore/plBufferedFileReader.h
Normal file
@ -0,0 +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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
350
Sources/Plasma/PubUtilLib/plAudioCore/plFastWavReader.cpp
Normal file
350
Sources/Plasma/PubUtilLib/plAudioCore/plFastWavReader.cpp
Normal file
@ -0,0 +1,350 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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;
|
||||
}
|
98
Sources/Plasma/PubUtilLib/plAudioCore/plFastWavReader.h
Normal file
98
Sources/Plasma/PubUtilLib/plAudioCore/plFastWavReader.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
581
Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp
Normal file
581
Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp
Normal file
@ -0,0 +1,581 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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==*/
|
||||
#include <process.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plSoundBuffer.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "../plFile/plFileUtils.h"
|
||||
#include "../plFile/hsFiles.h"
|
||||
#include "../plUnifiedTime/plUnifiedTime.h"
|
||||
#include "../pnUtils/pnUtils.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
#include "hsTimer.h"
|
||||
|
||||
static bool s_running;
|
||||
static LISTDECL(plSoundBuffer, link) s_loading;
|
||||
static CCritSect s_critsect;
|
||||
static CEvent s_event(kEventAutoReset);
|
||||
|
||||
static void GetFullPath( const char filename[], char *destStr )
|
||||
{
|
||||
char path[ kFolderIterator_MaxPath ];
|
||||
|
||||
if( strchr( filename, '\\' ) != nil )
|
||||
strcpy( path, filename );
|
||||
else
|
||||
sprintf( path, "sfx\\%s", filename );
|
||||
|
||||
strcpy( destStr, path );
|
||||
}
|
||||
|
||||
//// IGetReader //////////////////////////////////////////////////////////////
|
||||
// Makes sure the sound is ready to load without any extra processing (like
|
||||
// decompression or the like), then opens a reader for it.
|
||||
// fullpath tells the function whether to append 'sfx' to the path or not (we don't want to do this if were providing the full path)
|
||||
static plAudioFileReader *CreateReader( hsBool fullpath, const char filename[], plAudioFileReader::StreamType type, plAudioCore::ChannelSelect channel )
|
||||
{
|
||||
char path[512];
|
||||
if(fullpath) GetFullPath(filename, path);
|
||||
else
|
||||
strcpy(path, filename);
|
||||
|
||||
plAudioFileReader* reader = plAudioFileReader::CreateReader(path, channel, type);
|
||||
|
||||
if( reader == nil || !reader->IsValid() )
|
||||
{
|
||||
delete reader;
|
||||
return nil;
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
// our loading thread
|
||||
static void LoadCallback(void *)
|
||||
{
|
||||
LISTDECL(plSoundBuffer, link) templist;
|
||||
while(s_running)
|
||||
{
|
||||
s_critsect.Enter();
|
||||
{
|
||||
while(plSoundBuffer *buffer = s_loading.Head())
|
||||
{
|
||||
templist.Link(buffer);
|
||||
}
|
||||
}
|
||||
s_critsect.Leave();
|
||||
|
||||
if(!templist.Head())
|
||||
{
|
||||
s_event.Wait(kEventWaitForever);
|
||||
}
|
||||
else
|
||||
{
|
||||
plAudioFileReader *reader = nil;
|
||||
while(plSoundBuffer *buffer = templist.Head())
|
||||
{
|
||||
if(buffer->GetData())
|
||||
{
|
||||
reader = CreateReader(true, buffer->GetFileName(), buffer->GetAudioReaderType(), buffer->GetReaderSelect());
|
||||
|
||||
if( reader )
|
||||
{
|
||||
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
||||
reader->Read( readLen, buffer->GetData() );
|
||||
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
||||
}
|
||||
else
|
||||
buffer->SetError();
|
||||
}
|
||||
|
||||
templist.Unlink(buffer);
|
||||
buffer->SetLoaded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we need to be sure that all buffers are removed from our load list when shutting this thread down or we will hang,
|
||||
// since the sound buffer will wait to be destroyed until it is marked as loaded
|
||||
s_critsect.Enter();
|
||||
{
|
||||
while(plSoundBuffer *buffer = s_loading.Head())
|
||||
{
|
||||
buffer->SetLoaded(true);
|
||||
s_loading.Unlink(buffer);
|
||||
}
|
||||
}
|
||||
s_critsect.Leave();
|
||||
}
|
||||
|
||||
void plSoundBuffer::Init()
|
||||
{
|
||||
s_running = true;
|
||||
_beginthread(LoadCallback, 0, 0);
|
||||
}
|
||||
|
||||
void plSoundBuffer::Shutdown()
|
||||
{
|
||||
s_running = false;
|
||||
s_event.Signal();
|
||||
}
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plSoundBuffer::plSoundBuffer()
|
||||
{
|
||||
IInitBuffer();
|
||||
}
|
||||
|
||||
plSoundBuffer::plSoundBuffer( const char *fileName, UInt32 flags )
|
||||
{
|
||||
IInitBuffer();
|
||||
SetFileName( fileName );
|
||||
fFlags = flags;
|
||||
fValid = IGrabHeaderInfo();
|
||||
}
|
||||
|
||||
plSoundBuffer::~plSoundBuffer()
|
||||
{
|
||||
// if we are loading a sound we need to wait for the loading thread to be completely done processing this buffer.
|
||||
// otherwise it may try to access this buffer after it's been deleted
|
||||
if(fLoading)
|
||||
{
|
||||
while(!fLoaded)
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(!link.IsLinked());
|
||||
delete [] fFileName;
|
||||
UnLoad();
|
||||
}
|
||||
|
||||
void plSoundBuffer::IInitBuffer()
|
||||
{
|
||||
fError = false;
|
||||
fValid = false;
|
||||
fFileName = nil;
|
||||
fData = nil;
|
||||
fDataLength = 0;
|
||||
fFlags = 0;
|
||||
fDataRead = 0;
|
||||
fReader = nil;
|
||||
fLoaded = 0;
|
||||
fLoading = false;
|
||||
fHeader.fFormatTag = 0;
|
||||
fHeader.fNumChannels = 0;
|
||||
fHeader.fNumSamplesPerSec = 0;
|
||||
fHeader.fAvgBytesPerSec = 0;
|
||||
fHeader.fBlockAlign = 0;
|
||||
fHeader.fBitsPerSample = 0;
|
||||
}
|
||||
|
||||
//// GetDataLengthInSecs /////////////////////////////////////////////////////
|
||||
|
||||
hsScalar plSoundBuffer::GetDataLengthInSecs( void ) const
|
||||
{
|
||||
return (hsScalar)fDataLength / (hsScalar)fHeader.fAvgBytesPerSec;
|
||||
}
|
||||
|
||||
//// Read/Write //////////////////////////////////////////////////////////////
|
||||
|
||||
void plSoundBuffer::Read( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Read( s, mgr );
|
||||
|
||||
s->ReadSwap( &fFlags );
|
||||
s->ReadSwap( &fDataLength );
|
||||
fFileName = s->ReadSafeString();
|
||||
|
||||
s->ReadSwap( &fHeader.fFormatTag );
|
||||
s->ReadSwap( &fHeader.fNumChannels );
|
||||
s->ReadSwap( &fHeader.fNumSamplesPerSec );
|
||||
s->ReadSwap( &fHeader.fAvgBytesPerSec );
|
||||
s->ReadSwap( &fHeader.fBlockAlign );
|
||||
s->ReadSwap( &fHeader.fBitsPerSample );
|
||||
|
||||
fValid = false;
|
||||
if( !( fFlags & kIsExternal ) )
|
||||
{
|
||||
fData = TRACKED_NEW UInt8[ fDataLength ];
|
||||
if( fData == nil )
|
||||
fFlags |= kIsExternal;
|
||||
else
|
||||
{
|
||||
s->Read( fDataLength, fData );
|
||||
fValid = true;
|
||||
SetLoaded(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fData = nil;
|
||||
// fValid = EnsureInternal();
|
||||
fValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void plSoundBuffer::Write( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Write( s, mgr );
|
||||
|
||||
if( fData == nil )
|
||||
fFlags |= kIsExternal;
|
||||
|
||||
s->WriteSwap( fFlags );
|
||||
s->WriteSwap( fDataLength );
|
||||
|
||||
// Truncate the path to just a file name on write
|
||||
if( fFileName != nil )
|
||||
{
|
||||
char *nameOnly = strrchr( fFileName, '\\' );
|
||||
if( nameOnly != nil )
|
||||
s->WriteSafeString( nameOnly + 1 );
|
||||
else
|
||||
s->WriteSafeString( fFileName );
|
||||
}
|
||||
else
|
||||
s->WriteSafeString( nil );
|
||||
|
||||
s->WriteSwap( fHeader.fFormatTag );
|
||||
s->WriteSwap( fHeader.fNumChannels );
|
||||
s->WriteSwap( fHeader.fNumSamplesPerSec );
|
||||
s->WriteSwap( fHeader.fAvgBytesPerSec );
|
||||
s->WriteSwap( fHeader.fBlockAlign );
|
||||
s->WriteSwap( fHeader.fBitsPerSample );
|
||||
|
||||
if( !( fFlags & kIsExternal ) )
|
||||
s->Write( fDataLength, fData );
|
||||
}
|
||||
|
||||
//// SetFileName /////////////////////////////////////////////////////////////
|
||||
|
||||
void plSoundBuffer::SetFileName( const char *name )
|
||||
{
|
||||
if(fLoading)
|
||||
{
|
||||
hsAssert(false, "Unable to set SoundBuffer filename");
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] fFileName;
|
||||
if( name != nil )
|
||||
fFileName = hsStrcpy( name );
|
||||
else
|
||||
fFileName = nil;
|
||||
|
||||
// Data is no longer valid
|
||||
UnLoad();
|
||||
}
|
||||
|
||||
|
||||
//// GetReaderSelect /////////////////////////////////////////////////////////
|
||||
// Translates our flags into the ChannelSelect enum for plAudioFileReader
|
||||
|
||||
plAudioCore::ChannelSelect plSoundBuffer::GetReaderSelect( void ) const
|
||||
{
|
||||
if( fFlags & kOnlyLeftChannel )
|
||||
return plAudioCore::kLeft;
|
||||
else if( fFlags & kOnlyRightChannel )
|
||||
return plAudioCore::kRight;
|
||||
else
|
||||
return plAudioCore::kAll;
|
||||
}
|
||||
|
||||
//// IGetFullPath ////////////////////////////////////////////////////////////
|
||||
// Construct our current full path to our sound.
|
||||
|
||||
void plSoundBuffer::IGetFullPath( char *destStr )
|
||||
{
|
||||
if(!fFileName)
|
||||
{
|
||||
*destStr = 0;
|
||||
return;
|
||||
}
|
||||
char path[ kFolderIterator_MaxPath ];
|
||||
|
||||
|
||||
if( strchr( fFileName, '\\' ) != nil )
|
||||
strcpy( path, fFileName );
|
||||
else
|
||||
sprintf( path, "sfx\\%s", fFileName );
|
||||
|
||||
strcpy( destStr, path );
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Asyncload will queue up a buffer for loading in our loading list the first time it is called.
|
||||
// It will load in "length" number of bytes, if length is non zero. If length is zero the entire file will be loaded
|
||||
// When called subsequent times it will check to see if the data has been loaded.
|
||||
// Returns kPending while still loading the file. Returns kSuccess when the data has been loaded.
|
||||
// While a file is loading(fLoading == true, and fLoaded == false) a buffer, no paremeters of the buffer should be modified.
|
||||
plSoundBuffer::ELoadReturnVal plSoundBuffer::AsyncLoad(plAudioFileReader::StreamType type, unsigned length /* = 0 */ )
|
||||
{
|
||||
if(!s_running)
|
||||
return kError; // we cannot load the data since the load thread is no longer running
|
||||
if(!fLoading && !fLoaded)
|
||||
{
|
||||
fAsyncLoadLength = length;
|
||||
fStreamType = type;
|
||||
if(fData == nil )
|
||||
{
|
||||
fData = TRACKED_NEW UInt8[ fAsyncLoadLength ? fAsyncLoadLength : fDataLength ];
|
||||
if( fData == nil )
|
||||
return kError;
|
||||
}
|
||||
s_critsect.Enter();
|
||||
{
|
||||
fLoading = true;
|
||||
s_loading.Link(this);
|
||||
}
|
||||
s_critsect.Leave();
|
||||
s_event.Signal();
|
||||
}
|
||||
if(fLoaded)
|
||||
{
|
||||
if(fLoading) // ensures we only do this stuff one time
|
||||
{
|
||||
ELoadReturnVal retVal = kSuccess;
|
||||
if(fError)
|
||||
{
|
||||
retVal = kError;
|
||||
fError = false;
|
||||
}
|
||||
if(fReader)
|
||||
{
|
||||
fHeader = fReader->GetHeader();
|
||||
SetDataLength(fReader->GetDataSize());
|
||||
}
|
||||
|
||||
fFlags &= ~kIsExternal;
|
||||
fLoading = false;
|
||||
return retVal;
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
return kPending;
|
||||
}
|
||||
|
||||
//// ForceNonInternal ////////////////////////////////////////////////////////
|
||||
// destroys loaded, and frees data
|
||||
void plSoundBuffer::UnLoad( void )
|
||||
{
|
||||
if(fLoaded)
|
||||
int i = 0;
|
||||
if(fLoading)
|
||||
return;
|
||||
|
||||
if(fReader)
|
||||
fReader->Close();
|
||||
|
||||
delete fReader;
|
||||
fReader = nil;
|
||||
|
||||
delete [] fData;
|
||||
fData = nil;
|
||||
SetLoaded(false);
|
||||
fFlags |= kIsExternal;
|
||||
|
||||
}
|
||||
|
||||
//// IRoundDataPos ///////////////////////////////////////////////////////////
|
||||
|
||||
void plSoundBuffer::RoundDataPos( UInt32 &pos )
|
||||
{
|
||||
UInt32 extra = pos & ( fHeader.fBlockAlign - 1 );
|
||||
pos -= extra;
|
||||
}
|
||||
|
||||
// transfers ownership to caller
|
||||
plAudioFileReader *plSoundBuffer::GetAudioReader()
|
||||
{
|
||||
plAudioFileReader * reader = fReader;
|
||||
fReader = nil;
|
||||
return reader;
|
||||
}
|
||||
|
||||
// WARNING: called by the loader thread(only)
|
||||
// the reader will be handed off for later use. This is useful for streaming sound if we want to load the first chunk of data
|
||||
// and the continue streaming the file from disk.
|
||||
void plSoundBuffer::SetAudioReader(plAudioFileReader *reader)
|
||||
{
|
||||
if(fReader)
|
||||
fReader->Close();
|
||||
delete fReader;
|
||||
fReader = reader;
|
||||
}
|
||||
|
||||
void plSoundBuffer::SetLoaded(bool loaded)
|
||||
{
|
||||
fLoaded = loaded;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* for plugins only
|
||||
*
|
||||
***/
|
||||
|
||||
//// SetInternalData /////////////////////////////////////////////////////////
|
||||
|
||||
void plSoundBuffer::SetInternalData( plWAVHeader &header, UInt32 length, UInt8 *data )
|
||||
{
|
||||
if(fLoading) return;
|
||||
fFileName = nil;
|
||||
fHeader = header;
|
||||
fFlags = 0;
|
||||
|
||||
fDataLength = length;
|
||||
fData = TRACKED_NEW UInt8[ length ];
|
||||
memcpy( fData, data, length );
|
||||
|
||||
fValid = true;
|
||||
}
|
||||
|
||||
//// EnsureInternal //////////////////////////////////////////////////////////
|
||||
// for plugins only
|
||||
plSoundBuffer::ELoadReturnVal plSoundBuffer::EnsureInternal()
|
||||
{
|
||||
if( fData == nil )
|
||||
{
|
||||
fData = TRACKED_NEW UInt8[fDataLength ];
|
||||
if( fData == nil )
|
||||
return kError;
|
||||
}
|
||||
if(!fReader)
|
||||
fReader = IGetReader(true);
|
||||
//else
|
||||
// fReader->Open();
|
||||
|
||||
if( fReader == nil )
|
||||
return kError;
|
||||
|
||||
unsigned readLen = fDataLength;
|
||||
if( !fReader->Read( readLen, fData ) )
|
||||
{
|
||||
delete [] fData;
|
||||
fData = nil;
|
||||
return kError;
|
||||
}
|
||||
|
||||
if(fReader)
|
||||
{
|
||||
fReader->Close();
|
||||
delete fReader;
|
||||
fReader = nil;
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
//// IGrabHeaderInfo /////////////////////////////////////////////////////////
|
||||
hsBool plSoundBuffer::IGrabHeaderInfo( void )
|
||||
{
|
||||
static char path[ 512 ];
|
||||
|
||||
if( fFileName != nil )
|
||||
{
|
||||
IGetFullPath( path );
|
||||
|
||||
// Go grab from the WAV file
|
||||
if(!fReader)
|
||||
{
|
||||
fReader = plAudioFileReader::CreateReader(path, GetReaderSelect(), plAudioFileReader::kStreamNative);
|
||||
if( fReader == nil || !fReader->IsValid() )
|
||||
{
|
||||
delete fReader;
|
||||
fReader = nil;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fHeader = fReader->GetHeader();
|
||||
fDataLength = fReader->GetDataSize();
|
||||
RoundDataPos( fDataLength );
|
||||
|
||||
fReader->Close();
|
||||
delete fReader;
|
||||
fReader = nil;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//// IGetReader //////////////////////////////////////////////////////////////
|
||||
// Makes sure the sound is ready to load without any extra processing (like
|
||||
// decompression or the like), then opens a reader for it.
|
||||
// fullpath tells the function whether to append 'sfx' to the path or not (we don't want to do this if were providing the full path)
|
||||
plAudioFileReader *plSoundBuffer::IGetReader( hsBool fullpath )
|
||||
{
|
||||
char path[512];
|
||||
if(fullpath) IGetFullPath(path);
|
||||
else
|
||||
strcpy(path, fFileName);
|
||||
|
||||
// Go grab from the WAV file
|
||||
plAudioFileReader::StreamType type = plAudioFileReader::kStreamWAV;
|
||||
if (HasFlag(kStreamCompressed))
|
||||
type = plAudioFileReader::kStreamNative;
|
||||
|
||||
plAudioFileReader* reader = plAudioFileReader::CreateReader(path, GetReaderSelect(), type);
|
||||
|
||||
if( reader == nil || !reader->IsValid() )
|
||||
{
|
||||
delete reader;
|
||||
return nil;
|
||||
}
|
||||
|
||||
fHeader = reader->GetHeader();
|
||||
fDataLength = reader->GetDataSize();
|
||||
RoundDataPos( fDataLength );
|
||||
|
||||
return reader;
|
||||
}
|
162
Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h
Normal file
162
Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.h
Normal file
@ -0,0 +1,162 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
97
Sources/Plasma/PubUtilLib/plAudioCore/plSoundDeswizzler.cpp
Normal file
97
Sources/Plasma/PubUtilLib/plAudioCore/plSoundDeswizzler.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
73
Sources/Plasma/PubUtilLib/plAudioCore/plSoundDeswizzler.h
Normal file
73
Sources/Plasma/PubUtilLib/plAudioCore/plSoundDeswizzler.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*==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/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
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
|
Reference in New Issue
Block a user