Changed: #795 Handle safely when audio decoder fails to be created
This commit is contained in:
parent
4ac6c26dfd
commit
49ad587f0d
6 changed files with 54 additions and 33 deletions
|
@ -85,7 +85,7 @@ public:
|
|||
// TODO: getTime
|
||||
|
||||
private:
|
||||
void prepareDecoder();
|
||||
bool prepareDecoder();
|
||||
inline bool bufferMore(uint bytes);
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<ATOM Name="MinDistance" Value="100000"/>
|
||||
<ATOM Name="MaxDistance" Value="200000"/>
|
||||
<ATOM Name="Async" Value ="true"/>
|
||||
<ATOM Name="FilePath" Value="D:/source/kaetemi/toverhex/src/samples/music_stream/data/aeon_1_10_mystic_river.ogg"/>
|
||||
<ATOM Name="FilePath" Value="Pyr Entrance.ogg"/>
|
||||
</VSTRUCT>
|
||||
<ATOM Name="AbsolutePosition" Value="false"/>
|
||||
<ATOM Name="Priority" Value="Highest"/>
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
#define NL_SOUND_DATA "."
|
||||
#endif // NL_SOUND_DATA
|
||||
|
||||
#define SAMPLE_OGG "D:/source/kaetemi/toverhex/src/samples/music_stream/data/aeon_1_10_mystic_river.ogg"
|
||||
#define RYZOM_DATA "P:/data"
|
||||
#define SAMPLE_OGG "Pyr Entrance.ogg"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
@ -93,6 +94,8 @@ static void initSample()
|
|||
CVector upvec(0.0f, 0.0f, 1.0f);
|
||||
s_AudioMixer->getListener()->setPos(initpos);
|
||||
s_AudioMixer->getListener()->setOrientation(frontvec, upvec);
|
||||
|
||||
CPath::addSearchPath(RYZOM_DATA, true, false);
|
||||
|
||||
//NLMISC::CHTimer::startBench();
|
||||
|
||||
|
|
|
@ -1651,6 +1651,7 @@ void CAudioMixerUser::update()
|
|||
_MusicChannelFaders[i].update();
|
||||
|
||||
// Check all playing track and stop any terminated buffer.
|
||||
std::list<CSourceCommon *>::size_type nbWaitingSources = _Sources.size();
|
||||
for (i=0; i<_Tracks.size(); ++i)
|
||||
{
|
||||
if (!_Tracks[i]->isPlaying())
|
||||
|
@ -1662,13 +1663,14 @@ void CAudioMixerUser::update()
|
|||
}
|
||||
|
||||
// try to play any waiting source.
|
||||
if (!_SourceWaitingForPlay.empty())
|
||||
if (!_SourceWaitingForPlay.empty() && nbWaitingSources)
|
||||
{
|
||||
// check if the source still exist before trying to play it
|
||||
if (_Sources.find(_SourceWaitingForPlay.front()) != _Sources.end())
|
||||
_SourceWaitingForPlay.front()->play();
|
||||
// nldebug("Before POP Sources waiting : %u", _SourceWaitingForPlay.size());
|
||||
_SourceWaitingForPlay.pop_front();
|
||||
--nbWaitingSources;
|
||||
// nldebug("After POP Sources waiting : %u", _SourceWaitingForPlay.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,39 +63,53 @@ void CStreamFileSource::play()
|
|||
// note: CStreamSource will assert crash if already physically playing!
|
||||
|
||||
|
||||
if (m_Thread->isRunning() && m_WaitingForPlay)
|
||||
if (m_WaitingForPlay)
|
||||
{
|
||||
if (m_NextBuffer || !m_FreeBuffers)
|
||||
if (m_Thread->isRunning())
|
||||
{
|
||||
nldebug("play waiting, play stream %s", getStreamFileSound()->getFilePath().c_str());
|
||||
CStreamSource::play();
|
||||
if (!_Playing && !m_WaitingForPlay)
|
||||
if (m_NextBuffer || !m_FreeBuffers)
|
||||
{
|
||||
nldebug("playing not possible or necessary for some reason");
|
||||
nldebug("play waiting, play stream %s", getStreamFileSound()->getFilePath().c_str());
|
||||
CStreamSource::play();
|
||||
if (!_Playing && !m_WaitingForPlay)
|
||||
{
|
||||
nldebug("playing not possible or necessary for some reason");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nldebug("play waiting, hop onto waiting list %s", getStreamFileSound()->getFilePath().c_str());
|
||||
m_WaitingForPlay = true;
|
||||
CAudioMixerUser *mixer = CAudioMixerUser::instance();
|
||||
mixer->addSourceWaitingForPlay(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nldebug("play waiting, hop onto waiting list %s", getStreamFileSound()->getFilePath().c_str());
|
||||
m_WaitingForPlay = true;
|
||||
CAudioMixerUser *mixer = CAudioMixerUser::instance();
|
||||
mixer->addSourceWaitingForPlay(this);
|
||||
// thread went kaboom while not started playing yet, probably the audiodecoder cannot be started
|
||||
// don't play
|
||||
m_WaitingForPlay = false;
|
||||
}
|
||||
}
|
||||
else if (!_Playing)
|
||||
{
|
||||
nldebug("play go %s", getStreamFileSound()->getFilePath().c_str());
|
||||
if (!m_WaitingForPlay)
|
||||
{
|
||||
//if (!m_WaitingForPlay)
|
||||
//{
|
||||
// thread may be stopping from stop call
|
||||
m_Thread->wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("Already waiting for play");
|
||||
}
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// nlwarning("Already waiting for play");
|
||||
//}
|
||||
if (!getStreamFileSound()->getAsync())
|
||||
prepareDecoder();
|
||||
{
|
||||
if (!prepareDecoder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
// else load audiodecoder in thread
|
||||
m_WaitingForPlay = true;
|
||||
m_Thread->start();
|
||||
|
@ -221,7 +235,7 @@ bool CStreamFileSource::isLoadingAsync()
|
|||
return m_WaitingForPlay;
|
||||
}
|
||||
|
||||
void CStreamFileSource::prepareDecoder()
|
||||
bool CStreamFileSource::prepareDecoder()
|
||||
{
|
||||
// creates a new decoder or keeps going with the current decoder if the stream was paused
|
||||
|
||||
|
@ -243,13 +257,15 @@ void CStreamFileSource::prepareDecoder()
|
|||
if (!m_AudioDecoder)
|
||||
{
|
||||
nlwarning("Failed to create IAudioDecoder, likely invalid format");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
this->setFormat(m_AudioDecoder->getChannels(), m_AudioDecoder->getBitsPerSample(), (uint32)m_AudioDecoder->getSamplesPerSec());
|
||||
}
|
||||
uint samples, bytes;
|
||||
this->getRecommendedBufferSize(samples, bytes);
|
||||
this->preAllocate(bytes * 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool CStreamFileSource::bufferMore(uint bytes) // buffer from bytes (minimum) to bytes * 2 (maximum)
|
||||
|
@ -271,7 +287,10 @@ void CStreamFileSource::run()
|
|||
|
||||
bool looping = _Looping;
|
||||
if (getStreamFileSound()->getAsync())
|
||||
prepareDecoder();
|
||||
{
|
||||
if (!prepareDecoder())
|
||||
return;
|
||||
}
|
||||
uint samples, bytes;
|
||||
this->getRecommendedBufferSize(samples, bytes);
|
||||
uint32 recSleep = 40;
|
||||
|
|
|
@ -161,7 +161,7 @@ void CStreamSource::play()
|
|||
delete this;
|
||||
}
|
||||
nldebug("CStreamSource %p : play FAILED, source is too far away !", (CAudioMixerUser::IMixerEvent*)this);
|
||||
m_WaitingForPlay = false;
|
||||
// m_WaitingForPlay = false; // not necessary, delete ensures waiting for thread stop
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -182,12 +182,9 @@ void CStreamSource::play()
|
|||
|
||||
// pSource->setPos( _Position, false);
|
||||
pSource->setPos(getVirtualPos(), false);
|
||||
if (!m_Buffers[0]->isStereo())
|
||||
{
|
||||
pSource->setMinMaxDistances(m_StreamSound->getMinDistance(), m_StreamSound->getMaxDistance(), false);
|
||||
setDirection(_Direction); // because there is a workaround inside
|
||||
pSource->setVelocity(_Velocity);
|
||||
}
|
||||
pSource->setMinMaxDistances(m_StreamSound->getMinDistance(), m_StreamSound->getMaxDistance(), false);
|
||||
setDirection(_Direction); // because there is a workaround inside
|
||||
pSource->setVelocity(_Velocity);
|
||||
pSource->setGain(getFinalGain());
|
||||
pSource->setSourceRelativeMode(_RelativeMode);
|
||||
// pSource->setLooping(_Looping);
|
||||
|
@ -435,7 +432,7 @@ uint32 CStreamSource::getRecommendedSleepTime() const
|
|||
{
|
||||
if (m_FreeBuffers > 0) return 0;
|
||||
uint32 sleepTime = (uint32)((1000.0f * ((float)m_LastSize) / (float)m_BytesPerSecond) * m_PitchInv);
|
||||
clamp(sleepTime, (uint32)0, (uint32)1000);
|
||||
clamp(sleepTime, (uint32)0, (uint32)80);
|
||||
return sleepTime;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue