/// <summary>
        ///     Removes and audio stream from a mixer.
        /// </summary>
        /// <param name="audioStream">The audio stream.</param>
        /// <param name="mixerChannel">The mixer channel.</param>
        public static void RemoveFromMixer(AudioStream audioStream, MixerChannel mixerChannel)
        {
            if (audioStream == null || !audioStream.IsAudioLoaded())
            {
                return;
            }

            //throw new Exception("Audio file null or not audio not loaded");

            if (mixerChannel.ChannelId == int.MinValue)
            {
                throw new Exception("Mixer channel not initialized");
            }

            //lock (Lock)
            {
                // DebugHelper.WriteLine($"RemoveFromMixer {audioStream.Description} {audioStream.Channel}...");
                BassMix.BASS_Mixer_ChannelPause(audioStream.ChannelId);
                Bass.BASS_ChannelLock(mixerChannel.ChannelId, true);

                foreach (var channel in audioStream.ChannelIds)
                {
                    BassMix.BASS_Mixer_ChannelRemove(channel);
                }

                Bass.BASS_ChannelLock(mixerChannel.ChannelId, false);
                // DebugHelper.WriteLine("done");


                if (audioStream.MixerChannelId == mixerChannel.ChannelId)
                {
                    audioStream.MixerChannelId = int.MinValue;
                }
            }
        }
Пример #2
0
 public void clearDeckB()
 {
     // remove deck A, set to zero
     BassMix.BASS_Mixer_ChannelRemove(_deckB);
     Bass.BASS_StreamFree(_deckB);
     _deckB = 0;
 }
Пример #3
0
 public void DetachChannel(ChannelInfo info)
 {
     if (info.BassHandle.HasValue)
     {
         Bass.BASS_ChannelPause(info.BassHandle.Value);
         BassMix.BASS_Mixer_ChannelRemove(info.BassHandle.Value);
     }
     this.Streams.Remove(info);
 }
Пример #4
0
 /// <summary>
 /// Stops and clears the current stream (if any)
 /// </summary>
 void StopAndClearCurrentStream()
 {
     if (_currentStream > -1)
     {
         Bass.BASS_ChannelStop(_currentStream);
         BassMix.BASS_Mixer_ChannelRemove(_currentStream);
         Bass.BASS_StreamFree(_currentStream);
         _currentStream = -1;
     }
 }
Пример #5
0
 public void Stop()
 {
     try
     {
         BassMix.BASS_Mixer_ChannelRemove(this.Channel);
     }
     catch (DllNotFoundException)
     {
         Functions.DownloadDlls();
     }
 }
Пример #6
0
 public override void OnStopped()
 {
     if (this._streamCopy != 0)
     {
         if (this.TargetMixerStream != 0)
         {
             BassMix.BASS_Mixer_ChannelRemove(this._streamCopy);
         }
         Bass.BASS_ChannelRemoveLink(base.ChannelHandle, this._streamCopy);
         Bass.BASS_StreamFree(this._streamCopy);
         this._streamCopy = 0;
     }
 }
Пример #7
0
        //public long

        public void FreeResources()
        {
            if (StreamMixer != Bass.FALSE &&
                Stream != Bass.FALSE &&
                Bass.BASS_ChannelIsActive(Stream) != BASSActive.BASS_ACTIVE_STOPPED)
            {
                BassMix.BASS_Mixer_ChannelRemove(StreamPlugged);
            }

            Bass.BASS_StreamFree(Stream);
            //Bass.BASS_StreamFree(StreamPlugged);

            Stream        = Bass.FALSE;
            StreamPlugged = Bass.FALSE;
        }
Пример #8
0
        /// <summary>
        /// Unloads the sample audio data.
        /// </summary>
        /// <param name="sample">The sample.</param>
        public void UnloadSample(Sample sample)
        {
            if (sample.Channel == int.MinValue)
            {
                return;
            }

            Debug.Print("Unloading sample " + sample.Description);

            BassMix.BASS_Mixer_ChannelRemove(sample.Channel);
            Bass.BASS_StreamFree(sample.Channel);
            sample.Channel = int.MinValue;

            sample.AudioDataHandle.Free();
            sample.AudioData = null;
        }
