private int prepareStream(Stream data, bool quick) { //encapsulate incoming stream with async buffer if it isn't already. dataStream = data as AsyncBufferStream ?? new AsyncBufferStream(data, quick ? 8 : -1); fileCallbacks = new FileCallbacks(new DataStreamFileProcedures(dataStream)); BassFlags flags = Preview ? 0 : BassFlags.Decode | BassFlags.Prescan; int stream = Bass.CreateStream(StreamSystem.NoBuffer, flags, fileCallbacks.Callbacks, fileCallbacks.Handle); 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 stream also frees // all parent decoding streams. const int bass_nodevice = 0x20000; Bass.ChannelSetDevice(stream, bass_nodevice); tempoAdjustStream = BassFx.TempoCreate(stream, BassFlags.Decode | BassFlags.FxFreeSource); Bass.ChannelSetDevice(tempoAdjustStream, bass_nodevice); stream = BassFx.ReverseCreate(tempoAdjustStream, 5f, BassFlags.Default | BassFlags.FxFreeSource); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoUseQuickAlgorithm, 1); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoOverlapMilliseconds, 4); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoSequenceMilliseconds, 30); } return(stream); }
private void LoadSong() { BassFlags Flags = Preview ? 0 : (BassFlags.Decode | BassFlags.Prescan); // Create a new stream CleanStream = Bass.CreateStream(AudioFile.Content, 0, AudioFile.Size, Flags); if (!Preview) { Stream = BassFx.TempoCreate(CleanStream, BassFlags.Decode | BassFlags.FxFreeSource); TempoStream = Stream; Stream = BassFx.ReverseCreate(Stream, 5f, BassFlags.FxFreeSource); Bass.ChannelSetAttribute(Stream, ChannelAttribute.TempoUseQuickAlgorithm, 1); Bass.ChannelSetAttribute(Stream, ChannelAttribute.TempoOverlapMilliseconds, 4); Bass.ChannelSetAttribute(Stream, ChannelAttribute.TempoSequenceMilliseconds, 30); } else { Stream = CleanStream; } Length = (Bass.ChannelBytes2Seconds(Stream, Bass.ChannelGetLength(Stream)) * 1000); Bass.ChannelGetAttribute(Stream, ChannelAttribute.Frequency, out InitialFrequency); SetDirection(false); }
public AudioTrackBass(Stream data, bool quick = false) { Preview = quick; BassFlags flags = Preview ? 0 : (BassFlags.Decode | BassFlags.Prescan); if (data == null) throw new ArgumentNullException(@"Data couldn't be loaded!"); //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); }
public TempoDecoder(Decoder decoder, Resolution BufferKind = Resolution.Short) : base(BufferKind) { this.decoder = decoder; Handle = BassFx.TempoCreate(decoder.Handle, BassFlags.Float | BufferKind.ToBassFlag()); }
/// <summary> /// Constructs a new <see cref="TrackBass"/> from provided audio data. /// </summary> /// <param name="data">The sample data stream.</param> /// <param name="quick">If true, the track will not be fully loaded, and should only be used for preview purposes. Defaults to false.</param> public TrackBass(Stream data, bool quick = false) { EnqueueAction(() => { 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); procedures = CreateDataStreamFileProcedures(dataStream); if (!RuntimeInfo.SupportsIL) { pinnedProcedures = GCHandle.Alloc(procedures, GCHandleType.Pinned); } BassFlags flags = Preview ? 0 : BassFlags.Decode | BassFlags.Prescan | BassFlags.Float; activeStream = Bass.CreateStream(StreamSystem.NoBuffer, flags, procedures.BassProcedures, RuntimeInfo.SupportsIL ? IntPtr.Zero : GCHandle.ToIntPtr(pinnedProcedures)); 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); } // will be -1 in case of an error double seconds = Bass.ChannelBytes2Seconds(activeStream, Bass.ChannelGetLength(activeStream)); bool success = seconds >= 0; if (success) { Length = seconds * 1000; Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out float frequency); initialFrequency = frequency; bitrate = (int)Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Bitrate); isLoaded = true; } }); InvalidateState(); }
private void LoadFile(string filename) { if (filename != string.Empty) { if (Bass.ChannelIsActive(fxStream) == PlaybackState.Playing) { StopPlayback(); } Bass.StreamFree(audioStream); Bass.StreamFree(fxStream); audioStream = Bass.CreateStream(filename, 0, 0, BassFlags.Decode | BassFlags.Prescan); audioLength = Bass.ChannelGetLength(audioStream); if (audioStream != 0 && Bass.LastError == Errors.OK) { fxStream = BassFx.TempoCreate(audioStream, BassFlags.FxFreeSource); if (fxStream != 0 && Bass.LastError == Errors.OK) { bassboost = new PeakEQ(fxStream, 0, 3); bassboost.UpdateBand(bassboost.AddBand(30), bassAmount.Value * 2); bassboost.UpdateBand(bassboost.AddBand(50), bassAmount.Value); playButton.IsEnabled = true; saveButton.IsEnabled = true; return; } } MessageBox.Show(this, "Чот нихуя"); } }
private int prepareStream(Stream data, bool quick) { switch (data) { case MemoryStream _: case UnmanagedMemoryStream _: case AsyncBufferStream _: // Buffering memory stream is definitely unworthy. dataStream = data; break; default: // It would be most likely a FileStream. // Consider to use RandomAccess to optimise in favor of FileStream in .NET 6 dataStream = new AsyncBufferStream(data, quick ? 8 : -1); break; } fileCallbacks = new FileCallbacks(new DataStreamFileProcedures(dataStream)); BassFlags flags = (Preview ? 0 : BassFlags.Decode | BassFlags.Prescan); // While this shouldn't cause issues, we've had a small subset of users reporting issues on windows. // To keep things working let's only apply to other platforms until we know more. // See https://github.com/ppy/osu/issues/18652. if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) { flags |= BassFlags.AsyncFile; } int stream = Bass.CreateStream(StreamSystem.NoBuffer, flags, fileCallbacks.Callbacks, fileCallbacks.Handle); bitrate = (int)Math.Round(Bass.ChannelGetAttribute(stream, ChannelAttribute.Bitrate)); 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 stream also frees // all parent decoding streams. const int bass_nodevice = 0x20000; Bass.ChannelSetDevice(stream, bass_nodevice); tempoAdjustStream = BassFx.TempoCreate(stream, BassFlags.Decode | BassFlags.FxFreeSource); Bass.ChannelSetDevice(tempoAdjustStream, bass_nodevice); stream = BassFx.ReverseCreate(tempoAdjustStream, 5f, BassFlags.Default | BassFlags.FxFreeSource | BassFlags.Decode); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoUseQuickAlgorithm, 1); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoOverlapMilliseconds, 4); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoSequenceMilliseconds, 30); } return(stream); }
public void OpenFile(string filePath) { Unload(); streamHandle = Bass.CreateStream(filePath, Flags: BassFlags.Decode | BassFlags.Prescan); activeHandle = BassFx.TempoCreate(streamHandle, BassFlags.FxFreeSource); syncHandle = Bass.ChannelSetSync(activeHandle, SyncFlags.End, 0, SyncProcedureEndStream); Bass.ChannelSetAttribute(activeHandle, ChannelAttribute.TempoUseQuickAlgorithm, 1); ApplyEffects(); status = PlayerStatus.FileLoaded; }
public override void Connect(IBassStreamComponent previous) { this.Rate = previous.Rate; this.Channels = previous.Channels; this.ChannelHandle = BassFx.TempoCreate(previous.ChannelHandle, previous.Flags); if (this.ChannelHandle == 0) { BassUtils.Throw(); } if (this.IsActive) { this.Update(); } }
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(); }
internal AudioStream(AudioManager manager, string path, ResourceContainer resourceContainer) : base(manager) { this.path = path; decodeStream = Bass.CreateStream(path, 0, 0, BassFlags.Decode | BassFlags.Prescan); if (decodeStream == 0) { Trace.WriteLine($"Failed to load audio stream ({path}): {Bass.LastError}"); return; } stream = BassFx.TempoCreate(decodeStream, BassFlags.Default); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoUseQuickAlgorithm, 1); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoOverlapMilliseconds, 4); Bass.ChannelSetAttribute(stream, ChannelAttribute.TempoSequenceMilliseconds, 30); Channel = stream; }
/// <summary> /// Loads the File Channel with FX. /// </summary> protected override int OnLoad(string FileName) { var h = Bass.CreateStream(FileName, Flags: BassFlags.Decode); if (h == 0) { return(0); } h = BassFx.TempoCreate(h, BassFlags.Decode | BassFlags.FxFreeSource); if (h == 0) { return(0); } _tempoHandle = h; return(BassFx.ReverseCreate(h, 2, BassFlags.FxFreeSource)); }
/// <summary> /// Constructs a new <see cref="TrackBass"/> from provided audio data. /// </summary> /// <param name="data">The sample data stream.</param> /// <param name="quick">If true, the track will not be fully loaded, and should only be used for preview purposes. Defaults to false.</param> public TrackBass(Stream data, bool quick = false) { if (data == null) { throw new ArgumentNullException(nameof(data)); } // todo: support this internally to match the underlying Track implementation (which can support this). const float tempo_minimum_supported = 0.05f; AggregateTempo.ValueChanged += t => { if (t.NewValue < tempo_minimum_supported) { throw new ArgumentException($"{nameof(TrackBass)} does not support {nameof(Tempo)} specifications below {tempo_minimum_supported}. Use {nameof(Frequency)} instead."); } }; EnqueueAction(() => { Preview = quick; //encapsulate incoming stream with async buffer if it isn't already. dataStream = data as AsyncBufferStream ?? new AsyncBufferStream(data, quick ? 8 : -1); fileCallbacks = new FileCallbacks(new DataStreamFileProcedures(dataStream)); BassFlags flags = Preview ? 0 : BassFlags.Decode | BassFlags.Prescan; activeStream = Bass.CreateStream(StreamSystem.NoBuffer, flags, fileCallbacks.Callbacks, fileCallbacks.Handle); 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(tempoAdjustStream, 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); } // will be -1 in case of an error double seconds = Bass.ChannelBytes2Seconds(activeStream, byteLength = Bass.ChannelGetLength(activeStream)); bool success = seconds >= 0; if (success) { Length = seconds * 1000; // Bass does not allow seeking to the end of the track, so the last available position is 1 sample before. lastSeekablePosition = Bass.ChannelBytes2Seconds(activeStream, byteLength - BYTES_PER_SAMPLE) * 1000; Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out float frequency); initialFrequency = frequency; bitrate = (int)Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Bitrate); stopCallback = new SyncCallback((a, b, c, d) => RaiseFailed()); endCallback = new SyncCallback((a, b, c, d) => { if (!Looping) { RaiseCompleted(); } }); Bass.ChannelSetSync(activeStream, SyncFlags.Stop, 0, stopCallback.Callback, stopCallback.Handle); Bass.ChannelSetSync(activeStream, SyncFlags.End, 0, endCallback.Callback, endCallback.Handle); isLoaded = true; } }); InvalidateState(); }
void OpenFile() { if (!_ofd.ShowDialog().Value) { return; } // free decode bpm stream and resources BassFx.BPMFree(_bpmchan); // free tempo, stream, music & bpm/beat callbacks Bass.StreamFree(_chan); Bass.MusicFree(_chan); // create decode channel _chan = Bass.CreateStream(_ofd.FileName, 0, 0, BassFlags.Decode); if (_chan == 0) { _chan = Bass.MusicLoad(_ofd.FileName, 0, 0, BassFlags.MusicRamp | BassFlags.Prescan | BassFlags.Decode, 0); } if (_chan == 0) { // not a WAV/MP3 or MOD Status = "Click Here to Open and Play a File..."; MessageBox.Show("Selected file couldn't be loaded!"); return; } // get channel info Bass.ChannelGetInfo(_chan, out _info); // create a new stream - decoded & resampled :) if ((_chan = BassFx.TempoCreate(_chan, BassFlags.Loop | BassFlags.FxFreeSource)) == 0) { Status = "Click Here to Open and Play a File..."; MessageBox.Show("Couldn't create a resampled stream!"); Bass.StreamFree(_chan); Bass.MusicFree(_chan); return; } // update the button to show the loaded file name (without path) Status = Path.GetFileName(_ofd.FileName); SampleRate = _info.Frequency; OnPropertyChanged(nameof(MinSampleRate)); OnPropertyChanged(nameof(MaxSampleRate)); // update tempo view Tempo = 0; // set the callback bpm and beat IsBpmPeriod = _isBpmPeriod; IsBeatPosition = _isBeatPosition; // play new created stream Bass.ChannelPlay(_chan); // create bpmChan stream and get bpm value for BpmPeriod seconds from current position var pos = Bass.ChannelBytes2Seconds(_chan, Bass.ChannelGetPosition(_chan)); var maxpos = Bass.ChannelBytes2Seconds(_chan, Bass.ChannelGetLength(_chan)); DecodingBPM(true, pos, pos + BpmPeriod >= maxpos ? maxpos - 1 : pos + BpmPeriod, _ofd.FileName); }
/// <summary> /// Constructs a new <see cref="TrackBass"/> from provided audio data. /// </summary> /// <param name="data">The sample data stream.</param> /// <param name="quick">If true, the track will not be fully loaded, and should only be used for preview purposes. Defaults to false.</param> public TrackBass(Stream data, bool quick = false) { EnqueueAction(() => { 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); fileCallbacks = new FileCallbacks(new DataStreamFileProcedures(dataStream)); BassFlags flags = Preview ? 0 : BassFlags.Decode | BassFlags.Prescan; activeStream = Bass.CreateStream(StreamSystem.NoBuffer, flags, fileCallbacks.Callbacks, fileCallbacks.Handle); 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); } // will be -1 in case of an error double seconds = Bass.ChannelBytes2Seconds(activeStream, Bass.ChannelGetLength(activeStream)); bool success = seconds >= 0; if (success) { Length = seconds * 1000; Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out float frequency); initialFrequency = frequency; bitrate = (int)Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Bitrate); stopCallback = new SyncCallback((a, b, c, d) => RaiseFailed()); endCallback = new SyncCallback((a, b, c, d) => { if (!Looping) { RaiseCompleted(); } }); Bass.ChannelSetSync(activeStream, SyncFlags.Stop, 0, stopCallback.Callback, stopCallback.Handle); Bass.ChannelSetSync(activeStream, SyncFlags.End, 0, endCallback.Callback, endCallback.Handle); isLoaded = true; } }); InvalidateState(); }