コード例 #1
0
 public MainWindowViewModel(DiscChanger discChanger, LibraryManager libraryManager)
 {
     DiscChanger        = new DiscChangerViewModel(discChanger);
     TrackStatus        = new TrackStatusViewModel(discChanger, libraryManager);
     CollectionExplorer = new CollectionExplorerViewModel(libraryManager, discChanger);
     VolumeControl      = new VolumeControlViewModel(discChanger);
 }
コード例 #2
0
 internal void Update(DiscChanger discChanger, string name, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort)
 {
     lock (this.DiscChangers)
     {
         if (DiscChangers.Any(dc => dc != discChanger && dc.Name == name))
         {
             throw new Exception($"Name {name} already exists");
         }
         if (DiscChangers.Any(dc => dc != discChanger && dc.Connection == connection && dc.PortName == portName && dc.NetworkHost == networkHost && dc.NetworkPort == networkPort))
         {
             throw new Exception($"Connection {connection}:{portName} {networkHost} already in use");
         }
         discChanger.Name = name;
         discChanger.Type = type;
         if (discChanger.Connection != connection ||
             discChanger.PortName != portName ||
             discChanger.CommandMode != commandMode ||
             discChanger.HardwareFlowControl != HardwareFlowControl ||
             discChanger.NetworkHost != networkHost ||
             discChanger.NetworkPort != networkPort)
         {
             discChanger.Disconnect();
             //discChanger.Protocol   = protocol;
             discChanger.Connection          = connection;
             discChanger.CommandMode         = commandMode;
             discChanger.PortName            = portName;
             discChanger.HardwareFlowControl = HardwareFlowControl;
             discChanger.NetworkHost         = networkHost;
             discChanger.NetworkPort         = networkPort;
             discChanger.Connect(this, this._hubContext, _logger);
         }
     }
 }
コード例 #3
0
 public MainWindowViewModel(DiscChanger discChanger, LibraryManager libraryManager)
 {
     DiscChanger        = new DiscChangerViewModel(discChanger);
     TrackStatus        = new TrackStatusViewModel(discChanger, libraryManager);
     CollectionExplorer = new CollectionExplorerViewModel(libraryManager, discChanger);
     VolumeControl      = new VolumeControlViewModel(discChanger);
     PanelItems         = new List <PanelItem>
     {
         new PanelItem()
         {
             IconID = "Icon_Hamburger", Title = "Test Menu Item"
         },
         new PanelItem()
         {
             IconID = "Icon_Hamburger", Title = "Test Menu Item"
         },
         new PanelItem()
         {
             IconID = "Icon_Hamburger", Title = "Test Menu Item"
         },
         new PanelItem()
         {
             IconID = "HambIcon_urger", Title = "Test Menu Item"
         },
     };
 }
コード例 #4
0
        public VolumeControlViewModel(DiscChanger discChanger)
        {
            this.discChanger = discChanger;

            discChanger.WhenAnyValue(x => x.CurrentTrack)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                if (IsMuted)
                {
                    discChanger.Volume = 0;
                }
                else
                {
                    discChanger.Volume = Volume;
                }
            });

            this.WhenAnyValue(x => x.Volume,
                              x => x.IsMuted)
            .Where(x => !x.Item2)
            .Subscribe(x => discChanger.Volume = x.Item1);

            this.WhenAnyValue(x => x.IsMuted)
            .Where(x => x)
            .Subscribe(_ => discChanger.Volume = 0);
        }
コード例 #5
0
        public CollectionExplorerViewModel(LibraryManager model, DiscChanger changer)
        {
            SelectArtwork = new SelectArtworkViewModel();

            model.Albums.ToObservableChangeSet()
            .Transform(album => new AlbumViewModel(album, changer))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _albums)
            .OnItemAdded(x =>
            {
                if (SelectedAlbum is null)
                {
                    SelectedAlbum = x;
                }
            })
            .DisposeMany()
            .Subscribe();

            ScanLibraryCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                await Task.Run(async() =>
                               await model.ScanMusicFolder(
                                   Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic))));
            });

            RxApp.MainThreadScheduler.Schedule(async() => { await model.LoadLibrary(); });
        }
