Exemple #1
0
        public override void Play(bool restart = true)
        {
            PendingActions.Enqueue(() =>
            {
                if (!IsLoaded)
                {
                    channel = 0;
                    return;
                }

                // We are creating a new channel for every playback, since old channels may
                // be overridden when too many other channels are created from the same sample.
                channel = ((SampleBass)Sample).CreateChannel();
                Bass.ChannelGetAttribute(channel, ChannelAttribute.Frequency, out initialFrequency);
            });

            InvalidateState();

            PendingActions.Enqueue(() =>
            {
                if (channel != 0)
                {
                    Bass.ChannelPlay(channel, restart);
                }
            });

            // Needs to happen on the main thread such that
            // Played does not become true for a short moment.
            playing = true;

            base.Play(restart);
        }
Exemple #2
0
        public override bool Seek(double seek)
        {
            // At this point the track may not yet be loaded which is indicated by a 0 length.
            // In that case we still want to return true, hence the conservative length.
            double conservativeLength  = Length == 0 ? double.MaxValue : Length;
            double conservativeClamped = MathHelper.Clamp(seek, 0, conservativeLength);

            Action action = null;

            action = () =>
            {
                // we only want to run the most fresh seek event, else we may fall behind (seeks can be relatively expensive).
                if (action != seekAction)
                {
                    return;
                }

                double clamped = MathHelper.Clamp(seek, 0, Length);

                if (clamped != CurrentTime)
                {
                    long pos = Bass.ChannelSeconds2Bytes(activeStream, clamped / 1000d);
                    Bass.ChannelSetPosition(activeStream, pos);
                }
            };

            seekAction = action;
            PendingActions.Enqueue(action);

            return(conservativeClamped == seek);
        }
        /// <summary>
        /// Specify an AudioTrack which should get exclusive playback over everything else.
        /// Will pause all other tracks and throw away any existing exclusive track.
        /// </summary>
        public void SetExclusive(Track track)
        {
            if (track == null)
            {
                throw new ArgumentNullException(nameof(track));
            }

            Track last;

            lock (exclusiveMutex)
            {
                if (exclusiveTrack == track)
                {
                    return;
                }
                last           = exclusiveTrack;
                exclusiveTrack = track;
            }

            PendingActions.Enqueue(() =>
            {
                foreach (var item in Items)
                {
                    if (!item.HasCompleted)
                    {
                        item.Stop();
                    }
                }

                last?.Dispose();
                AddItem(track);
            });
        }
        public override void Play(bool restart = true)
        {
            base.Play();

            PendingActions.Enqueue(() =>
            {
                if (!hasSample)
                {
                    channel = 0;
                    return;
                }

                if (!hasChannel)
                {
                    channel = Bass.SampleGetChannel(SampleId);
                    Bass.ChannelGetAttribute(channel, ChannelAttribute.Frequency, out initialFrequency);
                }
            });

            InvalidateState();

            PendingActions.Enqueue(() =>
            {
                Bass.ChannelPlay(channel, restart);
            });
        }
Exemple #5
0
 public override void Start()
 {
     isPlayed = true;
     PendingActions.Enqueue(() =>
     {
         Bass.ChannelPlay(activeStream);
     });
 }
 public override void Start()
 {
     Update(); //ensure state is valid.
     isPlayed = true;
     PendingActions.Enqueue(() =>
     {
         Bass.ChannelPlay(activeStream);
     });
 }
Exemple #7
0
        public SampleBass(byte[] data, ConcurrentQueue <Action> customPendingActions = null)
        {
            if (customPendingActions != null)
            {
                PendingActions = customPendingActions;
            }

            PendingActions.Enqueue(() => { sampleId = Bass.SampleLoad(data, 0, data.Length, 8, BassFlags.Default); });
        }
        public SampleBass(byte[] data, ConcurrentQueue <Action> customPendingActions = null, int concurrency = DEFAULT_CONCURRENCY)
            : base(concurrency)
        {
            if (customPendingActions != null)
            {
                PendingActions = customPendingActions;
            }

            PendingActions.Enqueue(() => { sampleId = Bass.SampleLoad(data, 0, data.Length, PlaybackConcurrency, BassFlags.Default | BassFlags.SampleOverrideLongestPlaying); });
        }
 public void AddItemToList(T item)
 {
     PendingActions.Enqueue(delegate
     {
         if (Items.Contains(item))
         {
             return;
         }
         Items.Add(item);
     });
 }
Exemple #10
0
 public override void Stop()
 {
     isPlayed = false;
     PendingActions.Enqueue(() =>
     {
         if (IsRunning)
         {
             Bass.ChannelPause(activeStream);
         }
     });
 }
        public override void Pause()
        {
            if (!hasChannel)
            {
                return;
            }

            base.Pause();
            PendingActions.Enqueue(() =>
            {
                Bass.ChannelPause(channel);
            });
        }
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (freeWhenDone)
            {
                var s = SampleId;
                PendingActions.Enqueue(() =>
                {
                    Bass.SampleFree(s);
                });
                SampleId = 0;
            }
        }
        protected override void OnStateChanged(object sender, EventArgs e)
        {
            base.OnStateChanged(sender, e);

            if (hasChannel)
            {
                PendingActions.Enqueue(() =>
                {
                    Bass.ChannelSetAttribute(channel, ChannelAttribute.Volume, VolumeCalculated);
                    Bass.ChannelSetAttribute(channel, ChannelAttribute.Pan, BalanceCalculated);
                    Bass.ChannelSetAttribute(channel, ChannelAttribute.Frequency, initialFrequency * FrequencyCalculated);
                });
            }
        }
Exemple #14
0
        public override void Stop()
        {
            base.Stop();

            PendingActions.Enqueue(() =>
            {
                if (Bass.ChannelIsActive(activeStream) == PlaybackState.Playing)
                {
                    Bass.ChannelPause(activeStream);
                }

                isPlayed = false;
            });
        }
        public override void Stop()
        {
            if (!hasChannel)
            {
                return;
            }

            base.Stop();

            PendingActions.Enqueue(() =>
            {
                Bass.ChannelStop(channel);
            });
        }
Exemple #16
0
        public TrackBass(Stream data, bool quick = false)
        {
            PendingActions.Enqueue(() =>
            {
                Preview = quick;

                if (data == null)
                {
                    throw new ArgumentNullException(nameof(data));
                }
                //encapsulate incoming stream with async buffer if it isn't already.
                dataStream = data as AsyncBufferStream ?? new AsyncBufferStream(data, quick ? 8 : -1);

                var procs = new DataStreamFileProcedures(dataStream);

                BassFlags flags = Preview ? 0 : BassFlags.Decode | BassFlags.Prescan;
                activeStream    = Bass.CreateStream(StreamSystem.NoBuffer, flags, procs.BassProcedures, IntPtr.Zero);

                if (!Preview)
                {
                    // We assign the BassFlags.Decode streams to the device "bass_nodevice" to prevent them from getting
                    // cleaned up during a Bass.Free call. This is necessary for seamless switching between audio devices.
                    // Further, we provide the flag BassFlags.FxFreeSource such that freeing the activeStream also frees
                    // all parent decoding streams.
                    const int bass_nodevice = 0x20000;

                    Bass.ChannelSetDevice(activeStream, bass_nodevice);
                    tempoAdjustStream = BassFx.TempoCreate(activeStream, BassFlags.Decode | BassFlags.FxFreeSource);
                    Bass.ChannelSetDevice(activeStream, bass_nodevice);
                    activeStream = BassFx.ReverseCreate(tempoAdjustStream, 5f, BassFlags.Default | BassFlags.FxFreeSource);

                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoUseQuickAlgorithm, 1);
                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoOverlapMilliseconds, 4);
                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoSequenceMilliseconds, 30);
                }

                Length = Bass.ChannelBytes2Seconds(activeStream, Bass.ChannelGetLength(activeStream)) * 1000;

                float frequency;
                Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out frequency);
                initialFrequency = frequency;
                bitrate          = (int)Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Bitrate);

                isLoaded = true;
                OnLoaded?.Invoke(this);
            });

            InvalidateState();
        }
Exemple #17
0
        public override bool Seek(double seek)
        {
            double clamped = MathHelper.Clamp(seek, 0, Length);

            PendingActions.Enqueue(() =>
            {
                if (clamped != CurrentTime)
                {
                    long pos = Bass.ChannelSeconds2Bytes(activeStream, clamped / 1000d);
                    Bass.ChannelSetPosition(activeStream, pos);
                }
            });

            return(clamped == seek);
        }
Exemple #18
0
 public override void Start()
 {
     base.Start();
     PendingActions.Enqueue(() =>
     {
         if (Bass.ChannelPlay(activeStream))
         {
             isPlayed = true;
         }
         else
         {
             isRunning = false;
         }
     });
 }
