예제 #1
0
 protected static void AddRealChannel(SoundRealChannel realChannel, bool is3D)
 {
     realChannel.index = real2DChannels.Count + real3DChannels.Count;
     realChannel.is3D  = is3D;
     if (is3D)
     {
         real3DChannels.Add(realChannel);
     }
     else
     {
         real2DChannels.Add(realChannel);
     }
 }
예제 #2
0
        static void UpdateChannels(double delta, bool update3DChannels)
        {
            List <SoundVirtualChannel> activeVirtualChannels;
            List <SoundRealChannel>    realChannels;

            if (update3DChannels)
            {
                activeVirtualChannels = activeVirtual3DChannels;
                realChannels          = real3DChannels;
            }
            else
            {
                activeVirtualChannels = activeVirtual2DChannels;
                realChannels          = real2DChannels;
            }

            //update virtual channels time
            if (delta != 0)
            {
                for (int n = 0; n < activeVirtualChannels.Count; n++)
                {
                    var virtualChannel = activeVirtualChannels[n];
                    if (!virtualChannel.IsTotalPaused())
                    {
                        virtualChannel.time += delta * virtualChannel.pitch;

                        var sound = virtualChannel.sound;
                        if (virtualChannel.time >= sound.Length)
                        {
                            if ((sound.Mode & SoundModes.Loop) != 0)
                            {
                                virtualChannel.time -= sound.Length;
                            }
                            else
                            {
                                if (virtualChannel.currentRealChannel == null || virtualChannel.time >= sound.Length + .1f)
                                {
                                    virtualChannel.Stop();
                                    n--;
                                }
                            }
                        }
                    }
                }
            }

            //calculate priority

            //!!!!slowly. часто обновляется может

            for (int n = 0; n < activeVirtualChannels.Count; n++)
            {
                var virtualChannel = activeVirtualChannels[n];
                var sound          = virtualChannel.sound;

                double priority = 0;

                if (virtualChannel.AttachedToScene == null || virtualChannel.AttachedToScene == listenerCurrentScene)
                {
                    if (virtualChannel.GetTotalVolume() != 0 && !virtualChannel.IsTotalPaused())
                    {
                        if (update3DChannels)
                        {
                            double distanceSqr = (virtualChannel.position - listenerPosition).LengthSquared();
                            priority = (100000000.0 - distanceSqr) * (virtualChannel.Priority + .00001);
                            //priority += 1.0f / distanceSqr + virtualChannel.Priority * 10000;
                        }
                        else
                        {
                            //if( ( sound.Mode & SoundModes.Stream ) != 0 )
                            //	priority += 10;
                            priority = (virtualChannel.Priority + .00001) * 10000000000;

                            //fix sorting jerking problem
                            priority += (double)sound.createIndex;
                        }

                        //if( ( sound.Mode & SoundModes.Mode3D ) == 0 )
                        //{
                        //	priority += 100000000;
                        //	if( ( sound.Mode & SoundModes.Stream ) != 0 )
                        //		priority += 100000000;
                        //}
                        //else
                        //{
                        //	double distanceSqr = ( virtualChannel.position - listenerPosition ).LengthSquared();

                        //	priority += ( 1000000.0 - distanceSqr ) + virtualChannel.priority * 10000;
                        //	//priority += 1.0f / distanceSqr + virtualChannel.Priority * 10000;
                        //}

                        ////only for small fix sorting jerking problem at the DataBuffer and Streams
                        //if( sound.Name == null || ( sound.Mode & SoundModes.Stream ) != 0 )
                        //	priority += (double)sound.createIndex;
                    }
                }

                virtualChannel.tempPriority = priority;
            }

            //Sort by priority
            CollectionUtility.SelectionSort(activeVirtualChannels, virtualChannelsTempPriorityComparer);
            //ListUtils.MergeSort( activeVirtualChannels, virtualChannelsTempPriorityComparer );

            //remove virtual channels from real channels
            for (int n = 0; n < activeVirtualChannels.Count; n++)
            {
                var virtualChannel = activeVirtualChannels[n];
                var realChannel    = virtualChannel.currentRealChannel;

                if (realChannel != null)
                {
                    if (n >= realChannels.Count || virtualChannel.tempPriority == 0)
                    {
                        realChannel.PreDetachVirtualChannel();
                        realChannel.currentVirtualChannel = null;
                        virtualChannel.currentRealChannel = null;
                    }
                }
            }

            //bind virtual channels to real channels
            var freeRealChannels = new Queue <SoundRealChannel>(realChannels.Count);

            foreach (var c in realChannels)
            {
                if (c.CurrentVirtualChannel == null)
                {
                    freeRealChannels.Enqueue(c);
                }
            }

            for (int n = 0; n < activeVirtualChannels.Count; n++)
            {
                //no free real channels
                if (freeRealChannels.Count == 0)
                {
                    break;
                }

                var virtualChannel = activeVirtualChannels[n];
                if (virtualChannel.currentRealChannel == null && virtualChannel.tempPriority != 0)
                {
                    var realChannel = freeRealChannels.Dequeue();

                    realChannel.currentVirtualChannel = virtualChannel;
                    virtualChannel.currentRealChannel = realChannel;
                    realChannel.PostAttachVirtualChannel();
                }
            }

            ////add virtual channels to real channels
            //int currentRealChannelIndex = 0;

            //for( int n = 0; n < activeVirtualChannels.Count; n++ )
            //{
            //	VirtualChannel virtualChannel = activeVirtualChannels[ n ];

            //	if( currentRealChannelIndex >= realChannels.Count )
            //		break;
            //	if( virtualChannel.currentRealChannel != null )
            //		continue;
            //	if( virtualChannel.tempPriority == 0 )
            //		continue;

            //	if( virtualChannel.Time >= virtualChannel.Sound.Length )
            //	{
            //		if( ( virtualChannel.Sound.Mode & SoundModes.Loop ) == 0 )
            //			continue;
            //		else
            //			virtualChannel.time -= virtualChannel.Sound.Length;
            //	}

            //	RealChannel realChannel = null;
            //	{
            //		while( realChannels[ currentRealChannelIndex ].CurrentVirtualChannel != null )
            //		{
            //			currentRealChannelIndex++;
            //			if( currentRealChannelIndex >= realChannels.Count )
            //				break;
            //		}

            //		if( currentRealChannelIndex < realChannels.Count )
            //		{
            //			realChannel = realChannels[ currentRealChannelIndex ];
            //			currentRealChannelIndex++;
            //		}
            //	}

            //	if( realChannel == null )
            //		break;

            //	if( realChannel.currentVirtualChannel != null )
            //		Log.Fatal( "SoundWorld: UpdateChannels: realChannel.currentVirtualChannel != null." );

            //	realChannel.currentVirtualChannel = virtualChannel;
            //	virtualChannel.currentRealChannel = realChannel;
            //	realChannel.PostAttachVirtualChannel();
            //}

            //update gain for 3d sound (calculate attenuation)
            if (update3DChannels)
            {
                for (int n = 0; n < real3DChannels.Count; n++)
                {
                    SoundRealChannel realChannel = real3DChannels[n];
                    if (realChannel.currentVirtualChannel != null)
                    {
                        //!!!!slowly enter to critical section for each real channel?
                        realChannel.UpdateVolume();
                    }
                }
            }
        }