コード例 #6
0
        public TrackStatusViewModel(DiscChanger discChanger, LibraryManager libraryManager)
        {
            this.WhenAnyValue(x => x.SeekPosition)
            .Skip(1)
            .Subscribe(x => { discChanger.Seek(TimeSpan.FromSeconds(SeekPosition * Duration.TotalSeconds)); });

            this.WhenAnyValue(x => x.Status)
            .Throttle(TimeSpan.FromSeconds(2))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => { Status = ""; });

            Model = discChanger;

            Observable.FromEventPattern(Model, nameof(Model.TrackChanged))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => LoadTrack(Model.CurrentTrack));

            Observable.FromEventPattern(Model, nameof(Model.TrackPositionChanged))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => UpdateCurrentPlayTime(Model.CurrentTrackPosition));

            Observable.FromEventPattern(Model, nameof(Model.SpectrumDataReady))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => InFFTData = Model.CurrentSpectrumData);

            Observable.FromEventPattern <string>(libraryManager, nameof(libraryManager.StatusChanged))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => Status = x.EventArgs);
        }
コード例 #7
0
        public VolumeControlViewModel(DiscChanger discChanger)
        {
            this.discChanger = discChanger;

            Observable.FromEventPattern(discChanger, nameof(discChanger.TrackChanged))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                if (IsMuted)
                {
                    discChanger.Volume = 0;
                }
                else
                {
                    discChanger.Volume = Volume;
                }
            });

            this.WhenAnyValue(x => x.Volume,
                              x => x.IsMuted)
            .Where(x => !x.Item2)
            .Subscribe(x => discChanger.Volume = x.Item1);

            this.WhenAnyValue(x => x.IsMuted)
            .Where(x => x)
            .Subscribe(_ => discChanger.Volume = 0);
        }
コード例 #8
0
        public AlbumViewModel(Album album, DiscChanger changer)
        {
            Model = album;

            GetArtworkCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                await MainWindowViewModel.Instance.CollectionExplorer.SelectArtwork.QueryAlbumCoverAsync(this);
            });

            LoadAlbumCommand = ReactiveCommand.CreateFromTask(async() => { await changer.LoadTrackList(album); });

            Model.Tracks.ToObservableChangeSet()
            .Transform(x => new TrackViewModel(x))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _tracks)
            .OnItemAdded(async x =>
            {
                if (!_coverLoaded)
                {
                    _coverLoaded = true;
                    try
                    {
                        Cover = await LoadCoverAsync();
                    }
                    catch (Exception e)
                    {
                    }
                }
            })
            .Subscribe();
        }
コード例 #9
0
        public async Task UpdateMetaData(Disc d, HashSet <string> metaDataTypes, bool changed = false)
        {
            DiscChanger dc = d.DiscChanger;

            System.Diagnostics.Debug.WriteLine($"About to Lookup {String.Join(',', metaDataTypes)} {dc?.Key} {d.Slot}");
            if (metaDataMusicBrainz != null && metaDataTypes.Contains(MetaDataMusicBrainz.Type))
            {
                try
                {
                    MetaDataMusicBrainz.Data mbd = await metaDataMusicBrainz.RetrieveMetaData(d);

                    if (mbd != null && d.DataMusicBrainz != mbd)
                    {
                        d.DataMusicBrainz = mbd; changed = true;
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine($"MusicBrainz Lookup failed {dc.Key} {d.Slot}: {e.Message}");
                    _logger.LogInformation(e, "MusicBrainz Lookup failed {Key} {Slot}", dc.Key, d.Slot);
                }
            }
            if (metaDataGD3 != null)
            {
                MetaDataGD3.Match gd3d = d.DataGD3Match;
                try
                {
                    if (metaDataTypes.Contains(MetaDataGD3.Type_Match))
                    {
                        gd3d = await metaDataGD3.RetrieveMatch(d);

                        if (gd3d != null && d.DataGD3Match != gd3d)
                        {
                            d.DataGD3Match = gd3d; changed = true;
                        }
                    }
                    if (gd3d != null && !gd3d.HasMetaData() && metaDataTypes.Contains(MetaDataGD3.Type_MetaData))
                    {
                        if (await gd3d.RetrieveMetaData())
                        {
                            changed = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine($"GD3 Match failed {dc.Key} {d.Slot}: {e.Message}");
                    _logger.LogInformation(e, "GD3 Match failed {Key} {Slot}", dc.Key, d.Slot);
                }
            }

            if (dc != null && changed)
            {
                await _hubContext.Clients.All.SendAsync("DiscData",
                                                        dc.Key,
                                                        d.Slot,
                                                        d.ToHtml());
            }
        }
コード例 #10
0
        public DiscChangerViewModel(DiscChanger discChanger)
        {
            _discChanger = discChanger;

            _isPaused = _discChanger.WhenAnyValue(x => x.IsPaused)
                        .ToProperty(this, nameof(IsPaused));

            PlayCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Play(); });

            ForwardCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Forward(); });

            BackCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Back(); });
        }