Exemple #19
0
        private void setDirection(bool reverse)
        {
            int newDirection = reverse ? -1 : 1;

            if (direction == newDirection)
            {
                return;
            }

            direction = newDirection;

            PendingActions.Enqueue(() =>
            {
                Bass.ChannelSetAttribute(activeStream, ChannelAttribute.ReverseDirection, direction);
            });
        }
Exemple #20
0
        public override void Stop()
        {
            if (channel == 0)
            {
                return;
            }

            base.Stop();

            PendingActions.Enqueue(() =>
            {
                Bass.ChannelStop(channel);
                // ChannelStop frees the channel.
                channel = 0;
            });
        }
Exemple #21
0
        public AudioTrackBass(Stream data, bool quick = false)
        {
            PendingActions.Enqueue(() =>
            {
                Preview = quick;

                BassFlags flags = Preview ? 0 : (BassFlags.Decode | BassFlags.Prescan);

                if (data == null)
                {
                    throw new ArgumentNullException(nameof(data));
                }
                //encapsulate incoming stream with async buffer if it isn't already.
                dataStream = data as AsyncBufferStream ?? new AsyncBufferStream(data, quick ? 8 : -1);

                procs = new DataStreamFileProcedures(dataStream);

                audioStreamPrefilter = Bass.CreateStream(StreamSystem.NoBuffer, flags, procs.BassProcedures, IntPtr.Zero);

                if (Preview)
                {
                    activeStream = audioStreamPrefilter;
                }
                else
                {
                    activeStream = BassFx.TempoCreate(audioStreamPrefilter, BassFlags.Decode);
                    activeStream = BassFx.ReverseCreate(activeStream, 5f, BassFlags.Default);

                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoUseQuickAlgorithm, 1);
                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoOverlapMilliseconds, 4);
                    Bass.ChannelSetAttribute(activeStream, ChannelAttribute.TempoSequenceMilliseconds, 30);
                }

                Length = (Bass.ChannelBytes2Seconds(activeStream, Bass.ChannelGetLength(activeStream)) * 1000);
                Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out initialFrequency);
                SampleRate = initialFrequency;

                Bass.ChannelSetDSP(activeStream, dspProcessor);
            });

            InvalidateState();
        }
Exemple #22
0
        public override bool Seek(double seek)
        {
            // At this point the track may not yet be loaded which is indicated by a 0 length.
            // In that case we still want to return true, hence the conservative length.
            double conservativeLength  = Length == 0 ? double.MaxValue : Length;
            double conservativeClamped = MathHelper.Clamp(seek, 0, conservativeLength);

            PendingActions.Enqueue(() =>
            {
                double clamped = MathHelper.Clamp(seek, 0, Length);

                if (clamped != CurrentTime)
                {
                    long pos = Bass.ChannelSeconds2Bytes(activeStream, clamped / 1000d);
                    Bass.ChannelSetPosition(activeStream, pos);
                }
            });

            return(conservativeClamped == seek);
        }
Exemple #23
0
        protected override void Dispose(bool disposing)
        {
            PendingActions.Enqueue(() =>
            {
                if (activeStream != 0)
                {
                    Bass.ChannelStop(activeStream);
                }

                if (audioStreamPrefilter != 0)
                {
                    Bass.StreamFree(audioStreamPrefilter);
                }

                activeStream         = 0;
                audioStreamPrefilter = 0;

                dataStream?.Dispose();
                dataStream = null;
            });

            base.Dispose(disposing);
        }
 internal void InvalidateState(object sender = null, EventArgs e = null)
 {
     PendingActions.Enqueue(() => OnStateChanged(this, null));
 }
 public void RegisterItem(T item)
 {
     PendingActions.Enqueue(() => item.AddAdjustmentDependency(this));
 }
 public AudioSampleBass(byte[] data)
 {
     PendingActions.Enqueue(() => {
         SampleId = Bass.SampleLoad(data, 0, data.Length, 8, BassFlags.Default);
     });
 }
Exemple #27
0
 internal void InvalidateState(double newValue = 0)
 {
     PendingActions.Enqueue(OnStateChanged);
 }
Exemple #28
0
 public void UnregisterItem(T item)
 {
     PendingActions.Enqueue(() => item.RemoveAdjustmentDependency(this));
 }