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 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();
                    }
                }
            }
        }
Example #3
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;
		}