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);
        }
        unsafe protected override void ShutdownLibrary()
        {
            if (thread != null)
            {
                needAbortThread = true;
                Thread.Sleep(50);
                thread.Abort();
            }

            if (realChannels != null)
            {
                realChannels.Clear();
                realChannels = null;
            }

            if (directSound != null)
            {
                IDirectSound8.Release(directSound);
                directSound = null;
            }

            if (criticalSection != null)
            {
                criticalSection.Dispose();
                criticalSection = null;
            }

            instance = null;
        }
        //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();
        }
        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);
        }
示例#9
0
        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;
            }
        }
        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);
            }
        }
示例#12
0
        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);
            }
        }
示例#14
0
        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 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();
                    }
                }
            }
        }
示例#16
0
        //

        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;
        }
示例#17
0
        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;
        }
示例#18
0
        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 protected override bool InitLibrary(IntPtr mainWindowHandle,
                                                   int maxReal2DChannels, int maxReal3DChannels)
        {
            NativeLibraryManager.PreLoadLibrary("libogg");
            NativeLibraryManager.PreLoadLibrary("libvorbis");
            NativeLibraryManager.PreLoadLibrary("libvorbisfile");
            NativeLibraryManager.PreLoadLibrary("DirectSoundNativeWrapper");

            {
                DSoundStructureSizes sizes = new DSoundStructureSizes();
                sizes.Init();

                DSoundStructureSizes originalSizes;
                DSound.GetStructureSizes(out originalSizes);

                FieldInfo[] fields = sizes.GetType().GetFields(
                    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                foreach (FieldInfo field in fields)
                {
                    int originalSize = (int)field.GetValue(originalSizes);
                    int size         = (int)field.GetValue(sizes);

                    if (originalSize != size)
                    {
                        Log.Fatal("DirectXSoundSystem: Invalid unmanaged bridge. " +
                                  "Invalid \"{0}\". Native size = \"{1}\". Managed size = \"{2}\".", field.Name,
                                  originalSize, size);
                        return(false);
                    }
                }
            }

            instance = this;

            criticalSection = CriticalSection.Create();

            DSound.CoInitialize(null);

            int hr;

            //create IDirectSound using the primary sound device
            void */*IDirectSound8*/ directSoundTemp;

            hr = DSound.DirectSoundCreate8(null, out directSoundTemp, null);
            if (Wrapper.FAILED(hr))
            {
                if (hr == DSound.Get_DSERR_NODRIVER())
                {
                    Log.InvisibleInfo("DirectXSoundSystem: No sound driver.");
                    return(false);
                }

                Error("DirectSoundCreate8", hr);
                return(false);
            }
            directSound = (IDirectSound8 *)directSoundTemp;

            //set DirectSound cooperative level
            hWnd = mainWindowHandle;
            hr   = IDirectSound8.SetCooperativeLevel(directSound, hWnd, DSound.DSSCL_PRIORITY);
            if (Wrapper.FAILED(hr))
            {
                Error("SetCooperativeLevel", hr);
                return(false);
            }

            //set primary buffer format
            {
                hr = SetPrimaryBufferFormat(2, 44100, 16, false);
                if (Wrapper.FAILED(hr))
                {
                    hr = SetPrimaryBufferFormat(2, 22050, 16, true);
                }
                if (Wrapper.FAILED(hr))
                {
                    return(false);
                }
            }

            //get listener
            {
                void */*IDirectSoundBuffer*/ primaryBuffer = null;

                // Obtain primary buffer, asking it for 3D control
                DSBUFFERDESC bufferDesc = new DSBUFFERDESC();
                //ZeroMemory( &bufferDesc, sizeof( DSBUFFERDESC ) );
                bufferDesc.dwSize  = (uint)sizeof(DSBUFFERDESC);
                bufferDesc.dwFlags = DSound.DSBCAPS_CTRL3D | DSound.DSBCAPS_PRIMARYBUFFER;

                hr = IDirectSound8.CreateSoundBuffer(directSound, ref bufferDesc,
                                                     out primaryBuffer, null);
                if (Wrapper.FAILED(hr))
                {
                    Error("CreateSoundBuffer", hr);
                    return(false);
                }

                void */*IDirectSound3DListener*/ listenerTemp = null;

                GUID guid = DSound.IID_IDirectSound3DListener;
                if (Wrapper.FAILED(hr = IDirectSoundBuffer.QueryInterface(primaryBuffer,
                                                                          ref guid, &listenerTemp)))
                {
                    IDirectSoundBuffer.Release(primaryBuffer);
                    Error("QueryInterface", hr);
                    return(false);
                }
                listener = (IDirectSound3DListener *)listenerTemp;

                IDirectSoundBuffer.Release(primaryBuffer);
            }

            //update general parameters
            {
                DS3DLISTENER parameters = new DS3DLISTENER();
                parameters.dwSize = (uint)sizeof(DS3DLISTENER);
                IDirectSound3DListener.GetAllParameters(listener, ref parameters);
                parameters.flDistanceFactor = 1;
                parameters.flRolloffFactor  = 0;
                parameters.flDopplerFactor  = DopplerScale;
                hr = IDirectSound3DListener.SetAllParameters(listener, ref parameters, DSound.DS3D_IMMEDIATE);
                if (Wrapper.FAILED(hr))
                {
                    Warning("IDirectSound3DListener.SetAllParameters", hr);
                }
            }

            GenerateRecordDriverList();

            //Channels
            realChannels = new List <DirectSoundRealChannel>();
            for (int n = 0; n < maxReal2DChannels; n++)
            {
                DirectSoundRealChannel realChannel = new DirectSoundRealChannel();
                AddRealChannel(realChannel, false);
                realChannels.Add(realChannel);
            }
            for (int n = 0; n < maxReal3DChannels; n++)
            {
                DirectSoundRealChannel realChannel = new DirectSoundRealChannel();
                AddRealChannel(realChannel, true);
                realChannels.Add(realChannel);
            }

            fileStreamRealChannels = new List <DirectSoundRealChannel>();

            thread = new Thread(new ThreadStart(ThreadFunction));
            thread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
            thread.IsBackground   = true;
            thread.Start();

            return(true);
        }
        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);
        }
