parent
57aa8b4d74
commit
bbd291a089
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* \file stream_file_sound.h
|
||||
* \brief CStreamFileSound
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSound
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE.
|
||||
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE 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
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSOUND_STREAM_FILE_SOUND_H
|
||||
#define NLSOUND_STREAM_FILE_SOUND_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
|
||||
// Project includes
|
||||
#include <nel/sound/stream_sound.h>
|
||||
|
||||
namespace NLSOUND {
|
||||
class CSourceMusicChannel;
|
||||
|
||||
/**
|
||||
* \brief CStreamFileSound
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSound
|
||||
*/
|
||||
class CStreamFileSound : public CStreamSound
|
||||
{
|
||||
public:
|
||||
friend CSourceMusicChannel;
|
||||
|
||||
public:
|
||||
CStreamFileSound();
|
||||
virtual ~CStreamFileSound();
|
||||
|
||||
/// Get the type of the sound.
|
||||
virtual TSOUND_TYPE getSoundType() { return SOUND_STREAM_FILE; }
|
||||
|
||||
/// Load the sound parameters from georges' form
|
||||
virtual void importForm(const std::string& filename, NLGEORGES::UFormElm& formRoot);
|
||||
|
||||
/// Used by the george sound plugin to check sound recursion (ie sound 'toto' use sound 'titi' witch also use sound 'toto' ...).
|
||||
virtual void getSubSoundList(std::vector<std::pair<std::string, CSound*> > &/* subsounds */) const { }
|
||||
|
||||
/// Serialize the sound data.
|
||||
virtual void serial(NLMISC::IStream &s);
|
||||
|
||||
/// Return the length of the sound in ms
|
||||
virtual uint32 getDuration() { return 0; }
|
||||
|
||||
inline bool getAsync() { return m_Async; }
|
||||
|
||||
inline const std::string &getFilePath() { return m_FilePath; }
|
||||
|
||||
private:
|
||||
/// Used by CSourceMusicChannel to set the filePath and default settings on other parameters.
|
||||
void setMusicFilePath(const std::string &filePath, bool async = true, bool loop = false);
|
||||
|
||||
private:
|
||||
CStreamFileSound(const CStreamFileSound &);
|
||||
CStreamFileSound &operator=(const CStreamFileSound &);
|
||||
|
||||
private:
|
||||
bool m_Async;
|
||||
std::string m_FilePath;
|
||||
|
||||
}; /* class CStreamFileSound */
|
||||
|
||||
} /* namespace NLSOUND */
|
||||
|
||||
#endif /* #ifndef NLSOUND_STREAM_FILE_SOUND_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* \file stream_file_source.h
|
||||
* \brief CStreamFileSource
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSource
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE.
|
||||
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE 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
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSOUND_STREAM_FILE_SOURCE_H
|
||||
#define NLSOUND_STREAM_FILE_SOURCE_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/thread.h>
|
||||
|
||||
// Project includes
|
||||
#include <nel/sound/stream_source.h>
|
||||
#include <nel/sound/stream_file_sound.h>
|
||||
|
||||
namespace NLSOUND {
|
||||
class IAudioDecoder;
|
||||
|
||||
/**
|
||||
* \brief CStreamFileSource
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSource
|
||||
*/
|
||||
class CStreamFileSource : public CStreamSource, private NLMISC::IRunnable
|
||||
{
|
||||
public:
|
||||
CStreamFileSource(CStreamFileSound *streamFileSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||
virtual ~CStreamFileSource();
|
||||
|
||||
/// Return the source type
|
||||
TSOURCE_TYPE getType() const { return SOURCE_STREAM_FILE; }
|
||||
|
||||
/// \name Playback control
|
||||
//@{
|
||||
/// Play
|
||||
virtual void play();
|
||||
/// Stop playing
|
||||
virtual void stop();
|
||||
/// Get playing state. Return false even if the source has stopped on its own.
|
||||
virtual bool isPlaying();
|
||||
/// Pause (following legacy music channel implementation)
|
||||
void pause();
|
||||
/// Resume (following legacy music channel implementation)
|
||||
void resume();
|
||||
/// check if song ended (following legacy music channel implementation)
|
||||
bool isEnded();
|
||||
//@}
|
||||
|
||||
/// \name Decoding thread
|
||||
//@{
|
||||
virtual void getName (std::string &result) const { result = "CStreamFileSource"; }
|
||||
virtual void run();
|
||||
//@}
|
||||
|
||||
// TODO: getTime
|
||||
|
||||
private:
|
||||
void bufferMore(uint bytes);
|
||||
|
||||
private:
|
||||
CStreamFileSource(const CStreamFileSource &);
|
||||
CStreamFileSource &operator=(const CStreamFileSource &);
|
||||
|
||||
private:
|
||||
inline CStreamFileSound *getStreamFileSound() { return static_cast<CStreamFileSound *>(m_StreamSound); }
|
||||
|
||||
NLMISC::IThread *m_Thread;
|
||||
|
||||
IAudioDecoder *m_AudioDecoder;
|
||||
|
||||
bool m_Paused;
|
||||
|
||||
}; /* class CStreamFileSource */
|
||||
|
||||
} /* namespace NLSOUND */
|
||||
|
||||
#endif /* #ifndef NLSOUND_STREAM_FILE_SOURCE_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* \file stream_file_sound.cpp
|
||||
* \brief CStreamFileSound
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSound
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE.
|
||||
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE 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
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stdsound.h"
|
||||
#include <nel/sound/stream_file_sound.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NLSOUND {
|
||||
|
||||
CStreamFileSound::CStreamFileSound()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CStreamFileSound::~CStreamFileSound()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CStreamFileSound::importForm(const std::string &filename, NLGEORGES::UFormElm &root)
|
||||
{
|
||||
// Call the base class
|
||||
CStreamSound::importForm(filename, root);
|
||||
|
||||
// Async
|
||||
root.getValueByName(m_Async, ".SoundType.Async");
|
||||
|
||||
// FilePath
|
||||
root.getValueByName(m_FilePath, ".SoundType.FilePath");
|
||||
}
|
||||
|
||||
void CStreamFileSound::serial(NLMISC::IStream &s)
|
||||
{
|
||||
CStreamSound::serial(s);
|
||||
|
||||
s.serial(m_Async);
|
||||
s.serial(m_FilePath);
|
||||
}
|
||||
|
||||
void CStreamFileSound::setMusicFilePath(const std::string &filePath, bool async, bool loop)
|
||||
{
|
||||
_ConeInnerAngle = NLMISC::Pi * 2;
|
||||
_ConeOuterAngle = NLMISC::Pi * 2;
|
||||
_Looping = loop;
|
||||
_Gain = 1.0f;
|
||||
_ConeOuterGain = 1.0f;
|
||||
_Direction = NLMISC::CVector(0.f, 0.f, 0.f);
|
||||
_Pitch = 1.0f;
|
||||
_Priority = HighestPri;
|
||||
_MaxDist = 9000.0f;
|
||||
_MinDist = 1000.0f;
|
||||
m_Async = async;
|
||||
m_FilePath = filePath;
|
||||
}
|
||||
|
||||
} /* namespace NLSOUND */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,244 @@
|
||||
/**
|
||||
* \file stream_file_source.cpp
|
||||
* \brief CStreamFileSource
|
||||
* \date 2012-04-11 09:57GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStreamFileSource
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE.
|
||||
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE 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
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stdsound.h"
|
||||
#include <nel/sound/stream_file_source.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
#include <nel/sound/audio_mixer_user.h>
|
||||
#include <nel/sound/audio_decoder.h>
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NLSOUND {
|
||||
|
||||
CStreamFileSource::CStreamFileSource(CStreamFileSound *streamFileSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||
: CStreamSource(streamFileSound, spawn, cb, cbUserParam, cluster, groupController), m_AudioDecoder(NULL), m_Paused(false)
|
||||
{
|
||||
m_Thread = NLMISC::IThread::create(this);
|
||||
}
|
||||
|
||||
CStreamFileSource::~CStreamFileSource()
|
||||
{
|
||||
stop();
|
||||
m_Thread->wait(); // thread must have stopped for delete!
|
||||
delete m_Thread;
|
||||
m_Thread = NULL;
|
||||
delete m_AudioDecoder;
|
||||
m_AudioDecoder = NULL;
|
||||
}
|
||||
|
||||
void CStreamFileSource::play()
|
||||
{
|
||||
// note: CStreamSource will assert crash if already physically playing!
|
||||
|
||||
nldebug("play");
|
||||
|
||||
if (m_Thread->isRunning() && m_WaitingForPlay)
|
||||
{
|
||||
if (m_NextBuffer || !m_FreeBuffers)
|
||||
{
|
||||
CStreamSource::play();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WaitingForPlay = true;
|
||||
CAudioMixerUser *mixer = CAudioMixerUser::instance();
|
||||
mixer->addSourceWaitingForPlay(this);
|
||||
}
|
||||
}
|
||||
else if (!_Playing)
|
||||
{
|
||||
if (!m_WaitingForPlay)
|
||||
{
|
||||
// thread may be stopping from stop call
|
||||
m_Thread->wait();
|
||||
}
|
||||
nlassert(!_Playing);
|
||||
m_WaitingForPlay = true;
|
||||
m_Thread->start();
|
||||
m_Thread->setPriority(NLMISC::ThreadPriorityHighest);
|
||||
CAudioMixerUser *mixer = CAudioMixerUser::instance();
|
||||
mixer->addSourceWaitingForPlay(this);
|
||||
}
|
||||
|
||||
/*if (!m_WaitingForPlay)
|
||||
{
|
||||
m_WaitingForPlay = true;
|
||||
|
||||
m_Thread->wait(); // thread must have stopped to restart it!
|
||||
|
||||
m_Thread->start();
|
||||
m_Thread->setPriority(NLMISC::ThreadPriorityHighest);
|
||||
}
|
||||
|
||||
CStreamSource::play();*/
|
||||
}
|
||||
|
||||
void CStreamFileSource::stop()
|
||||
{
|
||||
nldebug("stop");
|
||||
|
||||
CStreamSource::stop();
|
||||
|
||||
// thread will check _Playing to stop
|
||||
}
|
||||
|
||||
bool CStreamFileSource::isPlaying()
|
||||
{
|
||||
nldebug("isPlaying");
|
||||
|
||||
return m_Thread->isRunning();
|
||||
}
|
||||
|
||||
void CStreamFileSource::pause()
|
||||
{
|
||||
nldebug("pause");
|
||||
|
||||
if (!m_Paused)
|
||||
{
|
||||
// thread checks for this to not delete the audio decoder
|
||||
m_Paused = true;
|
||||
|
||||
// stop the underlying system
|
||||
CStreamSource::stop();
|
||||
|
||||
// thread will check _Playing to stop
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("Already paused");
|
||||
}
|
||||
}
|
||||
|
||||
void CStreamFileSource::resume()
|
||||
{
|
||||
nldebug("resume");
|
||||
|
||||
if (m_Paused)
|
||||
{
|
||||
m_Thread->wait(); // thread must have stopped to restart it!
|
||||
|
||||
play();
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("Not paused");
|
||||
}
|
||||
}
|
||||
|
||||
bool CStreamFileSource::isEnded()
|
||||
{
|
||||
return (!m_Thread->isRunning() && !_Playing && !m_WaitingForPlay && !m_Paused);
|
||||
}
|
||||
|
||||
void CStreamFileSource::bufferMore(uint bytes) // buffer from bytes (minimum) to bytes * 2 (maximum)
|
||||
{
|
||||
uint8 *buffer = this->lock(bytes * 2);
|
||||
if (buffer)
|
||||
{
|
||||
uint32 result = m_AudioDecoder->getNextBytes(buffer, bytes, bytes * 2);
|
||||
this->unlock(result);
|
||||
}
|
||||
}
|
||||
|
||||
void CStreamFileSource::run()
|
||||
{
|
||||
nldebug("run");
|
||||
|
||||
bool looping = _Looping;
|
||||
if (m_Paused)
|
||||
{
|
||||
// handle paused!
|
||||
m_Paused = false;
|
||||
}
|
||||
else if (m_AudioDecoder) // audio decoder should normally not exist when not paused and starting the thread
|
||||
{
|
||||
nlwarning("CAudioDecoder already exists, possible thread race bug with pause");
|
||||
delete m_AudioDecoder;
|
||||
m_AudioDecoder = NULL;
|
||||
}
|
||||
if (!m_AudioDecoder)
|
||||
{
|
||||
// load the file
|
||||
m_AudioDecoder = IAudioDecoder::createAudioDecoder(getStreamFileSound()->getFilePath(), getStreamFileSound()->getAsync(), getStreamFileSound()->getLooping());
|
||||
if (!m_AudioDecoder)
|
||||
{
|
||||
nlwarning("Failed to create IAudioDecoder, likely invalid format");
|
||||
return;
|
||||
}
|
||||
this->setFormat(m_AudioDecoder->getChannels(), m_AudioDecoder->getBitsPerSample(), (uint32)m_AudioDecoder->getSamplesPerSec());
|
||||
}
|
||||
uint samples, bytes;
|
||||
this->getRecommendedBufferSize(samples, bytes);
|
||||
bufferMore(bytes);
|
||||
while (_Playing || m_WaitingForPlay)
|
||||
{
|
||||
if (!m_AudioDecoder->isMusicEnded())
|
||||
{
|
||||
bool newLooping = _Looping;
|
||||
if (looping != newLooping)
|
||||
{
|
||||
m_AudioDecoder->setLooping(looping);
|
||||
looping = newLooping;
|
||||
}
|
||||
|
||||
bufferMore(bytes);
|
||||
NLMISC::nlSleep(this->getRecommendedSleepTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
// wait until done playing buffers
|
||||
while (this->hasFilledBuffersAvailable())
|
||||
NLMISC::nlSleep(40);
|
||||
// stop the physical source
|
||||
// if (hasPhysicalSource())
|
||||
// getPhysicalSource()->stop();
|
||||
// the audio mixer will call stop on the logical source
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_Paused)
|
||||
{
|
||||
// don't delete anything
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_AudioDecoder;
|
||||
m_AudioDecoder = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace NLSOUND */
|
||||
|
||||
/* end of file */
|
Loading…
Reference in New Issue