public override Channel PlayChannel(string url, out TAG_INFO tags) { if (url.ExisFile()) _files.Enqueue(url); else if (url.ExisDirectory()) { foreach ( var file in url.EnumerateAllFiles().Where(file => _supportetExtensions.Contains(file.GetExtension()))) { _files.Enqueue(file); } } else throw new BassException(BASSError.BASS_ERROR_FILEOPEN); #if(DEBUG) _files = RandomStringArrayTool.RandomizeStrings(_files.ToArray()); #endif string first = _files.Dequeue(); _currentChannel = _bassEngine.CreateFile(first, flags: DefaultFileFlags); _currentChannel.SetEntSync(FileEnd); tags = _currentChannel.Tag; return _currentChannel; }
private static bool ReadID3v2(IntPtr p, TAG_INFO tags) { if ((p == IntPtr.Zero) || (tags == null)) { return(false); } try { tags.ResetTags(); ID3v2Reader reader = new ID3v2Reader(p); while (reader.Read()) { string key = reader.GetKey(); object obj2 = reader.GetValue(); if ((key.Length > 0) && (obj2 is string)) { tags.EvalTagEntry(string.Format("{0}={1}", key, obj2)); } } reader.Close(); } catch { return(false); } return(true); }
internal void Init() { if (!parsed) { TrackInfo = BassTags.BASS_TAG_GetFromFile(TrackInfo.filename) ?? TrackInfo; NotifyPropertyChanged("asstring"); NotifyPropertyChanged("duration"); } }
public Track(string filename) { Filename = filename; m_Tags = BassTags.BASS_TAG_GetFromFile(Filename); if (m_Tags == null) { throw new ArgumentException("File not valid!"); } CreateStream(); }
public override Channel PlayChannel(string url, out TAG_INFO tags) { _stream = _engine.CreateWeb(url, flags: WebStreamFlags.Decode | WebStreamFlags.Fx | WebStreamFlags.Status); _stream.PreBufferFill = 10; tags = _stream.Tag; _stream.SetMetaUpdate(MetaSync); _stream.SetDownloadEnd(OnEnd); return _stream; }
public static TAG_INFO BASS_TAG_GetFromFile(string file, bool setDefaultTitle, bool prescan) { TAG_INFO tags = new TAG_INFO(file, setDefaultTitle); int stream = Un4seen.Bass.Bass.BASS_StreamCreateFile(file, 0L, 0L, BASSFlag.BASS_MUSIC_DECODE | (prescan ? BASSFlag.BASS_SAMPLE_OVER_POS : BASSFlag.BASS_DEFAULT)); if (stream != 0) { BASS_TAG_GetFromFile(stream, tags); Un4seen.Bass.Bass.BASS_StreamFree(stream); return(tags); } return(null); }
public static bool BASS_TAG_GetFromURL(int stream, TAG_INFO tags) { if ((stream == 0) || (tags == null)) { return(false); } bool flag = false; BASS_CHANNELINFO info = new BASS_CHANNELINFO(); if (Un4seen.Bass.Bass.BASS_ChannelGetInfo(stream, info)) { tags.channelinfo = info; } IntPtr data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_ICY); if (data == IntPtr.Zero) { data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_HTTP); } if (data != IntPtr.Zero) { flag = tags.UpdateFromMETA(data, false); } data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_META); if (data != IntPtr.Zero) { flag = tags.UpdateFromMETA(data, false); } else { data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_OGG); if (data == IntPtr.Zero) { data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_APE); } if (data == IntPtr.Zero) { data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, BASSTag.BASS_TAG_WMA); } if (data != IntPtr.Zero) { flag = tags.UpdateFromMETA(data, true); } } tags.duration = Un4seen.Bass.Bass.BASS_ChannelBytes2Seconds(stream, Un4seen.Bass.Bass.BASS_ChannelGetLength(stream)); return(flag); }
public void InitializeSound() { if (SoundInitialized != true) { if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Program.playerWindow.Handle)) { BassTimer = new BASSTimer(500); BassTimer.Tick += new EventHandler(BassTimer_Tick); SoundInitialized = true; TagInfo = new TAG_INFO(); } else { SoundInitialized = false; BASSError err = Bass.BASS_ErrorGetCode(); throw new Exception("Cannot init bass: " + err.ToString()); } } }
public static PlaylistItem GetTags(string path) { TAG_INFO tagInfo = new TAG_INFO(path); if (!new System.Text.RegularExpressions.Regex("^(ftp|http)").IsMatch(path)) { string extension = new System.IO.FileInfo(path).Extension; if (!MainForm.supportedExts.Contains("*" + extension.ToLower())) { MessageBox.Show("File \"" + path + "\" is an unsupported file type.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } int type = PlaylistItem.TYPE_STREAM_FILE; if (Bass.SupportedMusicExtensions.Contains("*" + extension)) type = PlaylistItem.TYPE_MUSIC; tagInfo = BassTags.BASS_TAG_GetFromFile(path); if (tagInfo == null) return new PlaylistItem("?", "?", "?", "?", path, type); else return new PlaylistItem(tagInfo.track, tagInfo.title, tagInfo.artist, tagInfo.album, path, type); } else { if (MainForm.stream != 0) { bool tagsAvailable = BassTags.BASS_TAG_GetFromURL(MainForm.stream, tagInfo); if (tagsAvailable) return new PlaylistItem(tagInfo.track, tagInfo.title, tagInfo.artist, tagInfo.album, path, PlaylistItem.TYPE_STREAM_URL); else return new PlaylistItem("?", "?", "?", "?", path, PlaylistItem.TYPE_STREAM_URL); } else return new PlaylistItem("?", "?", "?", "?", path, PlaylistItem.TYPE_STREAM_URL); } }
private void Instance_MetaUpdated(Un4seen.Bass.AddOn.Tags.TAG_INFO tagInfo) { RootDispatcher.Dispatcher.Invoke(() => { this.Title = AudioControllerService.Current.TagInfo.title; this.Artist = AudioControllerService.Current.TagInfo.artist; this.Album = AudioControllerService.Current.TagInfo.album; this.StreamInfo = AudioControllerService.Current.ChannelInfo.ToString(); this.LengthMMSS = AudioControllerService.Current.GetTotalTimeString(); this.LengthInBytes = AudioControllerService.Current.LengthInBytes; if (MetaUpdatedEvent != null) { System.Diagnostics.Debug.WriteLine("Firing MetaUpdatedEvent"); MetaUpdatedEvent(AudioControllerService.Current.TagInfo, null); } }); //SetVolume(volume); //AudioControllerService.Instance.SetPan(pan); }
public BassTag(TAG_INFO info) : this() { Title = info.title; Artist = info.artist; Album = info.album; Albumartist = info.albumartist; Year = info.year; Comment = info.comment; Genre = info.genre; Track = info.track; Disc = info.disc; Copyright = info.copyright; Encodedby = info.encodedby; Composer = info.composer; Publisher = info.publisher; Lyricist = info.lyricist; Remixer = info.remixer; Producer = info.producer; Bpm = info.bpm; Filename = info.filename; ReplaygainTrackGain = info.replaygain_track_gain; ReplaygainTrackPeak = info.replaygain_track_peak; Conductor = info.conductor; Grouping = info.grouping; Mood = info.mood; Rating = info.rating; Isrc = info.isrc; Duration = info.duration; Bitrate = info.bitrate; for (int i = 0; i < info.PictureCount; i++) { var pic = info.PictureGet(i); Pictures.Add(new BassPicture(pic)); } }
public void Stop() { if (!SoundInitialized || BassStream == 0) return; if (!Bass.BASS_ChannelStop(BassStream)) { throw new Exception("Cannot stop playback: " + Bass.BASS_ErrorGetCode().ToString()); } else { Bass.BASS_StreamFree(BassStream); BassStream = 0; DataProvider.currentlyPlayedStream.Close(); TagInfo = new TAG_INFO(); } }
public void PlayId(string id) { if (SoundInitialized) { DataProvider.currentlyPlayed = id; TagInfo = new TAG_INFO(); BassStream = Bass.BASS_StreamCreateFileUser(BASSStreamSystem.STREAMFILE_NOBUFFER, BASSFlag.BASS_STREAM_AUTOFREE, DataProvider.bassStreamingProc, IntPtr.Zero); if (BassStream == 0) { BASSError err = Bass.BASS_ErrorGetCode(); throw new Exception("Cannot create stream: " + err.ToString()); } if (BassTags.BASS_TAG_GetFromFile(BassStream, TagInfo)) { // nop } else Program.logging.addToLog("Cannot get tags for stream " + BassStream); BassTimer.Start(); Bass.BASS_ChannelPlay(BassStream, false); } }
public void PlayStream() { if(BassInit == false) { Console.WriteLine("PlayBarBASSVM: PlayStream: Bass not initialized"); return; } if(SelectedSong==null) { Console.WriteLine("PlayBarBASSVM: PlayStream: No selected song"); return; } if(!System.IO.File.Exists(SelectedSong.FilePath)) { Console.WriteLine("PlayBarBASSVM: PlayStream: Songpath doesn't exists - file not found"); return; } //indien een vorig lied nog aan het spelen is, stream vrijmaken voor volgend lied if(Bass.BASS_ChannelIsActive(_stream) == BASSActive.BASS_ACTIVE_PLAYING) Bass.BASS_StreamFree(_stream); _stream = Bass.BASS_StreamCreateFile(SelectedSong.FilePath, 0, 0, BASSFlag.BASS_DEFAULT); /* BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN */ if (_stream != 0) { Bass.BASS_ChannelPlay(_stream, false); // play the channel //bij iedere nieuwe stream moet de volume herzet worden, reset standaard float volume = (float)_sldVolume / 100; if (!Bass.BASS_ChannelSetAttribute(_stream, BASSAttribute.BASS_ATTRIB_VOL, volume)) Console.WriteLine("PlayBarBASSVM: Error trying to set volume: {0}", Bass.BASS_ErrorGetCode().ToString()); Messenger.Default.Send(new NotificationMessage<Song>(SelectedSong, MVVMMessages.Messages.MUSIC_NEW_SONG)); //bericht zenden dat nieuw lied speelt voor titlebar _updateTimer.Start(); //channelinfo BASS_CHANNELINFO info = new BASS_CHANNELINFO(); Bass.BASS_ChannelGetInfo(_stream, info); //filetags (id3v1 v2 ...) TAG_INFO tagInfo = new TAG_INFO(SelectedSong.FilePath); if (BassTags.BASS_TAG_GetFromFile(_stream, tagInfo)) { Console.WriteLine("PlayBarBASSVM: PlayStream: Playing:{0} - {1}", tagInfo.albumartist, tagInfo.title); } this.BtnPauseEnabled = true; this.BtnStopEnabled = true; this.BtnPlayEnabled = false; //sends event when track is finished om volgende track af te spelen Bass.BASS_ChannelSetSync(_stream, BASSSync.BASS_SYNC_END | BASSSync.BASS_SYNC_MIXTIME,0, _mySync, IntPtr.Zero); } else { Console.WriteLine("PlayBarBASSVM: PlayStream: Stream error: {0}", Bass.BASS_ErrorGetCode()); // error return; } }
/// <summary> /// Creates a stream for the given track. /// If the stream is created successfully, the track is automatically played. Thus, /// this implementation is synchronous. /// </summary> /// <param name="track">The track to create the stream for and play.</param> protected virtual void CreateStream(IAudioItem track) { int stream = 0; // If we have a webcast, create a stream for one of the available URIs if (track is IWebcast) { var streams = ((IWebcast)track).Streams; foreach (var si in streams) { var url = si.Uri.ToString(); stream = Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_STREAM_STATUS | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT, null, IntPtr.Zero); Log(Bass.BASS_ErrorGetCode().ToString()); if (stream != 0) { Un4seen.Bass.AddOn.Tags.TAG_INFO tagInfo = new TAG_INFO(url); if (BassTags.BASS_TAG_GetFromURL(stream, tagInfo)) { // display the tags... } break; } } } // Else, just load the track else if (track is IFileTrack) { var path = Path.GetFullPath(((ITrack)track).Uri.GetComponents(UriComponents.Path, UriFormat.SafeUnescaped)); stream = Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN); } // Start the stream if successfull if (stream != 0) this.StreamCreated(track, stream); else throw new NotImplementedException("Unhandled: no valid stream created"); }
private BassWebStreamInputSource(string url) { _url = url; _tagInfo = new TAG_INFO(_url); }
public void Update(string FileName) { ID_BasicTags = BassTags.BASS_TAG_GetFromFile(FileName); ReadTags(); }
public TrackTags(int music, SourceTypes type) { onRefreshTags = () => { }; TagsInfo = new TAG_INFO(); Pictures = new List<TCoverArtData>(); bool GetTags = (type == SourceTypes.Http) ? BassTags.BASS_TAG_GetFromURL(music, TagsInfo) : BassTags.BASS_TAG_GetFromFile(music, TagsInfo); TagsLoadOrRefresh(); LoadCurrentCovers(); HTags = TagsLib.TagsLibrary_Create(); MainPicture = (Pictures.Count > 0) ? PicFromMem.GetBitmapImageFromMemPtr(Pictures[0].Data,Pictures[0].DataSize) : null; switch (TagsInfo.channelinfo.ctype) { case BASSChannelType.BASS_CTYPE_MUSIC_IT: FileExtension = "it"; break; case BASSChannelType.BASS_CTYPE_MUSIC_MO3: FileExtension = "mo3"; break; case BASSChannelType.BASS_CTYPE_MUSIC_MOD: FileExtension = "mod"; break; case BASSChannelType.BASS_CTYPE_MUSIC_MTM: FileExtension = "mtm"; break; case BASSChannelType.BASS_CTYPE_MUSIC_S3M: FileExtension = "s3m"; break; case BASSChannelType.BASS_CTYPE_MUSIC_XM: FileExtension = "xm"; break; case BASSChannelType.BASS_CTYPE_RECORD: FileExtension = "HRECORD"; break; case BASSChannelType.BASS_CTYPE_SAMPLE: FileExtension = "HCHANNEL"; break; case BASSChannelType.BASS_CTYPE_STREAM: FileExtension = "HSTREAM"; break; case BASSChannelType.BASS_CTYPE_STREAM_AAC: FileExtension = "aac"; break; case BASSChannelType.BASS_CTYPE_STREAM_AC3: FileExtension = "ac3"; break; case BASSChannelType.BASS_CTYPE_STREAM_ADX: FileExtension = "adx"; break; case BASSChannelType.BASS_CTYPE_STREAM_AIFF: FileExtension = "aiff"; break; case BASSChannelType.BASS_CTYPE_STREAM_ALAC: FileExtension = "alac"; break; case BASSChannelType.BASS_CTYPE_STREAM_APE: FileExtension = "ape"; break; case BASSChannelType.BASS_CTYPE_STREAM_CA: FileExtension = "caf"; break; case BASSChannelType.BASS_CTYPE_STREAM_CD: FileExtension = "cda"; break; case BASSChannelType.BASS_CTYPE_STREAM_FLAC: FileExtension = "flac"; break; case BASSChannelType.BASS_CTYPE_STREAM_FLAC_OGG: FileExtension = "flac"; break; case BASSChannelType.BASS_CTYPE_STREAM_MIDI: FileExtension = "midi"; break; case BASSChannelType.BASS_CTYPE_STREAM_MIXER: FileExtension = "mixer"; break; case BASSChannelType.BASS_CTYPE_STREAM_MP1: FileExtension = "mp1"; break; case BASSChannelType.BASS_CTYPE_STREAM_MP2: FileExtension = "mp2"; break; case BASSChannelType.BASS_CTYPE_STREAM_MP3: FileExtension = "mp3"; break; case BASSChannelType.BASS_CTYPE_STREAM_MP4: FileExtension = "mp4"; break; case BASSChannelType.BASS_CTYPE_STREAM_MPC: FileExtension = "mpc"; break; case BASSChannelType.BASS_CTYPE_STREAM_OFR: FileExtension = "ofr"; break; case BASSChannelType.BASS_CTYPE_STREAM_OGG: FileExtension = "ogg"; break; case BASSChannelType.BASS_CTYPE_STREAM_SPLIT: FileExtension = "split"; break; case BASSChannelType.BASS_CTYPE_STREAM_SPX: FileExtension = "spx"; break; case BASSChannelType.BASS_CTYPE_STREAM_TTA: FileExtension = "tta"; break; case BASSChannelType.BASS_CTYPE_STREAM_VIDEO: FileExtension = "video"; break; case BASSChannelType.BASS_CTYPE_STREAM_WAV: FileExtension = "wav"; break; case BASSChannelType.BASS_CTYPE_STREAM_WAV_FLOAT: FileExtension = "wav"; break; case BASSChannelType.BASS_CTYPE_STREAM_WAV_PCM: FileExtension = "wav"; break; case BASSChannelType.BASS_CTYPE_STREAM_WINAMP: FileExtension = "Winamp"; break; case BASSChannelType.BASS_CTYPE_STREAM_WMA: FileExtension = "wma"; break; case BASSChannelType.BASS_CTYPE_STREAM_WMA_MP3: FileExtension = "wma"; break; case BASSChannelType.BASS_CTYPE_STREAM_WV: FileExtension = "wv"; break; case BASSChannelType.BASS_CTYPE_STREAM_WV_H: FileExtension = "wv"; break; case BASSChannelType.BASS_CTYPE_STREAM_WV_L: FileExtension = "wv"; break; case BASSChannelType.BASS_CTYPE_STREAM_WV_LH: FileExtension = "wv"; break; case BASSChannelType.BASS_CTYPE_UNKNOWN: FileExtension = "unknown"; break; } }
public static bool BASS_TAG_GetFromFile(int stream, TAG_INFO tags) { if ((stream == 0) || (tags == null)) { return(false); } bool flag = false; BASS_CHANNELINFO bass_channelinfo = new BASS_CHANNELINFO(); if (!Un4seen.Bass.Bass.BASS_ChannelGetInfo(stream, bass_channelinfo)) { return(flag); } tags.channelinfo = bass_channelinfo; BASSTag tagType = BASSTag.BASS_TAG_UNKNOWN; IntPtr p = BASS_TAG_GetIntPtr(stream, bass_channelinfo, out tagType); if (p != IntPtr.Zero) { switch (tagType) { case BASSTag.BASS_TAG_MUSIC_NAME: tags.title = Un4seen.Bass.Bass.BASS_ChannelGetMusicName(stream); tags.artist = Un4seen.Bass.Bass.BASS_ChannelGetMusicMessage(stream); flag = true; goto Label_0229; case BASSTag.BASS_TAG_MIDI_TRACK: { int num = 0; while (true) { IntPtr data = Un4seen.Bass.Bass.BASS_ChannelGetTags(stream, (BASSTag)(0x11000 + num)); if (!(data != IntPtr.Zero)) { if (!flag && (tags.NativeTags.Length > 0)) { flag = true; if (tags.NativeTags.Length > 0) { tags.title = tags.NativeTags[0].Trim(); } if (tags.NativeTags.Length > 1) { tags.artist = tags.NativeTags[1].Trim(); } } goto Label_0229; } flag |= tags.UpdateFromMETA(data, false); num++; } } case BASSTag.BASS_TAG_ID3: flag = ReadID3v1(p, tags); goto Label_0229; case BASSTag.BASS_TAG_ID3V2: flag = ReadID3v2(p, tags); goto Label_0229; case BASSTag.BASS_TAG_OGG: flag = tags.UpdateFromMETA(p, true); goto Label_0229; case BASSTag.BASS_TAG_HTTP: case BASSTag.BASS_TAG_ICY: case BASSTag.BASS_TAG_META: goto Label_0229; case BASSTag.BASS_TAG_APE: flag = tags.UpdateFromMETA(p, true); goto Label_0229; case BASSTag.BASS_TAG_MP4: flag = tags.UpdateFromMETA(p, true); goto Label_0229; case BASSTag.BASS_TAG_RIFF_INFO: flag = tags.UpdateFromMETA(p, false); goto Label_0229; } } Label_0229: tags.duration = Un4seen.Bass.Bass.BASS_ChannelBytes2Seconds(stream, Un4seen.Bass.Bass.BASS_ChannelGetLength(stream)); if (tags.bitrate == 0) { long num2 = Un4seen.Bass.Bass.BASS_StreamGetFilePosition(stream, BASSStreamFilePosition.BASS_FILEPOS_END); tags.bitrate = (int)((((double)num2) / (125.0 * tags.duration)) + 0.5); } return(flag); }
/// <summary> /// Starts Playback of the given file /// </summary> /// <param name="filePath"></param> /// <returns></returns> public override bool Play(string filePath) { if (!_initialized) { return false; } MusicStream currentStream = GetCurrentStream(); bool result = true; bool playbackStarted = false; Speed = 1; // Set playback Speed to normal speed try { if (currentStream != null && filePath.ToLowerInvariant().CompareTo(currentStream.FilePath.ToLowerInvariant()) == 0) { // Selected file is equal to current stream // Extend detection to permit to play the file if it failed. if (_state == PlayState.Paused || _state == PlayState.Init) { if (_state == PlayState.Paused) { // Resume paused stream currentStream.ResumePlayback(); } result = Bass.BASS_Start(); if (Config.MusicPlayer == AudioPlayer.Asio) { result = BassAsio.BASS_ASIO_ChannelReset(false, 0, BASSASIOReset.BASS_ASIO_RESET_PAUSE); // Continue playback of Paused stream } else if (Config.MusicPlayer == AudioPlayer.WasApi) { BassWasapi.BASS_WASAPI_Start(); } if (result) { _state = PlayState.Playing; if (PlaybackStateChanged != null) { PlaybackStateChanged(this, PlayState.Paused, _state); } } return result; } } else { // Cue support if ((currentStream != null && currentStream.IsPlaying)) { if (HandleCueFile(ref filePath, false)) { return true; } } } // If we're not Crossfading, we want to stop the current stream at this time if (currentStream != null && currentStream.IsPlaying) { if (!currentStream.IsCrossFading) { currentStream.FadeOutStop(); } } _state = PlayState.Init; // If WASAPI is started, we might run into troubles, because of a new stream needed, // So let's stop it here if (Config.MusicPlayer == AudioPlayer.WasApi && BassWasapi.BASS_WASAPI_IsStarted()) { Log.Debug("BASS: Stop WASAPI Device before start of new playback"); BassWasapi.BASS_WASAPI_Stop(true); } if (!PlayInternal(filePath)) { return false; } if (Config.MusicPlayer == AudioPlayer.Asio && !BassAsio.BASS_ASIO_IsStarted()) { BassAsio.BASS_ASIO_Stop(); playbackStarted = BassAsio.BASS_ASIO_Start(0); } else if (Config.MusicPlayer == AudioPlayer.WasApi && !BassWasapi.BASS_WASAPI_IsStarted()) { playbackStarted = BassWasapi.BASS_WASAPI_Start(); } else { if (Bass.BASS_ChannelIsActive(_mixer.BassStream) == BASSActive.BASS_ACTIVE_PLAYING) { playbackStarted = true; } else { playbackStarted = Bass.BASS_ChannelPlay(_mixer.BassStream, false); } } MusicStream stream = GetCurrentStream(); if (stream.BassStream != 0 && playbackStarted) { Log.Info("BASS: playback started"); // Set the Tag Info for Web Streams if (stream.Filetype.FileMainType == FileMainType.WebStream) { _tagInfo = stream.StreamTags; } // Slide in the Stream over the Cross fade Interval stream.SlideIn(); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_PLAYBACK_STARTED, 0, 0, 0, 0, 0, null); msg.Label = stream.FilePath; GUIWindowManager.SendThreadMessage(msg); NotifyPlaying = true; PlayState oldState = _state; _state = PlayState.Playing; if (oldState != _state && PlaybackStateChanged != null) { PlaybackStateChanged(this, oldState, _state); } if (PlaybackStart != null) { PlaybackStart(g_Player.MediaType.Music, filePath); } } else { Log.Error("BASS: Unable to play {0}. Reason: {1}.", filePath, Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode())); stream.Dispose(); result = false; } } catch (Exception ex) { result = false; Log.Error("BASS: Play caused an exception: {0}.", ex); } return result; }
/// <summary> /// Recode the file /// </summary> /// <param name = "fileName">Initial file</param> /// <param name = "outFileName">Target file</param> /// <param name = "targetSampleRate">Target sample rate</param> public void RecodeTheFile(string fileName, string outFileName, int targetSampleRate) { int stream = Un4seen.Bass.Bass.BASS_StreamCreateFile(fileName, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT); TAG_INFO tags = new TAG_INFO(); BassTags.BASS_TAG_GetFromFile(stream, tags); int mixerStream = BassMix.BASS_Mixer_StreamCreate(targetSampleRate, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT); if (BassMix.BASS_Mixer_StreamAddChannel(mixerStream, stream, BASSFlag.BASS_MIXER_FILTER)) { WaveWriter waveWriter = new WaveWriter(outFileName, mixerStream, true); const int length = 5512*10*4; float[] buffer = new float[length]; while (true) { int bytesRead = Un4seen.Bass.Bass.BASS_ChannelGetData(mixerStream, buffer, length); if (bytesRead == 0) break; waveWriter.Write(buffer, bytesRead); } waveWriter.Close(); } else throw new Exception(Un4seen.Bass.Bass.BASS_ErrorGetCode().ToString()); }
/// <summary> /// Starts Playback of the given file /// </summary> /// <param name="filePath"></param> /// <returns></returns> public bool Play(string filePath) { if (!_Initialized) { return false; } try { UpdateTimer.Stop(); } catch { throw new BassStreamException("Bass Error: Update Timer Error"); } int stream = GetCurrentStream(); bool doFade = false; bool result = true; Speed = 1; // Set playback Speed to normal speed try { if (Paused || (filePath.ToLower().CompareTo(FilePath.ToLower()) == 0 && stream != 0)) { bool doReturn = !Paused; // Selected file is equal to current stream if (_State == PlayState.Paused) { // Resume paused stream if (_SoftStop) { Bass.BASS_ChannelSlideAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1, 500); } else { Bass.BASS_ChannelSetAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1); } result = Bass.BASS_Start(); if (result) { _State = PlayState.Playing; UpdateTimer.Start(); if (PlaybackStateChanged != null) { PlaybackStateChanged(this, PlayState.Paused, _State); } } if (doReturn) return result; } } if (stream != 0 && StreamIsPlaying(stream)) { int oldStream = stream; double oldStreamDuration = GetTotalStreamSeconds(oldStream); double oldStreamElapsedSeconds = GetStreamElapsedTime(oldStream); double crossFadeSeconds = _CrossFadeIntervalMS; if (crossFadeSeconds > 0) crossFadeSeconds = crossFadeSeconds/1000.0; if ((oldStreamDuration - (oldStreamElapsedSeconds + crossFadeSeconds) > -1)) { FadeOutStop(oldStream); } else { Bass.BASS_ChannelStop(oldStream); } doFade = true; stream = GetNextStream(); if (stream != 0 || StreamIsPlaying(stream)) { FreeStream(stream); } } if (stream != 0) { if (!Stopped) // Check if stopped already to avoid that Stop() is called two or three times { Stop(true); } FreeStream(stream); } _State = PlayState.Init; // Make sure Bass is ready to begin playing again Bass.BASS_Start(); if (filePath != string.Empty) { // Turn on parsing of ASX files Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 2); BASSFlag streamFlags; if (_Mixing) { streamFlags = BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT; // Don't use the BASS_STREAM_AUTOFREE flag on a decoding channel. will produce a BASS_ERROR_NOTAVAIL } else { streamFlags = BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_AUTOFREE; } FilePath = filePath; _isRadio = false; if (filePath.ToLower().Contains(@"http://") || filePath.ToLower().Contains(@"https://") || filePath.ToLower().StartsWith("mms") || filePath.ToLower().StartsWith("rtsp")) { _isRadio = true; // We're playing Internet Radio Stream stream = Bass.BASS_StreamCreateURL(filePath, 0, streamFlags, DownloadProcDelegate, IntPtr.Zero); if (stream != 0) { // Get the Tags and set the Meta Tag SyncProc _tagInfo = new TAG_INFO(filePath); SetStreamTags(stream); if (BassTags.BASS_TAG_GetFromURL(stream, _tagInfo)) { GetMetaTags(); } Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_META, 0, MetaTagSyncProcDelegate, IntPtr.Zero); } Log.Debug("BASSAudio: Webstream found - trying to fetch stream {0}", Convert.ToString(stream)); } else if (IsMODFile(filePath)) { // Load a Mod file stream = Bass.BASS_MusicLoad(filePath, 0, 0, BASSFlag.BASS_SAMPLE_SOFTWARE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_MUSIC_AUTOFREE | BASSFlag.BASS_MUSIC_PRESCAN | BASSFlag.BASS_MUSIC_RAMP, 0); } else { // Create a Standard Stream stream = Bass.BASS_StreamCreateFile(filePath, 0, 0, streamFlags); } // Is Mixing, then we create a mixer channel and assign the stream to the mixer if ((_Mixing) && stream != 0) { // Do an upmix of the stereo according to the matrix. // Now Plugin the stream to the mixer and set the mixing matrix BassMix.BASS_Mixer_StreamAddChannel(_mixer, stream, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_BUFFER); BassMix.BASS_Mixer_ChannelSetMatrix(stream, _MixingMatrix); } Streams[CurrentStreamIndex] = stream; if (stream != 0) { // When we have a MIDI file, we need to assign the sound banks to the stream if (IsMidiFile(filePath) && soundFonts != null) { BassMidi.BASS_MIDI_StreamSetFonts(stream, soundFonts, soundFonts.Length); } StreamEventSyncHandles[CurrentStreamIndex] = RegisterPlaybackEvents(stream, CurrentStreamIndex); if (doFade && _CrossFadeIntervalMS > 0) { _CrossFading = true; // Reduce the stream volume to zero so we can fade it in... Bass.BASS_ChannelSetAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 0); // Fade in from 0 to 1 over the _CrossFadeIntervalMS duration Bass.BASS_ChannelSlideAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1, _CrossFadeIntervalMS); } } else { BASSError error = Bass.BASS_ErrorGetCode(); Log.Error("BASS: Unable to create Stream for {0}. Reason: {1}.", filePath, Enum.GetName(typeof(BASSError), error)); throw new BassStreamException("Bass Error: Unable to create stream - " + Enum.GetName(typeof(BASSError), error), error); } bool playbackStarted = false; if (_Mixing) { if (Bass.BASS_ChannelIsActive(_mixer) == BASSActive.BASS_ACTIVE_PLAYING) { playbackStarted = true; } else { playbackStarted = Bass.BASS_ChannelPlay(_mixer, false); } } else { playbackStarted = Bass.BASS_ChannelPlay(stream, false); } if (stream != 0 && playbackStarted) { Log.Info("BASS: playback started"); PlayState oldState = _State; _State = PlayState.Playing; UpdateTimer.Start(); if (oldState != _State && PlaybackStateChanged != null) { PlaybackStateChanged(this, oldState, _State); } if (PlaybackStart != null) { PlaybackStart(this, GetTotalStreamSeconds(stream)); } } else { BASSError error = Bass.BASS_ErrorGetCode(); Log.Error("BASS: Unable to play {0}. Reason: {1}.", filePath, Enum.GetName(typeof(BASSError), error)); throw new BassStreamException("Bass Error: Unable to play - " + Enum.GetName(typeof(BASSError), error), error); // Release all of the sync proc handles if (StreamEventSyncHandles[CurrentStreamIndex] != null) { UnregisterPlaybackEvents(stream, StreamEventSyncHandles[CurrentStreamIndex]); } result = false; } } } catch (Exception ex) { result = false; Log.Error("BASS: Play caused an exception: {0}.", ex); if (ex.GetType() == typeof (BassStreamException)) throw; throw new BassException("BASS: Play caused an exception: " + ex); } return result; }
private bool NewRecordingTitle([NotNull] TAG_INFO info) { bool result = IsRecording; if(result) StopRecordingInternal(); _tagInfo = info; if (_nextChannel != null && _recorder != null) _recorder.ChangeChannel(_nextChannel); return result; }
private void BeginPlayback([NotNull] string url, [NotNull] IPlaybackEngine playbackEngine) { if (_currentChannel != null && _currentChannel.IsActive) Stop(); _url = url; _playbackEngine = playbackEngine; _playbackEngine.ChannelSwitched += PlaybackEngineOnChannelSwitched; _playbackEngine.End += PlaybackEngineOnEnd; _playbackEngine.Initialize(_bassEngine, _plugins); TAG_INFO tags; _currentChannel = _playbackEngine.PlayChannel(url, out tags); _mixer = new Mix(flags:BassMixFlags.Software | BassMixFlags.Nonstop) {Equalizer = _equalizer}; _currentChannel.Mix = _mixer; _visualHelper.Channel = _mixer; _mixer.Play(); _play.Publish(EventArgs.Empty); _tagInfo = PublishTitle(tags); }
public Bass_TagReadWrite(string FileName) { ID_BasicTags = new TAG_INFO(); Update(FileName); ReadTags(); }
public int getBassStream(string filename) { if (_firstUseOfBass) ConfigBassForRadioStreams(); _isWma = false; //BassNet.Registration("*****@*****.**", "key"); _stream = Bass.BASS_StreamCreateURL(filename, 0, BASSFlag.BASS_STREAM_STATUS | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT, null, IntPtr.Zero); if (_stream == 0) { // try WMA streams... _stream = BassWma.BASS_WMA_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT); if (_stream != 0) _isWma = true; else return 0; } _tagInfo = new TAG_INFO(filename); _url = filename; _myHost.getDispatcher().Invoke(System.Windows.Threading.DispatcherPriority.DataBind, new Action( () => DoBuffer(_stream, _isWma))); _mySync = new SYNCPROC(MetaSync); Bass.BASS_ChannelSetSync(_stream, BASSSync.BASS_SYNC_META, 0, _mySync, IntPtr.Zero); Bass.BASS_ChannelSetSync(_stream, BASSSync.BASS_SYNC_WMA_CHANGE, 0, _mySync, IntPtr.Zero); _myHost.getBackgroundWorker().ProgressChanged += RadioNoiseProgressChanged; _buffered = false; return _stream; }
/// <summary> /// Get corresponding Album /// </summary> /// <param name = "tags">File Tags</param> /// <returns>Album to be used while inserting the fingerprints into the database</returns> private Album GetCoresspondingAlbum(TAG_INFO tags) { string album = tags.album; Album albumToInsert = null; if (String.IsNullOrEmpty(album)) //Check whether the album is not null { albumToInsert = _unknownAlbum; //The album is unknown } else { lock (_lockObject) { foreach (Album a in _listOfAllAlbums) if (a.Name == album) { albumToInsert = a; //There is already such an album in the database break; } if (albumToInsert == null) //No such album in the database INSERT! { int releaseYear = -1; try { releaseYear = Convert.ToInt32(tags.year.Split('-')[0].Trim()); } catch (Exception) { /*swallow*/ } albumToInsert = (releaseYear < 1900 || releaseYear > 2200) ? new Album(-1, album) : new Album(-1, album, releaseYear); try { _dalManager.InsertAlbum(albumToInsert); //Insert new ALBUM } catch (DalGatewayException ex) { if (MessageBox.Show(ex.Message + "\n Continue?", Resources.ExceptioInDal, MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.Cancel) return null; albumToInsert = _unknownAlbum; } if (albumToInsert != _unknownAlbum) _listOfAllAlbums.Add(albumToInsert); //Modify Local Variable } } } return albumToInsert; }
internal static TAG_INFO GetInfo(ITagInfo intInfo) { var info = new TAG_INFO() { title = intInfo.Title, artist = intInfo.Artist, album = intInfo.Album, albumartist = intInfo.Albumartist, year = intInfo.Year, comment = intInfo.Comment, genre = intInfo.Genre, track = intInfo.Track, disc = intInfo.Disc, copyright = intInfo.Copyright, encodedby = intInfo.Encodedby, composer = intInfo.Composer, publisher = intInfo.Publisher, lyricist = intInfo.Lyricist, remixer = intInfo.Remixer, producer = intInfo.Producer, bpm = intInfo.Bpm, filename = intInfo.Filename, replaygain_track_gain = intInfo.ReplaygainTrackGain, replaygain_track_peak = intInfo.ReplaygainTrackPeak, conductor = intInfo.Conductor, grouping = intInfo.Grouping, mood = intInfo.Mood, rating = intInfo.Rating, isrc = intInfo.Isrc, duration = intInfo.Duration, bitrate = intInfo.Bitrate }; foreach (var picture in intInfo.Pictures) { info.AddPicture(BassPicture.GeTagPicture(picture)); } return info; }
private TAG_INFO PublishTitle([NotNull] TAG_INFO info) { string newTitle; if (_script != null) // ReSharper disable once AssignNullToNotNullAttribute info = _script.GetTitleInfo(_url, info, out newTitle); else newTitle = info.title; if (info == null) info = new TAG_INFO {title = "Unkown", artist = "Unkown"}; if (string.IsNullOrWhiteSpace(newTitle)) newTitle = "Unkown"; Async.StartNew(() => _titleRecived.Publish(newTitle)); return info; }
private unsafe static bool ReadID3v1(IntPtr p, TAG_INFO tags) { if ((p == IntPtr.Zero) || (tags == null)) { return(false); } if (Marshal.PtrToStringAnsi(p, 3) != "TAG") { return(false); } IntPtr p1 = new IntPtr(p.ToInt64() + 3); tags.title = Marshal.PtrToStringAnsi(p, 30).TrimEnd(new char[1]); int index = tags.title.IndexOf('\0'); if (index > 0) { tags.title = tags.title.Substring(0, index).Trim(); } else if (tags.title.Length >= 30) { tags.title = tags.title.Substring(0, 30).Trim(); } p = new IntPtr(p.ToInt64() + 30); tags.artist = Marshal.PtrToStringAnsi(p, 30).TrimEnd(new char[1]); index = tags.artist.IndexOf('\0'); if (index > 0) { tags.artist = tags.artist.Substring(0, index).Trim(); } else if (tags.artist.Length >= 30) { tags.artist = tags.artist.Substring(0, 30).Trim(); } p = new IntPtr(p.ToInt64() + 30); tags.album = Marshal.PtrToStringAnsi(p, 30).TrimEnd(new char[1]); index = tags.album.IndexOf('\0'); if (index > 0) { tags.album = tags.album.Substring(0, index).Trim(); } else if (tags.album.Length >= 30) { tags.album = tags.album.Substring(0, 30).Trim(); } p = new IntPtr(p.ToInt64() + 30); tags.year = Marshal.PtrToStringAnsi(p, 4).TrimEnd(new char[1]); index = tags.year.IndexOf('\0'); if (index > 0) { tags.year = tags.year.Substring(0, index).Trim(); } else if (tags.year.Length >= 4) { tags.year = tags.year.Substring(0, 4).Trim(); } p = new IntPtr(p.ToInt64() + 4); tags.comment = Marshal.PtrToStringAnsi(p, 30).TrimEnd(new char[1]); index = tags.comment.IndexOf('\0'); if (index > 0) { tags.comment = tags.comment.Substring(0, index).Trim(); } else if (tags.comment.Length >= 30) { tags.comment = tags.comment.Substring(0, 30).Trim(); } p = new IntPtr(p.ToInt64() + 30); int num2 = Marshal.ReadByte(p); try { tags.genre = Enum.GetName(typeof(ID3v1Genre), num2); } catch { tags.genre = ID3v1Genre.Unknown.ToString(); } return(true); }
/// <summary> /// Method to Read Music Tags from Files /// </summary> /// <param name="songPath">Filepath</param> /// <returns>Tags /// tags[0]=album /// tags[1]=artist /// tags[2]=title /// /// </returns> public static string[] GetTags(String songPath) { var tags = new string[3]; var tagInfo = new TAG_INFO(); int stream = Bass.BASS_StreamCreateFile(songPath, 0, 0, BASSFlag.BASS_STREAM_DECODE); BassTags.BASS_TAG_GetFromFile(stream, tagInfo); Bass.BASS_StreamFree(stream); // and display what we get tags[0] = tagInfo.album; tags[1] = tagInfo.artist.Trim(); tags[2] = tagInfo.title.Trim(); /* tags[3] = tagInfo.comment; tags[4] = tagInfo.genre; tags[5] = tagInfo.year; tags[6] = tagInfo.track; * */ if (Bass.BASS_ErrorGetCode() != BASSError.BASS_OK && Bass.BASS_ErrorGetCode() != BASSError.BASS_ERROR_HANDLE) { var e = new BassWrapperException(Bass.BASS_ErrorGetCode(), "Tag Error") {Source = "BassWrapperTags"}; throw e; } return tags; }
/// <summary> /// Create the stream for the file assigned to the Musicstream /// </summary> private void CreateStream() { if (!_temporaryStream) { Log.Info("BASS: ---------------------------------------------"); Log.Info("BASS: Creating BASS audio stream"); } BASSFlag streamFlags = BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE; _fileType = Utils.GetFileType(_filePath); switch (_fileType.FileMainType) { case FileMainType.Unknown: return; case FileMainType.AudioFile: case FileMainType.MidiFile: _stream = Bass.BASS_StreamCreateFile(_filePath, 0, 0, streamFlags); if (!_temporaryStream) { // Read the Tag _musicTag = TagReader.TagReader.ReadTag(_filePath); } break; case FileMainType.CDTrack: // StreamCreateFile causes problems with Multisession disks, so use StreamCreate with driveindex and track index int driveindex = Config.CdDriveLetters.IndexOf(_filePath.Substring(0, 1)); int tracknum = Convert.ToInt16(_filePath.Substring(_filePath.IndexOf(".cda") - 2, 2)); _stream = BassCd.BASS_CD_StreamCreate(driveindex, tracknum - 1, streamFlags); break; case FileMainType.MODFile: _stream = Bass.BASS_MusicLoad(_filePath, 0, 0, BASSFlag.BASS_SAMPLE_SOFTWARE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_MUSIC_DECODE | BASSFlag.BASS_MUSIC_PRESCAN | BASSFlag.BASS_MUSIC_RAMP, 0); break; case FileMainType.WebStream: // Turn on parsing of ASX files Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 2); _stream = Bass.BASS_StreamCreateURL(_filePath, 0, streamFlags, null, IntPtr.Zero); if (_stream != 0 && !_temporaryStream) { // Get the Tags and set the Meta Tag SyncProc _tagInfo = new TAG_INFO(_filePath); SetStreamTags(_stream); if (BassTags.BASS_TAG_GetFromURL(_stream, _tagInfo)) { GetMetaTags(); } Bass.BASS_ChannelSetSync(_stream, BASSSync.BASS_SYNC_META, 0, _metaTagSyncProcDelegate, IntPtr.Zero); Log.Debug("BASS: Webstream found - fetching stream {0}", Convert.ToString(_stream)); } break; } if (_stream == 0) { Log.Error("BASS: Unable to create Stream for {0}. Reason: {1}.", _filePath, Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode())); return; } // When we have a MIDI file, we need to assign the sound banks to the stream if (_fileType.FileMainType == FileMainType.MidiFile && Config.SoundFonts != null) { BassMidi.BASS_MIDI_StreamSetFonts(_stream, Config.SoundFonts, Config.SoundFonts.Length); } _channelInfo = Bass.BASS_ChannelGetInfo(_stream); if (Bass.BASS_ErrorGetCode() != BASSError.BASS_OK) { Log.Error("BASS: Unable to get information for stream {0}. Reason: {1}.", _filePath, Enum.GetName(typeof(BASSError), Bass.BASS_ErrorGetCode())); return; } // This stream has just been created to check upfront, the sample rate // We don't need further processing of this stream if (_temporaryStream) { return; } Log.Info("BASS: Stream Information"); Log.Info("BASS: ---------------------------------------------"); Log.Info("BASS: File: {0}", _filePath); Log.Debug("BASS: Type of Stream: {0}", _channelInfo.ctype); Log.Info("BASS: Number of Channels: {0}", _channelInfo.chans); Log.Info("BASS: Stream Samplerate: {0}", _channelInfo.freq); Log.Debug("BASS: Stream Flags: {0}", _channelInfo.flags); Log.Info("BASS: ---------------------------------------------"); Log.Debug("BASS: Registering stream playback events"); RegisterPlaybackEvents(); AttachDspToStream(); if (Config.EnableReplayGain && _musicTag != null) { SetReplayGain(); } Log.Info("BASS: Successfully created BASS audio stream"); Log.Info("BASS: ---------------------------------------------"); }
private void GetReplayGainData() { if (_Profile.UseReplayGain) { _CurrentReplayGainInfo.AlbumGain = null; _CurrentReplayGainInfo.AlbumPeak = null; _CurrentReplayGainInfo.TrackGain = null; _CurrentReplayGainInfo.TrackPeak = null; // Find ID3V2 tags first, if not there, look for native tags. string[] id3v2Tags = Bass.BASS_ChannelGetTagsID3V2(_CurrentStream); if (id3v2Tags != null) { foreach (string tag in id3v2Tags) { //TXXX=replaygain_track_gain:-5.12 dB Log.Debug("Found ID3V2 tag: {0}", tag); int pos1 = tag.IndexOf("="); if (pos1 > -1) { int pos2 = tag.IndexOf(":", pos1); if (pos2 > -1) { string tagName = tag.Substring(pos1 + 1, pos2 - pos1 - 1).Trim().ToLower(); string tagValue = tag.Substring(pos2 + 1); SetRGTagValue(tagName, tagValue); } } } } else { // FLAC native // replaygain_track_gain=-5.71 dB TAG_INFO tags = new TAG_INFO(); BassTags.BASS_TAG_GetFromFile(_CurrentStream, tags); if (tags.NativeTags != null) { foreach (string tag in tags.NativeTags) { Log.Debug("Found native tag: {0}", tag); int pos1 = tag.IndexOf("="); if (pos1 > -1) { string tagName = tag.Substring(0, pos1).Trim().ToLower(); string tagValue = tag.Substring(pos1 + 1); SetRGTagValue(tagName, tagValue); } } } } Log.Info("Replay Gain Data: {0}", _CurrentReplayGainInfo.ToString()); } }
public abstract Channel PlayChannel(string url, out TAG_INFO tags);
/// <summary> /// This Message is sent from a MusicStream /// </summary> /// <param name="sender"></param> /// <param name="action"></param> private void OnMusicStreamMessage(object sender, MusicStream.StreamAction action) { if (sender == null) { return; } MusicStream musicStream = (MusicStream)sender; switch (action) { case MusicStream.StreamAction.Ended: break; case MusicStream.StreamAction.Crossfading: string nextSong = Playlists.PlayListPlayer.SingletonPlayer.GetNextSong(); if (nextSong != string.Empty) { g_Player.OnChanged(nextSong); PlayInternal(nextSong); g_Player.currentMedia = g_Player.MediaType.Music; g_Player.currentFilePlaying = nextSong; g_Player.OnStarted(); NotifyPlaying = true; } else { Log.Debug("BASS: Reached end of playlist."); g_Player.OnStopped(); Stop(); } break; case MusicStream.StreamAction.InternetStreamChanged: _tagInfo = musicStream.StreamTags; if (InternetStreamSongChanged != null) { InternetStreamSongChanged(this); } break; case MusicStream.StreamAction.Freed: { musicStream.Dispose(); } break; case MusicStream.StreamAction.Disposed: // Remove the stream from the active streams and free it lock (_streams) { if (_streams.Contains(musicStream)) { _streams.Remove(musicStream); } } break; } }
/// <summary> /// Starts Playback of the given file /// </summary> /// <param name="filePath"></param> /// <returns></returns> public override bool Play(string filePath) { if (!_Initialized) { return false; } int stream = GetCurrentStream(); bool doFade = false; bool result = true; Speed = 1; // Set playback Speed to normal speed try { if (filePath.ToLower().CompareTo(FilePath.ToLower()) == 0 && stream != 0) { // Selected file is equal to current stream if (_State == PlayState.Paused) { // Resume paused stream if (_SoftStop) { Bass.BASS_ChannelSlideAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1, 500); } else { Bass.BASS_ChannelSetAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1); } result = Bass.BASS_Start(); if (_useASIO) { result = BassAsio.BASS_ASIO_Start(0); } if (result) { _State = PlayState.Playing; if (PlaybackStateChanged != null) { PlaybackStateChanged(this, PlayState.Paused, _State); } } return result; } } else { // Cue support cueTrackStartPos = 0; cueTrackEndPos = 0; if (CueUtil.isCueFakeTrackFile(filePath)) { Log.Debug("BASS: Playing CUE Track: {0}", filePath); currentCueFakeTrackFileName = filePath; CueFakeTrack cueFakeTrack = CueUtil.parseCueFakeTrackFileName(filePath); if (!cueFakeTrack.CueFileName.Equals(currentCueFileName)) { // New CUE. Update chached cue. currentCueSheet = new CueSheet(cueFakeTrack.CueFileName); currentCueFileName = cueFakeTrack.CueFileName; } // Get track start position Track track = currentCueSheet.Tracks[cueFakeTrack.TrackNumber - currentCueSheet.Tracks[0].TrackNumber]; Index index = track.Indices[0]; cueTrackStartPos = CueUtil.cueIndexToFloatTime(index); // If single audio file and is not last track, set track end position. if (currentCueSheet.Tracks[currentCueSheet.Tracks.Length - 1].TrackNumber > track.TrackNumber) { Track nextTrack = currentCueSheet.Tracks[cueFakeTrack.TrackNumber - currentCueSheet.Tracks[0].TrackNumber + 1]; if (nextTrack.DataFile.Filename.Equals(track.DataFile.Filename)) { Index nindex = nextTrack.Indices[0]; cueTrackEndPos = CueUtil.cueIndexToFloatTime(nindex); } } // If audio file is not changed, just set new start/end position and reset pause string audioFilePath = System.IO.Path.GetDirectoryName(cueFakeTrack.CueFileName) + System.IO.Path.DirectorySeparatorChar + track.DataFile.Filename; if (audioFilePath.CompareTo(FilePath) == 0 /* && StreamIsPlaying(stream)*/) { setCueTrackEndPosition(stream); return true; } filePath = audioFilePath; } else { currentCueFileName = null; currentCueSheet = null; } } if (stream != 0 && StreamIsPlaying(stream)) { int oldStream = stream; double oldStreamDuration = GetTotalStreamSeconds(oldStream); double oldStreamElapsedSeconds = GetStreamElapsedTime(oldStream); double crossFadeSeconds = (double)_CrossFadeIntervalMS; if (crossFadeSeconds > 0) crossFadeSeconds = crossFadeSeconds / 1000.0; if ((oldStreamDuration - (oldStreamElapsedSeconds + crossFadeSeconds) > -1)) { FadeOutStop(oldStream); } else { Bass.BASS_ChannelStop(oldStream); } doFade = true; stream = GetNextStream(); if (stream != 0 || StreamIsPlaying(stream)) { FreeStream(stream); } } if (stream != 0) { if (!Stopped) // Check if stopped already to avoid that Stop() is called two or three times { Stop(); } FreeStream(stream); } _State = PlayState.Init; // Make sure Bass is ready to begin playing again Bass.BASS_Start(); float crossOverSeconds = 0; if (_CrossFadeIntervalMS > 0) { crossOverSeconds = (float)_CrossFadeIntervalMS / 1000f; } if (filePath != string.Empty) { // Turn on parsing of ASX files Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 2); // We need different flags for standard BASS and ASIO / Mixing BASSFlag streamFlags; if (_useASIO || _Mixing) { streamFlags = BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT; // Don't use the BASS_STREAM_AUTOFREE flag on a decoding channel. will produce a BASS_ERROR_NOTAVAIL } else { streamFlags = BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_AUTOFREE; } FilePath = filePath; // create the stream _isCDDAFile = false; _isRadio = false; _isLastFMRadio = false; if (Util.Utils.IsCDDA(filePath)) { _isCDDAFile = true; // StreamCreateFile causes problems with Multisession disks, so use StreamCreate with driveindex and track index int driveindex = _cdDriveLetters.IndexOf(filePath.Substring(0, 1)); int tracknum = Convert.ToInt16(filePath.Substring(filePath.IndexOf(".cda") - 2, 2)); stream = BassCd.BASS_CD_StreamCreate(driveindex, tracknum - 1, streamFlags); if (stream == 0) Log.Error("BASS: CD: {0}.", Enum.GetName(typeof (BASSError), Bass.BASS_ErrorGetCode())); } else if (filePath.ToLower().Contains(@"http://") || filePath.ToLower().Contains(@"https://") || filePath.ToLower().StartsWith("mms") || filePath.ToLower().StartsWith("rtsp")) { // We're playing Internet Radio Stream _isLastFMRadio = Util.Utils.IsLastFMStream(filePath); if (!_isLastFMRadio) { // We're playing Internet Radio Stream, but not LastFM _isRadio = true; } stream = Bass.BASS_StreamCreateURL(filePath, 0, streamFlags, null, IntPtr.Zero); if (stream != 0) { // Get the Tags and set the Meta Tag SyncProc _tagInfo = new TAG_INFO(filePath); SetStreamTags(stream); if (BassTags.BASS_TAG_GetFromURL(stream, _tagInfo)) { GetMetaTags(); } Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_META, 0, MetaTagSyncProcDelegate, IntPtr.Zero); } Log.Debug("BASSAudio: Webstream found - trying to fetch stream {0}", Convert.ToString(stream)); } else if (IsMODFile(filePath)) { // Load a Mod file stream = Bass.BASS_MusicLoad(filePath, 0, 0, BASSFlag.BASS_SAMPLE_SOFTWARE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_MUSIC_AUTOFREE | BASSFlag.BASS_MUSIC_PRESCAN | BASSFlag.BASS_MUSIC_RAMP, 0); } else { // Create a Standard Stream stream = Bass.BASS_StreamCreateFile(filePath, 0, 0, streamFlags); } // Is Mixing / ASIO enabled, then we create a mixer channel and assign the stream to the mixer if ((_Mixing || _useASIO) && stream != 0) { // Do an upmix of the stereo according to the matrix. // Now Plugin the stream to the mixer and set the mixing matrix BassMix.BASS_Mixer_StreamAddChannel(_mixer, stream, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_BUFFER); BassMix.BASS_Mixer_ChannelSetMatrix(stream, _MixingMatrix); } Streams[CurrentStreamIndex] = stream; if (stream != 0) { // When we have a MIDI file, we need to assign the sound banks to the stream if (IsMidiFile(filePath) && soundFonts != null) { BassMidi.BASS_MIDI_StreamSetFonts(stream, soundFonts, soundFonts.Length); } StreamEventSyncHandles[CurrentStreamIndex] = RegisterPlaybackEvents(stream, CurrentStreamIndex); if (doFade && CrossFadeIntervalMS > 0) { _CrossFading = true; // Reduce the stream volume to zero so we can fade it in... Bass.BASS_ChannelSetAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 0); // Fade in from 0 to 1 over the _CrossFadeIntervalMS duration Bass.BASS_ChannelSlideAttribute(stream, BASSAttribute.BASS_ATTRIB_VOL, 1, _CrossFadeIntervalMS); } // Attach active DSP effects to the Stream if (_dspActive) { // BASS effects if (_gain != null) { _gain.ChannelHandle = stream; _gain.Start(); } if (_damp != null) { int dampHandle = Bass.BASS_ChannelSetFX(stream, BASSFXType.BASS_FX_BFX_DAMP, _dampPrio); Bass.BASS_FXSetParameters(dampHandle, _damp); } if (_comp != null) { int compHandle = Bass.BASS_ChannelSetFX(stream, BASSFXType.BASS_FX_BFX_COMPRESSOR, _compPrio); Bass.BASS_FXSetParameters(compHandle, _comp); } // VST Plugins foreach (string plugin in _VSTPlugins) { int vstHandle = BassVst.BASS_VST_ChannelSetDSP(stream, plugin, BASSVSTDsp.BASS_VST_DEFAULT, 1); // Copy the parameters of the plugin as loaded on from the settings int vstParm = _vstHandles[plugin]; BassVst.BASS_VST_SetParamCopyParams(vstParm, vstHandle); } // Init Winamp DSP only if we got a winamp plugin actiavtes int waDspPlugin = 0; if (DSP.Settings.Instance.WinAmpPlugins.Count > 0 && !_waDspInitialised) { BassWaDsp.BASS_WADSP_Init(GUIGraphicsContext.ActiveForm); _waDspInitialised = true; foreach (WinAmpPlugin plugins in DSP.Settings.Instance.WinAmpPlugins) { waDspPlugin = BassWaDsp.BASS_WADSP_Load(plugins.PluginDll, 5, 5, 100, 100, null); if (waDspPlugin > 0) { _waDspPlugins[plugins.PluginDll] = waDspPlugin; BassWaDsp.BASS_WADSP_Start(waDspPlugin, 0, 0); } else { Log.Debug("Couldn't load WinAmp Plugin {0}. Error code: {1}", plugins.PluginDll, Enum.GetName(typeof (BASSError), Bass.BASS_ErrorGetCode())); } } } foreach (int waPluginHandle in _waDspPlugins.Values) { BassWaDsp.BASS_WADSP_ChannelSetDSP(waPluginHandle, stream, 1); } } } else { Log.Error("BASS: Unable to create Stream for {0}. Reason: {1}.", filePath, Enum.GetName(typeof (BASSError), Bass.BASS_ErrorGetCode())); } bool playbackStarted = false; if (_Mixing) { if (Bass.BASS_ChannelIsActive(_mixer) == BASSActive.BASS_ACTIVE_PLAYING) { setCueTrackEndPosition(stream); playbackStarted = true; } else { playbackStarted = Bass.BASS_ChannelPlay(_mixer, false); setCueTrackEndPosition(stream); } } else if (_useASIO) { // Get some information about the stream BASS_CHANNELINFO info = new BASS_CHANNELINFO(); Bass.BASS_ChannelGetInfo(stream, info); // In order to provide data for visualisation we need to clone the stream _streamcopy = new StreamCopy(); _streamcopy.ChannelHandle = stream; _streamcopy.StreamFlags = BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT; // decode the channel, so that we have a Streamcopy _asioHandler.Pan = _asioBalance; _asioHandler.Volume = (float)_StreamVolume / 100f; // Set the Sample Rate from the stream _asioHandler.SampleRate = (double)info.freq; // try to set the device rate too (saves resampling) BassAsio.BASS_ASIO_SetRate((double)info.freq); try { _streamcopy.Start(); // start the cloned stream } catch (Exception) { Log.Error("Captured an error on StreamCopy start"); } if (BassAsio.BASS_ASIO_IsStarted()) { setCueTrackEndPosition(stream); playbackStarted = true; } else { BassAsio.BASS_ASIO_Stop(); playbackStarted = BassAsio.BASS_ASIO_Start(0); setCueTrackEndPosition(stream); } } else { setCueTrackEndPosition(stream); playbackStarted = Bass.BASS_ChannelPlay(stream, false); } if (stream != 0 && playbackStarted) { Log.Info("BASS: playback started"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_PLAYBACK_STARTED, 0, 0, 0, 0, 0, null); msg.Label = FilePath; GUIWindowManager.SendThreadMessage(msg); NotifyPlaying = true; NeedUpdate = true; _IsFullScreen = GUIGraphicsContext.IsFullScreenVideo; _VideoPositionX = GUIGraphicsContext.VideoWindow.Left; _VideoPositionY = GUIGraphicsContext.VideoWindow.Top; _VideoWidth = GUIGraphicsContext.VideoWindow.Width; _VideoHeight = GUIGraphicsContext.VideoWindow.Height; // Re-Add the Viswindow to the Mainform Control (It got removed on a manual Stop) SetVisualizationWindow(); SetVideoWindow(); PlayState oldState = _State; _State = PlayState.Playing; if (oldState != _State && PlaybackStateChanged != null) { PlaybackStateChanged(this, oldState, _State); } if (PlaybackStart != null) { PlaybackStart(this, GetTotalStreamSeconds(stream)); } } else { Log.Error("BASS: Unable to play {0}. Reason: {1}.", filePath, Enum.GetName(typeof (BASSError), Bass.BASS_ErrorGetCode())); // Release all of the sync proc handles if (StreamEventSyncHandles[CurrentStreamIndex] != null) { UnregisterPlaybackEvents(stream, StreamEventSyncHandles[CurrentStreamIndex]); } result = false; } } } catch (Exception ex) { result = false; Log.Error("BASS: Play caused an exception: {0}.", ex); } return result; }