コード例 #11
0
 internal void Move(string key, int offset)
 {
     lock (this.DiscChangers)
     {
         int i = this.DiscChangers.FindIndex(dc => dc.Key == key);
         if (i >= 0)
         {
             int j = i + offset;
             if (j >= 0 && j < DiscChangers.Count)
             {
                 DiscChanger dc = DiscChangers[i];
                 DiscChangers[i]          = DiscChangers[i + offset];
                 DiscChangers[i + offset] = dc;
                 Save();
                 _hubContext.Clients.All.SendAsync("Reload");
             }
         }
     }
 }
コード例 #12
0
ファイル: App.xaml.cs プロジェクト: sss-software/Synfonia
        public override void OnFrameworkInitializationCompleted()
        {
            if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                var dc = new DiscChanger();
                MainWindowViewModel.Instance = new MainWindowViewModel(dc, new LibraryManager());
                desktop.MainWindow           = new MainWindow
                {
                    DataContext = MainWindowViewModel.Instance
                };

                desktop.MainWindow.Closing += (sender, e) =>
                {
                    dc.Dispose();
                };
            }

            base.OnFrameworkInitializationCompleted();
        }
コード例 #13
0
 internal void Add(string name, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort)
 {
     lock (this.DiscChangers)
     {
         string keyBase = new String(name.ToLower().Where(c => !char.IsWhiteSpace(c)).Take(6).ToArray());
         int    i       = 0;
         string key     = keyBase;
         while (key2DiscChanger.ContainsKey(key))
         {
             i++;
             key = keyBase + i.ToString();
         }
         DiscChanger dc = DiscChanger.Create(type); dc.Key = key;
         Update(dc, name, type, connection, commandMode, portName, HardwareFlowControl, networkHost, networkPort);
         DiscChangers.Add(dc);
         key2DiscChanger[key] = dc;
         Save();
         _hubContext.Clients.All.SendAsync("Reload");
     }
 }
コード例 #14
0
        public DiscChangerViewModel(DiscChanger discChanger)
        {
            _discChanger = discChanger;

            _isPlaying = _discChanger.WhenAnyValue(x => x.IsPlaying)
                         .ToProperty(this, nameof(IsPlaying));

            PlayCommand = ReactiveCommand.Create(() =>
            {
                if (_discChanger.IsPlaying)
                {
                    _discChanger.Pause();
                }
                else
                {
                    _discChanger.Play();
                }
            });

            ForwardCommand = ReactiveCommand.Create(_discChanger.Forward);

            BackCommand = ReactiveCommand.Create(_discChanger.Back);
        }
コード例 #15
0
        internal async Task <string> Test(string key, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort)
        {
            DiscChanger d = null;
            bool        b = key != null && key2DiscChanger.TryGetValue(key, out d) && connection == d.Connection && portName == d.PortName && networkHost == d.NetworkHost && networkPort == d.NetworkPort;

            if (b)
            {
                d.Disconnect();
            }
            DiscChanger dc = DiscChanger.Create(type);

            try
            {
                dc.Connection          = connection;
                dc.CommandMode         = commandMode;
                dc.PortName            = portName;
                dc.HardwareFlowControl = HardwareFlowControl;
                dc.NetworkHost         = networkHost;
                dc.NetworkPort         = networkPort;
                await dc.Connect(null, null, _logger);

                return(await dc.Test());
            }
            catch (Exception e)
            {
                return($"Disc changer testing of ({key},{type},{connection},{commandMode},{portName},{HardwareFlowControl},{networkHost}) returned error: {e.Message}");
            }
            finally
            {
                dc.Disconnect();
                if (b)
                {
                    await d.Connect();
                }
            }
        }
コード例 #16
0
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Hosted Service running.");
            System.Diagnostics.Debug.WriteLine("Hosted Service running.");
            Load();
            metaDataMusicBrainz = new MetaDataMusicBrainz(Path.Combine(discsPath, "MusicBrainz"), discsRelPath + "/MusicBrainz");
            metaDataGD3         = new MetaDataGD3(_provider, contentRootPath, Path.Combine(discsPath, "GD3"), discsRelPath + "/GD3");

            key2DiscChanger = new Dictionary <string, DiscChanger>(DiscChangers.Count);
            List <Task> connectTasks = new List <Task>(DiscChangers.Count);

            foreach (var discChanger in DiscChangers)
            {
                key2DiscChanger[discChanger.Key] = discChanger;
                foreach (var kvp in discChanger.Discs)
                {
                    Disc d = kvp.Value;
                    d.DataMusicBrainz = metaDataMusicBrainz.Get(d);
                    d.DataGD3Match    = metaDataGD3.Get(d);
                }
                try
                {
                    connectTasks.Add(discChanger.Connect(this, _hubContext, _logger));
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine("Exception connecting disc changer: " + discChanger.Key + ": " + e.Message);
                    await _hubContext.Clients.All.SendAsync("StatusData",
                                                            discChanger.Key,
                                                            null,
                                                            null,
                                                            null,
                                                            "off",
                                                            null);
                }
            }
            Task.WaitAll(connectTasks.ToArray());
            _logger.LogInformation("Hosted service starting");
            TimeSpan  discDataTimeOut          = TimeSpan.FromSeconds(3);
            const int NullStatusQueryFrequency = 40;//only query null status every 40x3 seconds
            var       metaDataSet = new HashSet <string> {
                MetaDataMusicBrainz.Type, MetaDataGD3.Type_Match
            };
            var metaDataSetWithGD3Lookup = new HashSet <string> {
                MetaDataMusicBrainz.Type, MetaDataGD3.Type_Match, MetaDataGD3.Type_MetaData
            };

            await Task.Factory.StartNew(async() =>
            {
                int countDown = NullStatusQueryFrequency;
                // loop until a cancellation is requested
                while (!cancellationToken.IsCancellationRequested)
                {
                    _logger.LogInformation("Hosted service executing - {0}", DateTime.Now);
                    try
                    {
                        Disc d         = await discDataMessages.ReceiveAsync(discDataTimeOut, cancellationToken);
                        DiscChanger dc = d.DiscChanger;
                        await UpdateMetaData(d, (metaDataGD3?.AutoLookupEnabled(d) ?? false) ? metaDataSetWithGD3Lookup : metaDataSet, true);
                        d.DateTimeAdded ??= DateTime.Now;
                        dc.Discs[d.Slot] = d;
                        needsSaving      = true;
                    }
                    catch (OperationCanceledException) { }
                    catch (TimeoutException)
                    {
                        if (needsSaving)
                        {
                            Save();
                        }
                        countDown--;
                        foreach (var discChanger in DiscChangers)
                        {
                            var status = discChanger.CurrentStatus();
                            if ((status == null && countDown == 0) /*||(status!=null&&status.IsOutDated())*/) //feature to refresh outdated status prevents auto off on DVP-CX777ES
                            {
                                discChanger.ClearStatus();
                                if (discChanger.Connected())
                                {
                                    discChanger.InitiateStatusUpdate();
                                }
                            }
                        }
                        if (countDown <= 0)
                        {
                            countDown = NullStatusQueryFrequency;
                        }
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine("Hosted Service Exception: " + e.Message);
                        _logger.LogInformation(e, "Hosted Service Exception");
                    }
                }
            }, cancellationToken);
        }