From c4adc53a0fd6193b2aeae572e04369841349a734 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Apr 2012 21:46:07 +0200 Subject: [PATCH] Removed: #795 XAudio2 music implementation --HG-- branch : sound_dev --- .../sound/driver/openal/sound_driver_al.cpp | 3 + .../driver/xaudio2/music_channel_xaudio2.cpp | 248 ------------------ .../driver/xaudio2/music_channel_xaudio2.h | 117 --------- .../driver/xaudio2/sound_driver_xaudio2.cpp | 39 +-- .../driver/xaudio2/sound_driver_xaudio2.h | 17 -- .../nel/src/sound/driver/xaudio2/stdxaudio2.h | 1 - 6 files changed, 4 insertions(+), 421 deletions(-) delete mode 100644 code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp delete mode 100644 code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h diff --git a/code/nel/src/sound/driver/openal/sound_driver_al.cpp b/code/nel/src/sound/driver/openal/sound_driver_al.cpp index 22b1eaf3f..e7eaca3f6 100644 --- a/code/nel/src/sound/driver/openal/sound_driver_al.cpp +++ b/code/nel/src/sound/driver/openal/sound_driver_al.cpp @@ -183,6 +183,9 @@ _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f) */ CSoundDriverAL::~CSoundDriverAL() { + // WARNING: Only internal resources are released here, + // the created instances must still be released by the user! + // Remove the allocated (but not exported) source and buffer names- // Release internal resources of all remaining ISource instances if (_Sources.size()) diff --git a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp b/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp deleted file mode 100644 index 4110ecf41..000000000 --- a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program 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. -// -// 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdxaudio2.h" - -// Project includes -#include "sound_driver_xaudio2.h" -#include "music_channel_xaudio2.h" - -using namespace std; -using namespace NLMISC; - -namespace NLSOUND { - -CMusicChannelXAudio2::CMusicChannelXAudio2(CSoundDriverXAudio2 *soundDriver) -: _MusicBuffer(NULL), _SourceVoice(NULL), _BufferPos(0), _SoundDriver(soundDriver), _Gain(1.0) -{ - nlwarning(NLSOUND_XAUDIO2_PREFIX "Initializing CMusicChannelXAudio2"); - - stop(); -} - -CMusicChannelXAudio2::~CMusicChannelXAudio2() -{ - release(); - if (_SoundDriver) { _SoundDriver->removeMusicChannel(this); _SoundDriver = NULL; } - - nlwarning(NLSOUND_XAUDIO2_PREFIX "Destroying CMusicChannelXAudio2"); -} - -void CMusicChannelXAudio2::release() -{ - nlwarning(NLSOUND_XAUDIO2_PREFIX "Releasing CMusicChannelXAudio2"); - - stop(); -} - -/** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ -bool CMusicChannelXAudio2::play(const std::string &filepath, bool async, bool loop) -{ - // nlinfo(NLSOUND_XAUDIO2_PREFIX "play %s %u", filepath.c_str(), (uint32)loop); - - _SoundDriver->performanceIncreaseMusicPlayCounter(); - - HRESULT hr; - - stop(); - - _MusicBuffer = IMusicBuffer::createMusicBuffer(filepath, async, loop); - - if (_MusicBuffer) - { - WAVEFORMATEX wfe; - wfe.cbSize = 0; - wfe.wFormatTag = WAVE_FORMAT_PCM; // todo: getFormat(); - wfe.nChannels = _MusicBuffer->getChannels(); - wfe.wBitsPerSample = _MusicBuffer->getBitsPerSample(); - wfe.nSamplesPerSec = _MusicBuffer->getSamplesPerSec(); - wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; - wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; - - XAUDIO2_VOICE_DETAILS voice_details; - _SoundDriver->getMasteringVoice()->GetVoiceDetails(&voice_details); - - // nlinfo(NLSOUND_XAUDIO2_PREFIX "Creating music voice with %u channels, %u bits per sample, %u samples per sec, " - // "on mastering voice with %u channels, %u samples per sec", - // (uint32)wfe.nChannels, (uint32)wfe.wBitsPerSample, (uint32)wfe.nSamplesPerSec, - // (uint32)voice_details.InputChannels, (uint32)voice_details.InputSampleRate); - - if (FAILED(hr = _SoundDriver->getXAudio2()->CreateSourceVoice(&_SourceVoice, &wfe, XAUDIO2_VOICE_NOPITCH, 1.0f, this, NULL, NULL))) - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED CreateSourceVoice"); - stop(); return false; - } - - _SourceVoice->SetVolume(_Gain); - _SourceVoice->Start(0); - } - else - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "no _MusicBuffer"); - return false; - } - - return true; -} - -/// Stop the music previously loaded and played (the Memory is also freed) -void CMusicChannelXAudio2::stop() -{ - if (_SourceVoice) { _SourceVoice->DestroyVoice(); _SourceVoice = NULL; } - if (_MusicBuffer) { delete _MusicBuffer; _MusicBuffer = NULL; } - // memset(_Buffer, 0, sizeof(_Buffer)); - _BufferPos = 0; -} - -/** Pause the music previously loaded and played (the Memory is not freed) - */ -void CMusicChannelXAudio2::pause() -{ - if (_SourceVoice) _SourceVoice->Stop(0); -} - -/// Resume the music previously paused -void CMusicChannelXAudio2::resume() -{ - if (_SourceVoice) _SourceVoice->Start(0); -} - -/// Return true if a song is finished. -bool CMusicChannelXAudio2::isEnded() -{ - if (_MusicBuffer) - { - if (!_MusicBuffer->isMusicEnded()) - return false; - } - if (_SourceVoice) - { - XAUDIO2_VOICE_STATE voice_state; - _SourceVoice->GetState(&voice_state); - if (voice_state.BuffersQueued) - { - // nldebug(NLSOUND_XAUDIO2_PREFIX "isEnded() -> voice_state.BuffersQueued, wait ..."); - return false; - } - } - // nldebug(NLSOUND_XAUDIO2_PREFIX "isEnded() -> stop()"); - stop(); - return true; -} - -/// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading -bool CMusicChannelXAudio2::isLoadingAsync() -{ - return false; -} - -/// Return the total length (in second) of the music currently played -float CMusicChannelXAudio2::getLength() -{ - if (_MusicBuffer) return _MusicBuffer->getLength(); - else return .0f; -} - -/** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: the volume of music is NOT affected by IListener::setGain() - */ -void CMusicChannelXAudio2::setVolume(float gain) -{ - _Gain = gain; - if (_SourceVoice) _SourceVoice->SetVolume(gain); -} - -void CMusicChannelXAudio2::OnVoiceProcessingPassStart(UINT32 BytesRequired) -{ - if (BytesRequired > 0) - { - // nlwarning(NLSOUND_XAUDIO2_PREFIX "Bytes Required: %u", BytesRequired); // byte req to not have disruption - - if (_MusicBuffer) - { - uint32 minimum = BytesRequired * 2; // give some more than required :p - if (_MusicBuffer->getRequiredBytes() > minimum) minimum = _MusicBuffer->getRequiredBytes(); - if (minimum > sizeof(_Buffer) - _BufferPos) _BufferPos = 0; - uint32 maximum = sizeof(_Buffer) - _BufferPos; - uint8 *buffer = &_Buffer[_BufferPos]; - uint32 length = _MusicBuffer->getNextBytes(buffer, minimum, maximum); - _BufferPos += length; - - if (length) - { - XAUDIO2_BUFFER xbuffer; - xbuffer.AudioBytes = length; - xbuffer.Flags = 0; - xbuffer.LoopBegin = 0; - xbuffer.LoopCount = 0; - xbuffer.LoopLength = 0; - xbuffer.pAudioData = buffer; - xbuffer.pContext = NULL; // nothing here for now - xbuffer.PlayBegin = 0; - xbuffer.PlayLength = 0; - - _SourceVoice->SubmitSourceBuffer(&xbuffer); - } - else - { - // nldebug(NLSOUND_XAUDIO2_PREFIX "!length -> delete _MusicBuffer"); - // set member var to null before deleting it to avoid crashing main thread - IMusicBuffer *music_buffer = _MusicBuffer; - _MusicBuffer = NULL; delete music_buffer; - _SourceVoice->Discontinuity(); - } - } - } -} - -void CMusicChannelXAudio2::OnVoiceProcessingPassEnd() -{ - -} - -void CMusicChannelXAudio2::OnStreamEnd() -{ - -} - -void CMusicChannelXAudio2::OnBufferStart(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnBufferEnd(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnLoopEnd(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnVoiceError(void * /* pBufferContext */, HRESULT /* Error */) -{ - -} - -} /* namespace NLSOUND */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h b/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h deleted file mode 100644 index ade13e25f..000000000 --- a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h +++ /dev/null @@ -1,117 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program 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. -// -// 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NLSOUND_MUSIC_CHANNEL_XAUDIO2_H -#define NLSOUND_MUSIC_CHANNEL_XAUDIO2_H - -#include - -namespace NLSOUND { - class CSoundDriverXAudio2; - class IMusicBuffer; - -/** - * \brief CMusicChannelXAudio2 - * \date 2008-08-30 13:31GMT - * \author Jan Boon (Kaetemi) - * CMusicChannelXAudio2 is an implementation of the IMusicChannel interface to run on XAudio2. - * TODO: Properly decode the audio on a seperate thread. - * TODO: Change IMusicChannel to IAudioStream, and fix the interface to make more sense. - */ -class CMusicChannelXAudio2 : public IMusicChannel, IXAudio2VoiceCallback -{ -protected: - // outside pointers - CSoundDriverXAudio2 *_SoundDriver; - - // pointers - IMusicBuffer *_MusicBuffer; - IXAudio2SourceVoice *_SourceVoice; - // todo: thread for async loading of music buffer and source voice - // isasyncloading checks if thread exists - // isended checks if not async loading too - - // instances - uint8 _Buffer[64 * 1024]; // no specific reason, lol - uint32 _BufferPos; // 0 - float _Gain; - -public: - CMusicChannelXAudio2(CSoundDriverXAudio2 *soundDriver); - virtual ~CMusicChannelXAudio2(); - void release(); - -private: - // XAudio2 Callbacks - // Called just before this voice's processing pass begins. - STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired); - // Called just after this voice's processing pass ends. - STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS); - // Called when this voice has just finished playing a buffer stream - // (as marked with the XAUDIO2_END_OF_STREAM flag on the last buffer). - STDMETHOD_(void, OnStreamEnd) (THIS); - // Called when this voice is about to start processing a new buffer. - STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext); - // Called when this voice has just finished processing a buffer. - // The buffer can now be reused or destroyed. - STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext); - // Called when this voice has just reached the end position of a loop. - STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext); - // Called in the event of a critical error during voice processing, - // such as a failing XAPO or an error from the hardware XMA decoder. - // The voice may have to be destroyed and re-created to recover from - // the error. The callback arguments report which buffer was being - // processed when the error occurred, and its HRESULT code. - STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error); - -public: - /** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ - virtual bool play(const std::string &filepath, bool async, bool loop); - - /// Stop the music previously loaded and played (the Memory is also freed) - virtual void stop(); - - /// Pause the music previously loaded and played (the Memory is not freed) - virtual void pause(); - - /// Resume the music previously paused - virtual void resume(); - - /// Return true if a song is finished. - virtual bool isEnded(); - - /// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading - virtual bool isLoadingAsync(); - - /// Return the total length (in second) of the music currently played - virtual float getLength(); - - /** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: the volume of music is NOT affected by IListener::setGain() - */ - virtual void setVolume(float gain); -}; /* class CMusicChannelXAudio2 */ - -} /* namespace NLSOUND */ - -#endif /* #ifndef NLSOUND_MUSIC_CHANNEL_XAUDIO2_H */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp index 826f9973b..7c4ea9bbf 100644 --- a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp +++ b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp @@ -19,7 +19,6 @@ // Project includes #include "listener_xaudio2.h" #include "source_xaudio2.h" -#include "music_channel_xaudio2.h" #include "effect_xaudio2.h" #include "sound_driver_xaudio2.h" @@ -132,8 +131,7 @@ CSoundDriverXAudio2::CSoundDriverXAudio2(ISoundDriver::IStringMapperProvider * / : _XAudio2(NULL), _MasteringVoice(NULL), _Listener(NULL), _SoundDriverOk(false), _CoInitOk(false), _OperationSetCounter(65536), _PerformanceCommit3DCounter(0), _PerformanceADPCMBufferSize(0), - _PerformancePCMBufferSize(0), _PerformanceMusicPlayCounter(0), - _PerformanceSourcePlayCounter(0) + _PerformancePCMBufferSize(0), _PerformanceSourcePlayCounter(0) { nlwarning(NLSOUND_XAUDIO2_PREFIX "Creating CSoundDriverXAudio2"); @@ -200,14 +198,6 @@ void CSoundDriverXAudio2::release() // WARNING: Only internal resources are released here, // the created instances must still be released by the user! - // Release internal resources of all remaining IMusicChannel instances - if (_MusicChannels.size()) - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "_MusicChannels.size(): '%u'", (uint32)_MusicChannels.size()); - set::iterator it(_MusicChannels.begin()), end(_MusicChannels.end()); - for (; it != end; ++it) (*it)->release(); - _MusicChannels.clear(); - } // Release internal resources of all remaining ISource instances if (_Sources.size()) { @@ -396,14 +386,6 @@ void CSoundDriverXAudio2::destroySourceVoice(IXAudio2SourceVoice *sourceVoice) if (sourceVoice) sourceVoice->DestroyVoice(); } -/// Create a music channel -IMusicChannel *CSoundDriverXAudio2::createMusicChannel() -{ - CMusicChannelXAudio2 *music_channel = new CMusicChannelXAudio2(this); - _MusicChannels.insert(music_channel); - return static_cast(music_channel); -} - /// Create the listener instance IListener *CSoundDriverXAudio2::createListener() { @@ -481,7 +463,6 @@ void CSoundDriverXAudio2::writeProfile(std::string& out) + "\n\tPCMBufferSize: " + toString(_PerformancePCMBufferSize) + "\n\tADPCMBufferSize: " + toString(_PerformanceADPCMBufferSize) + "\n\tSourcePlayCounter: " + toString(_PerformanceSourcePlayCounter) - + "\n\tMusicPlayCounter: " + toString(_PerformanceMusicPlayCounter) + "\n\tCommit3DCounter: " + toString(_PerformanceCommit3DCounter) + "\nXAUDIO2_PERFORMANCE_DATA" + "\n\tAudioCyclesSinceLastQuery: " + toString(performance.AudioCyclesSinceLastQuery) @@ -519,17 +500,6 @@ void CSoundDriverXAudio2::displayBench(NLMISC::CLog *log) NLMISC::CHTimer::display(log, CHTimer::TotalTime); } -/** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ -bool CSoundDriverXAudio2::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title) -{ - // add support for additional non-standard music file types info here - return IMusicBuffer::getInfo(filepath, artist, title); -} - /// Remove a buffer (should be called by the friend destructor of the buffer class) void CSoundDriverXAudio2::removeBuffer(CBufferXAudio2 *buffer) { @@ -543,13 +513,6 @@ void CSoundDriverXAudio2::removeSource(CSourceXAudio2 *source) if (_Sources.find(source) != _Sources.end()) _Sources.erase(source); else nlwarning("removeSource already called"); } - -/// (Internal) Remove a source (should be called by the destructor of the source class). -void CSoundDriverXAudio2::removeMusicChannel(CMusicChannelXAudio2 *musicChannel) -{ - if (_MusicChannels.find(musicChannel) != _MusicChannels.end()) _MusicChannels.erase(musicChannel); - else nlwarning("removeMusicChannel already called"); -} /// (Internal) Remove an effect (should be called by the destructor of the effect class) void CSoundDriverXAudio2::removeEffect(CEffectXAudio2 *effect) diff --git a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h index 681d36254..bcf847a5f 100644 --- a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h +++ b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h @@ -62,8 +62,6 @@ protected: std::set _Sources; /// Array with the allocated effects created by client code. std::set _Effects; - /// Array with the allocated music channels created by client code. - std::set _MusicChannels; /// Initialization Handle of X3DAudio. X3DAUDIO_HANDLE _X3DAudioHandle; //I /// Operation set counter @@ -73,7 +71,6 @@ protected: uint _PerformancePCMBufferSize; uint _PerformanceADPCMBufferSize; uint _PerformanceSourcePlayCounter; - uint _PerformanceMusicPlayCounter; uint _PerformanceCommit3DCounter; // user init vars @@ -108,8 +105,6 @@ public: } /// (Internal) Increase the source play counter by one. inline void performanceIncreaseSourcePlayCounter() { ++_PerformanceSourcePlayCounter; } - /// (Internal) Increase the music play counter by one. - inline void performanceIncreaseMusicPlayCounter() { ++_PerformanceMusicPlayCounter; } /// (Internal) Increase the commit 3d counter by one. inline void performanceIncreaseCommit3DCounter() { ++_PerformanceCommit3DCounter; } @@ -172,16 +167,6 @@ public: virtual void startBench(); virtual void endBench(); virtual void displayBench(NLMISC::CLog *log); - - /// Create a music channel, destroy with destroyMusicChannel. - virtual IMusicChannel *createMusicChannel(); - - /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ - virtual bool getMusicInfo(const std::string &filepath, std::string &artist, std::string &title); /// Get audio/container extensions that are supported natively by the driver implementation. virtual void getMusicExtensions(std::vector & /* extensions */) const { } @@ -192,8 +177,6 @@ public: void removeBuffer(CBufferXAudio2 *buffer); /// (Internal) Remove a source (should be called by the destructor of the source class). void removeSource(CSourceXAudio2 *source); - /// (Internal) Remove a source (should be called by the destructor of the music channel class). - void removeMusicChannel(CMusicChannelXAudio2 *musicChannel); /// (Internal) Remove the listener (should be called by the destructor of the listener class) inline void removeListener(CListenerXAudio2 *listener) { nlassert(_Listener == listener); _Listener = NULL; } /// (Internal) Remove an effect (should be called by the destructor of the effect class) diff --git a/code/nel/src/sound/driver/xaudio2/stdxaudio2.h b/code/nel/src/sound/driver/xaudio2/stdxaudio2.h index c043f3949..1a1d766e7 100644 --- a/code/nel/src/sound/driver/xaudio2/stdxaudio2.h +++ b/code/nel/src/sound/driver/xaudio2/stdxaudio2.h @@ -57,7 +57,6 @@ #include "nel/sound/driver/listener.h" #include "nel/sound/driver/sound_driver.h" #include "nel/sound/driver/source.h" -#include "nel/sound/driver/music_buffer.h" // Defines #define NLSOUND_XAUDIO2_NAME "NeLSound XAudio2 Driver"