diff --git a/CUEPlayer/CUEPlayer.csproj b/CUEPlayer/CUEPlayer.csproj
index d16a30b..9e63f88 100644
--- a/CUEPlayer/CUEPlayer.csproj
+++ b/CUEPlayer/CUEPlayer.csproj
@@ -84,6 +84,18 @@
frmCUEPlayer.cs
+
+ Form
+
+
+ Icecast.cs
+
+
+ Form
+
+
+ IcecastSettings.cs
+
Form
@@ -107,6 +119,12 @@
frmCUEPlayer.cs
+
+ Icecast.cs
+
+
+ IcecastSettings.cs
+
Output.cs
@@ -132,6 +150,7 @@
Settings.settings
True
+
@@ -146,6 +165,10 @@
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}
CUETools.Codecs.CoreAudio
+
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}
+ CUETools.Codecs.Icecast
+
{6458A13A-30EF-45A9-9D58-E5031B17BEE2}
CUETools.Codecs
@@ -248,6 +271,13 @@
+
+
+
+
+
+
+
diff --git a/CUEPlayer/CUEPlayer.sdf b/CUEPlayer/CUEPlayer.sdf
index 7626ba6..e33b1cf 100644
Binary files a/CUEPlayer/CUEPlayer.sdf and b/CUEPlayer/CUEPlayer.sdf differ
diff --git a/CUEPlayer/DataSet1.Designer.cs b/CUEPlayer/DataSet1.Designer.cs
index c9f6c9e..b23b8b6 100644
--- a/CUEPlayer/DataSet1.Designer.cs
+++ b/CUEPlayer/DataSet1.Designer.cs
@@ -458,10 +458,10 @@ namespace CUEPlayer {
this.columnid.ReadOnly = true;
this.columnid.Unique = true;
this.columnpath.AllowDBNull = false;
- this.columnpath.MaxLength = 100;
- this.columnartist.MaxLength = 100;
- this.columntitle.MaxLength = 100;
- this.columnalbum.MaxLength = 100;
+ this.columnpath.MaxLength = 255;
+ this.columnartist.MaxLength = 255;
+ this.columntitle.MaxLength = 255;
+ this.columnalbum.MaxLength = 255;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -616,11 +616,11 @@ namespace CUEPlayer {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public string artist {
get {
- try {
- return ((string)(this[this.tablePlaylist.artistColumn]));
+ if (this.IsartistNull()) {
+ return string.Empty;
}
- catch (global::System.InvalidCastException e) {
- throw new global::System.Data.StrongTypingException("The value for column \'artist\' in table \'Playlist\' is DBNull.", e);
+ else {
+ return ((string)(this[this.tablePlaylist.artistColumn]));
}
}
set {
@@ -631,11 +631,11 @@ namespace CUEPlayer {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public string title {
get {
- try {
- return ((string)(this[this.tablePlaylist.titleColumn]));
+ if (this.IstitleNull()) {
+ return string.Empty;
}
- catch (global::System.InvalidCastException e) {
- throw new global::System.Data.StrongTypingException("The value for column \'title\' in table \'Playlist\' is DBNull.", e);
+ else {
+ return ((string)(this[this.tablePlaylist.titleColumn]));
}
}
set {
@@ -646,11 +646,11 @@ namespace CUEPlayer {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public string album {
get {
- try {
- return ((string)(this[this.tablePlaylist.albumColumn]));
+ if (this.IsalbumNull()) {
+ return string.Empty;
}
- catch (global::System.InvalidCastException e) {
- throw new global::System.Data.StrongTypingException("The value for column \'album\' in table \'Playlist\' is DBNull.", e);
+ else {
+ return ((string)(this[this.tablePlaylist.albumColumn]));
}
}
set {
diff --git a/CUEPlayer/DataSet1.xsd b/CUEPlayer/DataSet1.xsd
index ec8a857..987caa8 100644
--- a/CUEPlayer/DataSet1.xsd
+++ b/CUEPlayer/DataSet1.xsd
@@ -32,7 +32,7 @@
-
+
SELECT [id], [path], [artist], [title], [album], [length], [track] FROM [Playlist]
@@ -69,43 +69,43 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
diff --git a/CUEPlayer/DataSet1.xss b/CUEPlayer/DataSet1.xss
index 5f28270..c50a493 100644
--- a/CUEPlayer/DataSet1.xss
+++ b/CUEPlayer/DataSet1.xss
@@ -1 +1,12 @@
-
\ No newline at end of file
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CUEPlayer/Deck.Designer.cs b/CUEPlayer/Deck.Designer.cs
index ca284d4..7a152c3 100644
--- a/CUEPlayer/Deck.Designer.cs
+++ b/CUEPlayer/Deck.Designer.cs
@@ -134,7 +134,7 @@
this.mediaSlider.ButtonStyle = MediaSlider.MediaSlider.ButtonType.GlassOverlap;
this.mediaSlider.ContextMenuStrip = null;
this.mediaSlider.LargeChange = 2;
- this.mediaSlider.Location = new System.Drawing.Point(0, 115);
+ this.mediaSlider.Location = new System.Drawing.Point(0, 112);
this.mediaSlider.Margin = new System.Windows.Forms.Padding(0);
this.mediaSlider.Maximum = 1;
this.mediaSlider.Minimum = 0;
@@ -242,7 +242,7 @@
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(361, 145);
+ this.ClientSize = new System.Drawing.Size(361, 136);
this.ControlBox = false;
this.Controls.Add(this.buttonNext);
this.Controls.Add(this.buttonRewind);
@@ -262,6 +262,7 @@
this.Name = "Deck";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Deck";
+ this.Load += new System.EventHandler(this.Deck_Load);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Deck_DragDrop);
this.DragOver += new System.Windows.Forms.DragEventHandler(this.Deck_DragOver);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
diff --git a/CUEPlayer/Deck.cs b/CUEPlayer/Deck.cs
index d654ab3..d21f0f1 100644
--- a/CUEPlayer/Deck.cs
+++ b/CUEPlayer/Deck.cs
@@ -21,6 +21,7 @@ namespace CUEPlayer
long playingFinish = 0;
Thread playThread;
int iSource;
+ AudioBuffer buff;
MixingSource mixer;
MixingWriter writer;
Deck nextDeck;
@@ -72,12 +73,15 @@ namespace CUEPlayer
textBoxAlbum.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].album;
textBoxTitle.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].title;
textBoxDuration.Text = "";
- pictureBox.Image = playingCue != null ? playingCue.Cover : pictureBox.InitialImage;
+ 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)
@@ -101,8 +105,6 @@ namespace CUEPlayer
private void PlayThread()
{
- AudioBuffer buff = new AudioBuffer(playingSource.PCM, 0x2000);
-
try
{
do
@@ -151,6 +153,8 @@ namespace CUEPlayer
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);
}
@@ -205,12 +209,6 @@ namespace CUEPlayer
private void buttonPlay_Click(object sender, EventArgs e)
{
- if (playingSource == null)
- {
- Playlist playlist = (MdiParent as frmCUEPlayer).wndPlaylist;
- LoadDeck(playlist.List.SelectedIndices[0]);
- }
- mixer.BufferPlaying(iSource, true);
if (playThread == null)
{
playThread = new Thread(PlayThread);
@@ -219,6 +217,12 @@ namespace CUEPlayer
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)
@@ -313,5 +317,10 @@ namespace CUEPlayer
playingSource.Position = playingStart;
}
}
+
+ private void Deck_Load(object sender, EventArgs e)
+ {
+
+ }
}
}
diff --git a/CUEPlayer/Icecast.Designer.cs b/CUEPlayer/Icecast.Designer.cs
new file mode 100644
index 0000000..b512ed0
--- /dev/null
+++ b/CUEPlayer/Icecast.Designer.cs
@@ -0,0 +1,119 @@
+namespace CUEPlayer
+{
+ partial class Icecast
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.timer1 = new System.Windows.Forms.Timer(this.components);
+ this.textBoxBytes = new System.Windows.Forms.TextBox();
+ this.checkBoxTransmit = new System.Windows.Forms.CheckBox();
+ this.buttonSettings = new System.Windows.Forms.Button();
+ this.textBoxLatency = new System.Windows.Forms.TextBox();
+ this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+ this.SuspendLayout();
+ //
+ // timer1
+ //
+ this.timer1.Enabled = true;
+ this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ //
+ // textBoxBytes
+ //
+ this.textBoxBytes.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.textBoxBytes.Enabled = false;
+ this.textBoxBytes.Location = new System.Drawing.Point(2, 87);
+ this.textBoxBytes.Name = "textBoxBytes";
+ this.textBoxBytes.ReadOnly = true;
+ this.textBoxBytes.Size = new System.Drawing.Size(70, 13);
+ this.textBoxBytes.TabIndex = 14;
+ this.textBoxBytes.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ //
+ // checkBoxTransmit
+ //
+ this.checkBoxTransmit.Appearance = System.Windows.Forms.Appearance.Button;
+ this.checkBoxTransmit.AutoSize = true;
+ this.checkBoxTransmit.Image = global::CUEPlayer.Properties.Resources.transmit_blue;
+ this.checkBoxTransmit.Location = new System.Drawing.Point(14, 106);
+ this.checkBoxTransmit.Name = "checkBoxTransmit";
+ this.checkBoxTransmit.Size = new System.Drawing.Size(22, 22);
+ this.checkBoxTransmit.TabIndex = 15;
+ this.checkBoxTransmit.UseVisualStyleBackColor = true;
+ this.checkBoxTransmit.CheckedChanged += new System.EventHandler(this.checkBoxTransmit_CheckedChanged);
+ //
+ // buttonSettings
+ //
+ this.buttonSettings.AutoSize = true;
+ this.buttonSettings.Image = global::CUEPlayer.Properties.Resources.cog;
+ this.buttonSettings.Location = new System.Drawing.Point(42, 106);
+ this.buttonSettings.Name = "buttonSettings";
+ this.buttonSettings.Size = new System.Drawing.Size(22, 22);
+ this.buttonSettings.TabIndex = 16;
+ this.buttonSettings.UseVisualStyleBackColor = true;
+ this.buttonSettings.Click += new System.EventHandler(this.buttonSettings_Click);
+ //
+ // textBoxLatency
+ //
+ this.textBoxLatency.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.textBoxLatency.Enabled = false;
+ this.textBoxLatency.Location = new System.Drawing.Point(2, 62);
+ this.textBoxLatency.Name = "textBoxLatency";
+ this.textBoxLatency.ReadOnly = true;
+ this.textBoxLatency.Size = new System.Drawing.Size(70, 13);
+ this.textBoxLatency.TabIndex = 17;
+ this.textBoxLatency.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
+ //
+ // Icecast
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(74, 136);
+ this.Controls.Add(this.textBoxLatency);
+ this.Controls.Add(this.buttonSettings);
+ this.Controls.Add(this.checkBoxTransmit);
+ this.Controls.Add(this.textBoxBytes);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Icecast";
+ this.Text = "Icecast";
+ this.Load += new System.EventHandler(this.Icecast_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Timer timer1;
+ private System.Windows.Forms.TextBox textBoxBytes;
+ private System.Windows.Forms.CheckBox checkBoxTransmit;
+ private System.Windows.Forms.Button buttonSettings;
+ private System.Windows.Forms.TextBox textBoxLatency;
+ private System.Windows.Forms.ToolTip toolTip1;
+ }
+}
\ No newline at end of file
diff --git a/CUEPlayer/Icecast.cs b/CUEPlayer/Icecast.cs
new file mode 100644
index 0000000..b0cf3f5
--- /dev/null
+++ b/CUEPlayer/Icecast.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Diagnostics;
+using System.Threading;
+using System.Net;
+using CUETools.Codecs;
+using CUETools.Codecs.Icecast;
+
+namespace CUEPlayer
+{
+ public partial class Icecast : Form
+ {
+ private IcecastWriter _icecastWriter;
+ private IcecastSettingsData _icecastSettings;
+ private CUETools.DSP.Mixer.MixingSource _mixer;
+ private Thread flushThread;
+ private AudioPipe buffer;
+ private bool close = false;
+ private int latency = 0;
+
+ public Icecast()
+ {
+ InitializeComponent();
+ }
+
+ private void Icecast_Load(object sender, EventArgs e)
+ {
+ if (Properties.Settings.Default.IcecastSettings == null)
+ Properties.Settings.Default.IcecastSettings = new IcecastSettingsData();
+ _icecastSettings = Properties.Settings.Default.IcecastSettings;
+ }
+
+ public void Init(frmCUEPlayer parent)
+ {
+ MdiParent = parent;
+ Show();
+ _mixer = parent.Mixer;
+ buffer = new AudioPipe(_mixer.PCM, _mixer.PCM.SampleRate * 10); // 10 secs
+ _mixer.AudioRead += new EventHandler(Mixer_AudioRead);
+ parent.updateMetadata += new EventHandler(parent_updateMetadata);
+
+ flushThread = new Thread(FlushThread);
+ flushThread.Priority = ThreadPriority.AboveNormal;
+ flushThread.IsBackground = true;
+ flushThread.Name = "Icecast";
+ flushThread.Start();
+ }
+
+ void parent_updateMetadata(object sender, UpdateMetadataEvent e)
+ {
+ if (_icecastWriter != null)
+ _icecastWriter.UpdateMetadata(e.artist, e.title);
+ }
+
+ private void FlushThread()
+ {
+ AudioBuffer result = new AudioBuffer(_mixer.PCM, _mixer.BufferSize);
+ while (true)
+ {
+ buffer.Read(result, -1);
+ if (_icecastWriter != null && !close)
+ {
+ try
+ {
+ _icecastWriter.Write(result);
+ }
+ catch (Exception ex)
+ {
+ close = true;
+ }
+ }
+ if (_icecastWriter != null && close)
+ {
+ _icecastWriter.Delete();
+ _icecastWriter = null;
+ }
+ }
+ }
+
+ void Mixer_AudioRead(object sender, CUETools.DSP.Mixer.AudioReadEventArgs e)
+ {
+ latency = buffer.Write(e.buffer);
+ //int bs = buffer.Write(e.buffer);
+ //if (bs > 0)
+ //{
+ // Trace.WriteLine(string.Format("buffer size {0}", bs));
+ //}
+ }
+
+ private void timer1_Tick(object sender, EventArgs e)
+ {
+ textBoxBytes.Text = _icecastWriter == null ? "" : string.Format("{0}K", _icecastWriter.BytesWritten/1024);
+ textBoxLatency.Text = (_icecastWriter == null || latency == 0 ) ? "" : string.Format("{0}", 1.0 * latency / buffer.PCM.SampleRate);
+ }
+
+ private void checkBoxTransmit_CheckedChanged(object sender, EventArgs e)
+ {
+ close = !checkBoxTransmit.Checked;
+ this.toolTip1.SetToolTip(this.checkBoxTransmit, "");
+ if (!close && _icecastWriter == null)
+ {
+ IcecastWriter icecastWriter = new IcecastWriter(_mixer.PCM, _icecastSettings);
+ try
+ {
+ icecastWriter.Connect();
+ if (icecastWriter.Response.StatusCode == HttpStatusCode.OK)
+ _icecastWriter = icecastWriter;
+ else
+ {
+ toolTip1.ToolTipIcon = ToolTipIcon.Error;
+ toolTip1.ToolTipTitle = icecastWriter.Response.StatusCode.ToString();
+ toolTip1.IsBalloon = true;
+ //toolTip1.Show(resp.StatusDescription, checkBoxTransmit, 0, 0, 2000);
+ toolTip1.SetToolTip(checkBoxTransmit, icecastWriter.Response.StatusDescription);
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine(ex.Message);
+ icecastWriter.Close();
+ toolTip1.ToolTipIcon = ToolTipIcon.Error;
+ toolTip1.ToolTipTitle = "Exception";
+ toolTip1.IsBalloon = true;
+ //toolTip1.Show(ex.Message, checkBoxTransmit, 0, 0, 2000);
+ toolTip1.SetToolTip(checkBoxTransmit, ex.Message);
+ }
+ }
+ }
+
+ private void buttonSettings_Click(object sender, EventArgs e)
+ {
+ IcecastSettings frm = new IcecastSettings(_icecastSettings);
+ if (frm.ShowDialog(this) == DialogResult.OK)
+ Properties.Settings.Default.Save();
+ }
+ }
+}
diff --git a/CUEPlayer/Icecast.resx b/CUEPlayer/Icecast.resx
new file mode 100644
index 0000000..7a6b65e
--- /dev/null
+++ b/CUEPlayer/Icecast.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 104, 17
+
+
\ No newline at end of file
diff --git a/CUEPlayer/IcecastSettings.Designer.cs b/CUEPlayer/IcecastSettings.Designer.cs
new file mode 100644
index 0000000..bd3f528
--- /dev/null
+++ b/CUEPlayer/IcecastSettings.Designer.cs
@@ -0,0 +1,301 @@
+namespace CUEPlayer
+{
+ partial class IcecastSettings
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IcecastSettings));
+ this.buttonCancel = new System.Windows.Forms.Button();
+ this.buttonOk = new System.Windows.Forms.Button();
+ this.textBoxServer = new System.Windows.Forms.TextBox();
+ this.textBoxPort = new System.Windows.Forms.TextBox();
+ this.textBoxPassword = new System.Windows.Forms.TextBox();
+ this.textBoxMount = new System.Windows.Forms.TextBox();
+ this.textBoxName = new System.Windows.Forms.TextBox();
+ this.textBoxDesctiption = new System.Windows.Forms.TextBox();
+ this.textBoxWeb = new System.Windows.Forms.TextBox();
+ this.comboBoxGenre = new System.Windows.Forms.ComboBox();
+ this.labelServer = new System.Windows.Forms.Label();
+ this.labelPort = new System.Windows.Forms.Label();
+ this.labelPassword = new System.Windows.Forms.Label();
+ this.labelMount = new System.Windows.Forms.Label();
+ this.labelStationName = new System.Windows.Forms.Label();
+ this.labelStationDescription = new System.Windows.Forms.Label();
+ this.labelWeb = new System.Windows.Forms.Label();
+ this.labelGenre = new System.Windows.Forms.Label();
+ this.textBoxMP3Options = new System.Windows.Forms.TextBox();
+ this.labelMP3Options = new System.Windows.Forms.Label();
+ this.icecastSettingsDataBindingSource = new System.Windows.Forms.BindingSource(this.components);
+ ((System.ComponentModel.ISupportInitialize)(this.icecastSettingsDataBindingSource)).BeginInit();
+ this.SuspendLayout();
+ //
+ // buttonCancel
+ //
+ this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.buttonCancel.Location = new System.Drawing.Point(197, 272);
+ this.buttonCancel.Name = "buttonCancel";
+ this.buttonCancel.Size = new System.Drawing.Size(75, 23);
+ this.buttonCancel.TabIndex = 0;
+ this.buttonCancel.Text = "Cancel";
+ this.buttonCancel.UseVisualStyleBackColor = true;
+ //
+ // buttonOk
+ //
+ this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.buttonOk.Location = new System.Drawing.Point(116, 272);
+ this.buttonOk.Name = "buttonOk";
+ this.buttonOk.Size = new System.Drawing.Size(75, 23);
+ this.buttonOk.TabIndex = 1;
+ this.buttonOk.Text = "OK";
+ this.buttonOk.UseVisualStyleBackColor = true;
+ //
+ // textBoxServer
+ //
+ this.textBoxServer.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Server", true));
+ this.textBoxServer.Location = new System.Drawing.Point(91, 12);
+ this.textBoxServer.Name = "textBoxServer";
+ this.textBoxServer.Size = new System.Drawing.Size(181, 20);
+ this.textBoxServer.TabIndex = 2;
+ //
+ // textBoxPort
+ //
+ this.textBoxPort.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Port", true));
+ this.textBoxPort.Location = new System.Drawing.Point(91, 38);
+ this.textBoxPort.Name = "textBoxPort";
+ this.textBoxPort.Size = new System.Drawing.Size(181, 20);
+ this.textBoxPort.TabIndex = 3;
+ //
+ // textBoxPassword
+ //
+ this.textBoxPassword.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Password", true));
+ this.textBoxPassword.Location = new System.Drawing.Point(91, 64);
+ this.textBoxPassword.Name = "textBoxPassword";
+ this.textBoxPassword.Size = new System.Drawing.Size(181, 20);
+ this.textBoxPassword.TabIndex = 4;
+ this.textBoxPassword.UseSystemPasswordChar = true;
+ //
+ // textBoxMount
+ //
+ this.textBoxMount.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Mount", true));
+ this.textBoxMount.Location = new System.Drawing.Point(91, 90);
+ this.textBoxMount.Name = "textBoxMount";
+ this.textBoxMount.Size = new System.Drawing.Size(181, 20);
+ this.textBoxMount.TabIndex = 5;
+ //
+ // textBoxName
+ //
+ this.textBoxName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Name", true));
+ this.textBoxName.Location = new System.Drawing.Point(91, 116);
+ this.textBoxName.Name = "textBoxName";
+ this.textBoxName.Size = new System.Drawing.Size(181, 20);
+ this.textBoxName.TabIndex = 6;
+ //
+ // textBoxDesctiption
+ //
+ this.textBoxDesctiption.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Desctiption", true));
+ this.textBoxDesctiption.Location = new System.Drawing.Point(91, 142);
+ this.textBoxDesctiption.Name = "textBoxDesctiption";
+ this.textBoxDesctiption.Size = new System.Drawing.Size(181, 20);
+ this.textBoxDesctiption.TabIndex = 7;
+ //
+ // textBoxWeb
+ //
+ this.textBoxWeb.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Url", true));
+ this.textBoxWeb.Location = new System.Drawing.Point(91, 168);
+ this.textBoxWeb.Name = "textBoxWeb";
+ this.textBoxWeb.Size = new System.Drawing.Size(181, 20);
+ this.textBoxWeb.TabIndex = 8;
+ //
+ // comboBoxGenre
+ //
+ this.comboBoxGenre.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "Genre", true));
+ this.comboBoxGenre.FormattingEnabled = true;
+ this.comboBoxGenre.Location = new System.Drawing.Point(91, 194);
+ this.comboBoxGenre.Name = "comboBoxGenre";
+ this.comboBoxGenre.Size = new System.Drawing.Size(181, 21);
+ this.comboBoxGenre.TabIndex = 9;
+ //
+ // labelServer
+ //
+ this.labelServer.AutoSize = true;
+ this.labelServer.Location = new System.Drawing.Point(12, 15);
+ this.labelServer.Name = "labelServer";
+ this.labelServer.Size = new System.Drawing.Size(38, 13);
+ this.labelServer.TabIndex = 10;
+ this.labelServer.Text = "Server";
+ //
+ // labelPort
+ //
+ this.labelPort.AutoSize = true;
+ this.labelPort.Location = new System.Drawing.Point(12, 41);
+ this.labelPort.Name = "labelPort";
+ this.labelPort.Size = new System.Drawing.Size(26, 13);
+ this.labelPort.TabIndex = 11;
+ this.labelPort.Text = "Port";
+ //
+ // labelPassword
+ //
+ this.labelPassword.AutoSize = true;
+ this.labelPassword.Location = new System.Drawing.Point(12, 67);
+ this.labelPassword.Name = "labelPassword";
+ this.labelPassword.Size = new System.Drawing.Size(53, 13);
+ this.labelPassword.TabIndex = 12;
+ this.labelPassword.Text = "Password";
+ //
+ // labelMount
+ //
+ this.labelMount.AutoSize = true;
+ this.labelMount.Location = new System.Drawing.Point(12, 93);
+ this.labelMount.Name = "labelMount";
+ this.labelMount.Size = new System.Drawing.Size(37, 13);
+ this.labelMount.TabIndex = 13;
+ this.labelMount.Text = "Mount";
+ //
+ // labelStationName
+ //
+ this.labelStationName.AutoSize = true;
+ this.labelStationName.Location = new System.Drawing.Point(12, 119);
+ this.labelStationName.Name = "labelStationName";
+ this.labelStationName.Size = new System.Drawing.Size(35, 13);
+ this.labelStationName.TabIndex = 14;
+ this.labelStationName.Text = "Name";
+ //
+ // labelStationDescription
+ //
+ this.labelStationDescription.AutoSize = true;
+ this.labelStationDescription.Location = new System.Drawing.Point(12, 145);
+ this.labelStationDescription.Name = "labelStationDescription";
+ this.labelStationDescription.Size = new System.Drawing.Size(60, 13);
+ this.labelStationDescription.TabIndex = 15;
+ this.labelStationDescription.Text = "Description";
+ //
+ // labelWeb
+ //
+ this.labelWeb.AutoSize = true;
+ this.labelWeb.Location = new System.Drawing.Point(12, 171);
+ this.labelWeb.Name = "labelWeb";
+ this.labelWeb.Size = new System.Drawing.Size(30, 13);
+ this.labelWeb.TabIndex = 16;
+ this.labelWeb.Text = "Web";
+ //
+ // labelGenre
+ //
+ this.labelGenre.AutoSize = true;
+ this.labelGenre.Location = new System.Drawing.Point(12, 197);
+ this.labelGenre.Name = "labelGenre";
+ this.labelGenre.Size = new System.Drawing.Size(36, 13);
+ this.labelGenre.TabIndex = 17;
+ this.labelGenre.Text = "Genre";
+ //
+ // textBoxMP3Options
+ //
+ this.textBoxMP3Options.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.icecastSettingsDataBindingSource, "MP3Options", true));
+ this.textBoxMP3Options.Location = new System.Drawing.Point(91, 221);
+ this.textBoxMP3Options.Name = "textBoxMP3Options";
+ this.textBoxMP3Options.Size = new System.Drawing.Size(181, 20);
+ this.textBoxMP3Options.TabIndex = 18;
+ //
+ // labelMP3Options
+ //
+ this.labelMP3Options.AutoSize = true;
+ this.labelMP3Options.Location = new System.Drawing.Point(12, 224);
+ this.labelMP3Options.Name = "labelMP3Options";
+ this.labelMP3Options.Size = new System.Drawing.Size(68, 13);
+ this.labelMP3Options.TabIndex = 19;
+ this.labelMP3Options.Text = "MP3 Options";
+ //
+ // icecastSettingsDataBindingSource
+ //
+ this.icecastSettingsDataBindingSource.DataSource = typeof(CUETools.Codecs.Icecast.IcecastSettingsData);
+ //
+ // IcecastSettings
+ //
+ this.AcceptButton = this.buttonOk;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.buttonCancel;
+ this.ClientSize = new System.Drawing.Size(284, 307);
+ this.Controls.Add(this.labelMP3Options);
+ this.Controls.Add(this.textBoxMP3Options);
+ this.Controls.Add(this.labelGenre);
+ this.Controls.Add(this.labelWeb);
+ this.Controls.Add(this.labelStationDescription);
+ this.Controls.Add(this.labelStationName);
+ this.Controls.Add(this.labelMount);
+ this.Controls.Add(this.labelPassword);
+ this.Controls.Add(this.labelPort);
+ this.Controls.Add(this.labelServer);
+ this.Controls.Add(this.comboBoxGenre);
+ this.Controls.Add(this.textBoxWeb);
+ this.Controls.Add(this.textBoxDesctiption);
+ this.Controls.Add(this.textBoxName);
+ this.Controls.Add(this.textBoxMount);
+ this.Controls.Add(this.textBoxPassword);
+ this.Controls.Add(this.textBoxPort);
+ this.Controls.Add(this.textBoxServer);
+ this.Controls.Add(this.buttonOk);
+ this.Controls.Add(this.buttonCancel);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "IcecastSettings";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Icecast Settings";
+ this.Load += new System.EventHandler(this.IcecastSettings_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.icecastSettingsDataBindingSource)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button buttonCancel;
+ private System.Windows.Forms.Button buttonOk;
+ private System.Windows.Forms.TextBox textBoxServer;
+ private System.Windows.Forms.TextBox textBoxPort;
+ private System.Windows.Forms.TextBox textBoxPassword;
+ private System.Windows.Forms.TextBox textBoxMount;
+ private System.Windows.Forms.TextBox textBoxName;
+ private System.Windows.Forms.TextBox textBoxDesctiption;
+ private System.Windows.Forms.TextBox textBoxWeb;
+ private System.Windows.Forms.ComboBox comboBoxGenre;
+ private System.Windows.Forms.Label labelServer;
+ private System.Windows.Forms.Label labelPort;
+ private System.Windows.Forms.Label labelPassword;
+ private System.Windows.Forms.Label labelMount;
+ private System.Windows.Forms.Label labelStationName;
+ private System.Windows.Forms.Label labelStationDescription;
+ private System.Windows.Forms.Label labelWeb;
+ private System.Windows.Forms.Label labelGenre;
+ private System.Windows.Forms.BindingSource icecastSettingsDataBindingSource;
+ private System.Windows.Forms.TextBox textBoxMP3Options;
+ private System.Windows.Forms.Label labelMP3Options;
+ }
+}
\ No newline at end of file
diff --git a/CUEPlayer/IcecastSettings.cs b/CUEPlayer/IcecastSettings.cs
new file mode 100644
index 0000000..ee14f5a
--- /dev/null
+++ b/CUEPlayer/IcecastSettings.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using CUETools.Codecs.Icecast;
+
+namespace CUEPlayer
+{
+ public partial class IcecastSettings : Form
+ {
+ public IcecastSettings(IcecastSettingsData data)
+ {
+ InitializeComponent();
+ icecastSettingsDataBindingSource.DataSource = data;
+ }
+
+ private void IcecastSettings_Load(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/CUEPlayer/IcecastSettings.resx b/CUEPlayer/IcecastSettings.resx
new file mode 100644
index 0000000..b42b501
--- /dev/null
+++ b/CUEPlayer/IcecastSettings.resx
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACjo6OampqaTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fX01aWlpKWlpaAwAA
+ AAAAAAAAAAAAAAAAAAAAAAAAra2tS6Ojo+Sampp8AAAAAAAAAAAAAAAAAAAAAGxsbIBlZWXAX19fRQAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtra28o6Oj95qampwAAAAAAAAAAH19faN0dHTzbGxsrgAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtra2MK2trf2jo6P+mpqaxJCQkMSGhob+fX199HR0
+ dCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2traWra2t/Ofk4//l4uH/kJCQ/IaG
+ hocAAAAAAAAAAAAAAAAAAAAAAAAAAOCfam/emmZm3ZdfDwAAAAAAAAAAv7+/Era2tvOtra3+o6Oj/pqa
+ muWQkJAMAAAAAAAAAAAAAAAA1Xs4P9V7OFXipXXb5K6E/96davbdmWMG3ZZcPgAAAAC/v7+j2tnY/9vZ
+ 2P+jo6OiAAAAANV+PCzVfTkF1Xs45NmGSf/VezjV5auA+e3Fp//ipHX/4J9tCd+daP/dl2Pq0q2PPL+/
+ v/u2trb6vZ+ISNiGR+HXhEP/1YI9CdV/PP/jp3r/1Xs48+ayifnuyq3/5ap+/+OneAPionL246d3/96a
+ Zj/Hx8dOv7+/KtuPUz/dlV3/2IlK9teFRAPVgkD/46p9/9V9OfDotpHY7suu/+Wxif/lrYIJ46h7q+e1
+ jv/goXCq3p1qP92ZYz/dllyq4qV2/9qOU6vaiU0J2YlI/+Knev/Vgj/V6byZkOzHqf/qvZv/5rOLQuWu
+ hRvlq4De6LWP/+Srf//jp3r/5KyA/92XY97dlFsb25FWQt2XX//goG7/2IZHjevBny3rvpz87syw/+i4
+ lPzmto4f5rKJDOWug4Tlqn7G46d4xuKicoTgn2oM3ppmH92XX/zlrID/249T/NqLTioAAAAA7MOikO7J
+ rv/vyq3/6buX/Oi2kULmtYwJAAAAAAAAAADjqHsJ4qV1QuChcPzlsIb/4qh6/92WXI0AAAAAAAAAAOzE
+ pQbsxKS37squ//DNtP/rwqL/6LqV/+i2kf/ms4v/5a+G/+ezi//qu5n/5rGI/+CfbbfenGcGAAAAAAAA
+ AAAAAAAAAAAAAOzEpXLsw6L2782x//HQuP/x07v/8NC5/+3Lrv/rwKD/5a6D9uWqfnIAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA7MSlJ+zEpY3sw6LM67+f/Ou+mvzpu5fM6LaRjea1jCcAAAAAAAAAAAAA
+ AAAAAAAA5+MAAOPHAADxjwAA8A8AAPgfAAAYHAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYEAAIAB
+ AADgBwAA8A8AAA==
+
+
+
\ No newline at end of file
diff --git a/CUEPlayer/Output.Designer.cs b/CUEPlayer/Output.Designer.cs
index 6d82c7a..d1d7863 100644
--- a/CUEPlayer/Output.Designer.cs
+++ b/CUEPlayer/Output.Designer.cs
@@ -29,12 +29,14 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Output));
this.mediaSliderVolume = new MediaSlider.MediaSlider();
this.peakMeterCtrl1 = new Ernzo.WinForms.Controls.PeakMeterCtrl();
- this.buttonPause = new System.Windows.Forms.Button();
- this.buttonPlay = new System.Windows.Forms.Button();
- this.buttonStop = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
+ this.checkBoxMute = new System.Windows.Forms.CheckBox();
+ this.imageList1 = new System.Windows.Forms.ImageList(this.components);
+ this.outputBindingSource = new System.Windows.Forms.BindingSource(this.components);
+ ((System.ComponentModel.ISupportInitialize)(this.outputBindingSource)).BeginInit();
this.SuspendLayout();
//
// mediaSliderVolume
@@ -61,7 +63,7 @@
this.mediaSliderVolume.Name = "mediaSliderVolume";
this.mediaSliderVolume.Orientation = System.Windows.Forms.Orientation.Vertical;
this.mediaSliderVolume.ShowButtonOnHover = false;
- this.mediaSliderVolume.Size = new System.Drawing.Size(37, 114);
+ this.mediaSliderVolume.Size = new System.Drawing.Size(37, 101);
this.mediaSliderVolume.SliderFlyOut = MediaSlider.MediaSlider.FlyOutStyle.None;
this.mediaSliderVolume.SmallChange = 1;
this.mediaSliderVolume.SmoothScrolling = true;
@@ -91,63 +93,61 @@
this.peakMeterCtrl1.FalloffColor = System.Drawing.Color.Blue;
this.peakMeterCtrl1.GridColor = System.Drawing.Color.Gainsboro;
this.peakMeterCtrl1.LEDCount = 25;
- this.peakMeterCtrl1.Location = new System.Drawing.Point(60, 9);
+ this.peakMeterCtrl1.Location = new System.Drawing.Point(46, 9);
this.peakMeterCtrl1.Margin = new System.Windows.Forms.Padding(0);
this.peakMeterCtrl1.Name = "peakMeterCtrl1";
- this.peakMeterCtrl1.Size = new System.Drawing.Size(15, 109);
+ this.peakMeterCtrl1.Size = new System.Drawing.Size(15, 101);
this.peakMeterCtrl1.TabIndex = 13;
this.peakMeterCtrl1.Text = "peakMeterCtrl1";
//
- // buttonPause
- //
- this.buttonPause.Image = global::CUEPlayer.Properties.Resources.control_pause_blue;
- this.buttonPause.Location = new System.Drawing.Point(59, 130);
- this.buttonPause.Name = "buttonPause";
- this.buttonPause.Size = new System.Drawing.Size(25, 25);
- this.buttonPause.TabIndex = 12;
- this.buttonPause.UseVisualStyleBackColor = true;
- this.buttonPause.Click += new System.EventHandler(this.buttonPause_Click);
- //
- // buttonPlay
- //
- this.buttonPlay.BackColor = System.Drawing.Color.Transparent;
- this.buttonPlay.BackgroundImage = global::CUEPlayer.Properties.Resources.control_play_blue;
- this.buttonPlay.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
- this.buttonPlay.FlatAppearance.BorderSize = 0;
- this.buttonPlay.Location = new System.Drawing.Point(9, 130);
- this.buttonPlay.Name = "buttonPlay";
- this.buttonPlay.Size = new System.Drawing.Size(25, 25);
- this.buttonPlay.TabIndex = 10;
- this.buttonPlay.UseVisualStyleBackColor = false;
- this.buttonPlay.Click += new System.EventHandler(this.buttonPlay_Click);
- //
- // buttonStop
- //
- this.buttonStop.Image = global::CUEPlayer.Properties.Resources.control_stop_blue;
- this.buttonStop.Location = new System.Drawing.Point(34, 130);
- this.buttonStop.Name = "buttonStop";
- this.buttonStop.Size = new System.Drawing.Size(25, 25);
- this.buttonStop.TabIndex = 11;
- this.buttonStop.UseVisualStyleBackColor = true;
- this.buttonStop.Click += new System.EventHandler(this.buttonStop_Click);
- //
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 50;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
+ // checkBoxMute
+ //
+ this.checkBoxMute.Appearance = System.Windows.Forms.Appearance.Button;
+ this.checkBoxMute.Checked = true;
+ this.checkBoxMute.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.checkBoxMute.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.outputBindingSource, "Muted", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.checkBoxMute.DataBindings.Add(new System.Windows.Forms.Binding("ImageIndex", this.outputBindingSource, "VolumeIcon", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+ this.checkBoxMute.FlatAppearance.BorderSize = 0;
+ this.checkBoxMute.FlatAppearance.CheckedBackColor = System.Drawing.Color.Transparent;
+ this.checkBoxMute.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent;
+ this.checkBoxMute.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
+ this.checkBoxMute.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.checkBoxMute.ImageIndex = 0;
+ this.checkBoxMute.ImageList = this.imageList1;
+ this.checkBoxMute.Location = new System.Drawing.Point(16, 110);
+ this.checkBoxMute.Name = "checkBoxMute";
+ this.checkBoxMute.Size = new System.Drawing.Size(22, 22);
+ this.checkBoxMute.TabIndex = 15;
+ this.checkBoxMute.UseVisualStyleBackColor = true;
+ //
+ // imageList1
+ //
+ this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
+ this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
+ this.imageList1.Images.SetKeyName(0, "sound_mute.png");
+ this.imageList1.Images.SetKeyName(1, "sound_none.png");
+ this.imageList1.Images.SetKeyName(2, "sound_low.png");
+ this.imageList1.Images.SetKeyName(3, "sound.png");
+ //
+ // outputBindingSource
+ //
+ this.outputBindingSource.DataSource = typeof(CUEPlayer.Output);
+ //
// Output
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(96, 168);
+ this.ClientSize = new System.Drawing.Size(74, 136);
this.ControlBox = false;
+ this.Controls.Add(this.checkBoxMute);
this.Controls.Add(this.mediaSliderVolume);
this.Controls.Add(this.peakMeterCtrl1);
- this.Controls.Add(this.buttonPause);
- this.Controls.Add(this.buttonPlay);
- this.Controls.Add(this.buttonStop);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.MinimizeBox = false;
@@ -155,6 +155,7 @@
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Output";
this.Load += new System.EventHandler(this.Output_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.outputBindingSource)).EndInit();
this.ResumeLayout(false);
}
@@ -163,9 +164,9 @@
private MediaSlider.MediaSlider mediaSliderVolume;
private Ernzo.WinForms.Controls.PeakMeterCtrl peakMeterCtrl1;
- private System.Windows.Forms.Button buttonPause;
- private System.Windows.Forms.Button buttonPlay;
- private System.Windows.Forms.Button buttonStop;
private System.Windows.Forms.Timer timer1;
+ private System.Windows.Forms.CheckBox checkBoxMute;
+ private System.Windows.Forms.ImageList imageList1;
+ private System.Windows.Forms.BindingSource outputBindingSource;
}
}
\ No newline at end of file
diff --git a/CUEPlayer/Output.cs b/CUEPlayer/Output.cs
index 568ef47..081a0f6 100644
--- a/CUEPlayer/Output.cs
+++ b/CUEPlayer/Output.cs
@@ -9,24 +9,39 @@ using System.Diagnostics;
using NAudio.CoreAudioApi;
using CUETools.Codecs;
using CUETools.Codecs.CoreAudio;
+using CUETools.DSP.Resampler;
+using CUETools.DSP.Mixer;
using CUETools.Processor;
namespace CUEPlayer
{
public partial class Output : Form
{
+ private IWavePlayer _player;
+ private AudioBuffer resampled;
+ private SOXResampler _resampler;
private MMDevice _device;
+ private DateTime _pauseTill;
+ private bool _muted;
- internal MMDevice Device
+ public int VolumeIcon
{
get
{
- return _device;
+ return _muted ? 0 : mediaSliderVolume.Value < 10 ? 1 : mediaSliderVolume.Value < 50 ? 2 : 3;
}
+ }
+ public bool Muted
+ {
+ get
+ {
+ return _muted;
+ }
set
{
- _device = value;
+ _muted = value;
+ _pauseTill = DateTime.Now;
}
}
@@ -35,13 +50,73 @@ namespace CUEPlayer
InitializeComponent();
}
+ private void Output_Load(object sender, EventArgs e)
+ {
+ peakMeterCtrl1.Start(50);
+ outputBindingSource.DataSource = this;
+ }
+
public void Init(frmCUEPlayer parent)
{
MdiParent = parent;
_device = WasapiOut.GetDefaultAudioEndpoint();
_device.AudioEndpointVolume.OnVolumeNotification += new AudioEndpointVolumeNotificationDelegate(AudioEndpointVolume_OnVolumeNotification);
mediaSliderVolume.Value = (int)(_device.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
+ //mediaSliderVolume.Maximum = (int)(_device.AudioEndpointVolume.VolumeRange);
Show();
+
+ int delay = 100;
+ try
+ {
+ _player = new WasapiOut(_device, NAudio.CoreAudioApi.AudioClientShareMode.Shared, true, delay, new AudioPCMConfig(32, 2, 44100));
+ }
+ catch
+ {
+ _player = null;
+ }
+ if (_player == null)
+ {
+ try
+ {
+ _player = new WasapiOut(_device, NAudio.CoreAudioApi.AudioClientShareMode.Shared, true, delay, new AudioPCMConfig(32, 2, 48000));
+ SOXResamplerConfig cfg;
+ cfg.quality = SOXResamplerQuality.Very;
+ cfg.phase = 50;
+ cfg.allow_aliasing = false;
+ cfg.bandwidth = 0;
+ _resampler = new SOXResampler(parent.Mixer.PCM, _player.PCM, cfg);
+ resampled = new AudioBuffer(_player.PCM, parent.Mixer.BufferSize * 2 * parent.Mixer.PCM.SampleRate / _player.PCM.SampleRate);
+ }
+ catch (Exception ex)
+ {
+ _player = null;
+ Trace.WriteLine(ex.Message);
+ }
+ }
+ parent.Mixer.AudioRead += new EventHandler(Mixer_AudioRead);
+ if (_player != null)
+ _player.Play();
+ }
+
+ void Mixer_AudioRead(object sender, AudioReadEventArgs e)
+ {
+ if (_muted || _player == null)
+ {
+ double tosleep = (_pauseTill - DateTime.Now).TotalMilliseconds;
+ if (tosleep > 0) System.Threading.Thread.Sleep((int)tosleep);
+ _pauseTill = DateTime.Now.AddMilliseconds(1000 * e.buffer.Length / e.buffer.PCM.SampleRate);
+ return;
+ }
+ if (_resampler == null)
+ _player.Write(e.buffer);
+ else
+ {
+ //Trace.WriteLine(string.Format("Flow: {0}", result.Length));
+ _resampler.Flow(e.buffer, resampled);
+ //Trace.WriteLine(string.Format("Play: {0}", resampled.Length));
+ if (resampled.Length != 0)
+ _player.Write(resampled);
+ }
}
void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
@@ -51,13 +126,17 @@ namespace CUEPlayer
if (this.InvokeRequired)
this.Invoke((MethodInvoker)delegate() { AudioEndpointVolume_OnVolumeNotification(data); });
else
+ {
mediaSliderVolume.Value = (int)(data.MasterVolume * 100);
+ outputBindingSource.ResetBindings(false);
+ }
}
private void mediaSliderVolume_Scrolled(object sender, EventArgs e)
{
try
{
+ outputBindingSource.ResetBindings(false);
_device.AudioEndpointVolume.MasterVolumeLevelScalar = mediaSliderVolume.Value / 100.0f;
}
catch (Exception ex)
@@ -82,25 +161,5 @@ namespace CUEPlayer
//peakValues[0] = (int)(_device.AudioMeterInformation.MasterPeakValue * 100);
peakMeterCtrl1.SetData(peakValues, 0, peakValues.Length);
}
-
- private void buttonPlay_Click(object sender, EventArgs e)
- {
- (MdiParent as frmCUEPlayer).buttonPlay_Click(sender, e);
- }
-
- private void buttonStop_Click(object sender, EventArgs e)
- {
- (MdiParent as frmCUEPlayer).buttonStop_Click(sender, e);
- }
-
- private void buttonPause_Click(object sender, EventArgs e)
- {
- (MdiParent as frmCUEPlayer).buttonPause_Click(sender, e);
- }
-
- private void Output_Load(object sender, EventArgs e)
- {
- peakMeterCtrl1.Start(50);
- }
}
}
diff --git a/CUEPlayer/Output.resx b/CUEPlayer/Output.resx
index 93f75a9..8bba917 100644
--- a/CUEPlayer/Output.resx
+++ b/CUEPlayer/Output.resx
@@ -120,4 +120,63 @@
17, 17
+
+ 214, 17
+
+
+ 104, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAC0
+ CgAAAk1TRnQBSQFMAgEBBAEAAQwBAAEEAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
+ AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
+ AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
+ AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
+ AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
+ AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
+ ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
+ AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
+ AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
+ AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
+ AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
+ AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
+ AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
+ AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
+ AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
+ ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
+ Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
+ AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
+ AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
+ AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
+ ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
+ Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
+ AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
+ AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
+ AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
+ AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
+ AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
+ AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AiQAB9AH/
+ BAAB8gHsCgAB8gH4DgAB8gH4DgAB8gHsCwAB/wHjAZQB/wEAAf8BvAJtCAAB/wG8Am0MAAH/AbwCbQwA
+ Af8BvAJtBQABvQH/BQABBwHjARYB8wHsAW0B6wFtBAAD9AHzAewBbQHrAW0IAAP0AfMB7AFtAesBbQQA
+ Af8DAAP0AfMB7AFtAesBbQQAAb0BRwFvBQAB6wFvARcBbwHrARIB6gFtBAAC6wNtARIB6gFtCAAC6wNt
+ ARIB6gFtAwABGgH/AwAC6wNtARIB6gFtAwABGgH/AUYBRwEaBAAB7AGSAW8BFwFGARQB6gFtBAAB+AGS
+ AesBbQESARUB6gFtCAAB+AGSAesBbQESARUB6gFtAgABGgEXARoB/wIAAewBkgHrAW0BEgEVAeoBbQIA
+ ARoBFwIaAUcBbwQAAewBkgFtAW4BFwFGAm0EAAHsAZIBbQHqARIBEwJtCAAB7AGSAW0B6gESARMCbQEA
+ AeMB9AIXAwAB7AGSAW0B6gESARMCbQEAAeMB9AIXAQACRgQAAewB9wLsAW8BFwFvAesEAAHsAfcC7AH4
+ AesB7AFtCAAB7AH3AuwB+AHrAewBbQEAARYB9AHjARcDAAHsAfcD7AHrAewBbQEAARYB9AHjARcBAAEX
+ AUYEAAHsAwcBkgFvARcBbwH/AwAB7AMHAZIB7AHtAesIAAHsAwcBkgHsAe0B6wIAARsB4wEaAf8CAAHs
+ AwcBkgHsAe0B6wIAARsB4wIaARcBFgQAAewD7QH3Ae8BbwEXAZQDAAHsA+0B9wHvAfcB6wgAAewD7QH3
+ Ae8B9wHrAwABGwH/AwAB7APtAfcB7wH3AesDAAEbAf8BbwHjARoEAAT0AfcBkgHvAW8BFgH/AgAE9AH3
+ AZIB7wH4CAAE9AH3AZIB7wH4BAAB/wMABPQB9wGSAe8B7AQAARoB4wGTCQAB/wHwAuwBGgH/BgAB/wHw
+ AuwMAAH/AfAC7AwAAf8B8ALsBQABGwH/CwAB8gGSCgAB8gGSDgAB8gGSDgAB8gGSiAABQgFNAT4HAAE+
+ AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/4EAEP8B8wHPAfwB/wH8Af8B/AH/AeEBDwHwAf8B8AH/
+ AfAB+QHwAQ8BAAH/AQAB9wEAAfEB8AEPAQAB/wEAAecBAAHgAfABDwEAAf8BAAHDAQABwAHwAQ8BAAH/
+ AQABhwEAAYQB8AEPAQAB/wEAAYcBAAGEAfABBwEAAf8BAAHDAQABwAHwAQcBAAH/AQAB5wEAAeAB8AED
+ AQAB/wEAAfcBAAHxAf8BAwHwAf8B8AH/AfAB+QH/Ac8B/AH/AfwB/wH8Ef8L
+
+
\ No newline at end of file
diff --git a/CUEPlayer/Playlist.Designer.cs b/CUEPlayer/Playlist.Designer.cs
index ed85e7d..01cb3e8 100644
--- a/CUEPlayer/Playlist.Designer.cs
+++ b/CUEPlayer/Playlist.Designer.cs
@@ -104,6 +104,7 @@
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.Name = "Playlist";
this.Text = "Playlist";
+ this.Load += new System.EventHandler(this.Playlist_Load);
this.contextMenuStripPlaylist.ResumeLayout(false);
this.ResumeLayout(false);
diff --git a/CUEPlayer/Playlist.cs b/CUEPlayer/Playlist.cs
index fe3b888..96e0438 100644
--- a/CUEPlayer/Playlist.cs
+++ b/CUEPlayer/Playlist.cs
@@ -33,7 +33,16 @@ namespace CUEPlayer
_icon_mgr = parent.IconMgr;
listViewTracks.SmallImageList = _icon_mgr.ImageList;
foreach (DataSet1.PlaylistRow row in dataSet.Playlist)
- listViewTracks.Items.Add(ToItem(row));
+ {
+ try
+ {
+ listViewTracks.Items.Add(ToItem(row));
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine(ex.Message);
+ }
+ }
}
public ListView List
@@ -161,5 +170,10 @@ namespace CUEPlayer
return;
}
}
+
+ private void Playlist_Load(object sender, EventArgs e)
+ {
+
+ }
}
}
diff --git a/CUEPlayer/Properties/AssemblyInfo.cs b/CUEPlayer/Properties/AssemblyInfo.cs
index 4fe4bde..8a33b29 100644
--- a/CUEPlayer/Properties/AssemblyInfo.cs
+++ b/CUEPlayer/Properties/AssemblyInfo.cs
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("CUEPlayer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyCompany("CUETools")]
[assembly: AssemblyProduct("CUEPlayer")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyCopyright("Copyright © Gregory S. Chudov 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("2.0.7.0")]
+[assembly: AssemblyFileVersion("2.0.7.0")]
diff --git a/CUEPlayer/Properties/DataSources/frmCUEPlayer.datasource b/CUEPlayer/Properties/DataSources/frmCUEPlayer.datasource
index a71c582..dfd281a 100644
--- a/CUEPlayer/Properties/DataSources/frmCUEPlayer.datasource
+++ b/CUEPlayer/Properties/DataSources/frmCUEPlayer.datasource
@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program.
-->
- CUEPlayer.frmCUEPlayer, CUEPlayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+ CUEPlayer.frmCUEPlayer, CUEPlayer, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null
\ No newline at end of file
diff --git a/CUEPlayer/Properties/Resources.Designer.cs b/CUEPlayer/Properties/Resources.Designer.cs
index 3f6c907..4999a65 100644
--- a/CUEPlayer/Properties/Resources.Designer.cs
+++ b/CUEPlayer/Properties/Resources.Designer.cs
@@ -60,6 +60,13 @@ namespace CUEPlayer.Properties {
}
}
+ internal static System.Drawing.Bitmap cog {
+ get {
+ object obj = ResourceManager.GetObject("cog", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
internal static System.Drawing.Bitmap control_eject {
get {
object obj = ResourceManager.GetObject("control_eject", resourceCulture);
@@ -143,5 +150,26 @@ namespace CUEPlayer.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
+
+ internal static System.Drawing.Bitmap sound {
+ get {
+ object obj = ResourceManager.GetObject("sound", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ internal static System.Drawing.Bitmap sound_mute {
+ get {
+ object obj = ResourceManager.GetObject("sound_mute", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ internal static System.Drawing.Bitmap transmit_blue {
+ get {
+ object obj = ResourceManager.GetObject("transmit_blue", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
}
}
diff --git a/CUEPlayer/Properties/Resources.resx b/CUEPlayer/Properties/Resources.resx
index ca47dd6..b489aee 100644
--- a/CUEPlayer/Properties/Resources.resx
+++ b/CUEPlayer/Properties/Resources.resx
@@ -118,8 +118,8 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\Resources\control_eject_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\ctdb.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\control_fastforward_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
@@ -130,20 +130,32 @@
..\Resources\control_eject.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\control_end_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\control_eject_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\control_stop_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\sound_mute.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\control_repeat_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\sound.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Resources\control_rewind_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\transmit_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Resources\control_pause_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\control_stop_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\control_end_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\control_play_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
@@ -151,7 +163,7 @@
..\Resources\control_equalizer_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\ctdb.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\cog.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
\ No newline at end of file
diff --git a/CUEPlayer/Properties/Settings.Designer.cs b/CUEPlayer/Properties/Settings.Designer.cs
index adad87b..1af32be 100644
--- a/CUEPlayer/Properties/Settings.Designer.cs
+++ b/CUEPlayer/Properties/Settings.Designer.cs
@@ -32,5 +32,27 @@ namespace CUEPlayer.Properties {
return ((string)(this["CUEPlayerConnectionString"]));
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::CUETools.Codecs.Icecast.IcecastSettingsData IcecastSettings {
+ get {
+ return ((global::CUETools.Codecs.Icecast.IcecastSettingsData)(this["IcecastSettings"]));
+ }
+ set {
+ this["IcecastSettings"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::CUEPlayer.CUEPlayerSettings AppSettings {
+ get {
+ return ((global::CUEPlayer.CUEPlayerSettings)(this["AppSettings"]));
+ }
+ set {
+ this["AppSettings"] = value;
+ }
+ }
}
}
diff --git a/CUEPlayer/Properties/Settings.settings b/CUEPlayer/Properties/Settings.settings
index c35c471..6289b05 100644
--- a/CUEPlayer/Properties/Settings.settings
+++ b/CUEPlayer/Properties/Settings.settings
@@ -10,5 +10,11 @@
</SerializableConnectionString>
Data Source=|DataDirectory|\CUEPlayer.sdf
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CUEPlayer/Resources/cog.png b/CUEPlayer/Resources/cog.png
new file mode 100644
index 0000000..67de2c6
Binary files /dev/null and b/CUEPlayer/Resources/cog.png differ
diff --git a/CUEPlayer/Resources/sound.png b/CUEPlayer/Resources/sound.png
new file mode 100644
index 0000000..6056d23
Binary files /dev/null and b/CUEPlayer/Resources/sound.png differ
diff --git a/CUEPlayer/Resources/sound_low.png b/CUEPlayer/Resources/sound_low.png
new file mode 100644
index 0000000..4d91863
Binary files /dev/null and b/CUEPlayer/Resources/sound_low.png differ
diff --git a/CUEPlayer/Resources/sound_mute.png b/CUEPlayer/Resources/sound_mute.png
new file mode 100644
index 0000000..b652d2a
Binary files /dev/null and b/CUEPlayer/Resources/sound_mute.png differ
diff --git a/CUEPlayer/Resources/sound_none.png b/CUEPlayer/Resources/sound_none.png
new file mode 100644
index 0000000..b497ebd
Binary files /dev/null and b/CUEPlayer/Resources/sound_none.png differ
diff --git a/CUEPlayer/Resources/transmit_blue.ico b/CUEPlayer/Resources/transmit_blue.ico
new file mode 100644
index 0000000..533f9e7
Binary files /dev/null and b/CUEPlayer/Resources/transmit_blue.ico differ
diff --git a/CUEPlayer/Resources/transmit_blue.png b/CUEPlayer/Resources/transmit_blue.png
new file mode 100644
index 0000000..7b1142f
Binary files /dev/null and b/CUEPlayer/Resources/transmit_blue.png differ
diff --git a/CUEPlayer/Settings.cs b/CUEPlayer/Settings.cs
new file mode 100644
index 0000000..9d26791
--- /dev/null
+++ b/CUEPlayer/Settings.cs
@@ -0,0 +1,28 @@
+namespace CUEPlayer.Properties {
+
+
+ // This class allows you to handle specific events on the settings class:
+ // The SettingChanging event is raised before a setting's value is changed.
+ // The PropertyChanged event is raised after a setting's value is changed.
+ // The SettingsLoaded event is raised after the setting values are loaded.
+ // The SettingsSaving event is raised before the setting values are saved.
+ internal sealed partial class Settings {
+
+ public Settings() {
+ // // To add event handlers for saving and changing settings, uncomment the lines below:
+ //
+ // this.SettingChanging += this.SettingChangingEventHandler;
+ //
+ // this.SettingsSaving += this.SettingsSavingEventHandler;
+ //
+ }
+
+ private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
+ // Add code to handle the SettingChangingEvent event here.
+ }
+
+ private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
+ // Add code to handle the SettingsSaving event here.
+ }
+ }
+}
diff --git a/CUEPlayer/app.config b/CUEPlayer/app.config
index b579cd0..d979376 100644
--- a/CUEPlayer/app.config
+++ b/CUEPlayer/app.config
@@ -7,4 +7,9 @@
connectionString="Data Source=|DataDirectory|\CUEPlayer.sdf"
providerName="Microsoft.SqlServerCe.Client.3.5" />
+
+
+
+
+
\ No newline at end of file
diff --git a/CUEPlayer/frmCUEPlayer.Designer.cs b/CUEPlayer/frmCUEPlayer.Designer.cs
index dd6e041..3df6216 100644
--- a/CUEPlayer/frmCUEPlayer.Designer.cs
+++ b/CUEPlayer/frmCUEPlayer.Designer.cs
@@ -28,24 +28,62 @@
///
private void InitializeComponent()
{
+ this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+ this.windowsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.icecastToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
+ // menuStrip1
+ //
+ this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.windowsToolStripMenuItem});
+ this.menuStrip1.Location = new System.Drawing.Point(0, 0);
+ this.menuStrip1.Name = "menuStrip1";
+ this.menuStrip1.Size = new System.Drawing.Size(1200, 24);
+ this.menuStrip1.TabIndex = 1;
+ this.menuStrip1.Text = "menuStrip1";
+ //
+ // windowsToolStripMenuItem
+ //
+ this.windowsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.icecastToolStripMenuItem});
+ this.windowsToolStripMenuItem.Name = "windowsToolStripMenuItem";
+ this.windowsToolStripMenuItem.Size = new System.Drawing.Size(68, 20);
+ this.windowsToolStripMenuItem.Text = "Windows";
+ //
+ // icecastToolStripMenuItem
+ //
+ this.icecastToolStripMenuItem.Name = "icecastToolStripMenuItem";
+ this.icecastToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+ this.icecastToolStripMenuItem.Text = "Icecast";
+ this.icecastToolStripMenuItem.Click += new System.EventHandler(this.icecastToolStripMenuItem_Click);
+ //
// frmCUEPlayer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1200, 477);
+ this.ClientSize = new System.Drawing.Size(1200, 474);
+ this.Controls.Add(this.menuStrip1);
this.IsMdiContainer = true;
+ this.MainMenuStrip = this.menuStrip1;
this.Name = "frmCUEPlayer";
this.Text = "CUEPlayer 2.0.7";
this.Load += new System.EventHandler(this.frmCUEPlayer_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmCUEPlayer_FormClosing);
+ this.menuStrip1.ResumeLayout(false);
+ this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
+ this.PerformLayout();
}
#endregion
+ private System.Windows.Forms.MenuStrip menuStrip1;
+ private System.Windows.Forms.ToolStripMenuItem windowsToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem icecastToolStripMenuItem;
+
}
}
diff --git a/CUEPlayer/frmCUEPlayer.cs b/CUEPlayer/frmCUEPlayer.cs
index 109497f..23e53aa 100644
--- a/CUEPlayer/frmCUEPlayer.cs
+++ b/CUEPlayer/frmCUEPlayer.cs
@@ -8,12 +8,9 @@ using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
-using NAudio.CoreAudioApi;
using CUEControls;
using CUETools.Codecs;
-using CUETools.Codecs.CoreAudio;
using CUETools.DSP.Mixer;
-using CUETools.DSP.Resampler;
using CUETools.Processor;
namespace CUEPlayer
@@ -22,12 +19,10 @@ namespace CUEPlayer
{
private ShellIconMgr _icon_mgr;
private CUEConfig _config;
- private IWavePlayer _player;
DataSet1TableAdapters.PlaylistTableAdapter adapterPlayList = new DataSet1TableAdapters.PlaylistTableAdapter();
private DataSet1 dataSet = new DataSet1();
private Thread mixThread;
private MixingSource _mixer;
- private SOXResampler _resampler;
internal Playlist wndPlaylist
{
@@ -85,236 +80,42 @@ namespace CUEPlayer
private void frmCUEPlayer_Load(object sender, EventArgs e)
{
- int delay = 100;
- AudioPCMConfig mixerPCM = AudioPCMConfig.RedBook;
+ if (Properties.Settings.Default.AppSettings == null)
+ {
+ Properties.Settings.Default.AppSettings = new CUEPlayerSettings();
+ Properties.Settings.Default.AppSettings.IcecastServers.Add(new CUETools.Codecs.Icecast.IcecastSettingsData());
+ }
//System.Data.SqlServerCe.SqlCeDataAdapter ad = new System.Data.SqlServerCe.SqlCeDataAdapter();
//ad.SelectCommand = new System.Data.SqlServerCe.SqlCeCommand("SELECT * FROM Playlist WHERE track=1", adapterPlayList.Connection);
//ad.Fill(dataSet.Playlist);
adapterPlayList.Fill(dataSet.Playlist);
- _mixer = new MixingSource(mixerPCM, delay, 2);
+ _mixer = new MixingSource(new AudioPCMConfig(32, 2, 44100), 100, 2);
outputA.Init(this);
browser.Init(this);
playlist.Init(this);
deckB.Init(this, null);
deckA.Init(this, deckB);
+ Icecast icecast = new Icecast();
+ icecast.Init(this);
//LayoutMdi(MdiLayout.TileHorizontal);
-
+
browser.Location = new Point(0, 0);
- browser.Height = ClientRectangle.Height - 5;
+ browser.Height = ClientRectangle.Height - 5 - menuStrip1.Height;
playlist.Location = new Point(browser.Location.X + browser.Width, 0);
- playlist.Height = ClientRectangle.Height - 5;
+ playlist.Height = ClientRectangle.Height - 5 - menuStrip1.Height;
deckA.Location = new Point(playlist.Location.X + playlist.Width, 0);
deckB.Location = new Point(playlist.Location.X + playlist.Width, deckA.Height);
outputA.Location = new Point(deckA.Location.X + deckA.Width, 0);
+ icecast.Location = new Point(deckA.Location.X + deckA.Width, outputA.Height);
- try
- {
- _player = new WasapiOut(outputA.Device, NAudio.CoreAudioApi.AudioClientShareMode.Shared, true, delay, new AudioPCMConfig(32, 2, 44100));
- }
- catch
- {
- _player = null;
- }
- if (_player == null)
- {
- try
- {
- _player = new WasapiOut(outputA.Device, NAudio.CoreAudioApi.AudioClientShareMode.Shared, true, delay, new AudioPCMConfig(32, 2, 48000));
- SOXResamplerConfig cfg;
- cfg.quality = SOXResamplerQuality.Very;
- cfg.phase = 50;
- cfg.allow_aliasing = false;
- cfg.bandwidth = 0;
- _resampler = new SOXResampler(mixerPCM, _player.PCM, cfg);
- }
- catch(Exception ex)
- {
- _player = null;
- Trace.WriteLine(ex.Message);
- }
- }
- if (_player != null)
- {
- _player.Play();
-
- mixThread = new Thread(MixThread);
- mixThread.Priority = ThreadPriority.AboveNormal;
- mixThread.IsBackground = true;
- mixThread.Name = "Mixer";
- mixThread.Start();
- }
- }
-
- Thread playThread;
-
- int playingRow;
-
- private void PlayThread()
- {
- AudioBuffer buff = new AudioBuffer(AudioPCMConfig.RedBook, 0x2000);
- IAudioSource playingSource = null;
- CUESheet playingCue = null;
- long playingOffs = 0;
- long playingFin = 0;
-
- try
- {
- do
- {
- // End of playlist entry or source file
- if (playingSource != null && (playingOffs == playingFin || playingSource.Remaining == 0))
- {
- this.Invoke((MethodInvoker)delegate()
- {
- playlist.List.Items[playingRow].BackColor = Color.White;
- });
- playingRow++;
- playingOffs = 0;
- if (playingRow >= dataSet.Playlist.Rows.Count)
- break;
- string path = dataSet.Playlist[playingRow].path;
- int track = dataSet.Playlist[playingRow].track;
-
- if (playingCue == null ||
- playingSource == null ||
- playingCue.InputPath != path ||
- playingSource.Position != (long)playingCue.TOC[track].Start * 588)
- {
- if (playingSource != null)
- {
- playingSource.Close();
- playingSource = null;
- }
- if (playingCue != null)
- {
- playingCue.Close();
- playingCue = null;
- }
- }
- else
- {
- playingFin = (long)playingCue.TOC[track].Length * 588;
- this.Invoke((MethodInvoker)delegate()
- {
- playlist.List.Items[playingRow].BackColor = Color.AliceBlue;
- //deckA.UpdateDeck(dataSet, playingRow, playingCue, playingFin);
- });
- }
- }
- // Open it
- if (playingSource == null)
- {
- string path = dataSet.Playlist[playingRow].path;
- int track = dataSet.Playlist[playingRow].track;
-
- try
- {
- playingCue = new CUESheet(_config);
- playingCue.Open(path);
- playingSource = new CUESheetAudio(playingCue);
- playingSource.Position = (long)playingCue.TOC[track].Start * 588 + playingOffs;
- playingSource = new AudioPipe(playingSource, 0x2000);
- playingFin = (long)playingCue.TOC[track].Length * 588;
- this.Invoke((MethodInvoker)delegate()
- {
- playlist.List.Items[playingRow].BackColor = Color.AliceBlue;
- //deckA.UpdateDeck(dataSet, playingRow, playingCue, playingFin);
- });
- }
- catch (Exception ex)
- {
- // skip it
- playingOffs = playingFin = 0;
- continue;
- }
- }
- playingSource.Read(buff, (int)(playingFin - playingOffs));
-
- this.Invoke((MethodInvoker)delegate()
- {
- deckA.PlayingOffset = (int)playingOffs;
- });
-
- _player.Write(buff);
- playingOffs += buff.Length;
- } while (_player.PlaybackState != PlaybackState.Stopped);
- }
- catch (Exception ex)
- {
- // Can't invoke while joining
-
- //if (playingRow < dataSet.Playlist.Rows.Count)
- // this.Invoke((MethodInvoker)delegate()
- // {
- // listViewTracks.Items[playingRow].BackColor = Color.White;
- // });
- }
-
- if (playingCue != null)
- {
- playingCue.Close();
- playingCue = null;
- }
- if (playingSource != null)
- {
- playingSource.Close();
- playingSource = null;
- }
- }
-
- internal void buttonPlay_Click(object sender, EventArgs e)
- {
- try
- {
- _player.Stop();
- if (playThread != null)
- {
- playThread.Join();
- playThread = null;
- }
-
- if (playlist.List.SelectedIndices.Count < 0)
- return;
-
- playingRow = playlist.List.SelectedIndices[0];
- playlist.List.Items[playingRow].BackColor = Color.AliceBlue;
-
- _player.Play();
-
- playThread = new Thread(new ThreadStart(PlayThread));
- playThread.Priority = ThreadPriority.AboveNormal;
- playThread.IsBackground = true;
- playThread.Start();
- }
- catch (Exception ex)
- {
- Trace.WriteLine(ex.Message);
- }
- }
-
- internal void buttonStop_Click(object sender, EventArgs e)
- {
- try
- {
- _player.Stop();
- if (playThread != null)
- {
- playThread.Join();
- playThread = null;
- }
- }
- catch (Exception ex)
- {
- Trace.WriteLine(ex.Message);
- }
- }
-
- internal void buttonPause_Click(object sender, EventArgs e)
- {
- _player.Pause();
+ mixThread = new Thread(MixThread);
+ mixThread.Priority = ThreadPriority.AboveNormal;
+ mixThread.IsBackground = true;
+ mixThread.Name = "Mixer";
+ mixThread.Start();
}
private void frmCUEPlayer_FormClosing(object sender, FormClosingEventArgs e)
@@ -331,23 +132,55 @@ namespace CUEPlayer
private void MixThread()
{
- AudioBuffer result = new AudioBuffer(
- new AudioPCMConfig(_player.PCM.BitsPerSample, _player.PCM.ChannelCount, _mixer.PCM.SampleRate), _mixer.BufferSize);
- AudioBuffer resampled = _resampler == null ? null : new AudioBuffer(_player.PCM, _mixer.BufferSize * 2 * _mixer.PCM.SampleRate / _player.PCM.SampleRate);
+ AudioBuffer result = new AudioBuffer(_mixer.PCM, _mixer.BufferSize);
while (true)
{
- //Trace.WriteLine(string.Format("Read"));
_mixer.Read(result, -1);
- if (_resampler == null)
- _player.Write(result);
- else
- {
- //Trace.WriteLine(string.Format("Flow: {0}", result.Length));
- _resampler.Flow(result, resampled);
- //Trace.WriteLine(string.Format("Play: {0}", resampled.Length));
- if (resampled.Length != 0)
- _player.Write(resampled);
- }
+ }
+ }
+
+ public event EventHandler updateMetadata;
+
+ public void UpdateMetadata(string artist, string title)
+ {
+ UpdateMetadataEvent e = new UpdateMetadataEvent();
+ e.artist = artist;
+ e.title = title;
+ if (updateMetadata != null)
+ updateMetadata(this, e);
+ }
+
+ private void icecastToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ Icecast icecast = new Icecast();
+ icecast.Init(this);
+ }
+ }
+
+ public class UpdateMetadataEvent: EventArgs
+ {
+ public string artist;
+ public string title;
+ }
+
+ public class CUEPlayerSettings
+ {
+ private BindingList icecastServers;
+
+ public CUEPlayerSettings()
+ {
+ icecastServers = new BindingList();
+ }
+
+ public BindingList IcecastServers
+ {
+ get
+ {
+ return icecastServers;
+ }
+ set
+ {
+ icecastServers = value;
}
}
}
diff --git a/CUEPlayer/frmCUEPlayer.resx b/CUEPlayer/frmCUEPlayer.resx
index e5c789f..87b404d 100644
--- a/CUEPlayer/frmCUEPlayer.resx
+++ b/CUEPlayer/frmCUEPlayer.resx
@@ -117,6 +117,9 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
39
diff --git a/CUETools.Codecs.FLAKE/FlakeWriter.cs b/CUETools.Codecs.FLAKE/FlakeWriter.cs
index db60b46..cee78b5 100644
--- a/CUETools.Codecs.FLAKE/FlakeWriter.cs
+++ b/CUETools.Codecs.FLAKE/FlakeWriter.cs
@@ -1502,9 +1502,11 @@ namespace CUETools.Codecs.FLAKE
if (bs < eparams.block_size)
{
- fixed (int* s = samplesBuffer)
- for (int ch = 0; ch < channels; ch++)
- AudioSamples.MemCpy(s + ch * Flake.MAX_BLOCKSIZE, s + bs + ch * Flake.MAX_BLOCKSIZE, eparams.block_size - bs);
+ for (int ch = 0; ch < (channels == 2 ? 4 : channels); ch++)
+ Buffer.BlockCopy(samplesBuffer, (bs + ch * Flake.MAX_BLOCKSIZE) * sizeof(int), samplesBuffer, ch * Flake.MAX_BLOCKSIZE * sizeof(int), (eparams.block_size - bs) * sizeof(int));
+ //fixed (int* s = samplesBuffer)
+ // for (int ch = 0; ch < channels; ch++)
+ // AudioSamples.MemCpy(s + ch * Flake.MAX_BLOCKSIZE, s + bs + ch * Flake.MAX_BLOCKSIZE, eparams.block_size - bs);
}
samplesInBuffer -= bs;
diff --git a/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj b/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj
new file mode 100644
index 0000000..d2e7e3a
--- /dev/null
+++ b/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj
@@ -0,0 +1,61 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}
+ Library
+ Properties
+ CUETools.Codecs.Icecast
+ CUETools.Codecs.Icecast
+ v2.0
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+ {1AF02E2C-2CB2-44B5-B417-37653071FEC6}
+ CUETools.Codecs.LAME
+ False
+
+
+ {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
+ CUETools.Codecs
+
+
+
+
+
\ No newline at end of file
diff --git a/CUETools.Codecs.Icecast/IcecastWriter.cs b/CUETools.Codecs.Icecast/IcecastWriter.cs
new file mode 100644
index 0000000..a93522d
--- /dev/null
+++ b/CUETools.Codecs.Icecast/IcecastWriter.cs
@@ -0,0 +1,264 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.IO;
+using System.Web;
+using CUETools.Codecs;
+
+namespace CUETools.Codecs.Icecast
+{
+ public class IcecastWriter: IAudioDest
+ {
+ private long _sampleOffset = 0;
+ private AudioPCMConfig pcm = AudioPCMConfig.RedBook;
+ private LAME.LAMEEncoderCBR encoder = null;
+ private HttpWebRequest req = null;
+ private HttpWebResponse resp = null;
+ private Stream reqStream;
+ private IcecastSettingsData settings = null;
+
+ public IAudioDest Encoder
+ {
+ get
+ {
+ return encoder;
+ }
+ }
+
+ public IcecastWriter(AudioPCMConfig pcm, IcecastSettingsData settings)
+ {
+ this.pcm = pcm;
+ this.settings = settings;
+ }
+
+ #region IAudioDest Members
+
+ public HttpWebResponse Response
+ {
+ get
+ {
+ return resp;
+ }
+ }
+
+ public void Connect()
+ {
+ Uri uri = new Uri("http://" + settings.Server + ":" + settings.Port + settings.Mount);
+ req = (HttpWebRequest)WebRequest.Create(uri);
+ //req.Proxy = proxy;
+ //req.UserAgent = userAgent;
+ req.ProtocolVersion = HttpVersion.Version10; // new Version("ICE/1.0");
+ req.Method = "SOURCE";
+ req.ContentType = "audio/mpeg";
+ req.Headers.Add("ice-name", settings.Name ?? "no name");
+ req.Headers.Add("ice-public", "1");
+ if ((settings.Url ?? "") != "") req.Headers.Add("ice-url", settings.Url);
+ if ((settings.Genre ?? "") != "") req.Headers.Add("ice-genre", settings.Genre);
+ if ((settings.Desctiption ?? "") != "") req.Headers.Add("ice-description", settings.Desctiption);
+ req.Headers.Add("Authorization", string.Format("Basic {0}", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("source:{0}", settings.Password)))));
+ req.Timeout = System.Threading.Timeout.Infinite;
+ req.ReadWriteTimeout = System.Threading.Timeout.Infinite;
+ //req.ContentLength = 999999999;
+ req.KeepAlive = false;
+ req.SendChunked = true;
+ req.AllowWriteStreamBuffering = false;
+ req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.BypassCache);
+
+ System.Reflection.PropertyInfo pi = typeof(ServicePoint).GetProperty("HttpBehaviour", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
+ pi.SetValue(req.ServicePoint, pi.PropertyType.GetField("Unknown").GetValue(null), null);
+
+ reqStream = req.GetRequestStream();
+
+ System.Reflection.FieldInfo fi = reqStream.GetType().GetField("m_HttpWriteMode", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
+ fi.SetValue(reqStream, fi.FieldType.GetField("Buffer").GetValue(null));
+ System.Reflection.MethodInfo mi = reqStream.GetType().GetMethod("CallDone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, new Type[0], null);
+ mi.Invoke(reqStream, null);
+
+ try
+ {
+ resp = req.GetResponse() as HttpWebResponse;
+ if (resp.StatusCode == HttpStatusCode.OK)
+ {
+ encoder = new CUETools.Codecs.LAME.LAMEEncoderCBR("", reqStream, AudioPCMConfig.RedBook);
+ encoder.Options = settings.MP3Options;
+ }
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status == WebExceptionStatus.ProtocolError)
+ resp = ex.Response as HttpWebResponse;
+ else
+ throw ex;
+ }
+ }
+
+ public void UpdateMetadata(string artist, string title)
+ {
+ string song = ((artist ?? "") != "" && (title ?? "") != "") ? artist + " - " + title : (title ?? "");
+ string metadata = "";
+ //if (station != "")
+ // metadata += "&name=" + Uri.EscapeDataString(station);
+ if (song != "")
+ metadata += "&song=" + Uri.EscapeDataString(song);
+ Uri uri = new Uri("http://" + settings.Server + ":" + settings.Port + "/admin/metadata?mode=updinfo&mount=" + settings.Mount + metadata);
+ HttpWebRequest req2 = (HttpWebRequest)WebRequest.Create(uri);
+ req2.Method = "GET";
+ req2.Credentials = new NetworkCredential("source", settings.Password);
+ //req.Proxy = proxy;
+ //req.UserAgent = userAgent;
+ //req2.Headers.Add("Authorization", string.Format("Basic {0}", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("source:{0}", settings.Password)))));
+ HttpStatusCode accResult = HttpStatusCode.OK;
+ try
+ {
+ HttpWebResponse resp = (HttpWebResponse)req2.GetResponse();
+ accResult = resp.StatusCode;
+ if (accResult == HttpStatusCode.OK)
+ {
+ }
+ resp.Close();
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status == WebExceptionStatus.ProtocolError)
+ accResult = ((HttpWebResponse)ex.Response).StatusCode;
+ else
+ accResult = HttpStatusCode.BadRequest;
+ }
+ }
+
+ public void Close()
+ {
+ if (encoder != null)
+ {
+ encoder.Close();
+ encoder = null;
+ }
+ if (reqStream != null)
+ {
+ reqStream.Close();
+ reqStream = null;
+ }
+ if (resp != null)
+ {
+ resp.Close();
+ resp = null;
+ }
+ if (req != null)
+ {
+ req.Abort();
+ req = null;
+ }
+ }
+
+ public void Delete()
+ {
+ if (encoder != null)
+ {
+ encoder.Delete();
+ encoder = null;
+ }
+ if (reqStream != null)
+ {
+ reqStream.Close();
+ reqStream = null;
+ }
+ if (resp != null)
+ {
+ resp.Close();
+ resp = null;
+ }
+ if (req != null)
+ {
+ req.Abort();
+ req = null;
+ }
+ }
+
+ AudioBuffer tmp;
+
+ public void Write(AudioBuffer src)
+ {
+ if (encoder == null)
+ throw new Exception("not connected");
+
+ if (tmp == null || tmp.Size < src.Size)
+ tmp = new AudioBuffer(AudioPCMConfig.RedBook, src.Size);
+ tmp.Prepare(-1);
+ Buffer.BlockCopy(src.Float, 0, tmp.Float, 0, src.Length * 8);
+ tmp.Length = src.Length;
+ encoder.Write(tmp);
+ }
+
+ public long Position
+ {
+ get
+ {
+ return _sampleOffset;
+ }
+ }
+
+ public long BlockSize
+ {
+ set { }
+ }
+
+ public long FinalSampleCount
+ {
+ set { ; }
+ }
+
+ public int CompressionLevel
+ {
+ get { return 0; }
+ set { }
+ }
+
+ public string Options
+ {
+ set
+ {
+ if (value == null || value == "") return;
+ throw new Exception("Unsupported options " + value);
+ }
+ }
+ public AudioPCMConfig PCM
+ {
+ get { return pcm; }
+ }
+
+ public string Path { get { return null; } }
+ #endregion
+
+ public long BytesWritten
+ {
+ get
+ {
+ return encoder == null ? 0 : encoder.BytesWritten;
+ }
+ }
+ }
+
+ public class IcecastSettingsData
+ {
+ private string server;
+ private string port = "8000";
+ private string password;
+ private string mount;
+ private string name;
+ private string description;
+ private string url;
+ private string genre;
+ private string mp3Options = "-m j -b 192";
+
+ public string Server { get { return server; } set { server = value; } }
+ public string Port { get { return port; } set { port = value; } }
+ public string Password { get { return password; } set { password = value; } }
+ public string Mount { get { return mount; } set { mount = value; } }
+ public string Name { get { return name; } set { name = value; } }
+ public string Desctiption { get { return description; } set { description = value; } }
+ public string Url { get { return url; } set { url = value; } }
+ public string Genre { get { return genre; } set { genre = value; } }
+ public string MP3Options { get { return mp3Options; } set { mp3Options = value; } }
+ }
+}
diff --git a/CUETools.Codecs.Icecast/Properties/AssemblyInfo.cs b/CUETools.Codecs.Icecast/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d0568ae
--- /dev/null
+++ b/CUETools.Codecs.Icecast/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CUETools.Codecs.Icecast")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CUETools.Codecs.Icecast")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("913f32e1-64c8-45d3-8f91-5dd1ba733fe9")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CUETools.Codecs.LAME/Encoder.cs b/CUETools.Codecs.LAME/Encoder.cs
index 00fe2f8..a608d6d 100644
--- a/CUETools.Codecs.LAME/Encoder.cs
+++ b/CUETools.Codecs.LAME/Encoder.cs
@@ -20,9 +20,12 @@ namespace CUETools.Codecs.LAME
private string _path;
private Stream _IO;
private long position = 0, sample_count = -1;
+ private long bytesWritten = 0;
public LAMEEncoder(string path, Stream IO, AudioPCMConfig pcm)
{
+ if (pcm.BitsPerSample != 16)// && pcm.BitsPerSample != 32)
+ throw new ArgumentOutOfRangeException("format", "Only 16 & 32 bits samples supported");
_pcm = pcm;
_path = path;
_IO = IO;
@@ -33,45 +36,50 @@ namespace CUETools.Codecs.LAME
{
}
- public void DeInit()
+ public void DeInit(bool flush)
{
if (!inited || closed)
return;
try
{
- uint EncodedSize = 0;
- if (m_InBufferPos > 0)
+ if (flush)
{
- if (Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, 0, (uint)m_InBufferPos, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
+ uint EncodedSize = 0;
+ if (m_InBufferPos > 0)
+ {
+ if (Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, 0, (uint)m_InBufferPos, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
+ {
+ if (EncodedSize > 0)
+ {
+ _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ bytesWritten += EncodedSize;
+ }
+ }
+ }
+ EncodedSize = 0;
+ if (Lame_encDll.beDeinitStream(m_hLameStream, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
{
if (EncodedSize > 0)
{
_IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ bytesWritten += EncodedSize;
}
}
}
- EncodedSize = 0;
- if (Lame_encDll.beDeinitStream(m_hLameStream, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
- {
- if (EncodedSize > 0)
- {
- _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
- }
- }
}
finally
{
Lame_encDll.beCloseStream(m_hLameStream);
_IO.Close();
- }
- closed = true;
+ closed = true;
+ }
}
public void Close()
{
bool needTag = !closed && _path != null && _path != "";
- DeInit();
+ DeInit(true);
if (needTag)
{
try
@@ -88,7 +96,7 @@ namespace CUETools.Codecs.LAME
{
if (!closed)
{
- DeInit();
+ DeInit(false);
if (_path != "")
File.Delete(_path);
}
@@ -150,6 +158,7 @@ namespace CUETools.Codecs.LAME
if (EncodedSize > 0)
{
_IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ bytesWritten += EncodedSize;
}
}
else
@@ -167,6 +176,7 @@ namespace CUETools.Codecs.LAME
if (EncodedSize > 0)
{
_IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ bytesWritten += EncodedSize;
}
}
else
@@ -234,6 +244,14 @@ namespace CUETools.Codecs.LAME
}
public string Path { get { return _path; } }
+
+ public long BytesWritten
+ {
+ get
+ {
+ return bytesWritten;
+ }
+ }
}
@@ -304,8 +322,9 @@ namespace CUETools.Codecs.LAME
[AudioEncoderClass("lame CBR", "mp3", false, "96 128 192 256 320", "256", 2)]
public class LAMEEncoderCBR : LAMEEncoder
{
- private int bps_index;
+ private uint bps;
private static readonly uint[] bps_table = new uint[] {96, 128, 192, 256, 320};
+ private MpegMode stereo = MpegMode.STEREO;
public LAMEEncoderCBR(string path, Stream IO, AudioPCMConfig pcm)
: base(path, IO, pcm)
@@ -321,20 +340,55 @@ namespace CUETools.Codecs.LAME
{
get
{
- return bps_index;
+ for (int i = 0; i < bps_table.Length; i++)
+ if (bps == bps_table[i])
+ return i;
+ return -1;
}
set
{
if (value < 0 || value > bps_table.Length)
throw new Exception("unsupported compression level");
- bps_index = value;
+ bps = bps_table[value];
+ }
+ }
+
+ public override string Options
+ {
+ set
+ {
+ if (value == null || value == "") return;
+ string[] args = value.Split();
+ for (int i = 0; i < args.Length; i++)
+ {
+ if (args[i] == "-b" && (++i) < args.Length)
+ {
+ bps = uint.Parse(args[i]);
+ continue;
+ }
+ if (args[i] == "-m" && (++i) < args.Length)
+ {
+ switch (args[i])
+ {
+ case "s": stereo = MpegMode.STEREO; break;
+ case "j": stereo = MpegMode.JOINT_STEREO; break;
+ case "d": stereo = MpegMode.DUAL_CHANNEL; break;
+ case "m": stereo = MpegMode.MONO; break;
+ default:
+ throw new Exception("Unsupported options " + value);
+ }
+ continue;
+ }
+ throw new Exception("Unsupported options " + value);
+ }
}
}
protected override BE_CONFIG MakeConfig()
{
- BE_CONFIG Mp3Config = new BE_CONFIG(PCM, bps_table[bps_index]);
+ BE_CONFIG Mp3Config = new BE_CONFIG(PCM, bps);
Mp3Config.format.lhv1.bWriteVBRHeader = 1;
+ Mp3Config.format.lhv1.nMode = stereo;
//Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; // --cbr
//Mp3Config.format.lhv1.nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY;
return Mp3Config;
diff --git a/CUETools.Codecs.LAME/Lame.cs b/CUETools.Codecs.LAME/Lame.cs
index 3a887a5..44b434f 100644
--- a/CUETools.Codecs.LAME/Lame.cs
+++ b/CUETools.Codecs.LAME/Lame.cs
@@ -139,9 +139,6 @@ namespace CUETools.Codecs.LAME
public LHV1(AudioPCMConfig format, uint MpeBitRate)
{
- if ( format.BitsPerSample != 16)
- throw new ArgumentOutOfRangeException("format", "Only 16 bits samples supported");
-
dwStructVersion = 1;
dwStructSize = (uint)Marshal.SizeOf(typeof(BE_CONFIG));
switch (format.SampleRate)
diff --git a/CUETools.Codecs/Codecs.cs b/CUETools.Codecs/Codecs.cs
index b7d4b5e..41e14a3 100644
--- a/CUETools.Codecs/Codecs.cs
+++ b/CUETools.Codecs/Codecs.cs
@@ -250,6 +250,8 @@ namespace CUETools.Codecs
Bytes16ToFloat(bytes, 0, fsamples, 0, length, pcm.ChannelCount);
//else if (pcm.BitsPerSample > 16 && PCM.BitsPerSample <= 24)
// BytesToFLACSamples_24(bytes, 0, fsamples, 0, length, pcm.ChannelCount, 24 - pcm.BitsPerSample);
+ else if (pcm.BitsPerSample == 32)
+ Buffer.BlockCopy(bytes, 0, fsamples, 0, length * 4 * pcm.ChannelCount);
else
throw new Exception("Unsupported bitsPerSample value");
}
@@ -356,6 +358,16 @@ namespace CUETools.Codecs
throw new Exception("Invalid length");
}
+ internal unsafe void Load(int dstOffset, AudioBuffer src, int srcOffset, int copyLength)
+ {
+ if (dataInBytes)
+ Buffer.BlockCopy(src.Bytes, srcOffset * pcm.BlockAlign, Bytes, dstOffset * pcm.BlockAlign, copyLength * pcm.BlockAlign);
+ if (dataInSamples)
+ Buffer.BlockCopy(src.Samples, srcOffset * pcm.ChannelCount * 4, Samples, dstOffset * pcm.ChannelCount * 4, copyLength * pcm.ChannelCount * 4);
+ if (dataInFloat)
+ Buffer.BlockCopy(src.Float, srcOffset * pcm.ChannelCount * 4, Float, dstOffset * pcm.ChannelCount * 4, copyLength * pcm.ChannelCount * 4);
+ }
+
public unsafe void Prepare(AudioBuffer _src, int _offset, int _length)
{
length = Math.Min(size, _src.Length - _offset);
@@ -365,19 +377,12 @@ namespace CUETools.Codecs
dataInFloat = false;
dataInSamples = false;
if (_src.dataInBytes)
- {
dataInBytes = true;
- fixed (byte* dest = Bytes, src = &_src.Bytes[_offset * pcm.BlockAlign])
- AudioSamples.MemCpy(dest, src, length * pcm.BlockAlign);
- }
else if (_src.dataInSamples)
- {
dataInSamples = true;
- fixed (int* dest = Samples, src = &_src.Samples[_offset, 0])
- AudioSamples.MemCpy(dest, src, Length * pcm.ChannelCount);
- }
- else if (_src.dataInFloat)
- throw new NotImplementedException();
+ else if (_src.dataInFloat)
+ dataInFloat = true;
+ Load(0, _src, _offset, length);
}
public void Swap(AudioBuffer buffer)
@@ -1731,6 +1736,10 @@ namespace CUETools.Codecs
Process _encoderProcess;
WAVWriter wrt;
CyclicBuffer outputBuffer = null;
+ bool useTempFile = false;
+ string tempFile = null;
+ long _finalSampleCount = -1;
+ bool closed = false;
public UserDefinedWriter(string path, Stream IO, AudioPCMConfig pcm, string encoder, string encoderParams, string encoderMode, int padding)
{
@@ -1738,15 +1747,23 @@ namespace CUETools.Codecs
_encoder = encoder;
_encoderParams = encoderParams;
_encoderMode = encoderMode;
+ useTempFile = _encoderParams.Contains("%I");
+ tempFile = path + ".tmp.wav";
_encoderProcess = new Process();
_encoderProcess.StartInfo.FileName = _encoder;
- _encoderProcess.StartInfo.Arguments = _encoderParams.Replace("%O", "\"" + path + "\"").Replace("%M", encoderMode).Replace("%P", padding.ToString());
+ _encoderProcess.StartInfo.Arguments = _encoderParams.Replace("%O", "\"" + path + "\"").Replace("%M", encoderMode).Replace("%P", padding.ToString()).Replace("%I", "\"" + tempFile + "\"");
_encoderProcess.StartInfo.CreateNoWindow = true;
- _encoderProcess.StartInfo.RedirectStandardInput = true;
+ if (!useTempFile)
+ _encoderProcess.StartInfo.RedirectStandardInput = true;
_encoderProcess.StartInfo.UseShellExecute = false;
if (!_encoderParams.Contains("%O"))
_encoderProcess.StartInfo.RedirectStandardOutput = true;
+ if (useTempFile)
+ {
+ wrt = new WAVWriter(tempFile, null, pcm);
+ return;
+ }
bool started = false;
Exception ex = null;
try
@@ -1772,9 +1789,32 @@ namespace CUETools.Codecs
public void Close()
{
+ if (closed)
+ return;
+ closed = true;
wrt.Close();
+ if (useTempFile && (_finalSampleCount < 0 || wrt.Position == _finalSampleCount))
+ {
+ bool started = false;
+ Exception ex = null;
+ try
+ {
+ started = _encoderProcess.Start();
+ if (started)
+ _encoderProcess.PriorityClass = Process.GetCurrentProcess().PriorityClass;
+ }
+ catch (Exception _ex)
+ {
+ ex = _ex;
+ }
+ if (!started)
+ throw new Exception(_encoder + ": " + (ex == null ? "please check the path" : ex.Message));
+ }
+ wrt = null;
if (!_encoderProcess.HasExited)
_encoderProcess.WaitForExit();
+ if (useTempFile)
+ File.Delete(tempFile);
if (outputBuffer != null)
outputBuffer.Close();
if (_encoderProcess.ExitCode != 0)
@@ -1797,7 +1837,7 @@ namespace CUETools.Codecs
public long FinalSampleCount
{
- set { wrt.FinalSampleCount = value; }
+ set { _finalSampleCount = wrt.FinalSampleCount = value; }
}
public long BlockSize
@@ -1948,6 +1988,7 @@ namespace CUETools.Codecs
public class AudioPipe : IAudioSource//, IDisposable
{
private AudioBuffer _readBuffer, _writeBuffer;
+ private AudioPCMConfig pcm;
long _sampleLen, _samplePos;
private int _maxLength;
private Thread _workThread;
@@ -1959,14 +2000,22 @@ namespace CUETools.Codecs
bool own;
ThreadPriority priority;
+ public AudioPipe(AudioPCMConfig pcm, int size)
+ {
+ this.pcm = pcm;
+ _readBuffer = new AudioBuffer(pcm, size);
+ _writeBuffer = new AudioBuffer(pcm, size);
+ _maxLength = size;
+ _sampleLen = -1;
+ _samplePos = 0;
+ }
+
public AudioPipe(IAudioSource source, int size, bool own, ThreadPriority priority)
+ : this(source.PCM, size)
{
this.own = own;
this.priority = priority;
_source = source;
- _readBuffer = new AudioBuffer(source, size);
- _writeBuffer = new AudioBuffer(source, size);
- _maxLength = size;
_sampleLen = _source.Length;
_samplePos = _source.Position;
}
@@ -2014,7 +2063,7 @@ namespace CUETools.Codecs
private void Go()
{
- if (_workThread != null || _ex != null) return;
+ if (_workThread != null || _ex != null || _source == null) return;
_workThread = new Thread(Decompress);
_workThread.Priority = priority;
_workThread.IsBackground = true;
@@ -2067,6 +2116,9 @@ namespace CUETools.Codecs
if (value == _samplePos)
return;
+ if (_source == null)
+ throw new NotSupportedException();
+
lock (this)
{
_close = true;
@@ -2107,10 +2159,40 @@ namespace CUETools.Codecs
{
get
{
- return _source.PCM;
+ return pcm;
}
}
+ public int Write(AudioBuffer buff)
+ {
+ if (_writeBuffer.Size < _writeBuffer.Length + buff.Length)
+ {
+ AudioBuffer realloced = new AudioBuffer(pcm, _writeBuffer.Size + buff.Size);
+ realloced.Prepare(_writeBuffer, 0, _writeBuffer.Length);
+ _writeBuffer = realloced;
+ }
+ if (_writeBuffer.Length == 0)
+ _writeBuffer.Prepare(buff, 0, buff.Length);
+ else
+ {
+ _writeBuffer.Load(_writeBuffer.Length, buff, 0, buff.Length);
+ _writeBuffer.Length += buff.Length;
+ }
+ lock (this)
+ {
+ if (!_haveData)
+ {
+ AudioBuffer temp = _writeBuffer;
+ _writeBuffer = _readBuffer;
+ _writeBuffer.Length = 0;
+ _readBuffer = temp;
+ _haveData = true;
+ Monitor.Pulse(this);
+ }
+ }
+ return _writeBuffer.Length;
+ }
+
public int Read(AudioBuffer buff, int maxLength)
{
Go();
@@ -2152,7 +2234,15 @@ namespace CUETools.Codecs
return buff.Length;
}
- public string Path { get { return _source.Path; } }
+ public string Path
+ {
+ get
+ {
+ if (_source == null)
+ return "";
+ return _source.Path;
+ }
+ }
}
public class NullStream : Stream
diff --git a/CUETools.DSP.Mixer/Mixer.cs b/CUETools.DSP.Mixer/Mixer.cs
index 77acce1..02d5cf4 100644
--- a/CUETools.DSP.Mixer/Mixer.cs
+++ b/CUETools.DSP.Mixer/Mixer.cs
@@ -15,9 +15,14 @@ namespace CUETools.DSP.Mixer
float[] volume;
long samplePos;
int size;
+ AudioReadEventArgs audioReadArgs = new AudioReadEventArgs();
+
+ public event EventHandler AudioRead;
public MixingSource(AudioPCMConfig pcm, int delay, int sources)
{
+ if (pcm.BitsPerSample != 32)
+ throw new NotSupportedException("please use 32 bits per sample (float)");
this.pcm = pcm;
this.size = delay * pcm.SampleRate / 1000;
this.buf = new MixingBuffer[2];
@@ -105,6 +110,14 @@ namespace CUETools.DSP.Mixer
mixoffs = 0;
}
samplePos += result.Length;
+
+ if (AudioRead != null)
+ {
+ audioReadArgs.source = this;
+ audioReadArgs.buffer = result;
+ AudioRead(this, audioReadArgs);
+ }
+
return result.Length;
}
@@ -331,7 +344,7 @@ namespace CUETools.DSP.Mixer
}
int chunk = Math.Min(buff.Length - buff_offs, mixbuff.source[iSource].Size - mixbuff.source[iSource].Length);
- Buffer.BlockCopy(buff.Bytes, buff_offs * bs, mixbuff.source[iSource].Bytes, mixbuff.source[iSource].Length * bs, chunk * bs);
+ Buffer.BlockCopy(buff.Float, buff_offs * bs, mixbuff.source[iSource].Float, mixbuff.source[iSource].Length * bs, chunk * bs);
mixbuff.source[iSource].Length += chunk;
buff_offs += chunk;
@@ -347,4 +360,10 @@ namespace CUETools.DSP.Mixer
public string Path { get { return ""; } }
}
+
+ public class AudioReadEventArgs: EventArgs
+ {
+ public IAudioSource source;
+ public AudioBuffer buffer;
+ }
}
diff --git a/CUETools.Flake/Program.cs b/CUETools.Flake/Program.cs
index fba04f2..3614543 100644
--- a/CUETools.Flake/Program.cs
+++ b/CUETools.Flake/Program.cs
@@ -45,7 +45,7 @@ namespace CUETools.FlakeExe
Console.WriteLine(" -f #[,#] Prediction order {max} or {min},{max} (0..4).");
}
- static void Main(string[] args)
+ static int Main(string[] args)
{
TextWriter stdout = Console.Out;
Console.SetOut(Console.Error);
@@ -143,13 +143,13 @@ namespace CUETools.FlakeExe
if (!ok)
{
Usage();
- return;
+ return 1;
}
}
if (input_file == null || ((input_file == "-" || Path.GetExtension(input_file) == ".flac") && output_file == null))
{
Usage();
- return;
+ return 2;
}
if (!quiet)
@@ -170,7 +170,7 @@ namespace CUETools.FlakeExe
else
{
Usage();
- return;
+ return 3;
}
if (buffered)
audioSource = new AudioPipe(audioSource, 0x10000);
@@ -231,7 +231,7 @@ namespace CUETools.FlakeExe
Usage();
Console.WriteLine("");
Console.WriteLine("Error: {0}.", ex.Message);
- return;
+ return 4;
}
if (!quiet)
@@ -240,25 +240,40 @@ namespace CUETools.FlakeExe
Console.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, TimeSpan.FromSeconds(audioSource.Length * 1.0 / audioSource.PCM.SampleRate));
}
- while (audioSource.Read(buff, -1) != 0)
+#if !DEBUG
+ try
+#endif
{
- audioDest.Write(buff);
- TimeSpan elapsed = DateTime.Now - start;
- if (!quiet)
+ while (audioSource.Read(buff, -1) != 0)
{
- if ((elapsed - lastPrint).TotalMilliseconds > 60)
+ audioDest.Write(buff);
+ TimeSpan elapsed = DateTime.Now - start;
+ if (!quiet)
{
- Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
- 100.0 * audioSource.Position / audioSource.Length,
- audioSource.Position / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
- elapsed,
- TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * audioSource.Length)
- );
- lastPrint = elapsed;
+ if ((elapsed - lastPrint).TotalMilliseconds > 60)
+ {
+ Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
+ 100.0 * audioSource.Position / audioSource.Length,
+ audioSource.Position / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
+ elapsed,
+ TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * audioSource.Length)
+ );
+ lastPrint = elapsed;
+ }
}
}
+ audioDest.Close();
}
- audioDest.Close();
+#if !DEBUG
+ catch (Exception ex)
+ {
+ Console.Error.Write("\r \r");
+ Console.WriteLine("Error : {0}", ex.Message);
+ audioDest.Delete();
+ audioSource.Close();
+ return 5;
+ }
+#endif
TimeSpan totalElapsed = DateTime.Now - start;
if (!quiet)
@@ -293,6 +308,7 @@ namespace CUETools.FlakeExe
flake.VBRMode
);
}
+ return 0;
}
}
}
diff --git a/CUETools/CUETools.sln b/CUETools/CUETools.sln
index 5b2e288..d594e28 100644
--- a/CUETools/CUETools.sln
+++ b/CUETools/CUETools.sln
@@ -167,6 +167,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.DSP.Mixer", "..\CU
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.DSP.Resampler", "..\CUETools.DSP.Resampler\CUETools.DSP.Resampler.csproj", "{A6303861-CA06-4C2C-A104-BA9291538F6F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.Icecast", "..\CUETools.Codecs.Icecast\CUETools.Codecs.Icecast.csproj", "{8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}"
+EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = CUETools1.vsmdi
@@ -630,6 +632,14 @@ Global
{A6303861-CA06-4C2C-A104-BA9291538F6F}.Release|Any CPU.Build.0 = Release|Any CPU
{A6303861-CA06-4C2C-A104-BA9291538F6F}.Release|Win32.ActiveCfg = Release|Any CPU
{A6303861-CA06-4C2C-A104-BA9291538F6F}.Release|x64.ActiveCfg = Release|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Release|Win32.ActiveCfg = Release|Any CPU
+ {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}.Release|x64.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE