using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using CUETools.Codecs; using CUETools.Processor; using CUETools.DSP.Mixer; namespace CUEPlayer { public partial class Deck : Form { IAudioSource playingSource = null; CUESheet playingCue = null; int playingRow = -1; long playingStart = 0; long playingFinish = 0; Thread playThread; int iSource; AudioBuffer buff; MixingSource mixer; MixingWriter writer; Deck nextDeck; bool needUpdate = false; public Deck(int iSource, string suffix) { InitializeComponent(); this.iSource = iSource; if (suffix != null) Text += " " + suffix; //mediaSliderA.FlyOutInfo += new MediaSlider.MediaSlider.FlyOutInfoDelegate(mediaSliderA_FlyOutInfo); } public void Init(frmCUEPlayer parent, Deck nextDeck) { MdiParent = parent; mixer = (parent as frmCUEPlayer).Mixer; writer = new MixingWriter(mixer, iSource); this.nextDeck = nextDeck; Show(); } //void mediaSliderA_FlyOutInfo(ref string data) //{ // TimeSpan ts = TimeSpan.FromSeconds(mediaSliderA.Value / 44100.0); // data = ts.ToString(); //} internal int PlayingOffset { set { if (!mediaSlider.Capture) mediaSlider.Value = value; } } internal void UpdateDeck() { if (needUpdate) { needUpdate = false; DataSet1 dataSet = (MdiParent as frmCUEPlayer).DataSet; mediaSlider.Maximum = (int)(playingFinish - playingStart); mediaSlider.Value = 0; textBoxArtist.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].artist; textBoxAlbum.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].album; textBoxTitle.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].title; textBoxDuration.Text = ""; pictureBox.Image = playingCue != null && playingCue.Cover != null ? playingCue.Cover : pictureBox.InitialImage; if (nextDeck != null && nextDeck.playingSource == null && playingRow >= 0 && playingRow < dataSet.Playlist.Rows.Count - 1) { nextDeck.LoadDeck(playingRow + 1); } if (playThread != null) (MdiParent as frmCUEPlayer).UpdateMetadata(textBoxArtist.Text, textBoxTitle.Text); } mediaSlider.Enabled = playingSource != null; if (playingSource != null) mediaSlider.Value = (int)(playingSource.Position - playingStart); } private void mediaSliderA_ValueChanged(object sender, EventArgs e) { if (mediaSlider.Maximum == 1) return; TimeSpan len1 = TimeSpan.FromSeconds(mediaSlider.Maximum / 44100.0); TimeSpan len2 = TimeSpan.FromSeconds(mediaSlider.Value / 44100.0); string lenStr1 = string.Format("{0:d}.{1:d2}:{2:d2}:{3:d2}", len1.Days, len1.Hours, len1.Minutes, len1.Seconds).TrimStart('0', ':', '.'); string lenStr2 = string.Format("{0:d}.{1:d2}:{2:d2}:{3:d2}", len2.Days, len2.Hours, len2.Minutes, len2.Seconds).TrimStart('0', ':', '.'); lenStr1 = "0:00".Substring(0, Math.Max(0, 4 - lenStr1.Length)) + lenStr1; lenStr2 = "0:00".Substring(0, Math.Max(0, 4 - lenStr2.Length)) + lenStr2; textBoxDuration.Text = lenStr2 + " / " + lenStr1; } private int seekTo = -1; private bool stopNow = false; private void PlayThread() { try { do { if (playingSource == null) writer.Pause(); else { if (seekTo >= 0 && playingStart + seekTo < playingFinish) { playingSource.Position = playingStart + seekTo; seekTo = -1; } if (playingSource.Position == playingFinish || stopNow || seekTo == (int)(playingFinish - playingStart)) { seekTo = -1; playingSource.Close(); playingSource = null; if (playingCue != null) { playingCue.Close(); playingCue = null; } playingFinish = 0; playingStart = 0; playingRow = -1; if (stopNow || nextDeck == null || nextDeck.playingSource == null) { writer.Flush(); stopNow = false; mixer.BufferPlaying(iSource, false); needUpdate = true; playThread = null; return; } playingSource = nextDeck.playingSource; playingCue = nextDeck.playingCue; playingStart = nextDeck.playingStart; playingFinish = nextDeck.playingFinish; playingRow = nextDeck.playingRow; needUpdate = true; nextDeck.playingSource = null; nextDeck.playingCue = null; nextDeck.playingStart = 0; nextDeck.playingFinish = 0; nextDeck.playingRow = -1; nextDeck.needUpdate = true; } if (buff == null || buff.PCM.SampleRate != playingSource.PCM.SampleRate || buff.PCM.ChannelCount != playingSource.PCM.ChannelCount || buff.PCM.BitsPerSample != playingSource.PCM.BitsPerSample) buff = new AudioBuffer(playingSource.PCM, 0x2000); playingSource.Read(buff, Math.Min(buff.Size, (int)(playingFinish - playingSource.Position))); writer.Write(buff); } } while (true); } catch (Exception) { } if (playingCue != null) { playingCue.Close(); playingCue = null; } if (playingSource != null) { playingSource.Close(); playingSource = null; } playThread = null; } internal void LoadDeck(int row) { CUEConfig _config = (MdiParent as frmCUEPlayer).Config; DataSet1 dataSet = (MdiParent as frmCUEPlayer).DataSet; Playlist playlist = (MdiParent as frmCUEPlayer).wndPlaylist; string path = dataSet.Playlist[row].path; int track = dataSet.Playlist[row].track; try { playingCue = new CUESheet(_config); playingCue.Open(path); playingSource = new CUESheetAudio(playingCue); playingSource.Position = (long)playingCue.TOC[track].Start * 588; playingSource = new AudioPipe(playingSource, 0x2000); playingStart = playingSource.Position; playingFinish = playingStart + (long)playingCue.TOC[track].Length * 588; playingRow = row; //playlist.List.Items[playingRow].BackColor = Color.AliceBlue; needUpdate = true; UpdateDeck(); } catch (Exception) { playingStart = playingFinish = 0; playingCue = null; playingSource = null; return; } } private void buttonPlay_Click(object sender, EventArgs e) { if (playThread == null) { playThread = new Thread(PlayThread); playThread.Priority = ThreadPriority.AboveNormal; playThread.IsBackground = true; playThread.Name = Text; playThread.Start(); } if (playingSource == null) { Playlist playlist = (MdiParent as frmCUEPlayer).wndPlaylist; LoadDeck(playlist.List.SelectedIndices[0]); } mixer.BufferPlaying(iSource, true); } private void buttonStop_Click(object sender, EventArgs e) { if (playThread != null) { stopNow = true; playThread.Join(); } else { if (playingSource != null) { playingSource.Close(); playingSource = null; } if (playingCue != null) { playingCue.Close(); playingCue = null; } playingFinish = 0; playingStart = 0; playingRow = -1; needUpdate = true; UpdateDeck(); } } private void buttonPause_Click(object sender, EventArgs e) { mixer.BufferPlaying(iSource, false); } private void timer1_Tick(object sender, EventArgs e) { UpdateDeck(); } private void mediaSlider_Scrolled(object sender, EventArgs e) { if (playThread != null) { seekTo = mediaSlider.Value; } else { if (playingSource != null) playingSource.Position = playingStart + mediaSlider.Value; } } private void mediaSliderVolume_Scrolled(object sender, EventArgs e) { writer.Volume = mediaSliderVolume.Value / 100.0f; } private void Deck_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.Serializable)) { e.Effect = DragDropEffects.Copy; } } private void Deck_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.Serializable)) { ListView.SelectedIndexCollection indexes = e.Data.GetData(DataFormats.Serializable) as ListView.SelectedIndexCollection; if (playThread == null && indexes != null) { LoadDeck(indexes[0]); } } } private void buttonNext_Click(object sender, EventArgs e) { seekTo = (int)(playingFinish - playingStart); } private void buttonRewind_Click(object sender, EventArgs e) { if (playThread != null) { seekTo = 0; } else if (playingSource != null) { playingSource.Position = playingStart; } } private void Deck_Load(object sender, EventArgs e) { } } }