/// <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; } } }
public void clearDeckB() { // remove deck A, set to zero BassMix.BASS_Mixer_ChannelRemove(_deckB); Bass.BASS_StreamFree(_deckB); _deckB = 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); }
/// <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; } }
public void Stop() { try { BassMix.BASS_Mixer_ChannelRemove(this.Channel); } catch (DllNotFoundException) { Functions.DownloadDlls(); } }
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; } }
//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; }
/// <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; }
/// <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; }
/// <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); } }
/// <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); }
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"); }