sfxXAudioBuffer.cpp
Engine/source/sfx/xaudio/sfxXAudioBuffer.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "sfx/xaudio/sfxXAudioBuffer.h" 25#include "sfx/xaudio/sfxXAudioVoice.h" 26 27 28//#define DEBUG_SPEW 29 30 31SFXXAudioBuffer* SFXXAudioBuffer::create( const ThreadSafeRef< SFXStream>& stream, SFXDescription* description ) 32{ 33 SFXXAudioBuffer *buffer = new SFXXAudioBuffer( stream, description ); 34 return buffer; 35} 36 37SFXXAudioBuffer::SFXXAudioBuffer( const ThreadSafeRef< SFXStream>& stream, SFXDescription* description ) 38 : Parent( stream, description ) 39{ 40 VECTOR_SET_ASSOCIATION( mBufferQueue ); 41} 42 43SFXXAudioBuffer::~SFXXAudioBuffer() 44{ 45 _flush(); 46} 47 48void SFXXAudioBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) 49{ 50 AssertFatal( SFXInternal::isSFXThread(), "SFXXAudioBuffer::write() - not on SFX thread" ); 51 52 using namespace SFXInternal; 53 54 // Unqueue processed packets. 55 56 if( isStreaming() ) 57 { 58 EnterCriticalSection( &_getUniqueVoice()->mLock ); 59 60 XAUDIO2_VOICE_STATE state; 61 _getUniqueVoice()->mXAudioVoice->GetState( &state ); 62 63 U32 numProcessed = mBufferQueue.size() - state.BuffersQueued; 64 for( U32 i = 0; i < numProcessed; ++ i ) 65 { 66 destructSingle< SFXStreamPacket* >( mBufferQueue.first().mPacket ); 67 mBufferQueue.pop_front(); 68 69 #ifdef DEBUG_SPEW 70 Platform::outputDebugString( "[SFXXAudioBuffer] Unqueued packet" ); 71 #endif 72 } 73 74 LeaveCriticalSection( &_getUniqueVoice()->mLock ); 75 } 76 77 // Queue new packets. 78 79 for( U32 i = 0; i < num; ++ i ) 80 { 81 SFXStreamPacket* packet = packets[ i ]; 82 Buffer buffer; 83 84 if( packet->mIsLast ) 85 buffer.mData.Flags = XAUDIO2_END_OF_STREAM; 86 87 buffer.mPacket = packet; 88 buffer.mData.AudioBytes = packet->mSizeActual; 89 buffer.mData.pAudioData = packet->data; 90 91 mBufferQueue.push_back( buffer ); 92 93 #ifdef DEBUG_SPEW 94 Platform::outputDebugString( "[SFXXAudioBuffer] Queued packet" ); 95 #endif 96 97 // If this is a streaming buffer, submit the packet to the 98 // voice queue right away. 99 100 if( isStreaming() ) 101 { 102 EnterCriticalSection( &_getUniqueVoice()->mLock ); 103 104 IXAudio2SourceVoice* voice = _getUniqueVoice()->mXAudioVoice; 105 voice->SubmitSourceBuffer( &buffer.mData ); 106 107 LeaveCriticalSection( &_getUniqueVoice()->mLock ); 108 } 109 } 110} 111 112void SFXXAudioBuffer::_flush() 113{ 114 #ifdef DEBUG_SPEW 115 Platform::outputDebugString( "[SFXXAudioBuffer] Flushing buffer" ); 116 #endif 117 118 if( _getUniqueVoice() ) 119 _getUniqueVoice()->_stop(); 120 121 while( !mBufferQueue.empty() ) 122 { 123 destructSingle( mBufferQueue.last().mPacket ); 124 mBufferQueue.pop_back(); 125 } 126} 127