unsafe protected override void PreDetachVirtualChannel() { DirectSoundWorld.criticalSection.Enter(); DirectFileStreamSound currentFileStreamSound = currentSound as DirectFileStreamSound; if( currentFileStreamSound != null ) DirectSoundWorld.Instance.fileStreamRealChannels.Remove( this ); if( currentSound3DBuffer != null ) { IDirectSound3DBuffer8.Release( currentSound3DBuffer ); currentSound3DBuffer = null; } if( currentSoundBuffer != null ) { IDirectSoundBuffer.Stop( currentSoundBuffer ); currentSound.FreeBuffer( currentSoundBuffer ); currentSoundBuffer = null; } if( streamBuffer != null ) { NativeUtils.Free( (IntPtr)streamBuffer ); streamBuffer = null; } needStopAfterBufferRead = false; streamBufferLength = 0; needStopVirtualChannel = false; currentSound = null; DirectSoundWorld.criticalSection.Leave(); }
unsafe protected override void PostAttachVirtualChannel() { DirectSoundWorld.criticalSection.Enter(); int hr; currentSound = (DirectSound)CurrentVirtualChannel.CurrentSound; bool mode3d = (int)( currentSound.Mode & SoundMode.Mode3D ) != 0; bool loop = (int)( currentSound.Mode & SoundMode.Loop ) != 0; //DirectSampleSound DirectSampleSound currentSampleSound = currentSound as DirectSampleSound; if( currentSampleSound != null ) { int lastBufferCount = currentSound.soundBuffers.Count; currentSoundBuffer = currentSound.GetBuffer( currentSampleSound.soundSamples.Length ); if( currentSoundBuffer == null ) { PreDetachVirtualChannel(); DirectSoundWorld.criticalSection.Leave(); return; } bool needFillData = false; if( lastBufferCount == 0 ) needFillData = true; bool restored = false; if( !currentSound.RestoreSoundBuffers( out restored ) ) { PreDetachVirtualChannel(); DirectSoundWorld.criticalSection.Leave(); return; } if( restored ) needFillData = true; if( needFillData ) { if( !currentSampleSound.FillSoundBuffersWithData() ) { PreDetachVirtualChannel(); DirectSoundWorld.criticalSection.Leave(); return; } } } //DirectFileStreamSound, DirectDataStreamSound DirectFileStreamSound currentFileStreamSound = currentSound as DirectFileStreamSound; DirectDataStreamSound currentDataStreamSound = currentSound as DirectDataStreamSound; if( currentFileStreamSound != null || currentDataStreamSound != null ) { int needBufferSize; if( currentFileStreamSound != null ) { int numSamples = (int)currentFileStreamSound.vorbisFile.pcm_total( -1 ); int channels; int rate; currentFileStreamSound.vorbisFile.get_info( -1, out channels, out rate ); int sizeInBytes = numSamples * channels * 2; needBufferSize = sizeInBytes / 2; if( needBufferSize > 65536 * 2 ) needBufferSize = 65536 * 2; } else { needBufferSize = currentDataStreamSound.creationBufferSize; } currentSoundBuffer = currentSound.GetBuffer( needBufferSize ); if( currentSoundBuffer == null ) { PreDetachVirtualChannel(); DirectSoundWorld.criticalSection.Leave(); return; } streamBuffer = (byte*)NativeUtils.Alloc( NativeMemoryAllocationType.SoundAndVideo, currentSound.bufferSize ); streamBufferLength = 0; bool restored = false; if( !currentSound.RestoreSoundBuffers( out restored ) ) { PreDetachVirtualChannel(); DirectSoundWorld.criticalSection.Leave(); return; } if( restored ) { //buffer will be cleared in the BeginStreamPlay() } } //currentSound3DBuffer if( mode3d ) { void*/*IDirectSound3DBuffer8*/ sound3DBuffer; GUID guid = DSound.IID_IDirectSound3DBuffer8; hr = IDirectSoundBuffer.QueryInterface( currentSoundBuffer, ref guid, &sound3DBuffer ); if( Wrapper.FAILED( hr ) ) { PreDetachVirtualChannel(); DirectSoundWorld.Warning( "IDirectSoundBuffer.QueryInterface", hr ); DirectSoundWorld.criticalSection.Leave(); return; } currentSound3DBuffer = (IDirectSound3DBuffer8*)sound3DBuffer; } //update parameters if( mode3d ) { UpdatePosition2(); UpdateVelocity2(); } else UpdatePan2(); UpdatePitch2(); UpdateVolume2(); UpdateTime2(); if( currentFileStreamSound != null || currentDataStreamSound != null ) BeginStreamPlay(); uint playFlags = 0; if( loop || currentFileStreamSound != null || currentDataStreamSound != null ) playFlags |= DSound.DSBPLAY_LOOPING; hr = IDirectSoundBuffer.Play( currentSoundBuffer, 0, 0, playFlags ); if( Wrapper.FAILED( hr ) ) { PreDetachVirtualChannel(); DirectSoundWorld.Warning( "IDirectSoundBuffer.Play", hr ); DirectSoundWorld.criticalSection.Leave(); return; } if( currentFileStreamSound != null ) DirectSoundWorld.Instance.fileStreamRealChannels.Add( this ); needStopVirtualChannel = false; DirectSoundWorld.criticalSection.Leave(); }