mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 18:30:27 +01:00
5badefaf90
Also changed all "if (this==NULL) return;"s. Fixes some -Wtautological-undefined-compare warnings. Quoting Clang: "'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false"
266 lines
6.1 KiB
C++
266 lines
6.1 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation
|
|
|
|
|
|
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, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|
|
|
#include "Engine/StdH.h"
|
|
|
|
#include <Engine/Sound/SoundData.h>
|
|
|
|
#include <Engine/Base/Memory.h>
|
|
#include <Engine/Base/Stream.h>
|
|
#include <Engine/Base/ListIterator.inl>
|
|
#include <Engine/Sound/Wave.h>
|
|
#include <Engine/Sound/SoundDecoder.h>
|
|
#include <Engine/Sound/SoundLibrary.h>
|
|
#include <Engine/Sound/SoundObject.h>
|
|
|
|
#include <Engine/Templates/Stock_CSoundData.h>
|
|
|
|
/* ====================================================
|
|
*
|
|
* Sound data awareness functions
|
|
*/
|
|
|
|
/*
|
|
* Pause all playing
|
|
*/
|
|
void CSoundData::PausePlayingObjects(void)
|
|
{
|
|
// for all objects linked to data pause playing
|
|
FOREACHINLIST(CSoundObject, so_Node, sd_ClhLinkList, itCsoPause) {
|
|
// pause playing
|
|
itCsoPause->Pause();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* For all objects resume play
|
|
*/
|
|
void CSoundData::ResumePlayingObjects(void)
|
|
{
|
|
// for all objects resume play
|
|
FOREACHINLIST(CSoundObject, so_Node, sd_ClhLinkList, itCsoResume) {
|
|
// call play method again
|
|
itCsoResume->Resume();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Add object in sound aware list
|
|
*/
|
|
void CSoundData::AddObjectLink(CSoundObject &CsoAdd)
|
|
{
|
|
// add object to list tail
|
|
sd_ClhLinkList.AddTail(CsoAdd.so_Node);
|
|
}
|
|
|
|
/*
|
|
* Remove a object from aware list
|
|
*/
|
|
void CSoundData::RemoveObjectLink(CSoundObject &CsoRemove)
|
|
{
|
|
// remove it from list
|
|
CsoRemove.so_Node.Remove();
|
|
}
|
|
|
|
|
|
/* ====================================================
|
|
*
|
|
* Class global methods
|
|
*/
|
|
|
|
// Constructor
|
|
CSoundData::CSoundData()
|
|
{
|
|
sd_pswBuffer = NULL;
|
|
}
|
|
|
|
// Destructor
|
|
CSoundData::~CSoundData()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
|
|
// Free Buffer (and all linked Objects)
|
|
void CSoundData::ClearBuffer(void)
|
|
{
|
|
// if buffer exist
|
|
if( sd_pswBuffer!=NULL) {
|
|
// release it
|
|
FreeMemory( sd_pswBuffer);
|
|
sd_pswBuffer = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// Get Sound Length in seconds
|
|
double CSoundData::GetSecondsLength(void)
|
|
{
|
|
// if not encoded
|
|
if (!(sd_ulFlags&SDF_ENCODED) ) {
|
|
// len is read from wave
|
|
return sd_dSecondsLength;
|
|
// if encoded
|
|
} else {
|
|
// implement this!!!!
|
|
ASSERT(FALSE);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* ====================================================
|
|
*
|
|
* Input methods (load sound in SoundData class)
|
|
*/
|
|
|
|
// Read sound in memory
|
|
void CSoundData::Read_t(CTStream *inFile) // throw char *
|
|
{
|
|
// synchronize access to sounds
|
|
CTSingleLock slSounds(&_pSound->sl_csSound, TRUE);
|
|
|
|
ASSERT( sd_pswBuffer==NULL);
|
|
sd_ulFlags = NONE;
|
|
|
|
// get filename
|
|
CTFileName fnm = inFile->GetDescription();
|
|
// if this is encoded file
|
|
if (fnm.FileExt()==".ogg" || fnm.FileExt()==".mp3") {
|
|
CSoundDecoder *pmpd = new CSoundDecoder(fnm);
|
|
if (pmpd->IsOpen()) {
|
|
pmpd->GetFormat(sd_wfeFormat);
|
|
}
|
|
delete pmpd;
|
|
// mark that this is streaming encoded file
|
|
sd_ulFlags = SDF_ENCODED|SDF_STREAMING;
|
|
|
|
// if this is wave file
|
|
} else {
|
|
// load wave info
|
|
PCMWaveInput CpwiLoad;
|
|
sd_wfeFormat = CpwiLoad.LoadInfo_t(inFile);
|
|
// store sample length in seconds and average byte rate
|
|
sd_dSecondsLength = CpwiLoad.GetSecondsLength();
|
|
|
|
// if sound library is in lower format convert sound to library format
|
|
if ((_pSound->sl_SwfeFormat).nSamplesPerSec < sd_wfeFormat.nSamplesPerSec) {
|
|
sd_wfeFormat.nSamplesPerSec = (_pSound->sl_SwfeFormat).nSamplesPerSec;
|
|
}
|
|
// same goes for bits/sample (must be 16)
|
|
sd_wfeFormat.wBitsPerSample = 16;
|
|
|
|
// if library is active create buffer and load sound data
|
|
if (_pSound->IsActive()) {
|
|
// create Buffer
|
|
sd_slBufferSampleSize = CpwiLoad.GetDataLength(sd_wfeFormat);
|
|
SLONG slBufferSize = CpwiLoad.DetermineBufferSize(sd_wfeFormat);
|
|
sd_pswBuffer = (SWORD*)AllocMemory( slBufferSize+8);
|
|
// load data into buffer
|
|
CpwiLoad.LoadData_t( inFile, sd_pswBuffer, sd_wfeFormat);
|
|
// copy first sample to the last one (this is needed for linear interpolation)
|
|
(ULONG&)(((UBYTE*)sd_pswBuffer)[slBufferSize]) = *(ULONG*)sd_pswBuffer;
|
|
}
|
|
}
|
|
|
|
// add to sound aware list
|
|
_pSound->AddSoundAware(*this);
|
|
}
|
|
|
|
|
|
// Sound can't be written to file
|
|
void CSoundData::Write_t( CTStream *outFile)
|
|
{
|
|
ASSERTALWAYS("Cannot write sounds!");
|
|
throw TRANS("Cannot write sounds!");
|
|
}
|
|
|
|
/* Get the description of this object. */
|
|
CTString CSoundData::GetDescription(void)
|
|
{
|
|
CTString str;
|
|
str.PrintF("%dkHz %dbit %s %.2lfs",
|
|
sd_wfeFormat.nSamplesPerSec/1000,
|
|
sd_wfeFormat.wBitsPerSample,
|
|
sd_wfeFormat.nChannels==1 ? "mono" : "stereo",
|
|
sd_dSecondsLength);
|
|
return str;
|
|
}
|
|
|
|
|
|
/* ====================================================
|
|
*
|
|
* Class CLEAR method
|
|
*/
|
|
|
|
// Free memory allocated for sound and Release DXBuffer
|
|
void CSoundData::Clear(void)
|
|
{
|
|
// synchronize access to sounds
|
|
CTSingleLock slSounds(&_pSound->sl_csSound, TRUE);
|
|
|
|
// clear BASE class
|
|
CSerial::Clear();
|
|
|
|
// free DXBuffer
|
|
ClearBuffer();
|
|
|
|
// if added as sound aware, remove it from sound aware list
|
|
if(IsHooked()) {
|
|
_pSound->RemoveSoundAware(*this);
|
|
}
|
|
}
|
|
|
|
|
|
// check if this kind of objects is auto-freed
|
|
BOOL CSoundData::IsAutoFreed(void)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// get amount of memory used by this object
|
|
SLONG CSoundData::GetUsedMemory(void)
|
|
{
|
|
SLONG slUsed = sizeof(*this);
|
|
if( sd_pswBuffer!=NULL) {
|
|
ASSERT( sd_wfeFormat.nChannels==1 || sd_wfeFormat.nChannels==2);
|
|
slUsed += sd_slBufferSampleSize * sd_wfeFormat.nChannels *2; // all sounds are 16-bit
|
|
}
|
|
return slUsed;
|
|
}
|
|
|
|
|
|
/* ====================================================
|
|
*
|
|
* Reference counting functions
|
|
*/
|
|
|
|
// Add one reference
|
|
void CSoundData::AddReference(void)
|
|
{
|
|
ASSERT(this!=NULL);
|
|
MarkUsed();
|
|
}
|
|
|
|
|
|
// Remove one reference
|
|
void CSoundData::RemReference(void)
|
|
{
|
|
ASSERT(this!=NULL);
|
|
_pSoundStock->Release(this);
|
|
}
|