Пример #9
0
        /// <summary>
        /// Called when a stream has been created. This actually starts the playback of the stream.
        /// </summary>
        /// <param name="track">The track that is to be played.</param>
        /// <param name="stream">The BASS.NET stream pointer to play.</param>
        protected virtual void StreamCreated(IAudioItem track, int stream)
        {
            // Init mixer
            if (_mixer == -1)
            {
                _mixer = BassMix.BASS_Mixer_StreamCreate(44100, 6, BASSFlag.BASS_MIXER_END);

                // Set playback done callback on mixer
                _channelEndCallback = new SYNCPROC(ChannelEnd);
                Bass.BASS_ChannelSetSync(_mixer, BASSSync.BASS_SYNC_END | BASSSync.BASS_SYNC_MIXTIME, 0, _channelEndCallback, IntPtr.Zero);
            }

            // Load streamin mixer
            bool ok = BassMix.BASS_Mixer_StreamAddChannel(_mixer, stream, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_MIXER_MATRIX);

            if (!ok)
            {
                Log(Bass.BASS_ErrorGetCode().ToString(), Logger.LogLevel.Error);
            }

            // Set matrix
            SetMatrix(stream);

            // Remove current channel from mixer
            if (_currentStream != -1)
            {
                BassMix.BASS_Mixer_ChannelRemove(_currentStream);
                Bass.BASS_StreamFree(_currentStream);
            }

            //
            if (track is IWebcast)
            {
                SYNCPROC _mySync = new SYNCPROC(MetaSync);
                Bass.BASS_ChannelSetSync(_currentStream, BASSSync.BASS_SYNC_META, 0, _mySync, IntPtr.Zero);
            }

            // Play it!
            Bass.BASS_ChannelSetPosition(_mixer, 0);
            Bass.BASS_Start();
            Bass.BASS_ChannelPlay(_mixer, false);

            // Set current stuff
            _currentStream = stream;
        }
Пример #10
0
        /// <summary>
        /// End of Playback for a stream has been signaled
        /// Send event to Bass player to start playback of next song
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="stream"></param>
        /// <param name="data"></param>
        /// <param name="userData"></param>
        private void PlaybackEndProc(int handle, int stream, int data, IntPtr userData)
        {
            try
            {
                MusicStream musicstream;
                // Get the GC handle of the pinned object
                try
                {
                    musicstream = (MusicStream)_pinnedObjects[userData.ToInt32()].Target;
                }
                catch (KeyNotFoundException ex)
                {
                    Log.Error("BASS: GCHandle of Musicstream not found in Dictionary {0} {1}", userData.ToInt32(), ex.Message);
                    return;
                }

                Log.Debug("BASS: End of Song {0}", musicstream.FilePath);

                // We need to find out, if the nextsongs sample rate and / or number of channels are different to the one just ended
                // If this is the case we need a new mixer and the OnMusicStreamMessage needs to be invoked in a thread to avoid crashes.
                // In order to have gapless playback, it needs to be invoked in sync.
                MusicStream            nextStream = null;
                Playlists.PlayListItem nextSong   = Playlists.PlayListPlayer.SingletonPlayer.GetNextItem();
                MusicStream._fileType = Utils.GetFileType(musicstream.FilePath);
                if (nextSong != null && MusicStream._fileType.FileMainType != FileMainType.WebStream)
                {
                    nextStream = new MusicStream(nextSong.FileName, true);
                }
                else if (MusicStream._fileType.FileMainType == FileMainType.WebStream)
                {
                    if (MusicStreamMessage != null)
                    {
                        MusicStreamMessage(musicstream, MusicStream.StreamAction.InternetStreamChanged);
                        return;
                    }
                }

                bool newMixerNeeded = false;
                if (nextStream != null && nextStream.BassStream != 0)
                {
                    if (_bassPlayer.NewMixerNeeded(nextStream))
                    {
                        newMixerNeeded = true;
                    }
                    nextStream.Dispose();
                }

                if (newMixerNeeded)
                {
                    if (Config.MusicPlayer == AudioPlayer.WasApi && BassWasapi.BASS_WASAPI_IsStarted())
                    {
                        BassWasapi.BASS_WASAPI_Stop(true);
                    }

                    // Unplug the Source channel from the mixer
                    Log.Debug("BASS: Unplugging source channel from Mixer.");
                    BassMix.BASS_Mixer_ChannelRemove(musicstream.BassStream);

                    // invoke a thread because we need a new mixer
                    Log.Debug("BASS: Next song needs a new mixer.");

                    new Thread(() =>
                    {
                        if (MusicStreamMessage != null)
                        {
                            MusicStreamMessage(musicstream, MusicStream.StreamAction.Crossfading);
                        }
                    })
                    {
                        Name = "BASS"
                    }.Start();
                }
                else
                {
                    if (MusicStreamMessage != null)
                    {
                        MusicStreamMessage(musicstream, MusicStream.StreamAction.Crossfading);
                    }
                }
            }
            catch (AccessViolationException ex)
            {
                Log.Error("BASS: Caught AccessViolationException in Playback End Proc {0}", ex.Message);
            }
        }
