unsafe public override bool RecordStart(Sound sound) { criticalSection.Enter(); DirectCaptureSound captureSound = sound as DirectCaptureSound; if (captureSound == null) { criticalSection.Leave(); DirectSoundWorld.Warning("Recording failed. Is sound a not for recording."); return(false); } captureSound.readPosition = 0; int hr = IDirectSoundCaptureBuffer.Start(captureSound.captureBuffer, DSound.DSCBSTART_LOOPING); if (Wrapper.FAILED(hr)) { criticalSection.Leave(); DirectSoundWorld.Warning("IDirectSoundCaptureBuffer.Start", hr); return(false); } recordingSound = captureSound; criticalSection.Leave(); return(true); }
//file,data streams unsafe void BeginStreamPlay() { //clear buffer { void *lockedBuffer = null; uint lockedBufferSize = 0; int hr = IDirectSoundBuffer.Lock(currentSoundBuffer, 0, (uint)currentSound.bufferSize, &lockedBuffer, &lockedBufferSize, (void **)null, (uint *)null, 0); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.Lock", hr); return; } NativeUtils.FillMemory((IntPtr)lockedBuffer, (int)lockedBufferSize, (byte)(currentSound.waveFormat->wBitsPerSample == 8 ? 128 : 0)); IDirectSoundBuffer.Unlock(currentSoundBuffer, lockedBuffer, lockedBufferSize, null, 0); } UpdateStreamBuffer(true); UpdateStreamBuffer(false); streamNeedWriteFirstPart = true; needStopAfterBufferRead = false; }
//unsafe void UpdateMinDistance2() //{ // if( currentSound3DBuffer != null ) // { // float value = (float)CurrentVirtualChannel.MinDistance; // int hr = IDirectSound3DBuffer8.SetMinDistance( currentSound3DBuffer, value, // DSound.DS3D_IMMEDIATE ); // if( Wrapper.FAILED( hr ) ) // DirectSoundWorld.Warning( "IDirectSound3DBuffer8.SetMinDistance", hr ); // } //} //protected override void UpdateMinDistance() //{ // DirectSoundWorld.criticalSection.Enter(); // if( currentSound != null ) // UpdateMinDistance2(); // DirectSoundWorld.criticalSection.Leave(); //} unsafe void UpdatePitch2() { float pitch = (float)currentSound.waveFormat->nSamplesPerSec * CurrentVirtualChannel.GetTotalPitch(); int hr = IDirectSoundBuffer.SetFrequency(currentSoundBuffer, (uint)pitch); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.SetFrequency", hr); } }
unsafe void UpdateVelocity2() { if (currentSound3DBuffer != null) { Vec3 value = CurrentVirtualChannel.Velocity; int hr = IDirectSound3DBuffer8.SetVelocity(currentSound3DBuffer, value.X, value.Z, value.Y, DSound.DS3D_IMMEDIATE); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.SetVelocity", hr); } } }
unsafe public void UpdateStream() { if (currentSound == null) { return; } uint playPosition; uint writePosition; int hr = IDirectSoundBuffer.GetCurrentPosition(currentSoundBuffer, &playPosition, &writePosition); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.GetCurrentPosition", hr); return; } bool needRead; if (streamNeedWriteFirstPart) { needRead = (int)playPosition >= currentSound.bufferSize / 2 && (int)writePosition >= currentSound.bufferSize / 2; } else { needRead = (int)playPosition < currentSound.bufferSize / 2 && (int)writePosition < currentSound.bufferSize / 2; } if (needRead) { if (needStopAfterBufferRead) { needStopVirtualChannel = true; //CurrentVirtualChannel.Stop(); needStopAfterBufferRead = false; goto end; } UpdateStreamBuffer(streamNeedWriteFirstPart); streamNeedWriteFirstPart = !streamNeedWriteFirstPart; } end :; }
unsafe public override void RecordStop() { criticalSection.Enter(); if (recordingSound != null) { int hr = IDirectSoundCaptureBuffer.Stop(recordingSound.captureBuffer); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundCaptureBuffer.Stop", hr); } recordingSound = null; } criticalSection.Leave(); }
unsafe void UpdateSample() { uint status; int hr = IDirectSoundBuffer.GetStatus(currentSoundBuffer, out status); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.GetStatus", hr); return; } if ((status & DSound.DSBSTATUS_PLAYING) == 0) { CurrentVirtualChannel.Stop(); } }
unsafe void UpdatePan2() { float value = CurrentVirtualChannel.Pan; MathFunctions.Clamp(ref value, -1, 1); int pan; if (Math.Abs(value) < .001f) { pan = 0; } else if (value < -.999f) { pan = DSound.DSBPAN_LEFT; } else if (value > .999f) { pan = DSound.DSBPAN_RIGHT; } else { pan = (int)(20.0f * 100.0f * Math.Log10(1 - Math.Abs(value))); pan = Math.Abs(pan); if (value < 0) { pan = -pan; } if (pan < DSound.DSBPAN_LEFT) { pan = DSound.DSBPAN_LEFT; } if (pan > DSound.DSBPAN_RIGHT) { pan = DSound.DSBPAN_RIGHT; } } int hr = IDirectSoundBuffer.SetPan(currentSoundBuffer, pan); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.SetPan", hr); } }
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); }
public void Rewind() { if (vorbisFile != null) { vorbisFile.Dispose(); vorbisFile = null; } vorbisFileReader.RewindStreamToBegin(); vorbisFile = new VorbisFile.File(); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { DirectSoundWorld.Warning(string.Format("Creating sound failed \"{0}\".", Name)); return; } }
public unsafe bool RestoreSoundBuffers(out bool restored) { IDirectSoundBuffer *soundBuffer = (IDirectSoundBuffer *)soundBuffers[0].ToPointer(); int hr; restored = false; uint status; hr = IDirectSoundBuffer.GetStatus(soundBuffer, out status); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.GetStatus", hr); return(false); } if ((status & DSound.DSBSTATUS_BUFFERLOST) != 0) { int DSERR_BUFFERLOST = DSound.Get_DSERR_BUFFERLOST(); // Since the app could have just been activated, then // DirectSound may not be giving us control yet, so // the restoring the buffer may fail. // If it does, sleep until DirectSound gives us control. do { hr = IDirectSoundBuffer.Restore(soundBuffer); if (hr == DSERR_BUFFERLOST) { Thread.Sleep(10); } }while((hr = IDirectSoundBuffer.Restore(soundBuffer)) == DSERR_BUFFERLOST); restored = true; } return(true); }
unsafe void UpdateTime2() { float time = CurrentVirtualChannel.Time; //* 2 - 16 bit uint position = (uint)(time * ( currentSound.waveFormat->nChannels * currentSound.waveFormat->nSamplesPerSec * 2)); if (position >= (uint)currentSound.bufferSize - 4) { position = (uint)currentSound.bufferSize - 4; } position /= 4; position *= 4; int hr = IDirectSoundBuffer.SetCurrentPosition(currentSoundBuffer, position); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.SetCurrentPosition", hr); } }
unsafe public bool FillSoundBuffersWithData() { IDirectSoundBuffer *soundBuffer = (IDirectSoundBuffer *)soundBuffers[0].ToPointer(); int hr; void *lockedBuffer = null; uint lockedBufferSize = 0; hr = IDirectSoundBuffer.Lock(soundBuffer, 0, (uint)soundSamples.Length, &lockedBuffer, &lockedBufferSize, (void **)null, (uint *)null, 0); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.Lock", hr); return(false); } if ((int)lockedBufferSize < soundSamples.Length) { Log.Fatal("DirectSampleSound.FillSoundBuffersWithData: " + "lockedBufferSize >= soundSamples->Length"); } Marshal.Copy(soundSamples, 0, (IntPtr)lockedBuffer, soundSamples.Length); if (soundSamples.Length < (int)lockedBufferSize) { // fill with silence remaining bytes NativeUtils.FillMemory((IntPtr)((byte *)lockedBuffer + soundSamples.Length), (int)lockedBufferSize - soundSamples.Length, (byte)(waveFormat->wBitsPerSample == 8 ? 128 : 0)); } IDirectSoundBuffer.Unlock(soundBuffer, lockedBuffer, lockedBufferSize, (void *)null, 0); return(true); }
unsafe public override int RecordRead(byte[] buffer, int length) { DirectSoundWorld.criticalSection.Enter(); int hr; uint dwBufferPosition; hr = IDirectSoundCaptureBuffer.GetCurrentPosition(captureBuffer, (uint *)null, &dwBufferPosition); if (Wrapper.FAILED(hr)) { DirectSoundWorld.criticalSection.Leave(); return(0); } int bufferPosition = (int)dwBufferPosition; int bytesAvailable; if (bufferPosition >= readPosition) { bytesAvailable = bufferPosition - readPosition; } else { bytesAvailable = (bufferSize - readPosition) + bufferPosition; } int needLength = Math.Min(length, bytesAvailable); if (needLength == 0) { DirectSoundWorld.criticalSection.Leave(); return(0); } void *lockedBuffer = null; uint lockedBufferSize = 0; void *lockedBuffer2 = null; uint lockedBufferSize2 = 0; int startPosition = readPosition - needLength; if (startPosition < 0) { startPosition += bufferSize; } hr = IDirectSoundCaptureBuffer.Lock(captureBuffer, (uint)startPosition, (uint)needLength, &lockedBuffer, &lockedBufferSize, &lockedBuffer2, &lockedBufferSize2, 0); if (Wrapper.FAILED(hr)) { DirectSoundWorld.criticalSection.Leave(); DirectSoundWorld.Warning("IDirectSoundCaptureBuffer.Lock", hr); return(0); } if (lockedBuffer != null && lockedBufferSize != 0) { Marshal.Copy((IntPtr)lockedBuffer, buffer, 0, (int)lockedBufferSize); } if (lockedBuffer2 != null && lockedBufferSize2 != 0) { Marshal.Copy((IntPtr)lockedBuffer2, buffer, (int)lockedBufferSize, (int)lockedBufferSize2); } IDirectSoundCaptureBuffer.Unlock(captureBuffer, lockedBuffer, lockedBufferSize, lockedBuffer2, lockedBufferSize2); readPosition += needLength; if (readPosition >= bufferSize) { readPosition -= bufferSize; } DirectSoundWorld.criticalSection.Leave(); return((int)lockedBufferSize + (int)lockedBufferSize2); }
unsafe public DirectCaptureSound(SoundMode mode, int channels, int frequency, int bufferSize) { SoundMode newMode = mode | SoundMode.Loop | SoundMode.Software; int hr; if (DirectSoundWorld.Instance.recordDriverIndex == -1) { DirectSoundWorld.Warning("Recording failed. No active device."); return; } GUID deviceGuid = DirectSoundWorld.Instance.recordDriverGuids[ DirectSoundWorld.Instance.recordDriverIndex]; //soundCapture void */*IDirectSoundCapture8*/ tempSoundCapture; hr = DSound.DirectSoundCaptureCreate(&deviceGuid, out tempSoundCapture, null); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("DirectSoundCaptureCreate", hr); return; } soundCapture = (IDirectSoundCapture8 *)tempSoundCapture; //waveFormat waveFormat = (WAVEFORMATEX *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, sizeof(WAVEFORMATEX)); NativeUtils.ZeroMemory((IntPtr)waveFormat, sizeof(WAVEFORMATEX)); waveFormat->wFormatTag = DSound.WAVE_FORMAT_PCM; waveFormat->nChannels = (ushort)channels; waveFormat->nSamplesPerSec = (uint)frequency; waveFormat->wBitsPerSample = 16; waveFormat->nBlockAlign = (ushort)((waveFormat->nChannels * waveFormat->wBitsPerSample) / 8); waveFormat->nAvgBytesPerSec = waveFormat->nSamplesPerSec * waveFormat->nBlockAlign; //captureBuffer DSCBUFFERDESC bufferDesc = new DSCBUFFERDESC(); //ZeroMemory( &bufferDesc, sizeof( DSCBUFFERDESC ) ); bufferDesc.dwSize = (uint)sizeof(DSCBUFFERDESC); bufferDesc.dwBufferBytes = (uint)bufferSize; bufferDesc.lpwfxFormat = waveFormat; void */*IDirectSoundCaptureBuffer*/ tempCaptureBuffer; hr = IDirectSoundCapture8.CreateCaptureBuffer(soundCapture, ref bufferDesc, out tempCaptureBuffer, null); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("CreateCaptureBuffer", hr); IDirectSoundCapture8.Release(soundCapture); soundCapture = null; return; } captureBuffer = (IDirectSoundCaptureBuffer *)tempCaptureBuffer; //get bufferSize DSCBCAPS bufferCaps = new DSCBCAPS(); //ZeroMemory( &bufferCaps, sizeof( DSCBCAPS ) ); bufferCaps.dwSize = (uint)sizeof(DSCBCAPS); IDirectSoundCaptureBuffer.GetCaps(captureBuffer, ref bufferCaps); this.bufferSize = (int)bufferCaps.dwBufferBytes; Init(null, newMode, 100000.0f, channels, frequency); }
// unsafe public DirectFileStreamSound(VirtualFileStream stream, bool closeStreamAfterReading, SoundType soundType, string name, SoundMode mode, out bool initialized) { initialized = false; if (soundType == SoundType.Unknown) { if (name != null) { soundType = GetSoundTypeByName(name); } else { soundType = GetSoundTypeByStream(stream); } } if (soundType != SoundType.OGG) { DirectSoundWorld.Warning(string.Format( "Streaming is not supported for \"{0}\" files ({1}).", soundType, name)); return; } vorbisFile = new VorbisFile.File(); vorbisFileReader = new VorbisFileReader(stream, closeStreamAfterReading); if (!vorbisFileReader.OpenVorbisFile(vorbisFile)) { vorbisFileReader.Dispose(); DirectSoundWorld.Warning(string.Format("Creating sound \"{0}\" failed.", name)); return; } int channels; int frequency; long numSamples = vorbisFile.pcm_total(-1); vorbisFile.get_info(-1, out channels, out frequency); //convert to mono for 3D if ((int)(mode & SoundMode.Mode3D) != 0 && channels == 2) { needConvertToMono = true; channels = 1; } waveFormat = (WAVEFORMATEX *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, sizeof(WAVEFORMATEX)); NativeUtils.ZeroMemory((IntPtr)waveFormat, sizeof(WAVEFORMATEX)); waveFormat->wFormatTag = DSound.WAVE_FORMAT_PCM; waveFormat->nChannels = (ushort)channels; waveFormat->nSamplesPerSec = (uint)frequency; waveFormat->wBitsPerSample = 16; waveFormat->nBlockAlign = (ushort)((waveFormat->nChannels * waveFormat->wBitsPerSample) / 8); waveFormat->nAvgBytesPerSec = waveFormat->nSamplesPerSec * waveFormat->nBlockAlign; double length = (double)numSamples / (double)frequency; Init(name, mode, (float)length, channels, frequency); initialized = true; }
unsafe public DirectSampleSound(VirtualFileStream stream, SoundType soundType, string name, SoundMode mode, out bool initialized) { initialized = false; int channels; int frequency; float timeLength; if (soundType == SoundType.Unknown) { if (name != null) { soundType = GetSoundTypeByName(name); } else { soundType = GetSoundTypeByStream(stream); } } string error; if (!LoadSamplesFromStream(stream, soundType, out channels, out frequency, out timeLength, out error)) { if (name != null) { DirectSoundWorld.Warning(string.Format("Creating sound \"{0}\" failed ({1}).", name, error)); } else { DirectSoundWorld.Warning(string.Format("Creating sound from stream failed ({0}).", error)); } return; } //convert to mono for 3D if ((int)(mode & SoundMode.Mode3D) != 0 && channels == 2) { byte[] oldSamples = soundSamples; soundSamples = new byte[oldSamples.Length / 2]; for (int n = 0; n < soundSamples.Length; n += 2) { soundSamples[n + 0] = oldSamples[n * 2 + 0]; soundSamples[n + 1] = oldSamples[n * 2 + 1]; } channels = 1; } //create buffer waveFormat = (WAVEFORMATEX *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, sizeof(WAVEFORMATEX)); NativeUtils.ZeroMemory((IntPtr)waveFormat, sizeof(WAVEFORMATEX)); waveFormat->wFormatTag = DSound.WAVE_FORMAT_PCM; waveFormat->nChannels = (ushort)channels; waveFormat->nSamplesPerSec = (uint)frequency; waveFormat->wBitsPerSample = 16; waveFormat->nBlockAlign = (ushort)((waveFormat->nChannels * waveFormat->wBitsPerSample) / 8); waveFormat->nAvgBytesPerSec = waveFormat->nSamplesPerSec * waveFormat->nBlockAlign; Init(name, mode, timeLength, channels, frequency); initialized = true; }
unsafe IDirectSoundBuffer *CreateBuffer(int needBufferSize) { uint creationFlags = 0; if ((int)(Mode & SoundMode.Mode3D) != 0) { creationFlags |= DSound.DSBCAPS_CTRL3D; } else { creationFlags |= DSound.DSBCAPS_CTRLPAN; } if ((int)(Mode & SoundMode.Software) != 0) { creationFlags |= DSound.DSBCAPS_LOCSOFTWARE; } creationFlags |= DSound.DSBCAPS_CTRLFREQUENCY; creationFlags |= DSound.DSBCAPS_CTRLVOLUME; creationFlags |= DSound.DSBCAPS_GETCURRENTPOSITION2; if ((creationFlags & DSound.DSBCAPS_CTRLFX) != 0) { //нельзя DuplicateSoundBuffer делать для DSBCAPS_CTRLFX //не забыть патом данные заливать во все буферы Log.Fatal("(creationFlags & DSBCAPS_CTRLFX) != 0."); } int hr; void */*IDirectSoundBuffer*/ soundBuffer; if (soundBuffers.Count == 0) { DSBUFFERDESC bufferDesc = new DSBUFFERDESC(); //ZeroMemory( &bufferDesc, sizeof( DSBUFFERDESC ) ); bufferDesc.dwSize = (uint)sizeof(DSBUFFERDESC); bufferDesc.dwFlags = creationFlags; bufferDesc.dwBufferBytes = (uint)needBufferSize; bufferDesc.guid3DAlgorithm = DSound.DS3DALG_DEFAULT; bufferDesc.lpwfxFormat = waveFormat; hr = IDirectSound8.CreateSoundBuffer(DirectSoundWorld.Instance.directSound, ref bufferDesc, out soundBuffer, null); //hr = DirectSoundWorld.Instance.directSound->CreateSoundBuffer( // &bufferDesc, &soundBuffer, NULL ); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("CreateSoundBuffer", hr); return(null); } //get bufferSize DSBCAPS bufferCaps = new DSBCAPS(); //ZeroMemory( &bufferCaps, sizeof( DSBCAPS ) ); bufferCaps.dwSize = (uint)sizeof(DSBCAPS); IDirectSoundBuffer.GetCaps(soundBuffer, ref bufferCaps); bufferSize = (int)bufferCaps.dwBufferBytes; } else { hr = IDirectSound8.DuplicateSoundBuffer(DirectSoundWorld.Instance.directSound, (IDirectSoundBuffer *)soundBuffers[0].ToPointer(), out soundBuffer); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("DuplicateSoundBuffer", hr); return(null); } } return((IDirectSoundBuffer *)soundBuffer); }
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); }
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 UpdateVolume2() { float value = CurrentVirtualChannel.GetTotalVolume() * CurrentVirtualChannel.GetRolloffFactor(); int volume; if (value > 0.001f) { volume = (int)(20.0f * 100.0f * Math.Log10(value)); } else { volume = DSound.DSBVOLUME_MIN; } if (volume < DSound.DSBVOLUME_MIN) { volume = DSound.DSBVOLUME_MIN; } if (volume > DSound.DSBVOLUME_MAX) { volume = DSound.DSBVOLUME_MAX; } //update volume for dublicate buffers (IDirectSoundBuffer8.SetVolume problem) //it need have volume not equal to original buffer. bool isOriginalBuffer = false; IDirectSoundBuffer *originalBuffer = (IDirectSoundBuffer *) currentSound.soundBuffers[0].ToPointer(); isOriginalBuffer = originalBuffer == currentSoundBuffer; if (!isOriginalBuffer) { int originalBufferVolume = 0; IDirectSoundBuffer.GetVolume(originalBuffer, out originalBufferVolume); if (volume == originalBufferVolume) { if (volume == DSound.DSBVOLUME_MAX) { volume = DSound.DSBVOLUME_MAX - 1; } else { volume++; } } } //change volume int hr = IDirectSoundBuffer.SetVolume(currentSoundBuffer, volume); if (Wrapper.FAILED(hr)) { DirectSoundWorld.Warning("IDirectSoundBuffer.SetVolume", hr); } //update volume of dublicate buffers if (isOriginalBuffer) { List <DirectSoundRealChannel> realChannels = DirectSoundWorld.Instance.realChannels; for (int nRealChannel = 0; nRealChannel < realChannels.Count; nRealChannel++) { DirectSoundRealChannel realChannel = realChannels[nRealChannel]; if (realChannel != this && realChannel.currentSound == currentSound) { realChannel.UpdateVolume(); } } } }