public override Sound SoundCreate(VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, SoundMode mode) { criticalSection.Enter(); DirectSound sound; bool initialized; if ((int)(mode & SoundMode.Stream) == 0) { sound = new DirectSampleSound(stream, soundType, null, mode, out initialized); if (closeStreamAfterReading) { stream.Close(); } } else { sound = new DirectFileStreamSound(stream, closeStreamAfterReading, soundType, null, mode, out initialized); } if (!initialized) { sound.Dispose(); sound = null; } criticalSection.Leave(); return(sound); }
//file stream unsafe int ReadDataFromFileStream(IntPtr buffer, int needRead) { DirectFileStreamSound currentFileStreamSound = (DirectFileStreamSound)currentSound; while (streamBufferLength < needRead) { int readBytes = currentFileStreamSound.vorbisFile.read( (IntPtr)(streamBuffer + streamBufferLength), currentSound.bufferSize - streamBufferLength, 0, 2, 1, IntPtr.Zero); //convert to mono for 3D if (readBytes > 0 && currentFileStreamSound.needConvertToMono) { byte *pointer = (byte *)streamBuffer + streamBufferLength; readBytes /= 2; for (int n = 0; n < readBytes; n += 2) { *(pointer + n + 0) = *(pointer + n * 2 + 0); *(pointer + n + 1) = *(pointer + n * 2 + 1); } } if (readBytes > 0) { streamBufferLength += readBytes; } else { break; } } if (streamBufferLength == 0) { return(0); } int totalReaded = Math.Min(streamBufferLength, needRead); NativeUtils.CopyMemory(buffer, (IntPtr)streamBuffer, totalReaded); streamBufferLength -= totalReaded; if (streamBufferLength > 0) { NativeUtils.MoveMemory((IntPtr)streamBuffer, (IntPtr)(streamBuffer + totalReaded), streamBufferLength); } return(totalReaded); }
public override Sound SoundCreate(string name, SoundMode mode) { criticalSection.Enter(); DirectSound sound; sound = (DirectSound)base.SoundCreate(name, mode); if (sound != null) { criticalSection.Leave(); return(sound); } VirtualFileStream stream = CreateFileStream(name); if (stream == null) { criticalSection.Leave(); DirectSoundWorld.Warning(string.Format("Creating sound \"{0}\" failed.", name)); return(null); } bool initialized; if ((int)(mode & SoundMode.Stream) == 0) { sound = new DirectSampleSound(stream, SoundType.Unknown, name, mode, out initialized); stream.Close(); } else { sound = new DirectFileStreamSound(stream, true, SoundType.Unknown, name, mode, out initialized); } if (!initialized) { sound.Dispose(); sound = null; } criticalSection.Leave(); return(sound); }
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(); }
unsafe void UpdateStreamBuffer(bool firstPart) { DirectFileStreamSound currentFileStreamSound = currentSound as DirectFileStreamSound; void *lockedBuffer = null; uint lockedBufferSize = 0; int hr = IDirectSoundBuffer.Lock(currentSoundBuffer, (uint)(firstPart ? 0 : currentSound.bufferSize / 2), (uint)(currentSound.bufferSize / 2), &lockedBuffer, &lockedBufferSize, (void **)null, (uint *)null, 0); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.Lock", hr); return; } if ((int)lockedBufferSize < currentSound.bufferSize / 2) { Log.Fatal("DirectSoundRealChannel.UpdateStreamBuffer: " + "lockedBufferSize >= currentSound->bufferSize / 2."); } bool repeated = false; int readed = 0; again: if (currentFileStreamSound != null) { readed += ReadDataFromFileStream((IntPtr)((byte *)lockedBuffer + readed), currentSound.bufferSize / 2 - readed); } else { readed += ReadDataFromDataStream((IntPtr)((byte *)lockedBuffer + readed), currentSound.bufferSize / 2 - readed); } if (readed < currentSound.bufferSize / 2) { NativeUtils.FillMemory((IntPtr)((byte *)lockedBuffer + readed), (int)lockedBufferSize - readed, (byte)(currentSound.waveFormat->wBitsPerSample == 8 ? 128 : 0)); if ((int)(currentSound.Mode & SoundMode.Loop) != 0) { if (currentFileStreamSound != null) { //loop play. we need recreate vorbis file currentFileStreamSound.Rewind(); if (!repeated) { repeated = true; goto again; } } } } if (readed == 0) { //need stop if ((int)(currentSound.Mode & SoundMode.Loop) == 0) { if (currentFileStreamSound != null) { needStopAfterBufferRead = true; } } } IDirectSoundBuffer.Unlock(currentSoundBuffer, lockedBuffer, lockedBufferSize, null, 0); }
public override Sound SoundCreate( VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, SoundMode mode ) { criticalSection.Enter(); DirectSound sound; bool initialized; if( (int)( mode & SoundMode.Stream ) == 0 ) { sound = new DirectSampleSound( stream, soundType, null, mode, out initialized ); if( closeStreamAfterReading ) stream.Close(); } else { sound = new DirectFileStreamSound( stream, closeStreamAfterReading, soundType, null, mode, out initialized ); } if( !initialized ) { sound.Dispose(); sound = null; } criticalSection.Leave(); return sound; }
public override Sound SoundCreate( string name, SoundMode mode ) { criticalSection.Enter(); DirectSound sound; sound = (DirectSound)base.SoundCreate( name, mode ); if( sound != null ) { criticalSection.Leave(); return sound; } VirtualFileStream stream = CreateFileStream( name ); if( stream == null ) { criticalSection.Leave(); DirectSoundWorld.Warning( string.Format( "Creating sound \"{0}\" failed.", name ) ); return null; } bool initialized; if( (int)( mode & SoundMode.Stream ) == 0 ) { sound = new DirectSampleSound( stream, SoundType.Unknown, name, mode, out initialized ); stream.Close(); } else { sound = new DirectFileStreamSound( stream, true, SoundType.Unknown, name, mode, out initialized ); } if( !initialized ) { sound.Dispose(); sound = null; } criticalSection.Leave(); return sound; }