Пример #11
0
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 public void Dispose()
 {
     BassMix.BASS_Mixer_ChannelRemove(channelHandle);
     Bassh.BASS_StreamFree(channelHandle);
 }
Пример #12
0
 public void RemoveSample(Sample sample)
 {
     BassMix.BASS_Mixer_ChannelRemove(sample.Channel);
     Bass.BASS_StreamFree(sample.Channel);
     Samples.Remove(sample);
 }
        /// <summary>
        ///     Saves audio data as a mono wave.
        /// </summary>
        /// <param name="audioData">The audio data.</param>
        /// <param name="outFilename">The output filename.</param>
        /// <param name="length">The maximum length in seconds, or 0 for no limit.</param>
        /// <param name="gain">The gain.</param>
        /// <exception cref="System.Exception">Cannot load audio data</exception>
        public static void SaveAsMonoWave(byte[] audioData, string outFilename, double length, float gain)
        {
            // DebugHelper.WriteLine("SaveAsMonoWave");

            var audioDataHandle  = GCHandle.Alloc(audioData, GCHandleType.Pinned);
            var audioDataPointer = audioDataHandle.AddrOfPinnedObject();

            var channel = Bass.BASS_StreamCreateFile(audioDataPointer, 0, audioData.Length,
                                                     BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_STREAM_PRESCAN);

            if (channel == 0)
            {
                throw new Exception("Cannot load audio data");
            }

            // create a mono 44100Hz mixer
            var mixer = BassMix.BASS_Mixer_StreamCreate(44100, 1, BASSFlag.BASS_MIXER_END | BASSFlag.BASS_STREAM_DECODE);

            // plug in the source
            BassMix.BASS_Mixer_StreamAddChannel(mixer, channel,
                                                BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_NORAMPIN);

            AudioStreamHelper.SetReplayGain(mixer, gain);

            const BASSEncode flags = BASSEncode.BASS_ENCODE_PCM;

            BassEnc.BASS_Encode_Start(mixer, outFilename, flags, null, IntPtr.Zero);

            const int startByte = 0;

            if (length == 0)
            {
                length = Bass.BASS_ChannelBytes2Seconds(channel, Bass.BASS_ChannelGetLength(channel));
            }

            var totalTransferLength = Bass.BASS_ChannelSeconds2Bytes(mixer, length);

            Bass.BASS_ChannelSetPosition(channel, startByte, BASSMode.BASS_POS_BYTES);
            while (totalTransferLength > 0)
            {
                var buffer = new byte[65536];

                var transferLength = totalTransferLength;
                if (transferLength > buffer.Length)
                {
                    transferLength = buffer.Length;
                }

                // get the decoded sample data
                var transferred = Bass.BASS_ChannelGetData(mixer, buffer, (int)transferLength);

                if (transferred <= 1)
                {
                    break;                   // error or the end
                }
                totalTransferLength -= transferred;
            }
            BassEnc.BASS_Encode_Stop(mixer);

            BassMix.BASS_Mixer_ChannelRemove(channel);
            Bass.BASS_StreamFree(channel);
            Bass.BASS_StreamFree(mixer);

            audioDataHandle.Free();

            // DebugHelper.WriteLine("END SaveAsMonoWave");
        }