示例#21
0
		unsafe protected override void ShutdownLibrary()
		{
			if( thread != null )
			{
				needAbortThread = true;
				Thread.Sleep( 50 );
				thread.Abort();
			}

			if( realChannels != null )
			{
				realChannels.Clear();
				realChannels = null;
			}

			if( directSound != null )
			{
				IDirectSound8.Release( directSound );
				directSound = null;
			}

			if( criticalSection != null )
			{
				criticalSection.Dispose();
				criticalSection = null;
			}

			instance = null;
		}
示例#22
0
        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 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();
        }
示例#24
0
        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);
        }
示例#25
0
		unsafe protected override bool InitLibrary( IntPtr mainWindowHandle,
			int maxReal2DChannels, int maxReal3DChannels )
		{
			NativeLibraryManager.PreLoadLibrary( "libogg" );
			NativeLibraryManager.PreLoadLibrary( "libvorbis" );
			NativeLibraryManager.PreLoadLibrary( "libvorbisfile" );
			NativeLibraryManager.PreLoadLibrary( "DirectSoundNativeWrapper" );

			{
				DSoundStructureSizes sizes = new DSoundStructureSizes();
				sizes.Init();

				DSoundStructureSizes originalSizes;
				DSound.GetStructureSizes( out originalSizes );

				FieldInfo[] fields = sizes.GetType().GetFields(
					BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );

				foreach( FieldInfo field in fields )
				{
					int originalSize = (int)field.GetValue( originalSizes );
					int size = (int)field.GetValue( sizes );

					if( originalSize != size )
					{
						Log.Fatal( "DirectXSoundSystem: Invalid unmanaged bridge. " +
							"Invalid \"{0}\". Native size = \"{1}\". Managed size = \"{2}\".", field.Name,
							originalSize, size );
						return false;
					}
				}
			}

			instance = this;

			criticalSection = CriticalSection.Create();

			DSound.CoInitialize( null );

			int hr;

			//create IDirectSound using the primary sound device
			void*/*IDirectSound8*/ directSoundTemp;
			hr = DSound.DirectSoundCreate8( null, out directSoundTemp, null );
			if( Wrapper.FAILED( hr ) )
			{
				if( hr == DSound.Get_DSERR_NODRIVER() )
				{
					Log.InvisibleInfo( "DirectXSoundSystem: No sound driver." );
					return false;
				}

				Error( "DirectSoundCreate8", hr );
				return false;
			}
			directSound = (IDirectSound8*)directSoundTemp;

			//set DirectSound cooperative level
			hWnd = mainWindowHandle;
			hr = IDirectSound8.SetCooperativeLevel( directSound, hWnd, DSound.DSSCL_PRIORITY );
			if( Wrapper.FAILED( hr ) )
			{
				Error( "SetCooperativeLevel", hr );
				return false;
			}

			//set primary buffer format
			{
				hr = SetPrimaryBufferFormat( 2, 44100, 16, false );
				if( Wrapper.FAILED( hr ) )
					hr = SetPrimaryBufferFormat( 2, 22050, 16, true );
				if( Wrapper.FAILED( hr ) )
					return false;
			}

			//get listener
			{
				void*/*IDirectSoundBuffer*/ primaryBuffer = null;

				// Obtain primary buffer, asking it for 3D control
				DSBUFFERDESC bufferDesc = new DSBUFFERDESC();
				//ZeroMemory( &bufferDesc, sizeof( DSBUFFERDESC ) );
				bufferDesc.dwSize = (uint)sizeof( DSBUFFERDESC );
				bufferDesc.dwFlags = DSound.DSBCAPS_CTRL3D | DSound.DSBCAPS_PRIMARYBUFFER;

				hr = IDirectSound8.CreateSoundBuffer( directSound, ref bufferDesc,
					out primaryBuffer, null );
				if( Wrapper.FAILED( hr ) )
				{
					Error( "CreateSoundBuffer", hr );
					return false;
				}

				void*/*IDirectSound3DListener*/ listenerTemp = null;

				GUID guid = DSound.IID_IDirectSound3DListener;
				if( Wrapper.FAILED( hr = IDirectSoundBuffer.QueryInterface( primaryBuffer,
					ref guid, &listenerTemp ) ) )
				{
					IDirectSoundBuffer.Release( primaryBuffer );
					Error( "QueryInterface", hr );
					return false;
				}
				listener = (IDirectSound3DListener*)listenerTemp;

				IDirectSoundBuffer.Release( primaryBuffer );
			}

			//update general parameters
			{
				DS3DLISTENER parameters = new DS3DLISTENER();
				parameters.dwSize = (uint)sizeof( DS3DLISTENER );
				IDirectSound3DListener.GetAllParameters( listener, ref parameters );
				parameters.flDistanceFactor = 1;
				parameters.flRolloffFactor = 0;
				parameters.flDopplerFactor = DopplerScale;
				hr = IDirectSound3DListener.SetAllParameters( listener, ref parameters, DSound.DS3D_IMMEDIATE );
				if( Wrapper.FAILED( hr ) )
					Warning( "IDirectSound3DListener.SetAllParameters", hr );
			}

			GenerateRecordDriverList();

			//Channels
			realChannels = new List<DirectSoundRealChannel>();
			for( int n = 0; n < maxReal2DChannels; n++ )
			{
				DirectSoundRealChannel realChannel = new DirectSoundRealChannel();
				AddRealChannel( realChannel, false );
				realChannels.Add( realChannel );
			}
			for( int n = 0; n < maxReal3DChannels; n++ )
			{
				DirectSoundRealChannel realChannel = new DirectSoundRealChannel();
				AddRealChannel( realChannel, true );
				realChannels.Add( realChannel );
			}

			fileStreamRealChannels = new List<DirectSoundRealChannel>();

			thread = new Thread( new ThreadStart( ThreadFunction ) );
			thread.CurrentCulture = new System.Globalization.CultureInfo( "en-US" );
			thread.IsBackground = true;
			thread.Start();

			return true;
		}