예제 #1
0
        unsafe public DirectDataStreamSound(SoundMode mode, int channels, int frequency, int bufferSize,
                                            SoundWorld.DataReadDelegate dataReadCallback)
        {
            this.dataReadCallback   = dataReadCallback;
            this.creationBufferSize = bufferSize;

            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(null, mode, 100000.0f, channels, frequency);
        }
예제 #2
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);
        }
예제 #3
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;
        }
예제 #4
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;
        }
        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();
        }
예제 #6
0
        unsafe protected override void PostAttachVirtualChannel()
        {
            OpenALSoundWorld.criticalSection.Enter();

            currentSound = (OpenALSound)CurrentVirtualChannel.CurrentSound;

            OpenALSampleSound     sampleSound     = currentSound as OpenALSampleSound;
            OpenALDataBufferSound streamSound     = null;
            OpenALFileStreamSound fileStreamSound = null;
            OpenALDataStreamSound dataStreamSound = null;

            if (sampleSound == null)
            {
                streamSound     = currentSound as OpenALDataBufferSound;
                fileStreamSound = currentSound as OpenALFileStreamSound;
                dataStreamSound = currentSound as OpenALDataStreamSound;
            }

            //create streamBuffer
            if (fileStreamSound != null)
            {
                int bufferSize = 0;

                int numSamples = (int)fileStreamSound.vorbisFile.pcm_total(-1);
                int channels;
                int rate;
                fileStreamSound.vorbisFile.get_info(-1, out channels, out rate);

                if (fileStreamSound.needConvertToMono)
                {
                    channels = 1;
                }

                int sizeInBytes = numSamples * channels * 2;

                bufferSize = sizeInBytes / 2;
                if (bufferSize > 65536 * 4)
                {
                    bufferSize = 65536 * 4;
                }

                streamBufferSize = bufferSize;
                streamBuffer     = (byte *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo, streamBufferSize);
            }

            if (dataStreamSound != null)
            {
                streamBufferSize = dataStreamSound.bufferSize;
                streamBuffer     = (byte *)NativeUtils.Alloc(NativeMemoryAllocationType.SoundAndVideo,
                                                             streamBufferSize);
            }

            //init source

            bool mode3d = (currentSound.Mode & SoundMode.Mode3D) != 0;
            bool loop   = (currentSound.Mode & SoundMode.Loop) != 0;

            if (alSource == 0)
            {
                Al.alGenSources(1, out alSource);
                if (OpenALSoundWorld.CheckError())
                {
                    PreDetachVirtualChannel();
                    OpenALSoundWorld.criticalSection.Leave();
                    return;
                }
            }


            if (sampleSound != null)
            {
                //no stream sound
                Al.alSourcei(alSource, Al.AL_BUFFER, sampleSound.alBuffer);
                if (OpenALSoundWorld.CheckError())
                {
                    PreDetachVirtualChannel();
                    OpenALSoundWorld.criticalSection.Leave();
                    return;
                }
            }

            if (fileStreamSound != null)
            {
                FileStreamStartPlay();
            }

            if (dataStreamSound != null)
            {
                DataStreamStartPlay();
            }

            Al.alSourcei(alSource, Al.AL_SOURCE_RELATIVE, mode3d ? Al.AL_FALSE : Al.AL_TRUE);

            //update parameters
            if (mode3d)
            {
                UpdatePosition2();
                UpdateVelocity2();
            }
            else
            {
                UpdatePan2();
            }
            UpdatePitch2();
            UpdateVolume2();

            if (sampleSound != null)
            {
                Al.alSourcei(alSource, Al.AL_LOOPING, loop ? Al.AL_TRUE : Al.AL_FALSE);
            }
            else
            {
                Al.alSourcei(alSource, Al.AL_LOOPING, Al.AL_FALSE);
            }
            if (OpenALSoundWorld.CheckError())
            {
                PreDetachVirtualChannel();
                OpenALSoundWorld.criticalSection.Leave();
                return;
            }

            UpdateTime2();

            //unpause
            Al.alSourcePlay(alSource);
            OpenALSoundWorld.CheckError();

            //add to fileStreamChannels
            if (fileStreamSound != null)
            {
                OpenALSoundWorld.Instance.fileStreamRealChannels.Add(this);
            }

            OpenALSoundWorld.criticalSection.Leave();
        }