mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
2.0.7
This commit is contained in:
@@ -2245,7 +2245,7 @@ namespace Bwg.Scsi
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public CommandStatus ReadCDText(out byte [] data)
|
||||
public CommandStatus ReadCDText(out byte [] data, int _timeout)
|
||||
{
|
||||
ushort len;
|
||||
|
||||
@@ -2256,7 +2256,7 @@ namespace Bwg.Scsi
|
||||
}
|
||||
|
||||
data = null;
|
||||
using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 4, Command.CmdDirection.In, 5 * 60))
|
||||
using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 4, Command.CmdDirection.In, _timeout))
|
||||
{
|
||||
cmd.SetCDB8(2, 5); // CDText info in leadin
|
||||
cmd.SetCDB16(7, 4);
|
||||
@@ -2276,7 +2276,7 @@ namespace Bwg.Scsi
|
||||
}
|
||||
}
|
||||
|
||||
using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60))
|
||||
using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, _timeout))
|
||||
{
|
||||
cmd.SetCDB8(2, 5); // CDText info in leadin
|
||||
cmd.SetCDB16(7, len);
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Windows.Forms.Design;
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
|
||||
namespace BBBNOVA
|
||||
namespace CUEControls
|
||||
{
|
||||
public class BNComboBox : ListControl
|
||||
{
|
||||
@@ -178,7 +178,7 @@ namespace BBBNOVA
|
||||
public BNRadius Radius
|
||||
{
|
||||
get { return _radius; }
|
||||
set { _radius = value; }
|
||||
set { if (value != null) _radius = value; }
|
||||
}
|
||||
|
||||
[Category("Appearance"), Description("Selects the type of border around drop down list."), DefaultValue(BorderStyle.None)]
|
||||
@@ -556,6 +556,16 @@ namespace BBBNOVA
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Color GetOuterBorderColor()
|
||||
{
|
||||
return (Enabled) ? BackColor : BackColor;
|
||||
}
|
||||
|
||||
protected virtual Color GetInnerBorderColor()
|
||||
{
|
||||
return (Enabled) ? BackColor : SystemColors.Control;
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
@@ -597,19 +607,19 @@ namespace BBBNOVA
|
||||
Color foreColor = Color.FromArgb(IsDroppedDown ? 100 : 50, ForeColor);
|
||||
Brush brInnerBrush = new LinearGradientBrush(
|
||||
new Rectangle(rectInner.X, rectInner.Y, rectInner.Width, rectInner.Height + 1),
|
||||
Color.FromArgb((hovered || IsDroppedDown || Focused) ? 200 : 100, ForeColor), Color.Transparent,
|
||||
Color.FromArgb((hovered || IsDroppedDown || Focused) ? 200 : 100, ForeColor),
|
||||
Color.Transparent,
|
||||
LinearGradientMode.Vertical);
|
||||
Brush brBackground;
|
||||
if (this.DropDownStyle == ComboBoxStyle.DropDownList)
|
||||
brBackground = new LinearGradientBrush(pathInnerBorder.GetBounds(), BackColor, foreColor, LinearGradientMode.Vertical);
|
||||
brBackground = new LinearGradientBrush(pathInnerBorder.GetBounds(), BackColor, hovered ? Color.FromArgb(100, SystemColors.HotTrack) : foreColor, LinearGradientMode.Vertical);
|
||||
else
|
||||
brBackground = new SolidBrush(BackColor);
|
||||
Pen penOuterBorder = new Pen(BackColor, 0);
|
||||
Pen penInnerBorder = new Pen(brInnerBrush, 0);
|
||||
LinearGradientBrush brButtonLeft = new LinearGradientBrush(rectBtn, BackColor, ForeColor, LinearGradientMode.Vertical);
|
||||
ColorBlend blend = new ColorBlend();
|
||||
blend.Colors = new Color[] { Color.Transparent, foreColor, Color.Transparent };
|
||||
blend.Positions = new float[] { 0.0f, 0.5f, 1.0f};
|
||||
blend.Positions = new float[] { 0.0f, 0.5f, 1.0f };
|
||||
brButtonLeft.InterpolationColors = blend;
|
||||
Pen penLeftButton = new Pen(brButtonLeft, 0);
|
||||
Brush brButton = new LinearGradientBrush(pathBtnBorder.GetBounds(), BackColor, foreColor, LinearGradientMode.Vertical);
|
||||
@@ -620,10 +630,17 @@ namespace BBBNOVA
|
||||
{
|
||||
e.Graphics.FillPath(brButton, pathBtnBorder);
|
||||
}
|
||||
Color outerBorderColor = GetOuterBorderColor();
|
||||
if (outerBorderColor.IsSystemColor)
|
||||
{
|
||||
Pen penOuterBorder = SystemPens.FromSystemColor(outerBorderColor);
|
||||
e.Graphics.DrawPath(penOuterBorder, pathOuterBorder);
|
||||
}
|
||||
else using (Pen penOuterBorder = new Pen(outerBorderColor))
|
||||
e.Graphics.DrawPath(penOuterBorder, pathOuterBorder);
|
||||
e.Graphics.DrawPath(penInnerBorder, pathInnerBorder);
|
||||
|
||||
e.Graphics.DrawLine(penLeftButton, rectBtn.Left + 1, rectInner.Top+1, rectBtn.Left + 1, rectInner.Bottom-1);
|
||||
e.Graphics.DrawLine(penLeftButton, rectBtn.Left + 1, rectInner.Top + 1, rectBtn.Left + 1, rectInner.Bottom - 1);
|
||||
|
||||
|
||||
//Glimph
|
||||
@@ -640,7 +657,7 @@ namespace BBBNOVA
|
||||
path.CloseFigure();
|
||||
e.Graphics.RotateTransform(0);
|
||||
|
||||
SolidBrush br = new SolidBrush(Enabled?Color.Gray:Color.Gainsboro);
|
||||
SolidBrush br = new SolidBrush(Enabled ? Color.Gray : Color.Gainsboro);
|
||||
e.Graphics.FillPath(br, path);
|
||||
e.Graphics.ResetTransform();
|
||||
br.Dispose();
|
||||
@@ -689,7 +706,6 @@ namespace BBBNOVA
|
||||
pathInnerBorder.Dispose();
|
||||
pathBtnBorder.Dispose();
|
||||
|
||||
penOuterBorder.Dispose();
|
||||
penInnerBorder.Dispose();
|
||||
penLeftButton.Dispose();
|
||||
|
||||
@@ -857,8 +873,8 @@ namespace BBBNOVA
|
||||
{
|
||||
if (DrawMode == DrawMode.Normal)
|
||||
{
|
||||
Color fg = _hoverItem != -1 && _hoverItem == e.Index ? BackColor : ForeColor;
|
||||
Color bg = _hoverItem != -1 && _hoverItem == e.Index ? ForeColor : BackColor;
|
||||
Color fg = _hoverItem != -1 && _hoverItem == e.Index ? SystemColors.HighlightText : ForeColor;
|
||||
Color bg = _hoverItem != -1 && _hoverItem == e.Index ? SystemColors.Highlight : BackColor;
|
||||
e.Graphics.FillRectangle(new SolidBrush(bg), e.Bounds);
|
||||
|
||||
if (e.Index >= 0)
|
||||
@@ -1132,4 +1148,38 @@ namespace BBBNOVA
|
||||
}
|
||||
}
|
||||
|
||||
public class BNComboBoxItem<T>
|
||||
{
|
||||
string text;
|
||||
string imageKey;
|
||||
T value;
|
||||
|
||||
public string ImageKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return imageKey;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return text ?? value.ToString();
|
||||
}
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public BNComboBoxItem(string text, string imageKey, T value)
|
||||
{
|
||||
this.text = text;
|
||||
this.imageKey = imageKey;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmCUERipper.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="frmCUERipper.ru-RU.resx">
|
||||
<DependentUpon>frmCUERipper.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="frmProperties.resx">
|
||||
<DependentUpon>frmProperties.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -100,6 +103,7 @@
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.ru-RU.resx" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
|
||||
90
CUERipper/Properties/Resources.Designer.cs
generated
90
CUERipper/Properties/Resources.Designer.cs
generated
@@ -95,6 +95,60 @@ namespace CUERipper.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detecting drives.
|
||||
/// </summary>
|
||||
internal static string DetectingDrives {
|
||||
get {
|
||||
return ResourceManager.GetString("DetectingDrives", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Done ripping.
|
||||
/// </summary>
|
||||
internal static string DoneRipping {
|
||||
get {
|
||||
return ResourceManager.GetString("DoneRipping", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Rip probably contains errors.
|
||||
/// </summary>
|
||||
internal static string DoneRippingErrors {
|
||||
get {
|
||||
return ResourceManager.GetString("DoneRippingErrors", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You can try to repair it using CUETools.
|
||||
/// </summary>
|
||||
internal static string DoneRippingRepair {
|
||||
get {
|
||||
return ResourceManager.GetString("DoneRippingRepair", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exception.
|
||||
/// </summary>
|
||||
internal static string ExceptionMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("ExceptionMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to load ripper module.
|
||||
/// </summary>
|
||||
internal static string FailedToLoadRipperModule {
|
||||
get {
|
||||
return ResourceManager.GetString("FailedToLoadRipperModule", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon flac {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("flac", resourceCulture);
|
||||
@@ -116,6 +170,15 @@ namespace CUERipper.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Looking up album via.
|
||||
/// </summary>
|
||||
internal static string LookingUpVia {
|
||||
get {
|
||||
return ResourceManager.GetString("LookingUpVia", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon mp3 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("mp3", resourceCulture);
|
||||
@@ -130,6 +193,15 @@ namespace CUERipper.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No CD drives found.
|
||||
/// </summary>
|
||||
internal static string NoDrives {
|
||||
get {
|
||||
return ResourceManager.GetString("NoDrives", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon ogg {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("ogg", resourceCulture);
|
||||
@@ -137,6 +209,24 @@ namespace CUERipper.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Paused.
|
||||
/// </summary>
|
||||
internal static string PausedMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("PausedMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to retry.
|
||||
/// </summary>
|
||||
internal static string Retry {
|
||||
get {
|
||||
return ResourceManager.GetString("Retry", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon tta {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("tta", resourceCulture);
|
||||
|
||||
@@ -160,4 +160,34 @@
|
||||
<data name="wv" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\wv.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="DoneRipping" xml:space="preserve">
|
||||
<value>Done ripping</value>
|
||||
</data>
|
||||
<data name="DoneRippingErrors" xml:space="preserve">
|
||||
<value>Rip probably contains errors</value>
|
||||
</data>
|
||||
<data name="DoneRippingRepair" xml:space="preserve">
|
||||
<value>You can try to repair it using CUETools</value>
|
||||
</data>
|
||||
<data name="ExceptionMessage" xml:space="preserve">
|
||||
<value>Exception</value>
|
||||
</data>
|
||||
<data name="FailedToLoadRipperModule" xml:space="preserve">
|
||||
<value>Failed to load ripper module</value>
|
||||
</data>
|
||||
<data name="LookingUpVia" xml:space="preserve">
|
||||
<value>Looking up album via</value>
|
||||
</data>
|
||||
<data name="NoDrives" xml:space="preserve">
|
||||
<value>No CD drives found</value>
|
||||
</data>
|
||||
<data name="PausedMessage" xml:space="preserve">
|
||||
<value>Paused</value>
|
||||
</data>
|
||||
<data name="Retry" xml:space="preserve">
|
||||
<value>retry</value>
|
||||
</data>
|
||||
<data name="DetectingDrives" xml:space="preserve">
|
||||
<value>Detecting drives</value>
|
||||
</data>
|
||||
</root>
|
||||
79
CUERipper/frmCUERipper.Designer.cs
generated
79
CUERipper/frmCUERipper.Designer.cs
generated
@@ -51,21 +51,22 @@ namespace CUERipper
|
||||
this.lblWriteOffset = new System.Windows.Forms.Label();
|
||||
this.checkBoxEACMode = new System.Windows.Forms.CheckBox();
|
||||
this.groupBoxSettings = new System.Windows.Forms.GroupBox();
|
||||
this.bnComboBoxLosslessOrNot = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxLosslessOrNot = new CUEControls.BNComboBox();
|
||||
this.losslessOrNotBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.bindingSourceCR = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.bnComboBoxEncoder = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxEncoder = new CUEControls.BNComboBox();
|
||||
this.encodersBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.labelSecureMode = new System.Windows.Forms.Label();
|
||||
this.bnComboBoxFormat = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxFormat = new CUEControls.BNComboBox();
|
||||
this.formatsBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.labelEncoderMinMode = new System.Windows.Forms.Label();
|
||||
this.bnComboBoxImage = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxImage = new CUEControls.BNComboBox();
|
||||
this.cUEStylesBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.labelEncoderMaxMode = new System.Windows.Forms.Label();
|
||||
this.labelEncoderMode = new System.Windows.Forms.Label();
|
||||
this.trackBarEncoderMode = new System.Windows.Forms.TrackBar();
|
||||
this.trackBarSecureMode = new System.Windows.Forms.TrackBar();
|
||||
this.imageListChecked = new System.Windows.Forms.ImageList(this.components);
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.progressBarErrors = new ProgressODoom.ProgressBarEx();
|
||||
this.plainBackgroundPainter1 = new ProgressODoom.PlainBackgroundPainter();
|
||||
@@ -74,15 +75,14 @@ namespace CUERipper
|
||||
this.gradientGlossPainter1 = new ProgressODoom.GradientGlossPainter();
|
||||
this.progressBarCD = new ProgressODoom.ProgressBarEx();
|
||||
this.plainProgressPainter2 = new ProgressODoom.PlainProgressPainter();
|
||||
this.comboBoxOutputFormat = new System.Windows.Forms.ComboBox();
|
||||
this.txtOutputPath = new System.Windows.Forms.TextBox();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.bnComboBoxRelease = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxRelease = new CUEControls.BNComboBox();
|
||||
this.releasesBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.imageListMetadataSource = new System.Windows.Forms.ImageList(this.components);
|
||||
this.bnComboBoxDrives = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxDrives = new CUEControls.BNComboBox();
|
||||
this.drivesBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.bnComboBoxOutputFormat = new BBBNOVA.BNComboBox();
|
||||
this.bnComboBoxOutputFormat = new CUEControls.BNComboBox();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.contextMenuStripRelease.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericWriteOffset)).BeginInit();
|
||||
@@ -202,8 +202,9 @@ namespace CUERipper
|
||||
// buttonGo
|
||||
//
|
||||
resources.ApplyResources(this.buttonGo, "buttonGo");
|
||||
this.buttonGo.BackColor = System.Drawing.Color.Transparent;
|
||||
this.buttonGo.Name = "buttonGo";
|
||||
this.buttonGo.UseVisualStyleBackColor = true;
|
||||
this.buttonGo.UseVisualStyleBackColor = false;
|
||||
this.buttonGo.Click += new System.EventHandler(this.buttonGo_Click);
|
||||
//
|
||||
// buttonAbort
|
||||
@@ -287,13 +288,14 @@ namespace CUERipper
|
||||
this.bnComboBoxLosslessOrNot.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.bnComboBoxLosslessOrNot.DropDownWidth = 80;
|
||||
this.bnComboBoxLosslessOrNot.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
this.bnComboBoxLosslessOrNot.ImageKeyMember = "ImageKey";
|
||||
this.bnComboBoxLosslessOrNot.ImageList = null;
|
||||
this.bnComboBoxLosslessOrNot.IsDroppedDown = false;
|
||||
resources.ApplyResources(this.bnComboBoxLosslessOrNot, "bnComboBoxLosslessOrNot");
|
||||
this.bnComboBoxLosslessOrNot.MaxDropDownItems = 8;
|
||||
this.bnComboBoxLosslessOrNot.MinimumSize = new System.Drawing.Size(40, 21);
|
||||
this.bnComboBoxLosslessOrNot.Name = "bnComboBoxLosslessOrNot";
|
||||
this.bnComboBoxLosslessOrNot.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxLosslessOrNot.Radius")));
|
||||
this.bnComboBoxLosslessOrNot.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxLosslessOrNot.Radius")));
|
||||
this.bnComboBoxLosslessOrNot.SelectedIndex = -1;
|
||||
this.bnComboBoxLosslessOrNot.SelectedItem = null;
|
||||
this.bnComboBoxLosslessOrNot.Sorted = false;
|
||||
@@ -322,7 +324,7 @@ namespace CUERipper
|
||||
this.bnComboBoxEncoder.MaxDropDownItems = 8;
|
||||
this.bnComboBoxEncoder.MinimumSize = new System.Drawing.Size(40, 21);
|
||||
this.bnComboBoxEncoder.Name = "bnComboBoxEncoder";
|
||||
this.bnComboBoxEncoder.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxEncoder.Radius")));
|
||||
this.bnComboBoxEncoder.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxEncoder.Radius")));
|
||||
this.bnComboBoxEncoder.SelectedIndex = -1;
|
||||
this.bnComboBoxEncoder.SelectedItem = null;
|
||||
this.bnComboBoxEncoder.Sorted = false;
|
||||
@@ -353,7 +355,7 @@ namespace CUERipper
|
||||
this.bnComboBoxFormat.MaxDropDownItems = 8;
|
||||
this.bnComboBoxFormat.MinimumSize = new System.Drawing.Size(40, 21);
|
||||
this.bnComboBoxFormat.Name = "bnComboBoxFormat";
|
||||
this.bnComboBoxFormat.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxFormat.Radius")));
|
||||
this.bnComboBoxFormat.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxFormat.Radius")));
|
||||
this.bnComboBoxFormat.SelectedIndex = -1;
|
||||
this.bnComboBoxFormat.SelectedItem = null;
|
||||
this.bnComboBoxFormat.Sorted = false;
|
||||
@@ -383,7 +385,7 @@ namespace CUERipper
|
||||
this.bnComboBoxImage.MaxDropDownItems = 8;
|
||||
this.bnComboBoxImage.MinimumSize = new System.Drawing.Size(40, 21);
|
||||
this.bnComboBoxImage.Name = "bnComboBoxImage";
|
||||
this.bnComboBoxImage.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxImage.Radius")));
|
||||
this.bnComboBoxImage.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxImage.Radius")));
|
||||
this.bnComboBoxImage.SelectedIndex = -1;
|
||||
this.bnComboBoxImage.SelectedItem = null;
|
||||
this.bnComboBoxImage.Sorted = false;
|
||||
@@ -418,6 +420,15 @@ namespace CUERipper
|
||||
this.trackBarSecureMode.Name = "trackBarSecureMode";
|
||||
this.trackBarSecureMode.Scroll += new System.EventHandler(this.trackBarSecureMode_Scroll);
|
||||
//
|
||||
// imageListChecked
|
||||
//
|
||||
this.imageListChecked.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListChecked.ImageStream")));
|
||||
this.imageListChecked.TransparentColor = System.Drawing.Color.Transparent;
|
||||
this.imageListChecked.Images.SetKeyName(0, "checked");
|
||||
this.imageListChecked.Images.SetKeyName(1, "unchecked");
|
||||
this.imageListChecked.Images.SetKeyName(2, "disabled");
|
||||
this.imageListChecked.Images.SetKeyName(3, "mix");
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Image = global::CUERipper.Properties.Resources.cddb;
|
||||
@@ -491,22 +502,8 @@ namespace CUERipper
|
||||
this.plainProgressPainter2.LeadingEdge = System.Drawing.Color.Transparent;
|
||||
this.plainProgressPainter2.ProgressBorderPainter = null;
|
||||
//
|
||||
// comboBoxOutputFormat
|
||||
//
|
||||
this.comboBoxOutputFormat.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
|
||||
this.comboBoxOutputFormat.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
|
||||
this.comboBoxOutputFormat.FormattingEnabled = true;
|
||||
resources.ApplyResources(this.comboBoxOutputFormat, "comboBoxOutputFormat");
|
||||
this.comboBoxOutputFormat.Name = "comboBoxOutputFormat";
|
||||
this.toolTip1.SetToolTip(this.comboBoxOutputFormat, resources.GetString("comboBoxOutputFormat.ToolTip"));
|
||||
this.comboBoxOutputFormat.SelectedIndexChanged += new System.EventHandler(this.comboBoxOutputFormat_SelectedIndexChanged);
|
||||
this.comboBoxOutputFormat.MouseLeave += new System.EventHandler(this.comboBoxOutputFormat_MouseLeave);
|
||||
this.comboBoxOutputFormat.TextUpdate += new System.EventHandler(this.comboBoxOutputFormat_TextUpdate);
|
||||
//
|
||||
// txtOutputPath
|
||||
//
|
||||
this.txtOutputPath.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
|
||||
this.txtOutputPath.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.FileSystem;
|
||||
resources.ApplyResources(this.txtOutputPath, "txtOutputPath");
|
||||
this.txtOutputPath.Name = "txtOutputPath";
|
||||
this.txtOutputPath.ReadOnly = true;
|
||||
@@ -529,7 +526,7 @@ namespace CUERipper
|
||||
this.bnComboBoxRelease.MaxDropDownItems = 8;
|
||||
this.bnComboBoxRelease.MinimumSize = new System.Drawing.Size(61, 21);
|
||||
this.bnComboBoxRelease.Name = "bnComboBoxRelease";
|
||||
this.bnComboBoxRelease.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxRelease.Radius")));
|
||||
this.bnComboBoxRelease.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxRelease.Radius")));
|
||||
this.bnComboBoxRelease.SelectedIndex = -1;
|
||||
this.bnComboBoxRelease.SelectedItem = null;
|
||||
this.bnComboBoxRelease.Sorted = false;
|
||||
@@ -545,8 +542,8 @@ namespace CUERipper
|
||||
//
|
||||
this.imageListMetadataSource.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListMetadataSource.ImageStream")));
|
||||
this.imageListMetadataSource.TransparentColor = System.Drawing.Color.Transparent;
|
||||
this.imageListMetadataSource.Images.SetKeyName(0, "musicbrainz.ico");
|
||||
this.imageListMetadataSource.Images.SetKeyName(1, "freedb16.png");
|
||||
this.imageListMetadataSource.Images.SetKeyName(0, "musicbrainz");
|
||||
this.imageListMetadataSource.Images.SetKeyName(1, "freedb");
|
||||
//
|
||||
// bnComboBoxDrives
|
||||
//
|
||||
@@ -563,7 +560,7 @@ namespace CUERipper
|
||||
this.bnComboBoxDrives.MaxDropDownItems = 8;
|
||||
this.bnComboBoxDrives.MinimumSize = new System.Drawing.Size(61, 21);
|
||||
this.bnComboBoxDrives.Name = "bnComboBoxDrives";
|
||||
this.bnComboBoxDrives.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxDrives.Radius")));
|
||||
this.bnComboBoxDrives.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxDrives.Radius")));
|
||||
this.bnComboBoxDrives.SelectedIndex = -1;
|
||||
this.bnComboBoxDrives.SelectedItem = null;
|
||||
this.bnComboBoxDrives.Sorted = false;
|
||||
@@ -587,11 +584,12 @@ namespace CUERipper
|
||||
this.bnComboBoxOutputFormat.MaxDropDownItems = 8;
|
||||
this.bnComboBoxOutputFormat.MinimumSize = new System.Drawing.Size(40, 21);
|
||||
this.bnComboBoxOutputFormat.Name = "bnComboBoxOutputFormat";
|
||||
this.bnComboBoxOutputFormat.Radius = ((BBBNOVA.BNRadius)(resources.GetObject("bnComboBoxOutputFormat.Radius")));
|
||||
this.bnComboBoxOutputFormat.Radius = ((CUEControls.BNRadius)(resources.GetObject("bnComboBoxOutputFormat.Radius")));
|
||||
this.bnComboBoxOutputFormat.SelectedIndex = -1;
|
||||
this.bnComboBoxOutputFormat.SelectedItem = null;
|
||||
this.bnComboBoxOutputFormat.Sorted = false;
|
||||
this.bnComboBoxOutputFormat.DroppedDown += new System.EventHandler(this.bnComboBoxOutputFormat_DroppedDown);
|
||||
this.bnComboBoxOutputFormat.Leave += new System.EventHandler(this.bnComboBoxOutputFormat_Leave);
|
||||
this.bnComboBoxOutputFormat.MouseLeave += new System.EventHandler(this.bnComboBoxOutputFormat_MouseLeave);
|
||||
this.bnComboBoxOutputFormat.TextChanged += new System.EventHandler(this.bnComboBoxOutputFormat_TextChanged);
|
||||
//
|
||||
@@ -603,7 +601,6 @@ namespace CUERipper
|
||||
this.Controls.Add(this.bnComboBoxRelease);
|
||||
this.Controls.Add(this.bnComboBoxDrives);
|
||||
this.Controls.Add(this.bnComboBoxOutputFormat);
|
||||
this.Controls.Add(this.comboBoxOutputFormat);
|
||||
this.Controls.Add(this.progressBarErrors);
|
||||
this.Controls.Add(this.progressBarCD);
|
||||
this.Controls.Add(this.groupBoxSettings);
|
||||
@@ -677,24 +674,24 @@ namespace CUERipper
|
||||
private ProgressODoom.ProgressBarEx progressBarCD;
|
||||
private ProgressODoom.PlainProgressPainter plainProgressPainter2;
|
||||
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelMusicBrainz;
|
||||
private System.Windows.Forms.ComboBox comboBoxOutputFormat;
|
||||
private System.Windows.Forms.TextBox txtOutputPath;
|
||||
private System.Windows.Forms.ToolTip toolTip1;
|
||||
private BBBNOVA.BNComboBox bnComboBoxImage;
|
||||
private CUEControls.BNComboBox bnComboBoxImage;
|
||||
private System.Windows.Forms.BindingSource bindingSourceCR;
|
||||
private System.Windows.Forms.ImageList imageListMetadataSource;
|
||||
private System.Windows.Forms.BindingSource cUEStylesBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxRelease;
|
||||
private CUEControls.BNComboBox bnComboBoxRelease;
|
||||
private System.Windows.Forms.BindingSource releasesBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxDrives;
|
||||
private CUEControls.BNComboBox bnComboBoxDrives;
|
||||
private System.Windows.Forms.BindingSource drivesBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxFormat;
|
||||
private CUEControls.BNComboBox bnComboBoxFormat;
|
||||
private System.Windows.Forms.BindingSource formatsBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxEncoder;
|
||||
private CUEControls.BNComboBox bnComboBoxEncoder;
|
||||
private System.Windows.Forms.BindingSource encodersBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxLosslessOrNot;
|
||||
private CUEControls.BNComboBox bnComboBoxLosslessOrNot;
|
||||
private System.Windows.Forms.BindingSource losslessOrNotBindingSource;
|
||||
private BBBNOVA.BNComboBox bnComboBoxOutputFormat;
|
||||
private CUEControls.BNComboBox bnComboBoxOutputFormat;
|
||||
private System.Windows.Forms.ImageList imageListChecked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ using CUETools.CDImage;
|
||||
using CUETools.Codecs;
|
||||
using CUETools.Processor;
|
||||
using CUETools.Ripper;
|
||||
using CUEControls;
|
||||
using MusicBrainz;
|
||||
using Freedb;
|
||||
|
||||
@@ -55,7 +56,11 @@ namespace CUERipper
|
||||
};
|
||||
|
||||
private BindingList<string> cueStyles = new BindingList<string> { "image", "tracks" };
|
||||
private BindingList<string> losslessOrNot = new BindingList<string> { "lossless", "lossy" };
|
||||
//private BindingList<string> losslessOrNot = new BindingList<string> { "lossless", "lossy" };
|
||||
private BindingList<BNComboBoxItem<AudioEncoderType>> losslessOrNot = new BindingList<BNComboBoxItem<AudioEncoderType>> {
|
||||
new BNComboBoxItem<AudioEncoderType>("lossless", "checked", AudioEncoderType.Lossless),
|
||||
new BNComboBoxItem<AudioEncoderType>("lossy", "unchecked", AudioEncoderType.Lossy)
|
||||
};
|
||||
private BindingList<ReleaseInfo> releases = new BindingList<ReleaseInfo>();
|
||||
private BindingList<DriveInfo> drives = new BindingList<DriveInfo>();
|
||||
private BindingList<FormatInfo> formats = new BindingList<FormatInfo>();
|
||||
@@ -69,7 +74,7 @@ namespace CUERipper
|
||||
}
|
||||
}
|
||||
|
||||
public BindingList<string> LosslessOrNot
|
||||
public BindingList<BNComboBoxItem<AudioEncoderType>> LosslessOrNot
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -126,16 +131,11 @@ namespace CUERipper
|
||||
SetupControls();
|
||||
|
||||
int iFormat, nFormats = sr.LoadInt32("OutputPathUseTemplates", 0, 10) ?? 0;
|
||||
for (iFormat = 0; iFormat < OutputPathUseTemplates.Length; iFormat++)
|
||||
comboBoxOutputFormat.Items.Add(OutputPathUseTemplates[iFormat]);
|
||||
for (iFormat = nFormats - 1; iFormat >= 0; iFormat--)
|
||||
comboBoxOutputFormat.Items.Add(sr.Load(string.Format("OutputPathUseTemplate{0}", iFormat)) ?? "");
|
||||
for (iFormat = 0; iFormat < OutputPathUseTemplates.Length; iFormat++)
|
||||
bnComboBoxOutputFormat.Items.Add(OutputPathUseTemplates[iFormat]);
|
||||
for (iFormat = nFormats - 1; iFormat >= 0; iFormat--)
|
||||
bnComboBoxOutputFormat.Items.Add(sr.Load(string.Format("OutputPathUseTemplate{0}", iFormat)) ?? "");
|
||||
|
||||
comboBoxOutputFormat.Text = sr.Load("PathFormat") ?? "%music%\\%artist%\\[%year% - ]%album%\\%artist% - %album%.cue";
|
||||
bnComboBoxOutputFormat.Text = sr.Load("PathFormat") ?? "%music%\\%artist%\\[%year% - ]%album%\\%artist% - %album%.cue";
|
||||
checkBoxEACMode.Checked = _config.createEACLOG;
|
||||
SelectedOutputAudioType = (AudioEncoderType?)sr.LoadInt32("OutputAudioType", null, null) ?? AudioEncoderType.Lossless;
|
||||
@@ -176,26 +176,22 @@ namespace CUERipper
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private void UpdateDrives()
|
||||
private void DrivesLookup(object o)
|
||||
{
|
||||
buttonGo.Enabled = false;
|
||||
foreach (DriveInfo driveInfo in drives)
|
||||
if (driveInfo.drive != null)
|
||||
driveInfo.drive.Close();
|
||||
drives.Clear();
|
||||
// Lookup
|
||||
drives.RaiseListChangedEvents = false;
|
||||
listTracks.Items.Clear();
|
||||
releases.Clear();
|
||||
selectedRelease = null;
|
||||
selectedDriveInfo = null;
|
||||
bnComboBoxRelease.Text = "";
|
||||
foreach (char drive in CDDrivesList.DrivesAvailable())
|
||||
{
|
||||
ICDRipper reader = Activator.CreateInstance(CUEProcessorPlugins.ripper) as ICDRipper;
|
||||
ICDRipper reader = null;
|
||||
string arName = null;
|
||||
int driveOffset;
|
||||
try
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
toolStripStatusLabel1.Text = Properties.Resources.DetectingDrives + ": " + drive + ":\\...";
|
||||
});
|
||||
reader = Activator.CreateInstance(CUEProcessorPlugins.ripper) as ICDRipper;
|
||||
reader.Open(drive);
|
||||
arName = reader.ARName;
|
||||
reader.Close();
|
||||
@@ -217,13 +213,41 @@ namespace CUERipper
|
||||
reader.DriveOffset = driveOffset;
|
||||
drives.Add(new DriveInfo(m_icon_mgr, drive + ":\\", reader));
|
||||
}
|
||||
if (drives.Count == 0)
|
||||
_workThread = null;
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
bnComboBoxDrives.Text = "No CD drives found";
|
||||
}
|
||||
SetupControls();
|
||||
drives.RaiseListChangedEvents = true;
|
||||
drives.ResetBindings();
|
||||
//bnComboBoxDrives.SelectedIndex = 0;
|
||||
if (drives.Count == 0)
|
||||
bnComboBoxDrives.Text = Properties.Resources.NoDrives;
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateDrives()
|
||||
{
|
||||
buttonGo.Enabled = false;
|
||||
foreach (DriveInfo driveInfo in drives)
|
||||
if (driveInfo.drive != null)
|
||||
driveInfo.drive.Close();
|
||||
drives.Clear();
|
||||
listTracks.Items.Clear();
|
||||
releases.Clear();
|
||||
selectedRelease = null;
|
||||
selectedDriveInfo = null;
|
||||
bnComboBoxRelease.Text = "";
|
||||
|
||||
if (CUEProcessorPlugins.ripper == null)
|
||||
{
|
||||
bnComboBoxDrives.Text = Properties.Resources.FailedToLoadRipperModule;
|
||||
return;
|
||||
}
|
||||
|
||||
_workThread = new Thread(DrivesLookup);
|
||||
_workThread.Priority = ThreadPriority.BelowNormal;
|
||||
_workThread.IsBackground = true;
|
||||
SetupControls();
|
||||
_workThread.Start(this);
|
||||
}
|
||||
|
||||
bool outputFormatVisible = false;
|
||||
@@ -232,14 +256,13 @@ namespace CUERipper
|
||||
{
|
||||
bool running = _workThread != null;
|
||||
|
||||
bnComboBoxOutputFormat.Visible = comboBoxOutputFormat.Visible = outputFormatVisible;
|
||||
bnComboBoxOutputFormat.Visible = outputFormatVisible;
|
||||
txtOutputPath.Visible = !outputFormatVisible;
|
||||
txtOutputPath.Enabled = !running && !outputFormatVisible;
|
||||
bnComboBoxRelease.Enabled = !running && releases.Count > 0;
|
||||
bnComboBoxDrives.Enabled = !running && drives.Count > 0;
|
||||
bnComboBoxOutputFormat.Enabled =
|
||||
comboBoxOutputFormat.Enabled =
|
||||
listTracks.Enabled =
|
||||
bnComboBoxDrives.Enabled =
|
||||
groupBoxSettings.Enabled = !running;
|
||||
buttonPause.Visible = buttonPause.Enabled = buttonAbort.Visible = buttonAbort.Enabled = running;
|
||||
buttonGo.Visible = buttonGo.Enabled = !running;
|
||||
@@ -263,7 +286,7 @@ namespace CUERipper
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
toolStripStatusLabel1.Text = "Paused...";
|
||||
toolStripStatusLabel1.Text = Properties.Resources.PausedMessage + "...";
|
||||
});
|
||||
Monitor.Wait(_startStop);
|
||||
}
|
||||
@@ -290,9 +313,10 @@ namespace CUERipper
|
||||
double speed = elapsed.TotalSeconds > 0 ? processed / elapsed.TotalSeconds / 75 : 1.0;
|
||||
|
||||
double percentTrck = (double)(e.Position - e.PassStart) / (e.PassEnd - e.PassStart);
|
||||
string retry = e.Pass > 0 ? " (" + Properties.Resources.Retry + " " + e.Pass.ToString() + ")" : "";
|
||||
string status = (elapsed.TotalSeconds > 0 && e.Pass >= 0) ?
|
||||
string.Format("{0} @{1:00.00}x{2}...", e.Action, speed, e.Pass > 0 ? " (Retry " + e.Pass.ToString() + ")" : "") :
|
||||
string.Format("{0}{1}...", e.Action, e.Pass > 0 ? " (Retry " + e.Pass.ToString() + ")" : "");
|
||||
string.Format("{0} @{1:00.00}x{2}...", e.Action, speed, retry) :
|
||||
string.Format("{0}{1}...", e.Action, retry);
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
toolStripStatusLabel1.Text = status;
|
||||
@@ -317,23 +341,14 @@ namespace CUERipper
|
||||
{
|
||||
cueSheet.Go();
|
||||
|
||||
bool submit = cueSheet.CTDB.AccResult == HttpStatusCode.NotFound ||
|
||||
cueSheet.CTDB.AccResult == HttpStatusCode.OK;
|
||||
//_cueSheet.CTDB.AccResult == HttpStatusCode.NoContent;
|
||||
if ((cueSheet.CTDB.AccResult == HttpStatusCode.NotFound || cueSheet.CTDB.AccResult == HttpStatusCode.OK)
|
||||
&& audioSource.CorrectionQuality > 0 && audioSource.ErrorsCount == 0)
|
||||
{
|
||||
DBEntry confirm = null;
|
||||
|
||||
submit &= audioSource.CorrectionQuality > 0;
|
||||
|
||||
foreach (DBEntry entry in cueSheet.CTDB.Entries)
|
||||
if (entry.toc.TrackOffsets == selectedDriveInfo.drive.TOC.TrackOffsets && !entry.hasErrors)
|
||||
confirm = entry;
|
||||
|
||||
for (int iSector = 0; iSector < (int)cueSheet.TOC.AudioLength; iSector++)
|
||||
if (audioSource.Errors[iSector])
|
||||
submit = false;
|
||||
|
||||
if (submit)
|
||||
{
|
||||
if (confirm != null)
|
||||
cueSheet.CTDB.Confirm(confirm);
|
||||
else
|
||||
@@ -343,8 +358,20 @@ namespace CUERipper
|
||||
cueSheet.Artist,
|
||||
cueSheet.Title);
|
||||
}
|
||||
//CUESheet.WriteText(_pathOut, _cueSheet.CUESheetContents(_style));
|
||||
//CUESheet.WriteText(Path.ChangeExtension(_pathOut, ".log"), _cueSheet.LOGContents());
|
||||
|
||||
bool canFix = false;
|
||||
if (cueSheet.CTDB.AccResult == HttpStatusCode.OK && audioSource.ErrorsCount != 0)
|
||||
{
|
||||
foreach (DBEntry entry in cueSheet.CTDB.Entries)
|
||||
if (entry.hasErrors && entry.canRecover)
|
||||
canFix = true;
|
||||
}
|
||||
this.Invoke((MethodInvoker)delegate()
|
||||
{
|
||||
DialogResult dlgRes = audioSource.ErrorsCount != 0 ?
|
||||
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + (canFix ? "\n" + Properties.Resources.DoneRippingRepair : "") + ".", Properties.Resources.DoneRippingErrors, MessageBoxButtons.OK, MessageBoxIcon.Error) :
|
||||
MessageBox.Show(this, cueSheet.GenerateAccurateRipStatus() + ".", Properties.Resources.DoneRipping, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
});
|
||||
}
|
||||
catch (StopException)
|
||||
{
|
||||
@@ -354,10 +381,10 @@ namespace CUERipper
|
||||
{
|
||||
this.Invoke((MethodInvoker)delegate()
|
||||
{
|
||||
string message = "Exception";
|
||||
string message = Properties.Resources.ExceptionMessage;
|
||||
for (Exception e = ex; e != null; e = e.InnerException)
|
||||
message += ": " + e.Message;
|
||||
DialogResult dlgRes = MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
DialogResult dlgRes = MessageBox.Show(this, message, Properties.Resources.ExceptionMessage, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
@@ -390,13 +417,6 @@ namespace CUERipper
|
||||
if (selectedDriveInfo == null)
|
||||
return;
|
||||
|
||||
if (!comboBoxOutputFormat.Items.Contains(comboBoxOutputFormat.Text) && comboBoxOutputFormat.Text.Contains("%"))
|
||||
{
|
||||
comboBoxOutputFormat.Items.Insert(OutputPathUseTemplates.Length, comboBoxOutputFormat.Text);
|
||||
if (comboBoxOutputFormat.Items.Count > OutputPathUseTemplates.Length + 10)
|
||||
comboBoxOutputFormat.Items.RemoveAt(OutputPathUseTemplates.Length + 10);
|
||||
}
|
||||
|
||||
if (!bnComboBoxOutputFormat.Items.Contains(bnComboBoxOutputFormat.Text) && bnComboBoxOutputFormat.Text.Contains("%"))
|
||||
{
|
||||
bnComboBoxOutputFormat.Items.Insert(OutputPathUseTemplates.Length, bnComboBoxOutputFormat.Text);
|
||||
@@ -460,7 +480,7 @@ namespace CUERipper
|
||||
//_progress.input = e.Uri.ToString();
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
toolStripStatusLabel1.Text = "Looking up album via " + (e == null ? "FreeDB" : "MusicBrainz");
|
||||
toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " " + (e == null ? "FreeDB" : "MusicBrainz") + "...";
|
||||
toolStripProgressBar1.Value = (100 + 2 * toolStripProgressBar1.Value) / 3;
|
||||
});
|
||||
}
|
||||
@@ -492,12 +512,12 @@ namespace CUERipper
|
||||
if (release != null)
|
||||
{
|
||||
r.metadata.FillFromMusicBrainz(release);
|
||||
r.ImageKey = "musicbrainz.ico";
|
||||
r.ImageKey = "musicbrainz";
|
||||
}
|
||||
else if (cdEntry != null)
|
||||
{
|
||||
r.metadata.FillFromFreedb(cdEntry);
|
||||
r.ImageKey = "freedb16.png";
|
||||
r.ImageKey = "freedb";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -521,12 +541,12 @@ namespace CUERipper
|
||||
cueSheet.OpenCD(audioSource);
|
||||
cueSheet.Action = CUEAction.Encode;
|
||||
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = "Contacting CTDB database..."; });
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " CTDB..."; });
|
||||
cueSheet.UseCUEToolsDB(true, "CUERipper 2.0.7: " + selectedDriveInfo.drive.ARName);
|
||||
cueSheet.CTDB.UploadHelper.onProgress += new EventHandler<Krystalware.UploadHelper.UploadProgressEventArgs>(UploadProgress);
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = "Contacting AccurateRip database..."; });
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " AccurateRip..."; });
|
||||
cueSheet.UseAccurateRip();
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = "Looking album info..."; });
|
||||
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " MusicBrainz..."; });
|
||||
|
||||
General.SetCUELine(cueSheet.Attributes, "REM", "DISCID", AccurateRipVerify.CalculateCDDBId(audioSource.TOC), false);
|
||||
General.SetCUELine(cueSheet.Attributes, "REM", "COMMENT", _config.createEACLOG ? "ExactAudioCopy v0.99pb4" : audioSource.RipperVersion, true);
|
||||
@@ -555,7 +575,7 @@ namespace CUERipper
|
||||
m_freedb.UserName = "gchudov";
|
||||
m_freedb.Hostname = "gmail.com";
|
||||
m_freedb.ClientName = "CUERipper";
|
||||
m_freedb.Version = "1.0";
|
||||
m_freedb.Version = "2.0.7";
|
||||
m_freedb.SetDefaultSiteAddress(Properties.Settings.Default.MAIN_FREEDB_SITEADDRESS);
|
||||
|
||||
QueryResult queryResult;
|
||||
@@ -612,16 +632,16 @@ namespace CUERipper
|
||||
releases.RaiseListChangedEvents = true;
|
||||
releases.ResetBindings();
|
||||
//bnComboBoxRelease.SelectedIndex = 0;
|
||||
toolStripStatusAr.Visible = cueSheet.ArVerify.ARStatus == null;
|
||||
toolStripStatusAr.Text = cueSheet.ArVerify.ARStatus == null ? cueSheet.ArVerify.WorstTotal().ToString() : "?";
|
||||
toolStripStatusAr.Enabled = cueSheet.ArVerify.ARStatus == null;
|
||||
toolStripStatusAr.Text = cueSheet.ArVerify.ARStatus == null ? cueSheet.ArVerify.WorstTotal().ToString() : "";
|
||||
toolStripStatusAr.ToolTipText = "AccurateRip: " + (cueSheet.ArVerify.ARStatus ?? "found") + ".";
|
||||
toolStripStatusCTDB.Visible = cueSheet.CTDB.DBStatus == null;
|
||||
toolStripStatusCTDB.Enabled = cueSheet.CTDB.DBStatus == null;
|
||||
toolStripStatusCTDB.Text = cueSheet.CTDB.DBStatus == null ? cueSheet.CTDB.Total.ToString() : "";
|
||||
toolStripStatusCTDB.ToolTipText = "CUETools DB: " + (cueSheet.CTDB.DBStatus ?? "found") + ".";
|
||||
toolStripStatusLabelMusicBrainz.Enabled = true;
|
||||
toolStripStatusLabelMusicBrainz.BorderStyle = results.Count > 0 ? Border3DStyle.SunkenInner : Border3DStyle.RaisedInner;
|
||||
toolStripStatusLabelMusicBrainz.Visible = true;
|
||||
toolStripStatusLabelMusicBrainz.Text = results.Count > 0 ? results.Count.ToString() : "-";
|
||||
toolStripStatusLabelMusicBrainz.ToolTipText = "Musicbrainz: " + results.Count.ToString() + " entries found.";
|
||||
toolStripStatusLabelMusicBrainz.Text = results.Count > 0 ? results.Count.ToString() : "";
|
||||
toolStripStatusLabelMusicBrainz.ToolTipText = "Musicbrainz: " + (results.Count > 0 ? results.Count.ToString() + " entries found." : "click to submit.");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -631,9 +651,15 @@ namespace CUERipper
|
||||
if (selectedDriveInfo == null)
|
||||
return;
|
||||
|
||||
toolStripStatusAr.Visible = false;
|
||||
toolStripStatusCTDB.Visible = false;
|
||||
toolStripStatusLabelMusicBrainz.Visible = false;
|
||||
toolStripStatusAr.Enabled = false;
|
||||
toolStripStatusAr.Text = "";
|
||||
toolStripStatusAr.ToolTipText = "";
|
||||
toolStripStatusCTDB.Enabled = false;
|
||||
toolStripStatusCTDB.Text = "";
|
||||
toolStripStatusCTDB.ToolTipText = "";
|
||||
toolStripStatusLabelMusicBrainz.Enabled = false;
|
||||
toolStripStatusLabelMusicBrainz.Text = "";
|
||||
toolStripStatusLabelMusicBrainz.ToolTipText = "";
|
||||
buttonGo.Enabled = false;
|
||||
listTracks.Items.Clear();
|
||||
releases.Clear();
|
||||
@@ -734,11 +760,11 @@ namespace CUERipper
|
||||
//sw.Save("CreateM3U", _config.createM3U);
|
||||
sw.Save("OutputAudioType", (int)SelectedOutputAudioType);
|
||||
sw.Save("ComboImage", bnComboBoxImage.SelectedIndex);
|
||||
sw.Save("PathFormat", comboBoxOutputFormat.Text);
|
||||
sw.Save("PathFormat", bnComboBoxOutputFormat.Text);
|
||||
sw.Save("SecureMode", trackBarSecureMode.Value);
|
||||
sw.Save("OutputPathUseTemplates", comboBoxOutputFormat.Items.Count - OutputPathUseTemplates.Length);
|
||||
for (int iFormat = comboBoxOutputFormat.Items.Count - 1; iFormat >= OutputPathUseTemplates.Length; iFormat--)
|
||||
sw.Save(string.Format("OutputPathUseTemplate{0}", iFormat - OutputPathUseTemplates.Length), comboBoxOutputFormat.Items[iFormat].ToString());
|
||||
sw.Save("OutputPathUseTemplates", bnComboBoxOutputFormat.Items.Count - OutputPathUseTemplates.Length);
|
||||
for (int iFormat = bnComboBoxOutputFormat.Items.Count - 1; iFormat >= OutputPathUseTemplates.Length; iFormat--)
|
||||
sw.Save(string.Format("OutputPathUseTemplate{0}", iFormat - OutputPathUseTemplates.Length), bnComboBoxOutputFormat.Items[iFormat].ToString());
|
||||
|
||||
sw.Close();
|
||||
}
|
||||
@@ -777,24 +803,17 @@ namespace CUERipper
|
||||
{
|
||||
get
|
||||
{
|
||||
return bnComboBoxLosslessOrNot.Text == "lossy" ? AudioEncoderType.Lossy
|
||||
: bnComboBoxLosslessOrNot.Text == "hybrid" ? AudioEncoderType.Hybrid
|
||||
: AudioEncoderType.Lossless;
|
||||
return (bnComboBoxLosslessOrNot.SelectedItem as BNComboBoxItem<AudioEncoderType>).Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
foreach (BNComboBoxItem<AudioEncoderType> item in losslessOrNot)
|
||||
if (value == item.Value)
|
||||
{
|
||||
case AudioEncoderType.Hybrid:
|
||||
bnComboBoxLosslessOrNot.SelectedItem = "hybrid";
|
||||
break;
|
||||
case AudioEncoderType.Lossy:
|
||||
bnComboBoxLosslessOrNot.SelectedItem = "lossy";
|
||||
break;
|
||||
default:
|
||||
bnComboBoxLosslessOrNot.SelectedItem = "lossless";
|
||||
break;
|
||||
bnComboBoxLosslessOrNot.SelectedItem = item;
|
||||
return;
|
||||
}
|
||||
throw new Exception("invalid value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,7 +882,7 @@ namespace CUERipper
|
||||
private void frmCUERipper_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_workThread == null && e.KeyCode == Keys.F5)
|
||||
UpdateDrive();
|
||||
UpdateDrives();
|
||||
}
|
||||
|
||||
private void comboBoxOutputFormat_SelectedIndexChanged(object sender, EventArgs e)
|
||||
@@ -879,29 +898,6 @@ namespace CUERipper
|
||||
style == CUEStyle.SingleFileWithCUE ? "." + selectedFormat.ToString() : ".cue", CUEAction.Encode, null);
|
||||
}
|
||||
|
||||
private void comboBoxOutputFormat_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
if (!outputFormatVisible)
|
||||
return;
|
||||
outputFormatVisible = false;
|
||||
bnComboBoxOutputFormat.Visible = false;
|
||||
txtOutputPath.Enabled = true;
|
||||
txtOutputPath.Visible = true;
|
||||
}
|
||||
|
||||
private void txtOutputPath_Enter(object sender, EventArgs e)
|
||||
{
|
||||
if (outputFormatVisible)
|
||||
return;
|
||||
outputFormatVisible = true;
|
||||
//comboBoxOutputFormat.Visible = true;
|
||||
bnComboBoxOutputFormat.Visible = true;
|
||||
bnComboBoxOutputFormat.Focus();
|
||||
//bnComboBoxOutputFormat.Select();
|
||||
txtOutputPath.Enabled = false;
|
||||
txtOutputPath.Visible = false;
|
||||
}
|
||||
|
||||
private void bnComboBoxRelease_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateRelease();
|
||||
@@ -1006,9 +1002,30 @@ namespace CUERipper
|
||||
comboBoxOutputFormat_TextUpdate(sender, e);
|
||||
}
|
||||
|
||||
private void txtOutputPath_Enter(object sender, EventArgs e)
|
||||
{
|
||||
if (outputFormatVisible)
|
||||
return;
|
||||
outputFormatVisible = true;
|
||||
bnComboBoxOutputFormat.Visible = true;
|
||||
bnComboBoxOutputFormat.Focus();
|
||||
txtOutputPath.Enabled = false;
|
||||
txtOutputPath.Visible = false;
|
||||
}
|
||||
|
||||
private void bnComboBoxOutputFormat_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
if (!outputFormatVisible)
|
||||
//if (!outputFormatVisible)
|
||||
// return;
|
||||
//outputFormatVisible = false;
|
||||
//bnComboBoxOutputFormat.Visible = false;
|
||||
//txtOutputPath.Enabled = true;
|
||||
//txtOutputPath.Visible = true;
|
||||
}
|
||||
|
||||
private void bnComboBoxOutputFormat_DroppedDown(object sender, EventArgs e)
|
||||
{
|
||||
if (!outputFormatVisible || bnComboBoxOutputFormat.IsDroppedDown || bnComboBoxOutputFormat.Focused)
|
||||
return;
|
||||
outputFormatVisible = false;
|
||||
bnComboBoxOutputFormat.Visible = false;
|
||||
@@ -1016,14 +1033,9 @@ namespace CUERipper
|
||||
txtOutputPath.Visible = true;
|
||||
}
|
||||
|
||||
private void bnComboBoxOutputFormat_DroppedDown(object sender, EventArgs e)
|
||||
private void bnComboBoxOutputFormat_Leave(object sender, EventArgs e)
|
||||
{
|
||||
if (!outputFormatVisible || bnComboBoxOutputFormat.IsDroppedDown)
|
||||
return;
|
||||
outputFormatVisible = false;
|
||||
bnComboBoxOutputFormat.Visible = false;
|
||||
txtOutputPath.Enabled = true;
|
||||
txtOutputPath.Visible = true;
|
||||
bnComboBoxOutputFormat_DroppedDown(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>statusStrip1.ZOrder" xml:space="preserve">
|
||||
<value>11</value>
|
||||
<value>10</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listTracks.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
@@ -243,7 +243,7 @@
|
||||
<value>2</value>
|
||||
</data>
|
||||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>376, 17</value>
|
||||
<value>357, 17</value>
|
||||
</metadata>
|
||||
<data name="listTracks.ToolTip" xml:space="preserve">
|
||||
<value>Double-click to edit track names</value>
|
||||
@@ -258,7 +258,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>listTracks.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="buttonGo.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Left, Right</value>
|
||||
@@ -288,7 +288,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>buttonGo.ZOrder" xml:space="preserve">
|
||||
<value>10</value>
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="buttonAbort.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Left, Right</value>
|
||||
@@ -321,7 +321,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>buttonAbort.ZOrder" xml:space="preserve">
|
||||
<value>12</value>
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="buttonPause.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Left, Right</value>
|
||||
@@ -354,7 +354,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>buttonPause.ZOrder" xml:space="preserve">
|
||||
<value>13</value>
|
||||
<value>12</value>
|
||||
</data>
|
||||
<metadata name="contextMenuStripRelease.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
@@ -459,7 +459,7 @@
|
||||
<value>11</value>
|
||||
</data>
|
||||
<metadata name="losslessOrNotBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>631, 456</value>
|
||||
<value>369, 95</value>
|
||||
</metadata>
|
||||
<metadata name="bindingSourceCR.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>210, 56</value>
|
||||
@@ -467,14 +467,6 @@
|
||||
<data name="bnComboBoxLosslessOrNot.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 19</value>
|
||||
</data>
|
||||
<data name="bnComboBoxLosslessOrNot.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxLosslessOrNot.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>80, 21</value>
|
||||
</data>
|
||||
@@ -485,7 +477,7 @@
|
||||
<value>bnComboBoxLosslessOrNot</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxLosslessOrNot.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxLosslessOrNot.Parent" xml:space="preserve">
|
||||
<value>groupBoxSettings</value>
|
||||
@@ -494,19 +486,11 @@
|
||||
<value>0</value>
|
||||
</data>
|
||||
<metadata name="encodersBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>451, 456</value>
|
||||
<value>189, 95</value>
|
||||
</metadata>
|
||||
<data name="bnComboBoxEncoder.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>92, 46</value>
|
||||
</data>
|
||||
<data name="bnComboBoxEncoder.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxEncoder.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>80, 21</value>
|
||||
</data>
|
||||
@@ -517,7 +501,7 @@
|
||||
<value>bnComboBoxEncoder</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxEncoder.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxEncoder.Parent" xml:space="preserve">
|
||||
<value>groupBoxSettings</value>
|
||||
@@ -553,19 +537,11 @@
|
||||
<value>2</value>
|
||||
</data>
|
||||
<metadata name="formatsBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>279, 456</value>
|
||||
<value>17, 95</value>
|
||||
</metadata>
|
||||
<data name="bnComboBoxFormat.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>92, 19</value>
|
||||
</data>
|
||||
<data name="bnComboBoxFormat.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxFormat.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>80, 21</value>
|
||||
</data>
|
||||
@@ -576,7 +552,7 @@
|
||||
<value>bnComboBoxFormat</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxFormat.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxFormat.Parent" xml:space="preserve">
|
||||
<value>groupBoxSettings</value>
|
||||
@@ -624,19 +600,11 @@
|
||||
<value>4</value>
|
||||
</data>
|
||||
<metadata name="cUEStylesBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>642, 56</value>
|
||||
<value>526, 56</value>
|
||||
</metadata>
|
||||
<data name="bnComboBoxImage.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 46</value>
|
||||
</data>
|
||||
<data name="bnComboBoxImage.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxImage.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>80, 21</value>
|
||||
</data>
|
||||
@@ -647,7 +615,7 @@
|
||||
<value>bnComboBoxImage</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxImage.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxImage.Parent" xml:space="preserve">
|
||||
<value>groupBoxSettings</value>
|
||||
@@ -800,7 +768,58 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>groupBoxSettings.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
<value>7</value>
|
||||
</data>
|
||||
<metadata name="imageListChecked.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>207, 17</value>
|
||||
</metadata>
|
||||
<data name="imageListChecked.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
|
||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACK
|
||||
CQAAAk1TRnQBSQFMAgEBBAEAAQwBAAEEAQABEAEAARABAAT/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/AP8AyAAB9AHx
|
||||
BvAB8QH0BgAB9AHxBvAB8QH0BgAB9AHyBvEB8gH0BgAB9AHxBvAB8QH0BgAC8QbzAvEGAALxBvMC8QYA
|
||||
AfIB9AL/AfQD/wH0AfIGAALxBvMC8QYAAfEB8wHyAfAB6gHwAvIB8wHxBgAB8QHzBvIB8wHxBgAB8QL/
|
||||
AfQB8QH0A/8B8QYAAfEB8wbyAfMB8QYAAfEB8wHxA20B8QLzAfEGAAHxCPMB8QYAAfEB/wH0A/EB9AL/
|
||||
AfEGAAHxAvMB7ALqAewC8wHxBgAB8QH0AuwB8ALsAfEB9AHxBgAB8QH0BvMB9AHxBgAB8gH0AvIB9ALy
|
||||
AvQB8gYAAfEB9AHzBOsB8wH0AfEGAAHyAfQB7AHyAfQB8gLsAfQB8gYAAfII9AHyBgAB8gH0AfID9ALy
|
||||
AfQB8gYAAfIC9ATsAvQB8gYAAfIB/wT0AfMB7QH/AfIGAAHyAf8G9AH/AfIGAAHyAvQD/wH0AfIB9AHy
|
||||
BgAB8gH/AfQB7wLtAe8B9AH/AfIGAAHyBv8B8gH/AfIGAAHyCP8B8gYAAfIB9AT/A/QB8gYAAfII/wHy
|
||||
BgAC8wb/AvMGAALzBv8C8wYAAfMI9AHzBgAC8wb/AvMGAAH/AfMG8gHzAf8GAAH/AfMG8gHzAf8GAAH/
|
||||
AfMG8gHzAf8GAAH/AfMG8gHzAf/DAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/
|
||||
gQAY/wHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEH
|
||||
AeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEH
|
||||
AeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcY/ws=
|
||||
</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>181, 22</value>
|
||||
@@ -809,19 +828,19 @@
|
||||
<value>toolStripMenuItem1</value>
|
||||
</data>
|
||||
<metadata name="plainBackgroundPainter1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>979, 17</value>
|
||||
<value>960, 17</value>
|
||||
</metadata>
|
||||
<metadata name="styledBorderPainter1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>643, 17</value>
|
||||
<value>624, 17</value>
|
||||
</metadata>
|
||||
<data name="progressBarErrors.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>382, 421</value>
|
||||
</data>
|
||||
<metadata name="plainProgressPainter1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>473, 17</value>
|
||||
<value>454, 17</value>
|
||||
</metadata>
|
||||
<metadata name="gradientGlossPainter1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>808, 17</value>
|
||||
<value>789, 17</value>
|
||||
</metadata>
|
||||
<data name="progressBarErrors.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>177, 23</value>
|
||||
@@ -839,7 +858,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>progressBarErrors.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="progressBarCD.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>382, 392</value>
|
||||
@@ -866,34 +885,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>progressBarCD.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="comboBoxOutputFormat.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 170</value>
|
||||
</data>
|
||||
<data name="comboBoxOutputFormat.MaxDropDownItems" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="comboBoxOutputFormat.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>553, 21</value>
|
||||
</data>
|
||||
<data name="comboBoxOutputFormat.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>32</value>
|
||||
</data>
|
||||
<data name="comboBoxOutputFormat.ToolTip" xml:space="preserve">
|
||||
<value>Template for output files (foobar2000 format)</value>
|
||||
</data>
|
||||
<data name=">>comboBoxOutputFormat.Name" xml:space="preserve">
|
||||
<value>comboBoxOutputFormat</value>
|
||||
</data>
|
||||
<data name=">>comboBoxOutputFormat.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBoxOutputFormat.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>comboBoxOutputFormat.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="txtOutputPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>7, 61</value>
|
||||
@@ -920,7 +912,7 @@
|
||||
<value>1</value>
|
||||
</data>
|
||||
<metadata name="releasesBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>824, 56</value>
|
||||
<value>708, 56</value>
|
||||
</metadata>
|
||||
<metadata name="imageListMetadataSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 56</value>
|
||||
@@ -974,14 +966,6 @@
|
||||
<data name="bnComboBoxRelease.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 33</value>
|
||||
</data>
|
||||
<data name="bnComboBoxRelease.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxRelease.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>552, 21</value>
|
||||
</data>
|
||||
@@ -995,7 +979,7 @@
|
||||
<value>bnComboBoxRelease</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxRelease.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxRelease.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
@@ -1004,19 +988,11 @@
|
||||
<value>2</value>
|
||||
</data>
|
||||
<metadata name="drivesBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>116, 456</value>
|
||||
<value>998, 56</value>
|
||||
</metadata>
|
||||
<data name="bnComboBoxDrives.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 6</value>
|
||||
</data>
|
||||
<data name="bnComboBoxDrives.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxDrives.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>552, 21</value>
|
||||
</data>
|
||||
@@ -1027,7 +1003,7 @@
|
||||
<value>bnComboBoxDrives</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxDrives.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxDrives.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
@@ -1038,14 +1014,6 @@
|
||||
<data name="bnComboBoxOutputFormat.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>6, 60</value>
|
||||
</data>
|
||||
<data name="bnComboBoxOutputFormat.Radius" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEJDVUVDb250cm9scywgVmVyc2lvbj0yLjAuNy4wLCBDdWx0dXJl
|
||||
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwFAQAAABBCQkJOT1ZBLkJOUmFkaXVzBAAAAAhfdG9w
|
||||
TGVmdAlfdG9wUmlnaHQLX2JvdHRvbUxlZnQMX2JvdHRvbVJpZ2h0AAAAAAgICAgCAAAAAgAAAAYAAAAC
|
||||
AAAAAgAAAAs=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bnComboBoxOutputFormat.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>552, 21</value>
|
||||
</data>
|
||||
@@ -1056,7 +1024,7 @@
|
||||
<value>bnComboBoxOutputFormat</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxOutputFormat.Type" xml:space="preserve">
|
||||
<value>BBBNOVA.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
<value>CUEControls.BNComboBox, CUEControls, Version=2.0.7.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>bnComboBoxOutputFormat.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
@@ -1575,6 +1543,12 @@
|
||||
<data name=">>cUEStylesBindingSource.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.BindingSource, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>imageListChecked.Name" xml:space="preserve">
|
||||
<value>imageListChecked</value>
|
||||
</data>
|
||||
<data name=">>imageListChecked.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem1.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem1</value>
|
||||
</data>
|
||||
|
||||
@@ -822,7 +822,7 @@ namespace CUETools.AccurateRip
|
||||
public static bool FindDriveReadOffset(string driveName, out int driveReadOffset)
|
||||
{
|
||||
string fileName = System.IO.Path.Combine(CachePath, "DriveOffsets.bin");
|
||||
if (!File.Exists(fileName))
|
||||
if (!File.Exists(fileName) || (DateTime.Now - File.GetLastWriteTime(fileName) > TimeSpan.FromDays(1)) )
|
||||
{
|
||||
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.accuraterip.com/accuraterip/DriveOffsets.bin");
|
||||
req.Method = "GET";
|
||||
@@ -835,7 +835,7 @@ namespace CUETools.AccurateRip
|
||||
return false;
|
||||
}
|
||||
Stream respStream = resp.GetResponseStream();
|
||||
FileStream myOffsetsSaved = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write);
|
||||
FileStream myOffsetsSaved = new FileStream(fileName, FileMode.Create, FileAccess.Write);
|
||||
byte[] buff = new byte[0x8000];
|
||||
do
|
||||
{
|
||||
|
||||
@@ -507,7 +507,7 @@ namespace CUETools.CTDB
|
||||
if (!hasErrors)
|
||||
return string.Format("verified OK, confidence {0}", conf);
|
||||
if (canRecover)
|
||||
return string.Format("contains {1} correctable errors, confidence {0}", conf, repair.CorrectableErrors);
|
||||
return string.Format("differs in {1} samples, confidence {0}", conf, repair.CorrectableErrors);
|
||||
if (httpStatus == HttpStatusCode.OK)
|
||||
return "could not be verified";
|
||||
return "could not be verified: " + httpStatus.ToString();
|
||||
|
||||
110
CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj
Normal file
110
CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj
Normal file
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CUETools.Codecs.CoreAudio</RootNamespace>
|
||||
<AssemblyName>CUETools.Codecs.CoreAudio</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CoreAudioApi\AudioCaptureClient.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioClient.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioClientBufferFlags.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioClientShareMode.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioClientStreamFlags.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolume.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeCallback.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeChannel.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeChannels.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeNotificationDelegate.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeStepInformation.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioEndpointVolumeVolumeRange.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioMeterInformation.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioMeterInformationChannels.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioRenderClient.cs" />
|
||||
<Compile Include="CoreAudioApi\AudioVolumeNotificationData.cs" />
|
||||
<Compile Include="CoreAudioApi\DataFlow.cs" />
|
||||
<Compile Include="CoreAudioApi\DeviceState.cs" />
|
||||
<Compile Include="CoreAudioApi\EEndpointHardwareSupport.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\AudioVolumeNotificationDataStruct.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\Blob.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\ClsCtx.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\ErrorCodes.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioCaptureClient.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioClient.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioEndpointVolume.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioEndpointVolumeCallback.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioMeterInformation.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IAudioRenderClient.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IMMDevice.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IMMDeviceCollection.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IMMDeviceEnumerator.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IMMEndpoint.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IMMNotificationClient.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\IPropertyStore.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\MMDeviceEnumeratorComObject.cs" />
|
||||
<Compile Include="CoreAudioApi\Interfaces\StorageAccessMode.cs" />
|
||||
<Compile Include="CoreAudioApi\MMDevice.cs" />
|
||||
<Compile Include="CoreAudioApi\MMDeviceCollection.cs" />
|
||||
<Compile Include="CoreAudioApi\MMDeviceEnumerator.cs" />
|
||||
<Compile Include="CoreAudioApi\PropertyKey.cs" />
|
||||
<Compile Include="CoreAudioApi\PropertyKeys.cs" />
|
||||
<Compile Include="CoreAudioApi\PropertyStore.cs" />
|
||||
<Compile Include="CoreAudioApi\PropertyStoreProperty.cs" />
|
||||
<Compile Include="CoreAudioApi\PropVariant.cs" />
|
||||
<Compile Include="CoreAudioApi\Role.cs" />
|
||||
<Compile Include="IWavePlayer.cs" />
|
||||
<Compile Include="PlaybackState.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WasapiOut.cs" />
|
||||
<Compile Include="WaveFormats\AdpcmWaveFormat.cs" />
|
||||
<Compile Include="WaveFormats\AudioMediaSubtypes.cs" />
|
||||
<Compile Include="WaveFormats\WaveFormat.cs" />
|
||||
<Compile Include="WaveFormats\WaveFormatEncoding.cs" />
|
||||
<Compile Include="WaveFormats\WaveFormatExtensible.cs" />
|
||||
<Compile Include="WaveFormats\WaveFormatExtraData.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj">
|
||||
<Project>{6458A13A-30EF-45A9-9D58-E5031B17BEE2}</Project>
|
||||
<Name>CUETools.Codecs</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
91
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioCaptureClient.cs
Normal file
91
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioCaptureClient.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Capture Client
|
||||
/// </summary>
|
||||
public class AudioCaptureClient : IDisposable
|
||||
{
|
||||
IAudioCaptureClient audioCaptureClientInterface;
|
||||
|
||||
internal AudioCaptureClient(IAudioCaptureClient audioCaptureClientInterface)
|
||||
{
|
||||
this.audioCaptureClientInterface = audioCaptureClientInterface;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a pointer to the buffer
|
||||
/// </summary>
|
||||
/// <returns>Pointer to the buffer</returns>
|
||||
public IntPtr GetBuffer(
|
||||
out int numFramesToRead,
|
||||
out AudioClientBufferFlags bufferFlags,
|
||||
out long devicePosition,
|
||||
out long qpcPosition)
|
||||
{
|
||||
IntPtr bufferPointer;
|
||||
Marshal.ThrowExceptionForHR(audioCaptureClientInterface.GetBuffer(out bufferPointer, out numFramesToRead, out bufferFlags, out devicePosition, out qpcPosition));
|
||||
return bufferPointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a pointer to the buffer
|
||||
/// </summary>
|
||||
/// <param name="numFramesToRead">Number of frames to read</param>
|
||||
/// <param name="bufferFlags">Buffer flags</param>
|
||||
/// <returns>Pointer to the buffer</returns>
|
||||
public IntPtr GetBuffer(
|
||||
out int numFramesToRead,
|
||||
out AudioClientBufferFlags bufferFlags)
|
||||
{
|
||||
IntPtr bufferPointer;
|
||||
long devicePosition;
|
||||
long qpcPosition;
|
||||
Marshal.ThrowExceptionForHR(audioCaptureClientInterface.GetBuffer(out bufferPointer, out numFramesToRead, out bufferFlags, out devicePosition, out qpcPosition));
|
||||
return bufferPointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the next packet
|
||||
/// </summary>
|
||||
public int GetNextPacketSize()
|
||||
{
|
||||
int numFramesInNextPacket;
|
||||
Marshal.ThrowExceptionForHR(audioCaptureClientInterface.GetNextPacketSize(out numFramesInNextPacket));
|
||||
return numFramesInNextPacket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release buffer
|
||||
/// </summary>
|
||||
/// <param name="numFramesWritten">Number of frames written</param>
|
||||
public void ReleaseBuffer(int numFramesWritten)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(audioCaptureClientInterface.ReleaseBuffer(numFramesWritten));
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Release the COM object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (audioCaptureClientInterface != null)
|
||||
{
|
||||
// althugh GC would do this for us, we want it done now
|
||||
// to let us reopen WASAPI
|
||||
Marshal.ReleaseComObject(audioCaptureClientInterface);
|
||||
audioCaptureClientInterface = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
296
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioClient.cs
Normal file
296
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioClient.cs
Normal file
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.Wave;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Windows Vista CoreAudio AudioClient
|
||||
/// </summary>
|
||||
public class AudioClient : IDisposable
|
||||
{
|
||||
IAudioClient audioClientInterface;
|
||||
WaveFormat mixFormat;
|
||||
AudioRenderClient audioRenderClient;
|
||||
AudioCaptureClient audioCaptureClient;
|
||||
|
||||
internal AudioClient(IAudioClient audioClientInterface)
|
||||
{
|
||||
this.audioClientInterface = audioClientInterface;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mix Format,
|
||||
/// Can be called before initialize
|
||||
/// </summary>
|
||||
public WaveFormat MixFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
if(mixFormat == null)
|
||||
{
|
||||
IntPtr waveFormatPointer;
|
||||
audioClientInterface.GetMixFormat(out waveFormatPointer);
|
||||
//WaveFormatExtensible waveFormat = new WaveFormatExtensible(44100,32,2);
|
||||
//Marshal.PtrToStructure(waveFormatPointer, waveFormat);
|
||||
WaveFormat waveFormat = WaveFormat.MarshalFromPtr(waveFormatPointer);
|
||||
Marshal.FreeCoTaskMem(waveFormatPointer);
|
||||
mixFormat = waveFormat;
|
||||
return waveFormat;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mixFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the Audio Client
|
||||
/// </summary>
|
||||
/// <param name="shareMode">Share Mode</param>
|
||||
/// <param name="streamFlags">Stream Flags</param>
|
||||
/// <param name="bufferDuration">Buffer Duration</param>
|
||||
/// <param name="periodicity">Periodicity</param>
|
||||
/// <param name="waveFormat">Wave Format</param>
|
||||
/// <param name="audioSessionGuid">Audio Session GUID (can be null)</param>
|
||||
public void Initialize(AudioClientShareMode shareMode,
|
||||
AudioClientStreamFlags streamFlags,
|
||||
long bufferDuration,
|
||||
long periodicity,
|
||||
WaveFormat waveFormat,
|
||||
Guid audioSessionGuid)
|
||||
{
|
||||
audioClientInterface.Initialize(shareMode, streamFlags, bufferDuration, periodicity, waveFormat, ref audioSessionGuid);
|
||||
// may have changed the mix format so reset it
|
||||
mixFormat = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the buffer size (must initialize first)
|
||||
/// </summary>
|
||||
public int BufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
uint bufferSize;
|
||||
audioClientInterface.GetBufferSize(out bufferSize);
|
||||
return (int) bufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream latency (must initialize first)
|
||||
/// </summary>
|
||||
public long StreamLatency
|
||||
{
|
||||
get
|
||||
{
|
||||
return audioClientInterface.GetStreamLatency();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current padding (must initialize first)
|
||||
/// </summary>
|
||||
public int CurrentPadding
|
||||
{
|
||||
get
|
||||
{
|
||||
int currentPadding;
|
||||
audioClientInterface.GetCurrentPadding(out currentPadding);
|
||||
return currentPadding;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default device period (can be called before initialize)
|
||||
/// </summary>
|
||||
public long DefaultDevicePeriod
|
||||
{
|
||||
get
|
||||
{
|
||||
long defaultDevicePeriod;
|
||||
long minimumDevicePeriod;
|
||||
audioClientInterface.GetDevicePeriod(out defaultDevicePeriod, out minimumDevicePeriod);
|
||||
return defaultDevicePeriod;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum device period (can be called before initialize)
|
||||
/// </summary>
|
||||
public long MinimumDevicePeriod
|
||||
{
|
||||
get
|
||||
{
|
||||
long defaultDevicePeriod;
|
||||
long minimumDevicePeriod;
|
||||
audioClientInterface.GetDevicePeriod(out defaultDevicePeriod, out minimumDevicePeriod);
|
||||
return minimumDevicePeriod;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: GetService:
|
||||
// IID_IAudioCaptureClient
|
||||
// IID_IAudioClock
|
||||
// IID_IAudioSessionControl
|
||||
// IID_IAudioStreamVolume
|
||||
// IID_IChannelAudioVolume
|
||||
// IID_ISimpleAudioVolume
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AudioRenderClient service
|
||||
/// </summary>
|
||||
public AudioRenderClient AudioRenderClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (audioRenderClient == null)
|
||||
{
|
||||
object audioRenderClientInterface;
|
||||
Guid audioRenderClientGuid = new Guid("F294ACFC-3146-4483-A7BF-ADDCA7C260E2");
|
||||
audioClientInterface.GetService(ref audioRenderClientGuid, out audioRenderClientInterface);
|
||||
audioRenderClient = new AudioRenderClient((IAudioRenderClient)audioRenderClientInterface);
|
||||
}
|
||||
return audioRenderClient;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AudioCaptureClient service
|
||||
/// </summary>
|
||||
public AudioCaptureClient AudioCaptureClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (audioCaptureClient == null)
|
||||
{
|
||||
object audioCaptureClientInterface;
|
||||
Guid audioCaptureClientGuid = new Guid("c8adbd64-e71e-48a0-a4de-185c395cd317");
|
||||
audioClientInterface.GetService(ref audioCaptureClientGuid, out audioCaptureClientInterface);
|
||||
audioCaptureClient = new AudioCaptureClient((IAudioCaptureClient)audioCaptureClientInterface);
|
||||
}
|
||||
return audioCaptureClient;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether if the specified output format is supported
|
||||
/// </summary>
|
||||
/// <param name="shareMode">The share mode.</param>
|
||||
/// <param name="desiredFormat">The desired format.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is format supported] [the specified share mode]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsFormatSupported(AudioClientShareMode shareMode,
|
||||
WaveFormat desiredFormat)
|
||||
{
|
||||
WaveFormatExtensible closestMatchFormat;
|
||||
return IsFormatSupported(shareMode, desiredFormat, out closestMatchFormat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specified output format is supported in shared mode
|
||||
/// </summary>
|
||||
/// <param name="shareMode">Share Mode</param>
|
||||
/// <param name="desiredFormat">Desired Format</param>
|
||||
/// <param name="closestMatchFormat">Output The closest match format.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is format supported] [the specified share mode]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat)
|
||||
{
|
||||
int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, out closestMatchFormat);
|
||||
// S_OK is 0, S_FALSE = 1
|
||||
if (hresult == 0)
|
||||
{
|
||||
// directly supported
|
||||
return true;
|
||||
}
|
||||
if (hresult == 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (hresult == (int)AudioClientErrors.UnsupportedFormat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(hresult);
|
||||
}
|
||||
// shouldn't get here
|
||||
throw new NotSupportedException("Unknown hresult " + hresult.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Starts the audio stream
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
audioClientInterface.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the audio stream.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
audioClientInterface.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Event Handle for buffer synchro.
|
||||
/// </summary>
|
||||
/// <param name="eventWaitHandle">The Wait Handle to setup</param>
|
||||
public void SetEventHandle(EventWaitHandle eventWaitHandle)
|
||||
{
|
||||
audioClientInterface.SetEventHandle(eventWaitHandle.SafeWaitHandle.DangerousGetHandle());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the audio stream
|
||||
/// Reset is a control method that the client calls to reset a stopped audio stream.
|
||||
/// Resetting the stream flushes all pending data and resets the audio clock stream
|
||||
/// position to 0. This method fails if it is called on a stream that is not stopped
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
audioClientInterface.Reset();
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (audioClientInterface != null)
|
||||
{
|
||||
if (audioRenderClient != null)
|
||||
{
|
||||
audioRenderClient.Dispose();
|
||||
audioRenderClient = null;
|
||||
}
|
||||
if (audioCaptureClient != null)
|
||||
{
|
||||
audioCaptureClient.Dispose();
|
||||
audioCaptureClient = null;
|
||||
}
|
||||
Marshal.ReleaseComObject(audioClientInterface);
|
||||
audioClientInterface = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Client Buffer Flags
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum AudioClientBufferFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// None
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
|
||||
/// </summary>
|
||||
DataDiscontinuity = 0x1,
|
||||
/// <summary>
|
||||
/// AUDCLNT_BUFFERFLAGS_SILENT
|
||||
/// </summary>
|
||||
Silent = 0x2,
|
||||
/// <summary>
|
||||
/// AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR
|
||||
/// </summary>
|
||||
TimestampError = 0x4
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// AUDCLNT_SHAREMODE
|
||||
/// </summary>
|
||||
public enum AudioClientShareMode
|
||||
{
|
||||
/// <summary>
|
||||
/// AUDCLNT_SHAREMODE_SHARED,
|
||||
/// </summary>
|
||||
Shared,
|
||||
/// <summary>
|
||||
/// AUDCLNT_SHAREMODE_EXCLUSIVE
|
||||
/// </summary>
|
||||
Exclusive,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// AUDCLNT_STREAMFLAGS
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum AudioClientStreamFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// None
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// AUDCLNT_STREAMFLAGS_CROSSPROCESS
|
||||
/// </summary>
|
||||
CrossProcess = 0x00010000,
|
||||
/// <summary>
|
||||
/// AUDCLNT_STREAMFLAGS_LOOPBACK
|
||||
/// </summary>
|
||||
Loopback = 0x00020000,
|
||||
/// <summary>
|
||||
/// AUDCLNT_STREAMFLAGS_EVENTCALLBACK
|
||||
/// </summary>
|
||||
EventCallback = 0x00040000,
|
||||
/// <summary>
|
||||
/// AUDCLNT_STREAMFLAGS_NOPERSIST
|
||||
/// </summary>
|
||||
NoPersist = 0x00080000,
|
||||
}
|
||||
}
|
||||
211
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioEndpointVolume.cs
Normal file
211
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioEndpointVolume.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume
|
||||
/// </summary>
|
||||
public class AudioEndpointVolume : IDisposable
|
||||
{
|
||||
private IAudioEndpointVolume _AudioEndPointVolume;
|
||||
private AudioEndpointVolumeChannels _Channels;
|
||||
private AudioEndpointVolumeStepInformation _StepInformation;
|
||||
private AudioEndpointVolumeVolumeRange _VolumeRange;
|
||||
private EEndpointHardwareSupport _HardwareSupport;
|
||||
private AudioEndpointVolumeCallback _CallBack;
|
||||
|
||||
/// <summary>
|
||||
/// On Volume Notification
|
||||
/// </summary>
|
||||
public event AudioEndpointVolumeNotificationDelegate OnVolumeNotification;
|
||||
|
||||
/// <summary>
|
||||
/// Volume Range
|
||||
/// </summary>
|
||||
public AudioEndpointVolumeVolumeRange VolumeRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return _VolumeRange;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hardware Support
|
||||
/// </summary>
|
||||
public EEndpointHardwareSupport HardwareSupport
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HardwareSupport;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Step Information
|
||||
/// </summary>
|
||||
public AudioEndpointVolumeStepInformation StepInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
return _StepInformation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Channels
|
||||
/// </summary>
|
||||
public AudioEndpointVolumeChannels Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Channels;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Master Volume Level
|
||||
/// </summary>
|
||||
public float MasterVolumeLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
float result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.GetMasterVolumeLevel(out result));
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.SetMasterVolumeLevel(value, Guid.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Master Volume Level Scalar
|
||||
/// </summary>
|
||||
public float MasterVolumeLevelScalar
|
||||
{
|
||||
get
|
||||
{
|
||||
float result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.GetMasterVolumeLevelScalar(out result));
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.SetMasterVolumeLevelScalar(value, Guid.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mute
|
||||
/// </summary>
|
||||
public bool Mute
|
||||
{
|
||||
get
|
||||
{
|
||||
bool result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.GetMute(out result));
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.SetMute(value, Guid.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Volume Step Up
|
||||
/// </summary>
|
||||
public void VolumeStepUp()
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.VolumeStepUp(Guid.Empty));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Volume Step Down
|
||||
/// </summary>
|
||||
public void VolumeStepDown()
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.VolumeStepDown(Guid.Empty));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Audio endpoint volume
|
||||
/// </summary>
|
||||
/// <param name="realEndpointVolume">IAudioEndpointVolume COM interface</param>
|
||||
internal AudioEndpointVolume(IAudioEndpointVolume realEndpointVolume)
|
||||
{
|
||||
uint HardwareSupp;
|
||||
|
||||
_AudioEndPointVolume = realEndpointVolume;
|
||||
_Channels = new AudioEndpointVolumeChannels(_AudioEndPointVolume);
|
||||
_StepInformation = new AudioEndpointVolumeStepInformation(_AudioEndPointVolume);
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.QueryHardwareSupport(out HardwareSupp));
|
||||
_HardwareSupport = (EEndpointHardwareSupport)HardwareSupp;
|
||||
_VolumeRange = new AudioEndpointVolumeVolumeRange(_AudioEndPointVolume);
|
||||
_CallBack = new AudioEndpointVolumeCallback(this);
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.RegisterControlChangeNotify(_CallBack));
|
||||
}
|
||||
internal void FireNotification(AudioVolumeNotificationData NotificationData)
|
||||
{
|
||||
AudioEndpointVolumeNotificationDelegate del = OnVolumeNotification;
|
||||
if (del != null)
|
||||
{
|
||||
del(NotificationData);
|
||||
}
|
||||
}
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_CallBack != null)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.UnregisterControlChangeNotify(_CallBack));
|
||||
_CallBack = null;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer
|
||||
/// </summary>
|
||||
~AudioEndpointVolume()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
// This class implements the IAudioEndpointVolumeCallback interface,
|
||||
// it is implemented in this class because implementing it on AudioEndpointVolume
|
||||
// (where the functionality is really wanted, would cause the OnNotify function
|
||||
// to show up in the public API.
|
||||
internal class AudioEndpointVolumeCallback : IAudioEndpointVolumeCallback
|
||||
{
|
||||
private AudioEndpointVolume _Parent;
|
||||
|
||||
internal AudioEndpointVolumeCallback(AudioEndpointVolume parent)
|
||||
{
|
||||
_Parent = parent;
|
||||
}
|
||||
|
||||
public void OnNotify(ref AudioVolumeNotificationDataStruct data)
|
||||
//public int OnNotify(IntPtr NotifyData)
|
||||
{
|
||||
//Since AUDIO_VOLUME_NOTIFICATION_DATA is dynamic in length based on the
|
||||
//number of audio channels available we cannot just call PtrToStructure
|
||||
//to get all data, thats why it is split up into two steps, first the static
|
||||
//data is marshalled into the data structure, then with some IntPtr math the
|
||||
//remaining floats are read from memory.
|
||||
//
|
||||
//AudioVolumeNotificationDataStruct data = (AudioVolumeNotificationDataStruct)Marshal.PtrToStructure(NotifyData, typeof(AudioVolumeNotificationDataStruct));
|
||||
|
||||
//Determine offset in structure of the first float
|
||||
//IntPtr Offset = Marshal.OffsetOf(typeof(AudioVolumeNotificationDataStruct), "ChannelVolume");
|
||||
//Determine offset in memory of the first float
|
||||
//IntPtr FirstFloatPtr = (IntPtr)((long)NotifyData + (long)Offset);
|
||||
|
||||
//float[] voldata = new float[data.nChannels];
|
||||
|
||||
//Read all floats from memory.
|
||||
//for (int i = 0; i < data.nChannels; i++)
|
||||
//{
|
||||
// voldata[i] = data.fMasterVolume;
|
||||
//}
|
||||
|
||||
//Create combined structure and Fire Event in parent class.
|
||||
AudioVolumeNotificationData NotificationData = new AudioVolumeNotificationData(data.guidEventContext, data.bMuted, data.fMasterVolume);
|
||||
_Parent.FireNotification(NotificationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume Channel
|
||||
/// </summary>
|
||||
public class AudioEndpointVolumeChannel
|
||||
{
|
||||
private uint _Channel;
|
||||
private IAudioEndpointVolume _AudioEndpointVolume;
|
||||
|
||||
internal AudioEndpointVolumeChannel(IAudioEndpointVolume parent, int channel)
|
||||
{
|
||||
_Channel = (uint)channel;
|
||||
_AudioEndpointVolume = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Volume Level
|
||||
/// </summary>
|
||||
public float VolumeLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
float result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndpointVolume.GetChannelVolumeLevel(_Channel,out result));
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndpointVolume.SetChannelVolumeLevel(_Channel, value,Guid.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Volume Level Scalar
|
||||
/// </summary>
|
||||
public float VolumeLevelScalar
|
||||
{
|
||||
get
|
||||
{
|
||||
float result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndpointVolume.GetChannelVolumeLevelScalar(_Channel, out result));
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(_AudioEndpointVolume.SetChannelVolumeLevelScalar(_Channel, value, Guid.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume Channels
|
||||
/// </summary>
|
||||
public class AudioEndpointVolumeChannels
|
||||
{
|
||||
IAudioEndpointVolume _AudioEndPointVolume;
|
||||
AudioEndpointVolumeChannel[] _Channels;
|
||||
|
||||
/// <summary>
|
||||
/// Channel Count
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int result;
|
||||
Marshal.ThrowExceptionForHR(_AudioEndPointVolume.GetChannelCount(out result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indexer - get a specific channel
|
||||
/// </summary>
|
||||
public AudioEndpointVolumeChannel this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Channels[index];
|
||||
}
|
||||
}
|
||||
|
||||
internal AudioEndpointVolumeChannels(IAudioEndpointVolume parent)
|
||||
{
|
||||
int ChannelCount;
|
||||
_AudioEndPointVolume = parent;
|
||||
|
||||
ChannelCount = Count;
|
||||
_Channels = new AudioEndpointVolumeChannel[ChannelCount];
|
||||
for (int i = 0; i < ChannelCount; i++)
|
||||
{
|
||||
_Channels[i] = new AudioEndpointVolumeChannel(_AudioEndPointVolume, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume Notifiaction Delegate
|
||||
/// </summary>
|
||||
/// <param name="data">Audio Volume Notification Data</param>
|
||||
public delegate void AudioEndpointVolumeNotificationDelegate( AudioVolumeNotificationData data);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume Step Information
|
||||
/// </summary>
|
||||
public class AudioEndpointVolumeStepInformation
|
||||
{
|
||||
private uint _Step;
|
||||
private uint _StepCount;
|
||||
internal AudioEndpointVolumeStepInformation(IAudioEndpointVolume parent)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(parent.GetVolumeStepInfo(out _Step, out _StepCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Step
|
||||
/// </summary>
|
||||
public uint Step
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Step;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// StepCount
|
||||
/// </summary>
|
||||
public uint StepCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _StepCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// modified for NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume Volume Range
|
||||
/// </summary>
|
||||
public class AudioEndpointVolumeVolumeRange
|
||||
{
|
||||
float _VolumeMindB;
|
||||
float _VolumeMaxdB;
|
||||
float _VolumeIncrementdB;
|
||||
|
||||
internal AudioEndpointVolumeVolumeRange(IAudioEndpointVolume parent)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(parent.GetVolumeRange(out _VolumeMindB,out _VolumeMaxdB,out _VolumeIncrementdB));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum Decibels
|
||||
/// </summary>
|
||||
public float MinDecibels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _VolumeMindB;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum Decibels
|
||||
/// </summary>
|
||||
public float MaxDecibels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _VolumeMaxdB;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment Decibels
|
||||
/// </summary>
|
||||
public float IncrementDecibels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _VolumeIncrementdB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Meter Information
|
||||
/// </summary>
|
||||
public class AudioMeterInformation
|
||||
{
|
||||
private IAudioMeterInformation _AudioMeterInformation;
|
||||
private EEndpointHardwareSupport _HardwareSupport;
|
||||
private AudioMeterInformationChannels _Channels;
|
||||
|
||||
internal AudioMeterInformation(IAudioMeterInformation realInterface)
|
||||
{
|
||||
int HardwareSupp;
|
||||
|
||||
_AudioMeterInformation = realInterface;
|
||||
Marshal.ThrowExceptionForHR(_AudioMeterInformation.QueryHardwareSupport(out HardwareSupp));
|
||||
_HardwareSupport = (EEndpointHardwareSupport)HardwareSupp;
|
||||
_Channels = new AudioMeterInformationChannels(_AudioMeterInformation);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Peak Values
|
||||
/// </summary>
|
||||
public AudioMeterInformationChannels PeakValues
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Channels;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hardware Support
|
||||
/// </summary>
|
||||
public EEndpointHardwareSupport HardwareSupport
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HardwareSupport;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Master Peak Value
|
||||
/// </summary>
|
||||
public float MasterPeakValue
|
||||
{
|
||||
get
|
||||
{
|
||||
float result;
|
||||
Marshal.ThrowExceptionForHR(_AudioMeterInformation.GetPeakValue(out result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Meter Information Channels
|
||||
/// </summary>
|
||||
public class AudioMeterInformationChannels
|
||||
{
|
||||
IAudioMeterInformation _AudioMeterInformation;
|
||||
|
||||
/// <summary>
|
||||
/// Metering Channel Count
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int result;
|
||||
Marshal.ThrowExceptionForHR(_AudioMeterInformation.GetMeteringChannelCount(out result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Peak value
|
||||
/// </summary>
|
||||
/// <param name="index">Channel index</param>
|
||||
/// <returns>Peak value</returns>
|
||||
public float this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] peakValues = new float[Count];
|
||||
GCHandle Params = GCHandle.Alloc(peakValues, GCHandleType.Pinned);
|
||||
Marshal.ThrowExceptionForHR(_AudioMeterInformation.GetChannelsPeakValues(peakValues.Length, Params.AddrOfPinnedObject()));
|
||||
Params.Free();
|
||||
return peakValues[index];
|
||||
}
|
||||
}
|
||||
|
||||
internal AudioMeterInformationChannels(IAudioMeterInformation parent)
|
||||
{
|
||||
_AudioMeterInformation = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioRenderClient.cs
Normal file
60
CUETools.Codecs.CoreAudio/CoreAudioApi/AudioRenderClient.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Render Client
|
||||
/// </summary>
|
||||
public class AudioRenderClient : IDisposable
|
||||
{
|
||||
IAudioRenderClient audioRenderClientInterface;
|
||||
|
||||
internal AudioRenderClient(IAudioRenderClient audioRenderClientInterface)
|
||||
{
|
||||
this.audioRenderClientInterface = audioRenderClientInterface;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a pointer to the buffer
|
||||
/// </summary>
|
||||
/// <param name="numFramesRequested">Number of frames requested</param>
|
||||
/// <returns>Pointer to the buffer</returns>
|
||||
public IntPtr GetBuffer(int numFramesRequested)
|
||||
{
|
||||
return audioRenderClientInterface.GetBuffer(numFramesRequested);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release buffer
|
||||
/// </summary>
|
||||
/// <param name="numFramesWritten">Number of frames written</param>
|
||||
/// <param name="bufferFlags">Buffer flags</param>
|
||||
public void ReleaseBuffer(int numFramesWritten,AudioClientBufferFlags bufferFlags)
|
||||
{
|
||||
audioRenderClientInterface.ReleaseBuffer(numFramesWritten, bufferFlags);
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Release the COM object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (audioRenderClientInterface != null)
|
||||
{
|
||||
// althugh GC would do this for us, we want it done now
|
||||
// to let us reopen WASAPI
|
||||
Marshal.ReleaseComObject(audioRenderClientInterface);
|
||||
audioRenderClientInterface = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Volume Notification Data
|
||||
/// </summary>
|
||||
public class AudioVolumeNotificationData
|
||||
{
|
||||
private Guid _EventContext;
|
||||
private bool _Muted;
|
||||
private float _MasterVolume;
|
||||
private int _Channels;
|
||||
private float[] _ChannelVolume;
|
||||
|
||||
/// <summary>
|
||||
/// Event Context
|
||||
/// </summary>
|
||||
public Guid EventContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return _EventContext;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Muted
|
||||
/// </summary>
|
||||
public bool Muted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Muted;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Master Volume
|
||||
/// </summary>
|
||||
public float MasterVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
return _MasterVolume;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Channels
|
||||
/// </summary>
|
||||
public int Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Channels;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Channel Volume
|
||||
/// </summary>
|
||||
public float[] ChannelVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ChannelVolume;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Audio Volume Notification Data
|
||||
/// </summary>
|
||||
/// <param name="eventContext"></param>
|
||||
/// <param name="muted"></param>
|
||||
/// <param name="masterVolume"></param>
|
||||
/// <param name="channelVolume"></param>
|
||||
public AudioVolumeNotificationData(Guid eventContext, bool muted, float masterVolume, float[] channelVolume)
|
||||
{
|
||||
_EventContext = eventContext;
|
||||
_Muted = muted;
|
||||
_MasterVolume = masterVolume;
|
||||
_Channels = channelVolume.Length;
|
||||
_ChannelVolume = channelVolume;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Audio Volume Notification Data
|
||||
/// </summary>
|
||||
/// <param name="eventContext"></param>
|
||||
/// <param name="muted"></param>
|
||||
/// <param name="masterVolume"></param>
|
||||
/// <param name="channels"></param>
|
||||
public AudioVolumeNotificationData(Guid eventContext, bool muted, float masterVolume)
|
||||
{
|
||||
_EventContext = eventContext;
|
||||
_Muted = muted;
|
||||
_MasterVolume = masterVolume;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
CUETools.Codecs.CoreAudio/CoreAudioApi/DataFlow.cs
Normal file
31
CUETools.Codecs.CoreAudio/CoreAudioApi/DataFlow.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// The EDataFlow enumeration defines constants that indicate the direction
|
||||
/// in which audio data flows between an audio endpoint device and an application
|
||||
/// </summary>
|
||||
public enum DataFlow
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio rendering stream.
|
||||
/// Audio data flows from the application to the audio endpoint device, which renders the stream.
|
||||
/// </summary>
|
||||
Render,
|
||||
/// <summary>
|
||||
/// Audio capture stream. Audio data flows from the audio endpoint device that captures the stream,
|
||||
/// to the application
|
||||
/// </summary>
|
||||
Capture,
|
||||
/// <summary>
|
||||
/// Audio rendering or capture stream. Audio data can flow either from the application to the audio
|
||||
/// endpoint device, or from the audio endpoint device to the application.
|
||||
/// </summary>
|
||||
All
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
52
CUETools.Codecs.CoreAudio/CoreAudioApi/DeviceState.cs
Normal file
52
CUETools.Codecs.CoreAudio/CoreAudioApi/DeviceState.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// adapted for NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Device State
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DeviceState
|
||||
{
|
||||
/// <summary>
|
||||
/// DEVICE_STATE_ACTIVE
|
||||
/// </summary>
|
||||
Active = 0x00000001,
|
||||
/// <summary>
|
||||
/// DEVICE_STATE_UNPLUGGED
|
||||
/// </summary>
|
||||
Unplugged = 0x00000002,
|
||||
/// <summary>
|
||||
/// DEVICE_STATE_NOTPRESENT
|
||||
/// </summary>
|
||||
NotPresent = 0x00000004,
|
||||
/// <summary>
|
||||
/// DEVICE_STATEMASK_ALL
|
||||
/// </summary>
|
||||
All = 0x00000007
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Endpoint Hardware Support
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum EEndpointHardwareSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Volume
|
||||
/// </summary>
|
||||
Volume = 0x00000001,
|
||||
/// <summary>
|
||||
/// Mute
|
||||
/// </summary>
|
||||
Mute = 0x00000002,
|
||||
/// <summary>
|
||||
/// Meter
|
||||
/// </summary>
|
||||
Meter = 0x00000004
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
internal struct AudioVolumeNotificationDataStruct
|
||||
{
|
||||
public Guid guidEventContext;
|
||||
public bool bMuted;
|
||||
public float fMasterVolume;
|
||||
public uint nChannels;
|
||||
public float ChannelVolume;
|
||||
|
||||
//Code Should Compile at warning level4 without any warnings,
|
||||
//However this struct will give us Warning CS0649: Field [Fieldname]
|
||||
//is never assigned to, and will always have its default value
|
||||
//You can disable CS0649 in the project options but that will disable
|
||||
//the warning for the whole project, it's a nice warning and we do want
|
||||
//it in other places so we make a nice dummy function to keep the compiler
|
||||
//happy.
|
||||
private void FixCS0649()
|
||||
{
|
||||
guidEventContext = Guid.Empty;
|
||||
bMuted = false;
|
||||
fMasterVolume = 0;
|
||||
nChannels = 0;
|
||||
ChannelVolume = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
49
CUETools.Codecs.CoreAudio/CoreAudioApi/Interfaces/Blob.cs
Normal file
49
CUETools.Codecs.CoreAudio/CoreAudioApi/Interfaces/Blob.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// Adapted for NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
internal struct Blob
|
||||
{
|
||||
public int Length;
|
||||
public IntPtr Data;
|
||||
|
||||
//Code Should Compile at warning level4 without any warnings,
|
||||
//However this struct will give us Warning CS0649: Field [Fieldname]
|
||||
//is never assigned to, and will always have its default value
|
||||
//You can disable CS0649 in the project options but that will disable
|
||||
//the warning for the whole project, it's a nice warning and we do want
|
||||
//it in other places so we make a nice dummy function to keep the compiler
|
||||
//happy.
|
||||
private void FixCS0649()
|
||||
{
|
||||
Length = 0;
|
||||
Data = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
CUETools.Codecs.CoreAudio/CoreAudioApi/Interfaces/ClsCtx.cs
Normal file
39
CUETools.Codecs.CoreAudio/CoreAudioApi/Interfaces/ClsCtx.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// is defined in WTypes.h
|
||||
/// </summary>
|
||||
[Flags]
|
||||
enum ClsCtx
|
||||
{
|
||||
INPROC_SERVER = 0x1,
|
||||
INPROC_HANDLER = 0x2,
|
||||
LOCAL_SERVER = 0x4,
|
||||
INPROC_SERVER16 = 0x8,
|
||||
REMOTE_SERVER = 0x10,
|
||||
INPROC_HANDLER16 = 0x20,
|
||||
//RESERVED1 = 0x40,
|
||||
//RESERVED2 = 0x80,
|
||||
//RESERVED3 = 0x100,
|
||||
//RESERVED4 = 0x200,
|
||||
NO_CODE_DOWNLOAD = 0x400,
|
||||
//RESERVED5 = 0x800,
|
||||
NO_CUSTOM_MARSHAL = 0x1000,
|
||||
ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
NO_FAILURE_LOG = 0x4000,
|
||||
DISABLE_AAA = 0x8000,
|
||||
ENABLE_AAA = 0x10000,
|
||||
FROM_DEFAULT_CONTEXT = 0x20000,
|
||||
ACTIVATE_32_BIT_SERVER = 0x40000,
|
||||
ACTIVATE_64_BIT_SERVER = 0x80000,
|
||||
ENABLE_CLOAKING = 0x100000,
|
||||
PS_DLL = unchecked ( (int) 0x80000000 ),
|
||||
INPROC = INPROC_SERVER | INPROC_HANDLER,
|
||||
SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
|
||||
ALL = SERVER | INPROC_HANDLER
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
enum AudioClientErrors
|
||||
{
|
||||
/// <summary>
|
||||
/// AUDCLNT_E_NOT_INITIALIZED
|
||||
/// </summary>
|
||||
NotInitialized = unchecked((int)0x88890001),
|
||||
/// <summary>
|
||||
/// AUDCLNT_E_UNSUPPORTED_FORMAT
|
||||
/// </summary>
|
||||
UnsupportedFormat = unchecked((int)0x88890008),
|
||||
/// <summary>
|
||||
/// AUDCLNT_E_DEVICE_IN_USE
|
||||
/// </summary>
|
||||
DeviceInUse = unchecked((int)0x8889000A),
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
|
||||
|
||||
[Guid("C8ADBD64-E71E-48a0-A4DE-185C395CD317"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IAudioCaptureClient
|
||||
{
|
||||
/*HRESULT GetBuffer(
|
||||
BYTE** ppData,
|
||||
UINT32* pNumFramesToRead,
|
||||
DWORD* pdwFlags,
|
||||
UINT64* pu64DevicePosition,
|
||||
UINT64* pu64QPCPosition
|
||||
);*/
|
||||
|
||||
int GetBuffer(
|
||||
out IntPtr dataBuffer,
|
||||
out int numFramesToRead,
|
||||
out AudioClientBufferFlags bufferFlags,
|
||||
out long devicePosition,
|
||||
out long qpcPosition);
|
||||
|
||||
int ReleaseBuffer(int numFramesRead);
|
||||
|
||||
int GetNextPacketSize(out int numFramesInNextPacket);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.Wave;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// n.b. WORK IN PROGRESS - this code will probably do nothing but crash at the moment
|
||||
/// Defined in AudioClient.h
|
||||
/// </summary>
|
||||
[Guid("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IAudioClient
|
||||
{
|
||||
void Initialize(AudioClientShareMode shareMode,
|
||||
AudioClientStreamFlags StreamFlags,
|
||||
long hnsBufferDuration, // REFERENCE_TIME
|
||||
long hnsPeriodicity, // REFERENCE_TIME
|
||||
[In] WaveFormat pFormat,
|
||||
[In] ref Guid AudioSessionGuid);
|
||||
|
||||
/// <summary>
|
||||
/// The GetBufferSize method retrieves the size (maximum capacity) of the endpoint buffer.
|
||||
/// </summary>
|
||||
void GetBufferSize(out uint bufferSize);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.I8)]
|
||||
long GetStreamLatency();
|
||||
|
||||
void GetCurrentPadding(out int currentPadding);
|
||||
|
||||
[PreserveSig]
|
||||
int IsFormatSupported(
|
||||
AudioClientShareMode shareMode,
|
||||
[In] WaveFormat pFormat,
|
||||
[Out, MarshalAs(UnmanagedType.LPStruct)] out WaveFormatExtensible closestMatchFormat);
|
||||
|
||||
void GetMixFormat(out IntPtr deviceFormatPointer);
|
||||
|
||||
// REFERENCE_TIME is 64 bit int
|
||||
void GetDevicePeriod(out long defaultDevicePeriod, out long minimumDevicePeriod);
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
void Reset();
|
||||
|
||||
void SetEventHandle(IntPtr eventHandle);
|
||||
|
||||
void GetService(ref Guid interfaceId, [MarshalAs(UnmanagedType.IUnknown)] out object interfacePointer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IAudioEndpointVolume
|
||||
{
|
||||
int RegisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
|
||||
int UnregisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
|
||||
int GetChannelCount(out int pnChannelCount);
|
||||
int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
|
||||
int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
|
||||
int GetMasterVolumeLevel(out float pfLevelDB);
|
||||
int GetMasterVolumeLevelScalar(out float pfLevel);
|
||||
int SetChannelVolumeLevel(uint nChannel, float fLevelDB, Guid pguidEventContext);
|
||||
int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, Guid pguidEventContext);
|
||||
int GetChannelVolumeLevel(uint nChannel, out float pfLevelDB);
|
||||
int GetChannelVolumeLevelScalar(uint nChannel, out float pfLevel);
|
||||
int SetMute([MarshalAs(UnmanagedType.Bool)] Boolean bMute, Guid pguidEventContext);
|
||||
int GetMute(out bool pbMute);
|
||||
int GetVolumeStepInfo(out uint pnStep, out uint pnStepCount);
|
||||
int VolumeStepUp(Guid pguidEventContext);
|
||||
int VolumeStepDown(Guid pguidEventContext);
|
||||
int QueryHardwareSupport(out uint pdwHardwareSupportMask);
|
||||
int GetVolumeRange(out float pflVolumeMindB, out float pflVolumeMaxdB, out float pflVolumeIncrementdB);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("657804FA-D6AD-4496-8A60-352752AF4F89"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IAudioEndpointVolumeCallback
|
||||
{
|
||||
//int OnNotify(IntPtr NotifyData);
|
||||
void OnNotify(ref AudioVolumeNotificationDataStruct pNotifyData);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IAudioMeterInformation
|
||||
{
|
||||
int GetPeakValue(out float pfPeak);
|
||||
int GetMeteringChannelCount(out int pnChannelCount);
|
||||
int GetChannelsPeakValues(int u32ChannelCount, [In] IntPtr afPeakValues);
|
||||
int QueryHardwareSupport(out int pdwHardwareSupportMask);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("F294ACFC-3146-4483-A7BF-ADDCA7C260E2"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IAudioRenderClient
|
||||
{
|
||||
IntPtr GetBuffer(int numFramesRequested);
|
||||
void ReleaseBuffer(int numFramesWritten, AudioClientBufferFlags bufferFlags);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("D666063F-1587-4E43-81F1-B948E807363F"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IMMDevice
|
||||
{
|
||||
// activationParams is a propvariant
|
||||
int Activate(ref Guid id, ClsCtx clsCtx, IntPtr activationParams,
|
||||
[MarshalAs(UnmanagedType.IUnknown)] out object interfacePointer);
|
||||
|
||||
int OpenPropertyStore(StorageAccessMode stgmAccess, out IPropertyStore properties);
|
||||
|
||||
int GetId(out string id);
|
||||
|
||||
int GetState(out DeviceState state);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IMMDeviceCollection
|
||||
{
|
||||
int GetCount(out int numDevices);
|
||||
int Item(int deviceNumber, out IMMDevice device);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IMMDeviceEnumerator
|
||||
{
|
||||
int EnumAudioEndpoints(DataFlow dataFlow, DeviceState stateMask,
|
||||
out IMMDeviceCollection devices);
|
||||
|
||||
int GetDefaultAudioEndpoint(DataFlow dataFlow, Role role, out IMMDevice endpoint);
|
||||
|
||||
int GetDevice(string id, out IMMDevice deviceName);
|
||||
|
||||
int RegisterEndpointNotificationCallback(IMMNotificationClient client);
|
||||
|
||||
int UnregisterEndpointNotificationCallback(IMMNotificationClient client);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// defined in MMDeviceAPI.h
|
||||
/// </summary>
|
||||
[Guid("1BE09788-6894-4089-8586-9A2A6C265AC5"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IMMEndpoint
|
||||
{
|
||||
int GetDataFlow(out DataFlow dataFlow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
[Guid("7991EEC9-7E89-4D85-8390-6C703CEC60C0"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IMMNotificationClient
|
||||
{
|
||||
int OnDeviceStateChanged(string deviceId, int newState);
|
||||
|
||||
int OnDeviceAdded(string pwstrDeviceId);
|
||||
|
||||
int OnDeviceRemoved(string deviceId);
|
||||
|
||||
int OnDefaultDeviceChanged(DataFlow flow, Role role, string defaultDeviceId);
|
||||
|
||||
int OnPropertyValueChanged(string pwstrDeviceId, PropertyKey key);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// is defined in propsys.h
|
||||
/// </summary>
|
||||
[Guid("886d8eeb-8cf2-4446-8d02-cdba1dbdcf99"),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
interface IPropertyStore
|
||||
{
|
||||
int GetCount(out int propCount);
|
||||
int GetAt(int property, out PropertyKey key);
|
||||
int GetValue(ref PropertyKey key, out PropVariant value);
|
||||
int SetValue(ref PropertyKey key, ref PropVariant value);
|
||||
int Commit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// implements IMMDeviceEnumerator
|
||||
/// </summary>
|
||||
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
|
||||
class MMDeviceEnumeratorComObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// MMDevice STGM enumeration
|
||||
/// </summary>
|
||||
enum StorageAccessMode
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
}
|
||||
}
|
||||
219
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDevice.cs
Normal file
219
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDevice.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// modified for NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// MM Device
|
||||
/// </summary>
|
||||
public class MMDevice
|
||||
{
|
||||
#region Variables
|
||||
private IMMDevice deviceInterface;
|
||||
private PropertyStore _PropertyStore;
|
||||
private AudioMeterInformation _AudioMeterInformation;
|
||||
private AudioEndpointVolume _AudioEndpointVolume;
|
||||
private AudioClient audioClient;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Guids
|
||||
private static Guid IID_IAudioMeterInformation = new Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064");
|
||||
private static Guid IID_IAudioEndpointVolume = new Guid("5CDF2C82-841E-4546-9722-0CF74078229A");
|
||||
private static Guid IID_IAudioClient = new Guid("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2");
|
||||
#endregion
|
||||
|
||||
#region Init
|
||||
private void GetPropertyInformation()
|
||||
{
|
||||
IPropertyStore propstore;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.OpenPropertyStore(StorageAccessMode.Read, out propstore));
|
||||
_PropertyStore = new PropertyStore(propstore);
|
||||
}
|
||||
|
||||
private void GetAudioClientInterface()
|
||||
{
|
||||
object result;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.Activate(ref IID_IAudioClient, ClsCtx.ALL, IntPtr.Zero, out result));
|
||||
audioClient = new AudioClient(result as IAudioClient);
|
||||
}
|
||||
|
||||
private void GetAudioMeterInformation()
|
||||
{
|
||||
object result;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.Activate(ref IID_IAudioMeterInformation, ClsCtx.ALL, IntPtr.Zero, out result));
|
||||
_AudioMeterInformation = new AudioMeterInformation(result as IAudioMeterInformation);
|
||||
}
|
||||
|
||||
private void GetAudioEndpointVolume()
|
||||
{
|
||||
object result;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.Activate(ref IID_IAudioEndpointVolume, ClsCtx.ALL, IntPtr.Zero, out result));
|
||||
_AudioEndpointVolume = new AudioEndpointVolume(result as IAudioEndpointVolume);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Audio Client
|
||||
/// </summary>
|
||||
public AudioClient AudioClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (audioClient == null)
|
||||
{
|
||||
GetAudioClientInterface();
|
||||
}
|
||||
return audioClient;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Audio Meter Information
|
||||
/// </summary>
|
||||
public AudioMeterInformation AudioMeterInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_AudioMeterInformation == null)
|
||||
GetAudioMeterInformation();
|
||||
|
||||
return _AudioMeterInformation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Audio Endpoint Volume
|
||||
/// </summary>
|
||||
public AudioEndpointVolume AudioEndpointVolume
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_AudioEndpointVolume == null)
|
||||
GetAudioEndpointVolume();
|
||||
|
||||
return _AudioEndpointVolume;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Properties
|
||||
/// </summary>
|
||||
public PropertyStore Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_PropertyStore == null)
|
||||
GetPropertyInformation();
|
||||
return _PropertyStore;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Friendly name
|
||||
/// </summary>
|
||||
public string FriendlyName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_PropertyStore == null)
|
||||
{
|
||||
GetPropertyInformation();
|
||||
}
|
||||
if (_PropertyStore.Contains(PropertyKeys.PKEY_DeviceInterface_FriendlyName))
|
||||
{
|
||||
return (string)_PropertyStore[PropertyKeys.PKEY_DeviceInterface_FriendlyName].Value;
|
||||
}
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Device ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
get
|
||||
{
|
||||
string Result;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.GetId(out Result));
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data Flow
|
||||
/// </summary>
|
||||
public DataFlow DataFlow
|
||||
{
|
||||
get
|
||||
{
|
||||
DataFlow Result;
|
||||
IMMEndpoint ep = deviceInterface as IMMEndpoint;
|
||||
ep.GetDataFlow(out Result);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Device State
|
||||
/// </summary>
|
||||
public DeviceState State
|
||||
{
|
||||
get
|
||||
{
|
||||
DeviceState Result;
|
||||
Marshal.ThrowExceptionForHR(deviceInterface.GetState(out Result));
|
||||
return Result;
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
internal MMDevice(IMMDevice realDevice)
|
||||
{
|
||||
deviceInterface = realDevice;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// To string
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return FriendlyName;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
96
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDeviceCollection.cs
Normal file
96
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDeviceCollection.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// updated for NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Multimedia Device Collection
|
||||
/// </summary>
|
||||
public class MMDeviceCollection : IEnumerable<MMDevice>
|
||||
{
|
||||
private IMMDeviceCollection _MMDeviceCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Device count
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int result;
|
||||
Marshal.ThrowExceptionForHR(_MMDeviceCollection.GetCount(out result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get device by index
|
||||
/// </summary>
|
||||
/// <param name="index">Device index</param>
|
||||
/// <returns>Device at the specified index</returns>
|
||||
public MMDevice this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
IMMDevice result;
|
||||
_MMDeviceCollection.Item(index, out result);
|
||||
return new MMDevice(result);
|
||||
}
|
||||
}
|
||||
|
||||
internal MMDeviceCollection(IMMDeviceCollection parent)
|
||||
{
|
||||
_MMDeviceCollection = parent;
|
||||
}
|
||||
|
||||
#region IEnumerable<MMDevice> Members
|
||||
|
||||
/// <summary>
|
||||
/// Get Enumerator
|
||||
/// </summary>
|
||||
/// <returns>Device enumerator</returns>
|
||||
public IEnumerator<MMDevice> GetEnumerator()
|
||||
{
|
||||
for (int index = 0; index < Count; index++)
|
||||
{
|
||||
yield return this[index];
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
89
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDeviceEnumerator.cs
Normal file
89
CUETools.Codecs.CoreAudio/CoreAudioApi/MMDeviceEnumerator.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// updated for use in NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// MM Device Enumerator
|
||||
/// </summary>
|
||||
public class MMDeviceEnumerator
|
||||
{
|
||||
private IMMDeviceEnumerator _realEnumerator;
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate Audio Endpoints
|
||||
/// </summary>
|
||||
/// <param name="dataFlow">Desired DataFlow</param>
|
||||
/// <param name="dwStateMask">State Mask</param>
|
||||
/// <returns>Device Collection</returns>
|
||||
public MMDeviceCollection EnumerateAudioEndPoints(DataFlow dataFlow, DeviceState dwStateMask)
|
||||
{
|
||||
IMMDeviceCollection result;
|
||||
Marshal.ThrowExceptionForHR(_realEnumerator.EnumAudioEndpoints(dataFlow, dwStateMask, out result));
|
||||
return new MMDeviceCollection(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Default Endpoint
|
||||
/// </summary>
|
||||
/// <param name="dataFlow">Data Flow</param>
|
||||
/// <param name="role">Role</param>
|
||||
/// <returns>Device</returns>
|
||||
public MMDevice GetDefaultAudioEndpoint(DataFlow dataFlow, Role role)
|
||||
{
|
||||
IMMDevice _Device = null;
|
||||
Marshal.ThrowExceptionForHR(((IMMDeviceEnumerator)_realEnumerator).GetDefaultAudioEndpoint(dataFlow, role, out _Device));
|
||||
return new MMDevice(_Device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get device by ID
|
||||
/// </summary>
|
||||
/// <param name="ID">Device ID</param>
|
||||
/// <returns>Device</returns>
|
||||
public MMDevice GetDevice(string ID)
|
||||
{
|
||||
IMMDevice _Device = null;
|
||||
Marshal.ThrowExceptionForHR(((IMMDeviceEnumerator)_realEnumerator).GetDevice(ID, out _Device));
|
||||
return new MMDevice(_Device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new MM Device Enumerator
|
||||
/// </summary>
|
||||
public MMDeviceEnumerator()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major < 6)
|
||||
{
|
||||
throw new NotSupportedException("This functionality is only supported on Windows Vista or newer.");
|
||||
}
|
||||
_realEnumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
|
||||
}
|
||||
}
|
||||
}
|
||||
157
CUETools.Codecs.CoreAudio/CoreAudioApi/PropVariant.cs
Normal file
157
CUETools.Codecs.CoreAudio/CoreAudioApi/PropVariant.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// adapted for use in NAudio
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// from Propidl.h.
|
||||
/// http://msdn.microsoft.com/en-us/library/aa380072(VS.85).aspx
|
||||
/// contains a union so we have to do an explicit layout
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct PropVariant
|
||||
{
|
||||
[FieldOffset(0)] short vt;
|
||||
[FieldOffset(2)] short wReserved1;
|
||||
[FieldOffset(4)] short wReserved2;
|
||||
[FieldOffset(6)] short wReserved3;
|
||||
[FieldOffset(8)] sbyte cVal;
|
||||
[FieldOffset(8)] byte bVal;
|
||||
[FieldOffset(8)] short iVal;
|
||||
[FieldOffset(8)] ushort uiVal;
|
||||
[FieldOffset(8)] int lVal;
|
||||
[FieldOffset(8)] uint ulVal;
|
||||
[FieldOffset(8)] int intVal;
|
||||
[FieldOffset(8)] uint uintVal;
|
||||
[FieldOffset(8)] long hVal;
|
||||
[FieldOffset(8)] long uhVal;
|
||||
[FieldOffset(8)] float fltVal;
|
||||
[FieldOffset(8)] double dblVal;
|
||||
[FieldOffset(8)] bool boolVal;
|
||||
[FieldOffset(8)] int scode;
|
||||
//CY cyVal;
|
||||
[FieldOffset(8)] DateTime date;
|
||||
[FieldOffset(8)] System.Runtime.InteropServices.ComTypes.FILETIME filetime;
|
||||
//CLSID* puuid;
|
||||
//CLIPDATA* pclipdata;
|
||||
//BSTR bstrVal;
|
||||
//BSTRBLOB bstrblobVal;
|
||||
[FieldOffset(8)] Blob blobVal;
|
||||
//LPSTR pszVal;
|
||||
[FieldOffset(8)] IntPtr pwszVal; //LPWSTR
|
||||
//IUnknown* punkVal;
|
||||
/*IDispatch* pdispVal;
|
||||
IStream* pStream;
|
||||
IStorage* pStorage;
|
||||
LPVERSIONEDSTREAM pVersionedStream;
|
||||
LPSAFEARRAY parray;
|
||||
CAC cac;
|
||||
CAUB caub;
|
||||
CAI cai;
|
||||
CAUI caui;
|
||||
CAL cal;
|
||||
CAUL caul;
|
||||
CAH cah;
|
||||
CAUH cauh;
|
||||
CAFLT caflt;
|
||||
CADBL cadbl;
|
||||
CABOOL cabool;
|
||||
CASCODE cascode;
|
||||
CACY cacy;
|
||||
CADATE cadate;
|
||||
CAFILETIME cafiletime;
|
||||
CACLSID cauuid;
|
||||
CACLIPDATA caclipdata;
|
||||
CABSTR cabstr;
|
||||
CABSTRBLOB cabstrblob;
|
||||
CALPSTR calpstr;
|
||||
CALPWSTR calpwstr;
|
||||
CAPROPVARIANT capropvar;
|
||||
CHAR* pcVal;
|
||||
UCHAR* pbVal;
|
||||
SHORT* piVal;
|
||||
USHORT* puiVal;
|
||||
LONG* plVal;
|
||||
ULONG* pulVal;
|
||||
INT* pintVal;
|
||||
UINT* puintVal;
|
||||
FLOAT* pfltVal;
|
||||
DOUBLE* pdblVal;
|
||||
VARIANT_BOOL* pboolVal;
|
||||
DECIMAL* pdecVal;
|
||||
SCODE* pscode;
|
||||
CY* pcyVal;
|
||||
DATE* pdate;
|
||||
BSTR* pbstrVal;
|
||||
IUnknown** ppunkVal;
|
||||
IDispatch** ppdispVal;
|
||||
LPSAFEARRAY* pparray;
|
||||
PROPVARIANT* pvarVal;
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to gets blob data
|
||||
/// </summary>
|
||||
byte[] GetBlob()
|
||||
{
|
||||
byte[] Result = new byte[blobVal.Length];
|
||||
Marshal.Copy(blobVal.Data, Result, 0, Result.Length);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property value
|
||||
/// </summary>
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
VarEnum ve = (VarEnum)vt;
|
||||
switch (ve)
|
||||
{
|
||||
case VarEnum.VT_I1:
|
||||
return bVal;
|
||||
case VarEnum.VT_I2:
|
||||
return iVal;
|
||||
case VarEnum.VT_I4:
|
||||
return lVal;
|
||||
case VarEnum.VT_I8:
|
||||
return hVal;
|
||||
case VarEnum.VT_INT:
|
||||
return iVal;
|
||||
case VarEnum.VT_UI4:
|
||||
return ulVal;
|
||||
case VarEnum.VT_LPWSTR:
|
||||
return Marshal.PtrToStringUni(pwszVal);
|
||||
case VarEnum.VT_BLOB:
|
||||
return GetBlob();
|
||||
}
|
||||
throw new NotImplementedException("PropVariant " + ve.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyKey.cs
Normal file
21
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyKey.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// PROPERTYKEY is defined in wtypes.h
|
||||
/// </summary>
|
||||
public struct PropertyKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Format ID
|
||||
/// </summary>
|
||||
public Guid formatId;
|
||||
/// <summary>
|
||||
/// Property ID
|
||||
/// </summary>
|
||||
public int propertyId;
|
||||
}
|
||||
}
|
||||
71
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyKeys.cs
Normal file
71
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyKeys.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Property Keys
|
||||
/// </summary>
|
||||
public static class PropertyKeys
|
||||
{
|
||||
/// <summary>
|
||||
/// PKEY_DeviceInterface_FriendlyName
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_DeviceInterface_FriendlyName = new Guid(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_FormFactor
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_FormFactor = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_ControlPanelPageProvider
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_ControlPanelPageProvider = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_Association
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_Association = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_PhysicalSpeakers
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_PhysicalSpeakers = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_GUID
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_GUID = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_Disable_SysFx
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_Disable_SysFx = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEndpoint_FullRangeSpeakers
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEndpoint_FullRangeSpeakers = new Guid(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e);
|
||||
/// <summary>
|
||||
/// PKEY_AudioEngine_DeviceFormat
|
||||
/// </summary>
|
||||
public static readonly Guid PKEY_AudioEngine_DeviceFormat = new Guid(0xf19f064d, 0x82c, 0x4e27, 0xbc, 0x73, 0x68, 0x82, 0xa1, 0xbb, 0x8e, 0x4c);
|
||||
|
||||
}
|
||||
}
|
||||
143
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyStore.cs
Normal file
143
CUETools.Codecs.CoreAudio/CoreAudioApi/PropertyStore.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// this version modified for NAudio from Ray Molenkamp's original
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Property Store class, only supports reading properties at the moment.
|
||||
/// </summary>
|
||||
public class PropertyStore
|
||||
{
|
||||
private IPropertyStore storeInterface;
|
||||
|
||||
/// <summary>
|
||||
/// Property Count
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int result;
|
||||
Marshal.ThrowExceptionForHR(storeInterface.GetCount(out result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets property by index
|
||||
/// </summary>
|
||||
/// <param name="index">Property index</param>
|
||||
/// <returns>The property</returns>
|
||||
public PropertyStoreProperty this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
PropVariant result;
|
||||
PropertyKey key = Get(index);
|
||||
Marshal.ThrowExceptionForHR(storeInterface.GetValue(ref key, out result));
|
||||
return new PropertyStoreProperty(key, result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains property guid
|
||||
/// </summary>
|
||||
/// <param name="guid">Looks for a specific Guid</param>
|
||||
/// <returns>True if found</returns>
|
||||
public bool Contains(Guid guid)
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
PropertyKey key = Get(i);
|
||||
if (key.formatId == guid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indexer by guid
|
||||
/// </summary>
|
||||
/// <param name="guid">Property guid</param>
|
||||
/// <returns>Property or null if not found</returns>
|
||||
public PropertyStoreProperty this[Guid guid]
|
||||
{
|
||||
get
|
||||
{
|
||||
PropVariant result;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
PropertyKey key = Get(i);
|
||||
if (key.formatId == guid)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(storeInterface.GetValue(ref key, out result));
|
||||
return new PropertyStoreProperty(key, result);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets property key at sepecified index
|
||||
/// </summary>
|
||||
/// <param name="index">Index</param>
|
||||
/// <returns>Property key</returns>
|
||||
public PropertyKey Get(int index)
|
||||
{
|
||||
PropertyKey key;
|
||||
Marshal.ThrowExceptionForHR(storeInterface.GetAt(index, out key));
|
||||
return key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets property value at specified index
|
||||
/// </summary>
|
||||
/// <param name="index">Index</param>
|
||||
/// <returns>Property value</returns>
|
||||
public PropVariant GetValue(int index)
|
||||
{
|
||||
PropVariant result;
|
||||
PropertyKey key = Get(index);
|
||||
Marshal.ThrowExceptionForHR(storeInterface.GetValue(ref key, out result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new property store
|
||||
/// </summary>
|
||||
/// <param name="store">IPropertyStore COM interface</param>
|
||||
internal PropertyStore(IPropertyStore store)
|
||||
{
|
||||
this.storeInterface = store;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
LICENSE
|
||||
-------
|
||||
Copyright (C) 2007 Ray Molenkamp
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this source code or the software it produces.
|
||||
|
||||
Permission is granted to anyone to use this source code for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
// modified from Ray Molenkamp's original
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.CoreAudioApi.Interfaces;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Property Store Property
|
||||
/// </summary>
|
||||
public class PropertyStoreProperty
|
||||
{
|
||||
private PropertyKey propertyKey;
|
||||
private PropVariant propertyValue;
|
||||
|
||||
internal PropertyStoreProperty(PropertyKey key, PropVariant value)
|
||||
{
|
||||
propertyKey = key;
|
||||
propertyValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property Key
|
||||
/// </summary>
|
||||
public PropertyKey Key
|
||||
{
|
||||
get
|
||||
{
|
||||
return propertyKey;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property Value
|
||||
/// </summary>
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return propertyValue.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
CUETools.Codecs.CoreAudio/CoreAudioApi/Role.cs
Normal file
26
CUETools.Codecs.CoreAudio/CoreAudioApi/Role.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// The ERole enumeration defines constants that indicate the role
|
||||
/// that the system has assigned to an audio endpoint device
|
||||
/// </summary>
|
||||
public enum Role
|
||||
{
|
||||
/// <summary>
|
||||
/// Games, system notification sounds, and voice commands.
|
||||
/// </summary>
|
||||
Console,
|
||||
/// <summary>
|
||||
/// Music, movies, narration, and live music recording
|
||||
/// </summary>
|
||||
Multimedia,
|
||||
/// <summary>
|
||||
/// Voice communications (talking to another person).
|
||||
/// </summary>
|
||||
Communications,
|
||||
}
|
||||
}
|
||||
216
CUETools.Codecs.CoreAudio/CoreAudioApi/WasapiCapture.cs
Normal file
216
CUETools.Codecs.CoreAudio/CoreAudioApi/WasapiCapture.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NAudio.Wave;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.CoreAudioApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Capture using Wasapi
|
||||
/// See http://msdn.microsoft.com/en-us/library/dd370800%28VS.85%29.aspx
|
||||
/// </summary>
|
||||
public class WasapiCapture : IWaveIn
|
||||
{
|
||||
private const long REFTIMES_PER_SEC = 10000000;
|
||||
private const long REFTIMES_PER_MILLISEC = 10000;
|
||||
private volatile bool stop;
|
||||
private byte[] recordBuffer;
|
||||
private Thread captureThread;
|
||||
private AudioClient audioClient;
|
||||
private int bytesPerFrame;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates recorded data is available
|
||||
/// </summary>
|
||||
public event EventHandler<WaveInEventArgs> DataAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that all recorded data has now been received.
|
||||
/// </summary>
|
||||
public event EventHandler RecordingStopped;
|
||||
|
||||
/// <summary>
|
||||
/// Initialises a new instance of the WASAPI capture class
|
||||
/// </summary>
|
||||
public WasapiCapture() :
|
||||
this(GetDefaultCaptureDevice())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialises a new instance of the WASAPI capture class
|
||||
/// </summary>
|
||||
/// <param name="captureDevice">Capture device to use</param>
|
||||
public WasapiCapture(MMDevice captureDevice)
|
||||
{
|
||||
this.audioClient = captureDevice.AudioClient;
|
||||
WaveFormat = audioClient.MixFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recording wave format
|
||||
/// </summary>
|
||||
public WaveFormat WaveFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default audio capture device
|
||||
/// </summary>
|
||||
/// <returns>The default audio capture device</returns>
|
||||
public static MMDevice GetDefaultCaptureDevice()
|
||||
{
|
||||
MMDeviceEnumerator devices = new MMDeviceEnumerator();
|
||||
return devices.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Console);
|
||||
}
|
||||
|
||||
private void InitializeCaptureDevice()
|
||||
{
|
||||
long requestedDuration = REFTIMES_PER_MILLISEC * 100;
|
||||
|
||||
if (!audioClient.IsFormatSupported(AudioClientShareMode.Shared, WaveFormat))
|
||||
{
|
||||
throw new ArgumentException("Unsupported Wave Format");
|
||||
}
|
||||
|
||||
audioClient.Initialize(AudioClientShareMode.Shared,
|
||||
AudioClientStreamFlags.None,
|
||||
requestedDuration,
|
||||
0,
|
||||
WaveFormat,
|
||||
Guid.Empty);
|
||||
|
||||
int bufferFrameCount = audioClient.BufferSize;
|
||||
bytesPerFrame = WaveFormat.Channels * WaveFormat.BitsPerSample / 8;
|
||||
recordBuffer = new byte[bufferFrameCount * bytesPerFrame];
|
||||
Debug.WriteLine(string.Format("record buffer size = {0}", recordBuffer.Length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start Recording
|
||||
/// </summary>
|
||||
public void StartRecording()
|
||||
{
|
||||
InitializeCaptureDevice();
|
||||
ThreadStart start = delegate { this.CaptureThread(this.audioClient); };
|
||||
this.captureThread = new Thread(start);
|
||||
|
||||
Debug.WriteLine("Thread starting...");
|
||||
this.stop = false;
|
||||
this.captureThread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop Recording
|
||||
/// </summary>
|
||||
public void StopRecording()
|
||||
{
|
||||
if (this.captureThread != null)
|
||||
{
|
||||
this.stop = true;
|
||||
|
||||
Debug.WriteLine("Thread ending...");
|
||||
|
||||
// wait for thread to end
|
||||
this.captureThread.Join();
|
||||
this.captureThread = null;
|
||||
|
||||
Debug.WriteLine("Done.");
|
||||
|
||||
this.stop = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CaptureThread(AudioClient client)
|
||||
{
|
||||
Debug.WriteLine(client.BufferSize);
|
||||
int bufferFrameCount = audioClient.BufferSize;
|
||||
|
||||
// Calculate the actual duration of the allocated buffer.
|
||||
long actualDuration = (long)((double)REFTIMES_PER_SEC *
|
||||
bufferFrameCount / WaveFormat.SampleRate);
|
||||
int sleepMilliseconds = (int)(actualDuration / REFTIMES_PER_MILLISEC / 2);
|
||||
|
||||
AudioCaptureClient capture = client.AudioCaptureClient;
|
||||
client.Start();
|
||||
|
||||
try
|
||||
{
|
||||
Debug.WriteLine(string.Format("sleep: {0} ms", sleepMilliseconds));
|
||||
while (!this.stop)
|
||||
{
|
||||
Thread.Sleep(sleepMilliseconds);
|
||||
ReadNextPacket(capture);
|
||||
}
|
||||
|
||||
client.Stop();
|
||||
|
||||
if (RecordingStopped != null)
|
||||
{
|
||||
RecordingStopped(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (capture != null)
|
||||
{
|
||||
capture.Dispose();
|
||||
}
|
||||
if (client != null)
|
||||
{
|
||||
client.Dispose();
|
||||
}
|
||||
|
||||
client = null;
|
||||
capture = null;
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("stop wasapi");
|
||||
}
|
||||
|
||||
private void ReadNextPacket(AudioCaptureClient capture)
|
||||
{
|
||||
IntPtr buffer;
|
||||
int framesAvailable;
|
||||
AudioClientBufferFlags flags;
|
||||
int packetSize = capture.GetNextPacketSize();
|
||||
int recordBufferOffset = 0;
|
||||
//Debug.WriteLine(string.Format("packet size: {0} samples", packetSize / 4));
|
||||
|
||||
while (packetSize != 0)
|
||||
{
|
||||
buffer = capture.GetBuffer(out framesAvailable, out flags);
|
||||
|
||||
int bytesAvailable = framesAvailable * bytesPerFrame;
|
||||
|
||||
//Debug.WriteLine(string.Format("got buffer: {0} frames", framesAvailable));
|
||||
|
||||
// if not silence...
|
||||
if ((flags & AudioClientBufferFlags.Silent) != AudioClientBufferFlags.Silent)
|
||||
{
|
||||
Marshal.Copy(buffer, recordBuffer, recordBufferOffset, bytesAvailable);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Clear(recordBuffer, recordBufferOffset, bytesAvailable);
|
||||
}
|
||||
recordBufferOffset += bytesAvailable;
|
||||
capture.ReleaseBuffer(framesAvailable);
|
||||
packetSize = capture.GetNextPacketSize();
|
||||
}
|
||||
if (DataAvailable != null)
|
||||
{
|
||||
DataAvailable(this, new WaveInEventArgs(recordBuffer, recordBufferOffset));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
StopRecording();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
CUETools.Codecs.CoreAudio/IWavePlayer.cs
Normal file
42
CUETools.Codecs.CoreAudio/IWavePlayer.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using CUETools.Codecs;
|
||||
|
||||
namespace CUETools.Codecs.CoreAudio
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the interface to a device that can play a WaveFile
|
||||
/// </summary>
|
||||
public interface IWavePlayer : IDisposable, IAudioDest
|
||||
{
|
||||
/// <summary>
|
||||
/// Begin playback
|
||||
/// </summary>
|
||||
void Play();
|
||||
|
||||
/// <summary>
|
||||
/// Stop playback
|
||||
/// </summary>
|
||||
void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Pause Playback
|
||||
/// </summary>
|
||||
void Pause();
|
||||
|
||||
/// <summary>
|
||||
/// Current playback state
|
||||
/// </summary>
|
||||
PlaybackState PlaybackState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The volume 1.0 is full scale
|
||||
/// </summary>
|
||||
float Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that playback has gone into a stopped state due to
|
||||
/// reaching the end of the input stream
|
||||
/// </summary>
|
||||
event EventHandler PlaybackStopped;
|
||||
}
|
||||
}
|
||||
25
CUETools.Codecs.CoreAudio/PlaybackState.cs
Normal file
25
CUETools.Codecs.CoreAudio/PlaybackState.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CUETools.Codecs.CoreAudio
|
||||
{
|
||||
/// <summary>
|
||||
/// Playback State
|
||||
/// </summary>
|
||||
public enum PlaybackState
|
||||
{
|
||||
/// <summary>
|
||||
/// Stopped
|
||||
/// </summary>
|
||||
Stopped,
|
||||
/// <summary>
|
||||
/// Playing
|
||||
/// </summary>
|
||||
Playing,
|
||||
/// <summary>
|
||||
/// Paused
|
||||
/// </summary>
|
||||
Paused
|
||||
}
|
||||
}
|
||||
36
CUETools.Codecs.CoreAudio/Properties/AssemblyInfo.cs
Normal file
36
CUETools.Codecs.CoreAudio/Properties/AssemblyInfo.cs
Normal file
@@ -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.CoreAudio")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("CUETools.Codecs.CoreAudio")]
|
||||
[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("f597837f-dd1c-4e0f-b915-0e929bf0dd35")]
|
||||
|
||||
// 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")]
|
||||
492
CUETools.Codecs.CoreAudio/WasapiOut.cs
Normal file
492
CUETools.Codecs.CoreAudio/WasapiOut.cs
Normal file
@@ -0,0 +1,492 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using CUETools.Codecs;
|
||||
using NAudio.CoreAudioApi;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CUETools.Codecs.CoreAudio
|
||||
{
|
||||
/// <summary>
|
||||
/// Support for playback using Wasapi
|
||||
/// </summary>
|
||||
public class WasapiOut : IWavePlayer
|
||||
{
|
||||
AudioClient audioClient;
|
||||
AudioClientShareMode shareMode;
|
||||
AudioRenderClient renderClient;
|
||||
int latencyMilliseconds;
|
||||
int bufferFrameCount;
|
||||
bool isUsingEventSync;
|
||||
EventWaitHandle frameEventWaitHandle;
|
||||
AudioBuffer[] readBuffers;
|
||||
volatile PlaybackState playbackState;
|
||||
Thread playThread;
|
||||
private long _sampleOffset;
|
||||
private AudioPCMConfig pcm;
|
||||
private NAudio.Wave.WaveFormat outputFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Playback Stopped
|
||||
/// </summary>
|
||||
public event EventHandler PlaybackStopped;
|
||||
|
||||
/// <summary>
|
||||
/// WASAPI Out using default audio endpoint
|
||||
/// </summary>
|
||||
/// <param name="shareMode">ShareMode - shared or exclusive</param>
|
||||
/// <param name="latency">Desired latency in milliseconds</param>
|
||||
public WasapiOut(AudioClientShareMode shareMode, int latency) :
|
||||
this(GetDefaultAudioEndpoint(), shareMode, true, latency, AudioPCMConfig.RedBook)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WASAPI Out using default audio endpoint
|
||||
/// </summary>
|
||||
/// <param name="shareMode">ShareMode - shared or exclusive</param>
|
||||
/// <param name="useEventSync">true if sync is done with event. false use sleep.</param>
|
||||
/// <param name="latency">Desired latency in milliseconds</param>
|
||||
public WasapiOut(AudioClientShareMode shareMode, bool useEventSync, int latency) :
|
||||
this(GetDefaultAudioEndpoint(), shareMode, useEventSync, latency, AudioPCMConfig.RedBook)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new WASAPI Output
|
||||
/// </summary>
|
||||
/// <param name="device">Device to use</param>
|
||||
/// <param name="shareMode"></param>
|
||||
/// <param name="useEventSync">true if sync is done with event. false use sleep.</param>
|
||||
/// <param name="latency"></param>
|
||||
public WasapiOut(MMDevice device, AudioClientShareMode shareMode, bool useEventSync, int latency, AudioPCMConfig pcm)
|
||||
{
|
||||
this.audioClient = device.AudioClient;
|
||||
this.shareMode = shareMode;
|
||||
this.isUsingEventSync = useEventSync;
|
||||
this.latencyMilliseconds = latency;
|
||||
this.pcm = pcm;
|
||||
this.outputFormat = new NAudio.Wave.WaveFormat(pcm.SampleRate, pcm.BitsPerSample, pcm.ChannelCount);
|
||||
NAudio.Wave.WaveFormatExtensible closestSampleRateFormat;
|
||||
if (!audioClient.IsFormatSupported(shareMode, outputFormat, out closestSampleRateFormat))
|
||||
throw new NotSupportedException("PCM format mismatch");
|
||||
Init();
|
||||
bufferFrameCount = audioClient.BufferSize;
|
||||
readBuffers = new AudioBuffer[2];
|
||||
readBuffers[0] = new AudioBuffer(pcm, bufferFrameCount);
|
||||
readBuffers[1] = new AudioBuffer(pcm, bufferFrameCount);
|
||||
//if (this.shareMode == AudioClientShareMode.Exclusive)
|
||||
// this.latencyMilliseconds = (int)(this.audioClient.DefaultDevicePeriod / 10000);
|
||||
}
|
||||
|
||||
|
||||
public static MMDevice GetDefaultAudioEndpoint()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major < 6)
|
||||
{
|
||||
throw new NotSupportedException("WASAPI supported only on Windows Vista and above");
|
||||
}
|
||||
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
|
||||
return enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
|
||||
}
|
||||
|
||||
private bool BufferReady(int iBuf, bool write)
|
||||
{
|
||||
return write ? readBuffers[iBuf].Length == 0 : readBuffers[iBuf].Length == readBuffers[iBuf].Size;
|
||||
}
|
||||
|
||||
public AudioBuffer GetBuffer(bool write)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
while (!BufferReady(0, write) && !BufferReady(1, write) && playbackState != PlaybackState.Stopped)
|
||||
Monitor.Wait(this);
|
||||
if (playbackState == PlaybackState.Stopped)
|
||||
return null;
|
||||
if (BufferReady(0, write))
|
||||
return readBuffers[0];
|
||||
return readBuffers[1];
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseBuffer(AudioBuffer buff, bool write, int length)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
buff.Length = length;
|
||||
Monitor.Pulse(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
AudioBuffer buff = GetBuffer(false);
|
||||
if (buff == null)
|
||||
{
|
||||
RaisePlaybackStopped();
|
||||
return;
|
||||
}
|
||||
|
||||
audioClient.Reset();
|
||||
|
||||
// fill a whole buffer
|
||||
IntPtr buffer = renderClient.GetBuffer(buff.Length);
|
||||
Marshal.Copy(buff.Bytes, 0, buffer, buff.ByteLength);
|
||||
renderClient.ReleaseBuffer(buff.Length, AudioClientBufferFlags.None);
|
||||
ReleaseBuffer(buff, false, 0);
|
||||
|
||||
// Create WaitHandle for sync
|
||||
WaitHandle[] waitHandles = new WaitHandle[] { frameEventWaitHandle };
|
||||
if (frameEventWaitHandle != null)
|
||||
frameEventWaitHandle.Reset();
|
||||
audioClient.Start();
|
||||
|
||||
if (isUsingEventSync && shareMode == AudioClientShareMode.Exclusive)
|
||||
{
|
||||
while (playbackState != PlaybackState.Stopped)
|
||||
{
|
||||
int indexHandle = WaitHandle.WaitAny(waitHandles, 10 * latencyMilliseconds, false);
|
||||
if (playbackState == PlaybackState.Playing && indexHandle != WaitHandle.WaitTimeout)
|
||||
{
|
||||
// In exclusive mode, always ask the max = bufferFrameCount = audioClient.BufferSize
|
||||
buff = GetBuffer(false);
|
||||
if (buff == null)
|
||||
break;
|
||||
buffer = renderClient.GetBuffer(buff.Length);
|
||||
Marshal.Copy(buff.Bytes, 0, buffer, buff.ByteLength);
|
||||
renderClient.ReleaseBuffer(buff.Length, AudioClientBufferFlags.None);
|
||||
ReleaseBuffer(buff, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buff = null;
|
||||
int offs = 0;
|
||||
while (playbackState != PlaybackState.Stopped)
|
||||
{
|
||||
// If using Event Sync, Wait for notification from AudioClient or Sleep half latency
|
||||
int indexHandle = 0;
|
||||
if (isUsingEventSync)
|
||||
{
|
||||
indexHandle = WaitHandle.WaitAny(waitHandles, 3 * latencyMilliseconds, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(latencyMilliseconds / 2);
|
||||
}
|
||||
|
||||
// If still playing and notification is ok
|
||||
if (playbackState == PlaybackState.Playing && indexHandle != WaitHandle.WaitTimeout)
|
||||
{
|
||||
// See how much buffer space is available.
|
||||
int numFramesAvailable = bufferFrameCount - audioClient.CurrentPadding;
|
||||
if (numFramesAvailable > 0)
|
||||
{
|
||||
if (buff == null)
|
||||
{
|
||||
buff = GetBuffer(false);
|
||||
offs = 0;
|
||||
}
|
||||
if (buff == null)
|
||||
break;
|
||||
numFramesAvailable = Math.Min(numFramesAvailable, buff.Length - offs);
|
||||
buffer = renderClient.GetBuffer(numFramesAvailable);
|
||||
Marshal.Copy(buff.Bytes, offs * pcm.BlockAlign, buffer, numFramesAvailable * pcm.BlockAlign);
|
||||
renderClient.ReleaseBuffer(numFramesAvailable, AudioClientBufferFlags.None);
|
||||
offs += numFramesAvailable;
|
||||
if (offs == buff.Length)
|
||||
{
|
||||
ReleaseBuffer(buff, false, 0);
|
||||
buff = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Thread.Sleep(isUsingEventSync ? latencyMilliseconds : latencyMilliseconds / 2);
|
||||
audioClient.Stop();
|
||||
if (playbackState == PlaybackState.Stopped)
|
||||
audioClient.Reset();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
playbackState = PlaybackState.Stopped;
|
||||
ReleaseBuffer(readBuffers[0], false, 0);
|
||||
ReleaseBuffer(readBuffers[1], false, 0);
|
||||
playThread = null;
|
||||
try
|
||||
{
|
||||
audioClient.Stop();
|
||||
}
|
||||
catch { }
|
||||
RaisePlaybackException(ex);
|
||||
return;
|
||||
}
|
||||
ReleaseBuffer(readBuffers[0], false, 0);
|
||||
ReleaseBuffer(readBuffers[1], false, 0);
|
||||
RaisePlaybackStopped();
|
||||
}
|
||||
|
||||
private void RaisePlaybackException(Exception ex)
|
||||
{
|
||||
RaisePlaybackStopped();
|
||||
}
|
||||
|
||||
private void RaisePlaybackStopped()
|
||||
{
|
||||
if (PlaybackStopped != null)
|
||||
{
|
||||
PlaybackStopped(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
#region IWavePlayer Members
|
||||
|
||||
/// <summary>
|
||||
/// Begin Playback
|
||||
/// </summary>
|
||||
public void Play()
|
||||
{
|
||||
switch (playbackState)
|
||||
{
|
||||
case PlaybackState.Playing:
|
||||
return;
|
||||
case PlaybackState.Paused:
|
||||
playbackState = PlaybackState.Playing;
|
||||
return;
|
||||
case PlaybackState.Stopped:
|
||||
playbackState = PlaybackState.Playing;
|
||||
playThread = new Thread(new ThreadStart(PlayThread));
|
||||
playThread.Priority = ThreadPriority.Highest;
|
||||
playThread.IsBackground = true;
|
||||
playThread.Name = "Pro Audio";
|
||||
playThread.Start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop playback and flush buffers
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (playbackState != PlaybackState.Stopped)
|
||||
{
|
||||
playbackState = PlaybackState.Stopped;
|
||||
if (frameEventWaitHandle != null)
|
||||
frameEventWaitHandle.Set();
|
||||
playThread.Join();
|
||||
playThread = null;
|
||||
ReleaseBuffer(readBuffers[0], false, 0);
|
||||
ReleaseBuffer(readBuffers[1], false, 0);
|
||||
active = null;
|
||||
active_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop playback without flushing buffers
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
if (playbackState == PlaybackState.Playing)
|
||||
{
|
||||
//playbackState = PlaybackState.Paused;
|
||||
}
|
||||
if (frameEventWaitHandle != null)
|
||||
frameEventWaitHandle.Set();
|
||||
}
|
||||
|
||||
private bool inited = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize for playing the specified format
|
||||
/// </summary>
|
||||
private void Init()
|
||||
{
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
long latencyRefTimes = latencyMilliseconds * 10000;
|
||||
// first attempt uses the WaveFormat from the WaveStream
|
||||
|
||||
// If using EventSync, setup is specific with shareMode
|
||||
if (isUsingEventSync)
|
||||
{
|
||||
// Init Shared or Exclusive
|
||||
if (shareMode == AudioClientShareMode.Shared)
|
||||
{
|
||||
// With EventCallBack and Shared, both latencies must be set to 0
|
||||
audioClient.Initialize(shareMode, AudioClientStreamFlags.EventCallback, 0, 0,
|
||||
outputFormat, Guid.Empty);
|
||||
|
||||
// Get back the effective latency from AudioClient
|
||||
latencyMilliseconds = (int)(audioClient.StreamLatency / 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// With EventCallBack and Exclusive, both latencies must equals
|
||||
audioClient.Initialize(shareMode, AudioClientStreamFlags.EventCallback, latencyRefTimes, latencyRefTimes,
|
||||
outputFormat, Guid.Empty);
|
||||
}
|
||||
|
||||
// Create the Wait Event Handle
|
||||
frameEventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
audioClient.SetEventHandle(frameEventWaitHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal setup for both sharedMode
|
||||
audioClient.Initialize(shareMode, AudioClientStreamFlags.None, latencyRefTimes, 0,
|
||||
outputFormat, Guid.Empty);
|
||||
}
|
||||
|
||||
// Get the RenderClient
|
||||
renderClient = audioClient.AudioRenderClient;
|
||||
inited = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Playback State
|
||||
/// </summary>
|
||||
public PlaybackState PlaybackState
|
||||
{
|
||||
get { return playbackState; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Volume
|
||||
/// </summary>
|
||||
public float Volume
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 1.0f)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (audioClient != null)
|
||||
Stop();
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
private AudioBuffer active = null;
|
||||
private int active_offset = 0;
|
||||
|
||||
public void Write(AudioBuffer src)
|
||||
{
|
||||
if (src.Length == 0)
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
int src_offs = 0;
|
||||
do
|
||||
{
|
||||
if (active == null)
|
||||
active = GetBuffer(true);
|
||||
if (active == null)
|
||||
throw new Exception("done");
|
||||
int toCopy = Math.Min(active.Size - active_offset, src.Length - src_offs);
|
||||
Array.Copy(src.Bytes, src_offs * pcm.BlockAlign, active.Bytes, active_offset * pcm.BlockAlign, toCopy * pcm.BlockAlign);
|
||||
src_offs += toCopy;
|
||||
active_offset += toCopy;
|
||||
if (active_offset == active.Size)
|
||||
{
|
||||
ReleaseBuffer(active, true, active.Size);
|
||||
active = null;
|
||||
active_offset = 0;
|
||||
}
|
||||
}
|
||||
while (src_offs < src.Length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAudioDest Members
|
||||
|
||||
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
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (audioClient != null)
|
||||
{
|
||||
Stop();
|
||||
|
||||
audioClient.Dispose();
|
||||
audioClient = null;
|
||||
renderClient = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
117
CUETools.Codecs.CoreAudio/WaveFormats/AdpcmWaveFormat.cs
Normal file
117
CUETools.Codecs.CoreAudio/WaveFormats/AdpcmWaveFormat.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.Wave
|
||||
{
|
||||
/// <summary>
|
||||
/// Microsoft ADPCM
|
||||
/// See http://icculus.org/SDL_sound/downloads/external_documentation/wavecomp.htm
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack=2)]
|
||||
public class AdpcmWaveFormat : WaveFormat
|
||||
{
|
||||
short samplesPerBlock;
|
||||
short numCoeff;
|
||||
// 7 pairs of coefficients
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
|
||||
short[] coefficients;
|
||||
|
||||
/// <summary>
|
||||
/// Empty constructor needed for marshalling from a pointer
|
||||
/// </summary>
|
||||
AdpcmWaveFormat() : this(8000,1)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Samples per block
|
||||
/// </summary>
|
||||
public int SamplesPerBlock
|
||||
{
|
||||
get { return samplesPerBlock; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of coefficients
|
||||
/// </summary>
|
||||
public int NumCoefficients
|
||||
{
|
||||
get { return numCoeff; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Coefficients
|
||||
/// </summary>
|
||||
public short[] Coefficients
|
||||
{
|
||||
get { return coefficients; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft ADPCM
|
||||
/// </summary>
|
||||
/// <param name="sampleRate">Sample Rate</param>
|
||||
/// <param name="channels">Channels</param>
|
||||
public AdpcmWaveFormat(int sampleRate, int channels) :
|
||||
base(sampleRate,0,channels)
|
||||
{
|
||||
this.waveFormatTag = WaveFormatEncoding.Adpcm;
|
||||
|
||||
// TODO: validate sampleRate, bitsPerSample
|
||||
this.extraSize = 32;
|
||||
switch(this.sampleRate)
|
||||
{
|
||||
case 8000:
|
||||
case 11025:
|
||||
blockAlign = 256;
|
||||
break;
|
||||
case 22050:
|
||||
blockAlign = 512;
|
||||
break;
|
||||
case 44100:
|
||||
default:
|
||||
blockAlign = 1024;
|
||||
break;
|
||||
}
|
||||
|
||||
this.bitsPerSample = 4;
|
||||
this.samplesPerBlock = (short) ((((blockAlign - (7 * channels)) * 8) / (bitsPerSample * channels)) + 2);
|
||||
this.averageBytesPerSecond =
|
||||
((this.SampleRate * blockAlign) / samplesPerBlock);
|
||||
|
||||
// samplesPerBlock = blockAlign - (7 * channels)) * (2 / channels) + 2;
|
||||
|
||||
|
||||
numCoeff = 7;
|
||||
coefficients = new short[14] {
|
||||
256,0,512,-256,0,0,192,64,240,0,460,-208,392,-232
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this wave format
|
||||
/// </summary>
|
||||
/// <param name="writer">Binary writer</param>
|
||||
public override void Serialize(System.IO.BinaryWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(samplesPerBlock);
|
||||
writer.Write(numCoeff);
|
||||
foreach (short coefficient in coefficients)
|
||||
{
|
||||
writer.Write(coefficient);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String Description of this WaveFormat
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("Microsoft ADPCM {0} Hz {1} channels {2} bits per sample {3} samples per block",
|
||||
this.SampleRate, this.channels, this.bitsPerSample, this.samplesPerBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
CUETools.Codecs.CoreAudio/WaveFormats/AudioMediaSubtypes.cs
Normal file
70
CUETools.Codecs.CoreAudio/WaveFormats/AudioMediaSubtypes.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NAudio.Dmo
|
||||
{
|
||||
class AudioMediaSubtypes
|
||||
{
|
||||
public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); // PCM audio.
|
||||
public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770"); // Obsolete. Do not use.
|
||||
public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770"); // MPEG1 Audio packet.
|
||||
public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770"); // MPEG1 Audio Payload.
|
||||
public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea"); // MPEG-2 audio data
|
||||
public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea"); // DVD audio data
|
||||
public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71"); // Corresponds to WAVE_FORMAT_DRM.
|
||||
public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71"); // Corresponds to WAVE_FORMAT_IEEE_FLOAT
|
||||
public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea"); // Dolby data
|
||||
public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71"); // Dolby AC3 over SPDIF.
|
||||
public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71"); // Equivalent to MEDIASUBTYPE_DOLBY_AC3_SPDIF.
|
||||
public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71"); // Equivalent to MEDIASUBTYPE_DOLBY_AC3_SPDIF.
|
||||
|
||||
// others?
|
||||
public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770");
|
||||
public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770");
|
||||
public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770");
|
||||
|
||||
public static readonly Guid[] AudioSubTypes = new Guid[]
|
||||
{
|
||||
MEDIASUBTYPE_PCM,
|
||||
MEDIASUBTYPE_PCMAudioObsolete,
|
||||
MEDIASUBTYPE_MPEG1Packet,
|
||||
MEDIASUBTYPE_MPEG1Payload,
|
||||
MEDIASUBTYPE_MPEG2_AUDIO,
|
||||
MEDIASUBTYPE_DVD_LPCM_AUDIO,
|
||||
MEDIASUBTYPE_DRM_Audio,
|
||||
MEDIASUBTYPE_IEEE_FLOAT,
|
||||
MEDIASUBTYPE_DOLBY_AC3,
|
||||
MEDIASUBTYPE_DOLBY_AC3_SPDIF,
|
||||
MEDIASUBTYPE_RAW_SPORT,
|
||||
MEDIASUBTYPE_SPDIF_TAG_241h,
|
||||
};
|
||||
|
||||
public static readonly string[] AudioSubTypeNames = new string[]
|
||||
{
|
||||
"PCM",
|
||||
"PCM Obsolete",
|
||||
"MPEG1Packet",
|
||||
"MPEG1Payload",
|
||||
"MPEG2_AUDIO",
|
||||
"DVD_LPCM_AUDIO",
|
||||
"DRM_Audio",
|
||||
"IEEE_FLOAT",
|
||||
"DOLBY_AC3",
|
||||
"DOLBY_AC3_SPDIF",
|
||||
"RAW_SPORT",
|
||||
"SPDIF_TAG_241h",
|
||||
};
|
||||
public static string GetAudioSubtypeName(Guid subType)
|
||||
{
|
||||
for (int index = 0; index < AudioSubTypes.Length; index++)
|
||||
{
|
||||
if (subType == AudioSubTypes[index])
|
||||
{
|
||||
return AudioSubTypeNames[index];
|
||||
}
|
||||
}
|
||||
return subType.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
373
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormat.cs
Normal file
373
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormat.cs
Normal file
@@ -0,0 +1,373 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NAudio.Wave
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Wave file format
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=2)]
|
||||
public class WaveFormat
|
||||
{
|
||||
/// <summary>format type</summary>
|
||||
protected WaveFormatEncoding waveFormatTag;
|
||||
/// <summary>number of channels</summary>
|
||||
protected short channels;
|
||||
/// <summary>sample rate</summary>
|
||||
protected int sampleRate;
|
||||
/// <summary>for buffer estimation</summary>
|
||||
protected int averageBytesPerSecond;
|
||||
/// <summary>block size of data</summary>
|
||||
protected short blockAlign;
|
||||
/// <summary>number of bits per sample of mono data</summary>
|
||||
protected short bitsPerSample;
|
||||
/// <summary>number of following bytes</summary>
|
||||
protected short extraSize;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PCM 44.1Khz stereo 16 bit format
|
||||
/// </summary>
|
||||
public WaveFormat() : this(44100,16,2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new 16 bit wave format with the specified sample
|
||||
/// rate and channel count
|
||||
/// </summary>
|
||||
/// <param name="sampleRate">Sample Rate</param>
|
||||
/// <param name="channels">Number of channels</param>
|
||||
public WaveFormat(int sampleRate, int channels)
|
||||
: this(sampleRate, 16, channels)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of a wave buffer equivalent to the latency in milliseconds.
|
||||
/// </summary>
|
||||
/// <param name="milliseconds">The milliseconds.</param>
|
||||
/// <returns></returns>
|
||||
public int ConvertLatencyToByteSize(int milliseconds)
|
||||
{
|
||||
int bytes = (int) ((AverageBytesPerSecond/1000.0)*milliseconds);
|
||||
if ((bytes%BlockAlign) != 0)
|
||||
{
|
||||
// Return the upper BlockAligned
|
||||
bytes = bytes + BlockAlign - (bytes % BlockAlign);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a WaveFormat with custom members
|
||||
/// </summary>
|
||||
/// <param name="tag">The encoding</param>
|
||||
/// <param name="sampleRate">Sample Rate</param>
|
||||
/// <param name="channels">Number of channels</param>
|
||||
/// <param name="averageBytesPerSecond">Average Bytes Per Second</param>
|
||||
/// <param name="blockAlign">Block Align</param>
|
||||
/// <param name="bitsPerSample">Bits Per Sample</param>
|
||||
/// <returns></returns>
|
||||
public static WaveFormat CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample)
|
||||
{
|
||||
WaveFormat waveFormat = new WaveFormat();
|
||||
waveFormat.waveFormatTag = tag;
|
||||
waveFormat.channels = (short)channels;
|
||||
waveFormat.sampleRate = sampleRate;
|
||||
waveFormat.averageBytesPerSecond = averageBytesPerSecond;
|
||||
waveFormat.blockAlign = (short)blockAlign;
|
||||
waveFormat.bitsPerSample = (short)bitsPerSample;
|
||||
waveFormat.extraSize = 0;
|
||||
return waveFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an A-law wave format
|
||||
/// </summary>
|
||||
/// <param name="sampleRate">Sample Rate</param>
|
||||
/// <param name="channels">Number of Channels</param>
|
||||
/// <returns>Wave Format</returns>
|
||||
public static WaveFormat CreateALawFormat(int sampleRate, int channels)
|
||||
{
|
||||
return CreateCustomFormat(WaveFormatEncoding.ALaw, sampleRate, channels, sampleRate * channels, 1, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Mu-law wave format
|
||||
/// </summary>
|
||||
/// <param name="sampleRate">Sample Rate</param>
|
||||
/// <param name="channels">Number of Channels</param>
|
||||
/// <returns>Wave Format</returns>
|
||||
public static WaveFormat CreateMuLawFormat(int sampleRate, int channels)
|
||||
{
|
||||
return CreateCustomFormat(WaveFormatEncoding.MuLaw, sampleRate, channels, sampleRate * channels, 1, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PCM format with the specified sample rate, bit depth and channels
|
||||
/// </summary>
|
||||
public WaveFormat(int rate, int bits, int channels)
|
||||
{
|
||||
if (channels < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Channels must be 1 or greater", "channels");
|
||||
}
|
||||
// minimum 16 bytes, sometimes 18 for PCM
|
||||
this.waveFormatTag = WaveFormatEncoding.Pcm;
|
||||
this.channels = (short)channels;
|
||||
this.sampleRate = rate;
|
||||
this.bitsPerSample = (short)bits;
|
||||
this.extraSize = 0;
|
||||
|
||||
this.blockAlign = (short)(channels * (bits / 8));
|
||||
this.averageBytesPerSecond = this.sampleRate * this.blockAlign;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new 32 bit IEEE floating point wave format
|
||||
/// </summary>
|
||||
/// <param name="sampleRate">sample rate</param>
|
||||
/// <param name="channels">number of channels</param>
|
||||
public static WaveFormat CreateIeeeFloatWaveFormat(int sampleRate, int channels)
|
||||
{
|
||||
WaveFormat wf = new WaveFormat();
|
||||
wf.waveFormatTag = WaveFormatEncoding.IeeeFloat;
|
||||
wf.channels = (short)channels;
|
||||
wf.bitsPerSample = 32;
|
||||
wf.sampleRate = sampleRate;
|
||||
wf.blockAlign = (short) (4*channels);
|
||||
wf.averageBytesPerSecond = sampleRate * wf.blockAlign;
|
||||
wf.extraSize = 0;
|
||||
return wf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to retrieve a WaveFormat structure from a pointer
|
||||
/// </summary>
|
||||
/// <param name="pointer">WaveFormat structure</param>
|
||||
/// <returns></returns>
|
||||
public static WaveFormat MarshalFromPtr(IntPtr pointer)
|
||||
{
|
||||
WaveFormat waveFormat = (WaveFormat)Marshal.PtrToStructure(pointer, typeof(WaveFormat));
|
||||
switch (waveFormat.Encoding)
|
||||
{
|
||||
case WaveFormatEncoding.Pcm:
|
||||
// can't rely on extra size even being there for PCM so blank it to avoid reading
|
||||
// corrupt data
|
||||
waveFormat.extraSize = 0;
|
||||
break;
|
||||
case WaveFormatEncoding.Extensible:
|
||||
waveFormat = (WaveFormatExtensible)Marshal.PtrToStructure(pointer, typeof(WaveFormatExtensible));
|
||||
break;
|
||||
case WaveFormatEncoding.Adpcm:
|
||||
waveFormat = (AdpcmWaveFormat)Marshal.PtrToStructure(pointer, typeof(AdpcmWaveFormat));
|
||||
break;
|
||||
default:
|
||||
if (waveFormat.ExtraSize > 0)
|
||||
{
|
||||
waveFormat = (WaveFormatExtraData)Marshal.PtrToStructure(pointer, typeof(WaveFormatExtraData));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return waveFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to marshal WaveFormat to an IntPtr
|
||||
/// </summary>
|
||||
/// <param name="format">WaveFormat</param>
|
||||
/// <returns>IntPtr to WaveFormat structure (needs to be freed by callee)</returns>
|
||||
public static IntPtr MarshalToPtr(WaveFormat format)
|
||||
{
|
||||
int formatSize = Marshal.SizeOf(format);
|
||||
IntPtr formatPointer = Marshal.AllocHGlobal(formatSize);
|
||||
Marshal.StructureToPtr(format, formatPointer, false);
|
||||
return formatPointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a new WaveFormat object from a stream
|
||||
/// </summary>
|
||||
/// <param name="br">A binary reader that wraps the stream</param>
|
||||
public WaveFormat(BinaryReader br)
|
||||
{
|
||||
int formatChunkLength = br.ReadInt32();
|
||||
if(formatChunkLength < 16)
|
||||
throw new ApplicationException("Invalid WaveFormat Structure");
|
||||
this.waveFormatTag = (WaveFormatEncoding) br.ReadUInt16();
|
||||
this.channels = br.ReadInt16();
|
||||
this.sampleRate = br.ReadInt32();
|
||||
this.averageBytesPerSecond = br.ReadInt32();
|
||||
this.blockAlign = br.ReadInt16();
|
||||
this.bitsPerSample = br.ReadInt16();
|
||||
if (formatChunkLength > 16)
|
||||
{
|
||||
|
||||
this.extraSize = br.ReadInt16();
|
||||
if (this.extraSize > formatChunkLength - 18)
|
||||
{
|
||||
Console.WriteLine("Format chunk mismatch");
|
||||
//RRL GSM exhibits this bug. Don't throw an exception
|
||||
//throw new ApplicationException("Format chunk length mismatch");
|
||||
|
||||
this.extraSize = (short) (formatChunkLength - 18);
|
||||
}
|
||||
|
||||
// read any extra data
|
||||
// br.ReadBytes(extraSize);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports this WaveFormat as a string
|
||||
/// </summary>
|
||||
/// <returns>String describing the wave format</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
switch (this.waveFormatTag)
|
||||
{
|
||||
case WaveFormatEncoding.Pcm:
|
||||
case WaveFormatEncoding.Extensible:
|
||||
// extensible just has some extra bits after the PCM header
|
||||
return String.Format("{0} bit PCM: {1}kHz {2} channels",
|
||||
bitsPerSample, sampleRate / 1000, channels);
|
||||
default:
|
||||
return this.waveFormatTag.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares with another WaveFormat object
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to compare to</param>
|
||||
/// <returns>True if the objects are the same</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
WaveFormat other = obj as WaveFormat;
|
||||
if(other != null)
|
||||
{
|
||||
return waveFormatTag == other.waveFormatTag &&
|
||||
channels == other.channels &&
|
||||
sampleRate == other.sampleRate &&
|
||||
averageBytesPerSecond == other.averageBytesPerSecond &&
|
||||
blockAlign == other.blockAlign &&
|
||||
bitsPerSample == other.bitsPerSample;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a Hashcode for this WaveFormat
|
||||
/// </summary>
|
||||
/// <returns>A hashcode</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int) waveFormatTag ^
|
||||
(int) channels ^
|
||||
sampleRate ^
|
||||
averageBytesPerSecond ^
|
||||
(int) blockAlign ^
|
||||
(int) bitsPerSample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the encoding type used
|
||||
/// </summary>
|
||||
public WaveFormatEncoding Encoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return waveFormatTag;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes this WaveFormat object to a stream
|
||||
/// </summary>
|
||||
/// <param name="writer">the output stream</param>
|
||||
public virtual void Serialize(BinaryWriter writer)
|
||||
{
|
||||
writer.Write((int)(18 + extraSize)); // wave format length
|
||||
writer.Write((short)Encoding);
|
||||
writer.Write((short)Channels);
|
||||
writer.Write((int)SampleRate);
|
||||
writer.Write((int)AverageBytesPerSecond);
|
||||
writer.Write((short)BlockAlign);
|
||||
writer.Write((short)BitsPerSample);
|
||||
writer.Write((short)extraSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of channels (1=mono,2=stereo etc)
|
||||
/// </summary>
|
||||
public int Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
return channels;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sample rate (samples per second)
|
||||
/// </summary>
|
||||
public int SampleRate
|
||||
{
|
||||
get
|
||||
{
|
||||
return sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average number of bytes used per second
|
||||
/// </summary>
|
||||
public int AverageBytesPerSecond
|
||||
{
|
||||
get
|
||||
{
|
||||
return averageBytesPerSecond;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the block alignment
|
||||
/// </summary>
|
||||
public virtual int BlockAlign
|
||||
{
|
||||
get
|
||||
{
|
||||
return blockAlign;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of bits per sample (usually 16 or 32, sometimes 24 or 8)
|
||||
/// Can be 0 for some codecs
|
||||
/// </summary>
|
||||
public int BitsPerSample
|
||||
{
|
||||
get
|
||||
{
|
||||
return bitsPerSample;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of extra bytes used by this waveformat. Often 0,
|
||||
/// except for compressed formats which store extra data after the WAVEFORMATEX header
|
||||
/// </summary>
|
||||
public int ExtraSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return extraSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
314
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormatEncoding.cs
Normal file
314
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormatEncoding.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
|
||||
namespace NAudio.Wave
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for WaveFormatEncoding.
|
||||
/// </summary>
|
||||
public enum WaveFormatEncoding : ushort
|
||||
{
|
||||
/// <summary>WAVE_FORMAT_UNKNOWN, Microsoft Corporation</summary>
|
||||
Unknown = 0x0000,
|
||||
/// <summary>WAVE_FORMAT_PCM Microsoft Corporation</summary>
|
||||
Pcm = 0x0001,
|
||||
/// <summary>WAVE_FORMAT_ADPCM Microsoft Corporation</summary>
|
||||
Adpcm = 0x0002,
|
||||
/// <summary>WAVE_FORMAT_IEEE_FLOAT Microsoft Corporation</summary>
|
||||
IeeeFloat = 0x0003,
|
||||
/// <summary>WAVE_FORMAT_VSELP Compaq Computer Corp.</summary>
|
||||
Vselp = 0x0004,
|
||||
/// <summary>WAVE_FORMAT_IBM_CVSD IBM Corporation</summary>
|
||||
IbmCvsd = 0x0005,
|
||||
/// <summary>WAVE_FORMAT_ALAW Microsoft Corporation</summary>
|
||||
ALaw = 0x0006,
|
||||
/// <summary>WAVE_FORMAT_MULAW Microsoft Corporation</summary>
|
||||
MuLaw = 0x0007,
|
||||
/// <summary>WAVE_FORMAT_DTS Microsoft Corporation</summary>
|
||||
Dts = 0x0008,
|
||||
/// <summary>WAVE_FORMAT_DRM Microsoft Corporation</summary>
|
||||
Drm = 0x0009,
|
||||
/// <summary>WAVE_FORMAT_OKI_ADPCM OKI</summary>
|
||||
OkiAdpcm = 0x0010,
|
||||
/// <summary>WAVE_FORMAT_DVI_ADPCM Intel Corporation</summary>
|
||||
DviAdpcm = 0x0011,
|
||||
/// <summary>WAVE_FORMAT_IMA_ADPCM Intel Corporation</summary>
|
||||
ImaAdpcm = DviAdpcm,
|
||||
/// <summary>WAVE_FORMAT_MEDIASPACE_ADPCM Videologic</summary>
|
||||
MediaspaceAdpcm = 0x0012,
|
||||
/// <summary>WAVE_FORMAT_SIERRA_ADPCM Sierra Semiconductor Corp </summary>
|
||||
SierraAdpcm = 0x0013,
|
||||
/// <summary>WAVE_FORMAT_G723_ADPCM Antex Electronics Corporation </summary>
|
||||
G723Adpcm = 0x0014,
|
||||
/// <summary>WAVE_FORMAT_DIGISTD DSP Solutions, Inc.</summary>
|
||||
DigiStd = 0x0015,
|
||||
/// <summary>WAVE_FORMAT_DIGIFIX DSP Solutions, Inc.</summary>
|
||||
DigiFix = 0x0016,
|
||||
/// <summary>WAVE_FORMAT_DIALOGIC_OKI_ADPCM Dialogic Corporation</summary>
|
||||
DialogicOkiAdpcm = 0x0017,
|
||||
/// <summary>WAVE_FORMAT_MEDIAVISION_ADPCM Media Vision, Inc.</summary>
|
||||
MediaVisionAdpcm = 0x0018,
|
||||
/// <summary>WAVE_FORMAT_CU_CODEC Hewlett-Packard Company </summary>
|
||||
CUCodec = 0x0019,
|
||||
/// <summary>WAVE_FORMAT_YAMAHA_ADPCM Yamaha Corporation of America</summary>
|
||||
YamahaAdpcm = 0x0020,
|
||||
/// <summary>WAVE_FORMAT_SONARC Speech Compression</summary>
|
||||
SonarC = 0x0021,
|
||||
/// <summary>WAVE_FORMAT_DSPGROUP_TRUESPEECH DSP Group, Inc </summary>
|
||||
DspGroupTruespeech = 0x0022,
|
||||
/// <summary>WAVE_FORMAT_ECHOSC1 Echo Speech Corporation</summary>
|
||||
EchoSpeechCorporation1 = 0x0023,
|
||||
/// <summary>WAVE_FORMAT_AUDIOFILE_AF36, Virtual Music, Inc.</summary>
|
||||
AudioFileAf36 = 0x0024,
|
||||
/// <summary>WAVE_FORMAT_APTX Audio Processing Technology</summary>
|
||||
Aptx = 0x0025,
|
||||
/// <summary>WAVE_FORMAT_AUDIOFILE_AF10, Virtual Music, Inc.</summary>
|
||||
AudioFileAf10 = 0x0026,
|
||||
/// <summary>WAVE_FORMAT_PROSODY_1612, Aculab plc</summary>
|
||||
Prosody1612 = 0x0027,
|
||||
/// <summary>WAVE_FORMAT_LRC, Merging Technologies S.A. </summary>
|
||||
Lrc = 0x0028,
|
||||
/// <summary>WAVE_FORMAT_DOLBY_AC2, Dolby Laboratories</summary>
|
||||
DolbyAc2 = 0x0030,
|
||||
/// <summary>WAVE_FORMAT_GSM610, Microsoft Corporation</summary>
|
||||
Gsm610 = 0x0031,
|
||||
/// <summary>WAVE_FORMAT_MSNAUDIO, Microsoft Corporation</summary>
|
||||
MsnAudio = 0x0032,
|
||||
/// <summary>WAVE_FORMAT_ANTEX_ADPCME, Antex Electronics Corporation</summary>
|
||||
AntexAdpcme = 0x0033,
|
||||
/// <summary>WAVE_FORMAT_CONTROL_RES_VQLPC, Control Resources Limited </summary>
|
||||
ControlResVqlpc = 0x0034,
|
||||
/// <summary>WAVE_FORMAT_DIGIREAL, DSP Solutions, Inc. </summary>
|
||||
DigiReal = 0x0035,
|
||||
/// <summary>WAVE_FORMAT_DIGIADPCM, DSP Solutions, Inc.</summary>
|
||||
DigiAdpcm = 0x0036,
|
||||
/// <summary>WAVE_FORMAT_CONTROL_RES_CR10, Control Resources Limited</summary>
|
||||
ControlResCr10 = 0x0037,
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_NMS_VBXADPCM = 0x0038, // Natural MicroSystems
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CS_IMAADPCM = 0x0039, // Crystal Semiconductor IMA ADPCM
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ECHOSC3 = 0x003A, // Echo Speech Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ROCKWELL_ADPCM = 0x003B, // Rockwell International
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ROCKWELL_DIGITALK = 0x003C, // Rockwell International
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_XEBEC = 0x003D, // Xebec Multimedia Solutions Limited
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G721_ADPCM = 0x0040, // Antex Electronics Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G728_CELP = 0x0041, // Antex Electronics Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MSG723 = 0x0042, // Microsoft Corporation
|
||||
/// <summary></summary>
|
||||
Mpeg = 0x0050, // WAVE_FORMAT_MPEG, Microsoft Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_RT24 = 0x0052, // InSoft, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_PAC = 0x0053, // InSoft, Inc.
|
||||
/// <summary></summary>
|
||||
MpegLayer3 = 0x0055, // WAVE_FORMAT_MPEGLAYER3, ISO/MPEG Layer3 Format Tag
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_LUCENT_G723 = 0x0059, // Lucent Technologies
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CIRRUS = 0x0060, // Cirrus Logic
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ESPCM = 0x0061, // ESS Technology
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE = 0x0062, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CANOPUS_ATRAC = 0x0063, // Canopus, co., Ltd.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G726_ADPCM = 0x0064, // APICOM
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G722_ADPCM = 0x0065, // APICOM
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DSAT_DISPLAY = 0x0067, // Microsoft Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 0x0069, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_AC8 = 0x0070, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_AC10 = 0x0071, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_AC16 = 0x0072, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_AC20 = 0x0073, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_RT24 = 0x0074, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_RT29 = 0x0075, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_RT29HW = 0x0076, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_VR12 = 0x0077, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_VR18 = 0x0078, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_TQ40 = 0x0079, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SOFTSOUND = 0x0080, // Softsound, Ltd.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VOXWARE_TQ60 = 0x0081, // Voxware Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MSRT24 = 0x0082, // Microsoft Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G729A = 0x0083, // AT&T Labs, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MVI_MVI2 = 0x0084, // Motion Pixels
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DF_G726 = 0x0085, // DataFusion Systems (Pty) (Ltd)
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DF_GSM610 = 0x0086, // DataFusion Systems (Pty) (Ltd)
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ISIAUDIO = 0x0088, // Iterated Systems, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ONLIVE = 0x0089, // OnLive! Technologies, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SBC24 = 0x0091, // Siemens Business Communications Sys
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DOLBY_AC3_SPDIF = 0x0092, // Sonic Foundry
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MEDIASONIC_G723 = 0x0093, // MediaSonic
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_PROSODY_8KBPS = 0x0094, // Aculab plc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ZYXEL_ADPCM = 0x0097, // ZyXEL Communications, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_PHILIPS_LPCBB = 0x0098, // Philips Speech Processing
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_PACKED = 0x0099, // Studer Professional Audio AG
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MALDEN_PHONYTALK = 0x00A0, // Malden Electronics Ltd.
|
||||
/// <summary>WAVE_FORMAT_GSM</summary>
|
||||
Gsm = 0x00A1,
|
||||
/// <summary>WAVE_FORMAT_G729</summary>
|
||||
G729 = 0x00A2,
|
||||
/// <summary>WAVE_FORMAT_G723</summary>
|
||||
G723 = 0x00A3,
|
||||
/// <summary>WAVE_FORMAT_ACELP</summary>
|
||||
Acelp = 0x00A4,
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_RHETOREX_ADPCM = 0x0100, // Rhetorex Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_IRAT = 0x0101, // BeCubed Software Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VIVO_G723 = 0x0111, // Vivo Software
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VIVO_SIREN = 0x0112, // Vivo Software
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DIGITAL_G723 = 0x0123, // Digital Equipment Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SANYO_LD_ADPCM = 0x0125, // Sanyo Electric Co., Ltd.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_ACEPLNET = 0x0130, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_ACELP4800 = 0x0131, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_ACELP8V3 = 0x0132, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_G729 = 0x0133, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_G729A = 0x0134, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SIPROLAB_KELVIN = 0x0135, // Sipro Lab Telecom Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_G726ADPCM = 0x0140, // Dictaphone Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_QUALCOMM_PUREVOICE = 0x0150, // Qualcomm, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_QUALCOMM_HALFRATE = 0x0151, // Qualcomm, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_TUBGSM = 0x0155, // Ring Zero Systems, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_MSAUDIO1 = 0x0160, // Microsoft Corporation
|
||||
/// <summary>
|
||||
/// WAVE_FORMAT_WMAUDIO2, Microsoft Corporation
|
||||
/// </summary>
|
||||
WAVE_FORMAT_WMAUDIO2 = 0x0161,
|
||||
/// <summary>
|
||||
/// WAVE_FORMAT_WMAUDIO3, Microsoft Corporation
|
||||
/// </summary>
|
||||
WAVE_FORMAT_WMAUDIO3 = 0x0162,
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_UNISYS_NAP_ADPCM = 0x0170, // Unisys Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_UNISYS_NAP_ULAW = 0x0171, // Unisys Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_UNISYS_NAP_ALAW = 0x0172, // Unisys Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_UNISYS_NAP_16K = 0x0173, // Unisys Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CREATIVE_ADPCM = 0x0200, // Creative Labs, Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 0x0202, // Creative Labs, Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 0x0203, // Creative Labs, Inc
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_UHER_ADPCM = 0x0210, // UHER informatic GmbH
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_QUARTERDECK = 0x0220, // Quarterdeck Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ILINK_VC = 0x0230, // I-link Worldwide
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_RAW_SPORT = 0x0240, // Aureal Semiconductor
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_ESST_AC3 = 0x0241, // ESS Technology, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_IPI_HSX = 0x0250, // Interactive Products, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_IPI_RPELP = 0x0251, // Interactive Products, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_CS2 = 0x0260, // Consistent Software
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SONY_SCX = 0x0270, // Sony Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_FM_TOWNS_SND = 0x0300, // Fujitsu Corp.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_BTV_DIGITAL = 0x0400, // Brooktree Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_QDESIGN_MUSIC = 0x0450, // QDesign Corporation
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_VME_VMPCM = 0x0680, // AT&T Labs, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_TPC = 0x0681, // AT&T Labs, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_OLIGSM = 0x1000, // Ing C. Olivetti & C., S.p.A.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_OLIADPCM = 0x1001, // Ing C. Olivetti & C., S.p.A.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_OLICELP = 0x1002, // Ing C. Olivetti & C., S.p.A.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_OLISBC = 0x1003, // Ing C. Olivetti & C., S.p.A.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_OLIOPR = 0x1004, // Ing C. Olivetti & C., S.p.A.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_LH_CODEC = 0x1100, // Lernout & Hauspie
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_NORRIS = 0x1400, // Norris Communications, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 0x1500, // AT&T Labs, Inc.
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DVM = 0x2000, // FAST Multimedia AG
|
||||
/// <summary>WAVE_FORMAT_EXTENSIBLE</summary>
|
||||
Extensible = 0xFFFE, // Microsoft
|
||||
/// <summary></summary>
|
||||
WAVE_FORMAT_DEVELOPMENT = 0xFFFF,
|
||||
|
||||
// others - not from MS headers
|
||||
/// <summary>WAVE_FORMAT_VORBIS1 "Og" Original stream compatible</summary>
|
||||
Vorbis1 = 0x674f,
|
||||
/// <summary>WAVE_FORMAT_VORBIS2 "Pg" Have independent header</summary>
|
||||
Vorbis2 = 0x6750,
|
||||
/// <summary>WAVE_FORMAT_VORBIS3 "Qg" Have no codebook header</summary>
|
||||
Vorbis3 = 0x6751,
|
||||
/// <summary>WAVE_FORMAT_VORBIS1P "og" Original stream compatible</summary>
|
||||
Vorbis1P = 0x676f,
|
||||
/// <summary>WAVE_FORMAT_VORBIS2P "pg" Have independent headere</summary>
|
||||
Vorbis2P = 0x6770,
|
||||
/// <summary>WAVE_FORMAT_VORBIS3P "qg" Have no codebook header</summary>
|
||||
Vorbis3P = 0x6771,
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using NAudio.Dmo;
|
||||
|
||||
namespace NAudio.Wave
|
||||
{
|
||||
/// <summary>
|
||||
/// WaveFormatExtensible
|
||||
/// http://www.microsoft.com/whdc/device/audio/multichaud.mspx
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
|
||||
public class WaveFormatExtensible : WaveFormat
|
||||
{
|
||||
short wValidBitsPerSample; // bits of precision, or is wSamplesPerBlock if wBitsPerSample==0
|
||||
int dwChannelMask; // which channels are present in stream
|
||||
Guid subFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor for marshalling
|
||||
/// </summary>
|
||||
WaveFormatExtensible()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new WaveFormatExtensible for PCM or IEEE
|
||||
/// </summary>
|
||||
public WaveFormatExtensible(int rate, int bits, int channels)
|
||||
: base(rate, bits, channels)
|
||||
{
|
||||
waveFormatTag = WaveFormatEncoding.Extensible;
|
||||
extraSize = 22;
|
||||
wValidBitsPerSample = (short) bits;
|
||||
for (int n = 0; n < channels; n++)
|
||||
{
|
||||
dwChannelMask |= (1 << n);
|
||||
}
|
||||
if (bits == 32)
|
||||
{
|
||||
// KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
subFormat = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT; // new Guid("00000003-0000-0010-8000-00aa00389b71");
|
||||
}
|
||||
else
|
||||
{
|
||||
// KSDATAFORMAT_SUBTYPE_PCM
|
||||
subFormat = AudioMediaSubtypes.MEDIASUBTYPE_PCM; // new Guid("00000001-0000-0010-8000-00aa00389b71");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
public override void Serialize(System.IO.BinaryWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(wValidBitsPerSample);
|
||||
writer.Write(dwChannelMask);
|
||||
byte[] guid = subFormat.ToByteArray();
|
||||
writer.Write(guid, 0, guid.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representation
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} wBitsPerSample:{1} dwChannelMask:{2} subFormat:{3} extraSize:{4}",
|
||||
base.ToString(),
|
||||
wValidBitsPerSample,
|
||||
dwChannelMask,
|
||||
subFormat,
|
||||
extraSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormatExtraData.cs
Normal file
41
CUETools.Codecs.CoreAudio/WaveFormats/WaveFormatExtraData.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
namespace NAudio.Wave
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
|
||||
class WaveFormatExtraData : WaveFormat
|
||||
{
|
||||
// try with 100 bytes for now, increase if necessary
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
|
||||
byte[] extraData = new byte[100];
|
||||
|
||||
/// <summary>
|
||||
/// parameterless constructor for marshalling
|
||||
/// </summary>
|
||||
WaveFormatExtraData()
|
||||
{
|
||||
}
|
||||
|
||||
public WaveFormatExtraData(BinaryReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
if (this.extraSize > 0)
|
||||
{
|
||||
reader.Read(extraData,0, extraSize);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(BinaryWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
if (extraSize > 0)
|
||||
{
|
||||
writer.Write(extraData, 0, extraSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +253,7 @@ namespace CUETools.Codecs
|
||||
{
|
||||
pcm = _pcm;
|
||||
size = _size;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
public AudioBuffer(AudioPCMConfig _pcm, int[,] _samples, int _length)
|
||||
@@ -581,7 +582,7 @@ namespace CUETools.Codecs
|
||||
|
||||
unsafe public static void MemCpy(byte* res, byte* smp, int n)
|
||||
{
|
||||
if ((((IntPtr)smp).ToInt64() & 4) == 0 && (((IntPtr)res).ToInt64() & 4) == 0 && n > 4)
|
||||
if ((((IntPtr)smp).ToInt64() & 3) == 0 && (((IntPtr)res).ToInt64() & 3) == 0 && n > 4)
|
||||
{
|
||||
MemCpy((int*)res, (int*)smp, n >> 2);
|
||||
int n4 = (n >> 2) << 2;
|
||||
@@ -599,6 +600,50 @@ namespace CUETools.Codecs
|
||||
*(res++) = smp;
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(long* res, long smp, int n)
|
||||
{
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = smp;
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(byte* res, byte smp, int n)
|
||||
{
|
||||
if (IntPtr.Size == 8 && (((IntPtr)res).ToInt64() & 7) == 0 && smp == 0 && n > 8)
|
||||
{
|
||||
MemSet((long*)res, 0, n >> 3);
|
||||
int n8 = (n >> 3) << 3;
|
||||
n -= n8;
|
||||
res += n8;
|
||||
}
|
||||
if ((((IntPtr)res).ToInt64() & 3) == 0 && smp == 0 && n > 4)
|
||||
{
|
||||
MemSet((int*)res, 0, n >> 2);
|
||||
int n4 = (n >> 2) << 2;
|
||||
n -= n4;
|
||||
res += n4;
|
||||
}
|
||||
for (int i = n; i > 0; i--)
|
||||
*(res++) = smp;
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(byte[] res, byte smp, int offs, int n)
|
||||
{
|
||||
fixed (byte* pres = &res[offs])
|
||||
MemSet(pres, smp, n);
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(int[] res, int smp, int offs, int n)
|
||||
{
|
||||
fixed (int* pres = &res[offs])
|
||||
MemSet(pres, smp, n);
|
||||
}
|
||||
|
||||
unsafe public static void MemSet(long[] res, long smp, int offs, int n)
|
||||
{
|
||||
fixed (long* pres = &res[offs])
|
||||
MemSet(pres, smp, n);
|
||||
}
|
||||
|
||||
public const uint UINT32_MAX = 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
@@ -1593,7 +1593,7 @@ string status = processor.Go();
|
||||
private bool _stop, _pause;
|
||||
private List<CUELine> _attributes;
|
||||
private List<TrackInfo> _tracks;
|
||||
private List<SourceInfo> _sources;
|
||||
internal List<SourceInfo> _sources;
|
||||
private List<string> _sourcePaths, _trackFilenames;
|
||||
private string _htoaFilename, _singleFilename;
|
||||
private bool _hasHTOAFilename = false, _hasTrackFilenames = false, _hasSingleFilename = false, _appliedWriteOffset;
|
||||
@@ -1704,6 +1704,14 @@ string status = processor.Go();
|
||||
_ripper = null;
|
||||
}
|
||||
|
||||
public string InputPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _inputPath;
|
||||
}
|
||||
}
|
||||
|
||||
public AccurateRipVerify ArVerify
|
||||
{
|
||||
get
|
||||
@@ -3624,9 +3632,11 @@ string status = processor.Go();
|
||||
{
|
||||
string prefix = "";
|
||||
if (hdcdDecoder != null && string.Format("{0:s}", hdcdDecoder) != "")
|
||||
prefix += string.Format("{0:s}, ", hdcdDecoder);
|
||||
prefix += string.Format("{0:s}", hdcdDecoder);
|
||||
if (_useAccurateRip)
|
||||
{
|
||||
if (prefix != "") prefix += ", ";
|
||||
prefix += "AR: ";
|
||||
if (_arVerify.ARStatus != null)
|
||||
prefix += _arVerify.ARStatus;
|
||||
else
|
||||
@@ -3641,7 +3651,18 @@ string status = processor.Go();
|
||||
else
|
||||
prefix += "rip not accurate";
|
||||
}
|
||||
} else
|
||||
}
|
||||
if (!_useCUEToolsDBFix && _useCUEToolsDB)
|
||||
{
|
||||
if (prefix != "") prefix += ", ";
|
||||
prefix += "CTDB: " + CTDB.Status;
|
||||
}
|
||||
if (_isCD && _ripper.ErrorsCount > 0)
|
||||
{
|
||||
if (prefix != "") prefix += ", ";
|
||||
prefix += "ripper found " + _ripper.ErrorsCount + " suspicious sectors";
|
||||
}
|
||||
if (prefix == "")
|
||||
prefix += "done";
|
||||
return prefix;
|
||||
}
|
||||
@@ -4225,6 +4246,22 @@ string status = processor.Go();
|
||||
return destTags;
|
||||
}
|
||||
|
||||
//public IAudioSource OpenSource(long position)
|
||||
//{
|
||||
// int pos = 0;
|
||||
// for (int iSource = 0; iSource < _sources.Count; iSource++)
|
||||
// {
|
||||
// if (position >= pos && position < pos + (int)_sources[iSource].Length)
|
||||
// {
|
||||
// IAudioSource audioSource = GetAudioSource(iSource);
|
||||
// audioSource.Position = position - pos;
|
||||
// return audioSource;
|
||||
// }
|
||||
// pos += (int)_sources[iSource].Length;
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
|
||||
public void WriteAudioFilesPass(string dir, CUEStyle style, int[] destLengths, bool htoaToFile, bool noOutput)
|
||||
{
|
||||
int iTrack, iIndex;
|
||||
@@ -4776,7 +4813,7 @@ string status = processor.Go();
|
||||
return AudioReadWrite.GetAudioDest(_audioEncoderType, path, finalSampleCount, bps, 44100, padding, _config);
|
||||
}
|
||||
|
||||
private IAudioSource GetAudioSource(int sourceIndex) {
|
||||
internal IAudioSource GetAudioSource(int sourceIndex) {
|
||||
SourceInfo sourceInfo = _sources[sourceIndex];
|
||||
IAudioSource audioSource;
|
||||
|
||||
@@ -5635,4 +5672,113 @@ string status = processor.Go();
|
||||
public StopException() : base() {
|
||||
}
|
||||
}
|
||||
|
||||
public class CUESheetAudio : IAudioSource
|
||||
{
|
||||
CUESheet cueSheet;
|
||||
IAudioSource currentAudio;
|
||||
int currentSource;
|
||||
long _samplePos, _sampleLen;
|
||||
|
||||
public CUESheetAudio(CUESheet cueSheet)
|
||||
{
|
||||
this.cueSheet = cueSheet;
|
||||
this.currentAudio = null;
|
||||
this._samplePos = 0;
|
||||
this._sampleLen = 0;
|
||||
this.currentSource = 0;
|
||||
for (int iSource = 0; iSource < cueSheet._sources.Count; iSource++)
|
||||
this._sampleLen += cueSheet._sources[iSource].Length;
|
||||
this.currentAudio = cueSheet.GetAudioSource(0);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (currentAudio != null)
|
||||
{
|
||||
currentAudio.Close();
|
||||
currentAudio = null;
|
||||
}
|
||||
}
|
||||
|
||||
public long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return _samplePos;
|
||||
}
|
||||
set
|
||||
{
|
||||
long sourceStart = 0;
|
||||
for (int iSource = 0; iSource < cueSheet._sources.Count; iSource++)
|
||||
{
|
||||
if (value >= sourceStart && value < sourceStart + cueSheet._sources[iSource].Length)
|
||||
{
|
||||
if (iSource != currentSource)
|
||||
{
|
||||
currentAudio.Close();
|
||||
currentSource = iSource;
|
||||
currentAudio = cueSheet.GetAudioSource(currentSource);
|
||||
}
|
||||
currentAudio.Position = value - sourceStart;
|
||||
_samplePos = value;
|
||||
return;
|
||||
}
|
||||
sourceStart += cueSheet._sources[iSource].Length;
|
||||
}
|
||||
throw new Exception("Invalid position");
|
||||
}
|
||||
}
|
||||
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sampleLen;
|
||||
}
|
||||
}
|
||||
|
||||
public long Remaining
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sampleLen - _samplePos;
|
||||
}
|
||||
}
|
||||
|
||||
public AudioPCMConfig PCM
|
||||
{
|
||||
get
|
||||
{
|
||||
return AudioPCMConfig.RedBook;
|
||||
}
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return cueSheet.InputPath;
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(AudioBuffer buff, int maxLength)
|
||||
{
|
||||
buff.Prepare(this, maxLength);
|
||||
|
||||
if (currentAudio.Remaining == 0)
|
||||
{
|
||||
currentSource++;
|
||||
if (currentSource >= cueSheet._sources.Count)
|
||||
{
|
||||
buff.Length = 0;
|
||||
return 0;
|
||||
}
|
||||
currentAudio.Close();
|
||||
currentAudio = cueSheet.GetAudioSource(currentSource);
|
||||
}
|
||||
|
||||
return currentAudio.Read(buff, maxLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace CUETools.Ripper.SCSI
|
||||
//if (st != Device.CommandStatus.Success)
|
||||
// throw new SCSIException("ReadPMA", m_device, st);
|
||||
|
||||
st = m_device.ReadCDText(out cdtext);
|
||||
//st = m_device.ReadCDText(out cdtext, _timeout);
|
||||
// new CDTextEncoderDecoder
|
||||
|
||||
_toc2 = null;
|
||||
@@ -718,8 +718,6 @@ namespace CUETools.Ripper.SCSI
|
||||
int sector = 3;
|
||||
int pass = 0;
|
||||
|
||||
_timeout = 10;
|
||||
|
||||
for (int c = 0; c <= 2 && !found; c++)
|
||||
for (int r = 0; r <= 1 && !found; r++)
|
||||
for (int m = 0; m <= 1 && !found; m++)
|
||||
@@ -750,8 +748,6 @@ namespace CUETools.Ripper.SCSI
|
||||
_autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds);
|
||||
found = st == Device.CommandStatus.Success;
|
||||
|
||||
_timeout = 1;
|
||||
|
||||
//sector += m_max_sectors;
|
||||
}
|
||||
//if (found)
|
||||
@@ -772,7 +768,6 @@ namespace CUETools.Ripper.SCSI
|
||||
else
|
||||
_readCDCommand = ReadCDCommand.Unknown;
|
||||
|
||||
_timeout = 10;
|
||||
_currentStart = -1;
|
||||
_currentEnd = -1;
|
||||
readCommandFound = found;
|
||||
@@ -861,8 +856,8 @@ namespace CUETools.Ripper.SCSI
|
||||
fixed (long* userData = &UserData[sector - _currentStart, 0, 0])
|
||||
fixed (byte* c2Count = &C2Count[sector - _currentStart, 0])
|
||||
{
|
||||
ZeroMemory((byte*)userData, 8 * 2 * 4 * 588 * Sectors2Read);
|
||||
ZeroMemory(c2Count, 294 * Sectors2Read);
|
||||
AudioSamples.MemSet((byte*)userData, 0, 8 * 2 * 4 * 588 * Sectors2Read);
|
||||
AudioSamples.MemSet(c2Count, 0, 294 * Sectors2Read);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,7 +870,7 @@ namespace CUETools.Ripper.SCSI
|
||||
{
|
||||
int size = (4 * 588 + (_c2ErrorMode == Device.C2ErrorMode.Mode294 ? 294 : _c2ErrorMode == Device.C2ErrorMode.Mode296 ? 296 : 0))
|
||||
* (int)Sectors2Read;
|
||||
MemSet(data, size, 0xff);
|
||||
AudioSamples.MemSet(data, 0xff, size);
|
||||
}
|
||||
if (_readCDCommand == ReadCDCommand.ReadCdBEh)
|
||||
st = m_device.ReadCDAndSubChannel(_mainChannelMode, Device.SubChannelMode.None, _c2ErrorMode, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, (IntPtr)((void*)data), _timeout);
|
||||
@@ -914,76 +909,6 @@ namespace CUETools.Ripper.SCSI
|
||||
throw ex;
|
||||
}
|
||||
|
||||
private unsafe void ZeroMemory(short *buf, int count)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
Int32* start = (Int32*)buf;
|
||||
Int32* end = (Int32*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = 0;
|
||||
}
|
||||
else if (IntPtr.Size == 8)
|
||||
{
|
||||
Int64* start = (Int64*)buf;
|
||||
Int64* end = (Int64*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = 0;
|
||||
}
|
||||
else
|
||||
throw new Exception("wierd IntPtr.Size");
|
||||
}
|
||||
|
||||
private unsafe void ZeroMemory(byte* buf, int count)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
Int32* start = (Int32*)buf;
|
||||
Int32* end = (Int32*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = 0;
|
||||
for (int i = 0; i < (count & 3); i++)
|
||||
buf[count - i - 1] = 0;
|
||||
}
|
||||
else if (IntPtr.Size == 8)
|
||||
{
|
||||
Int64* start = (Int64*)buf;
|
||||
Int64* end = (Int64*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = 0;
|
||||
for (int i = 0; i < (count & 7); i++)
|
||||
buf[count - i - 1] = 0;
|
||||
}
|
||||
else
|
||||
throw new Exception("wierd IntPtr.Size");
|
||||
}
|
||||
|
||||
private unsafe void MemSet(byte* buf, int count, byte val)
|
||||
{
|
||||
Int32 intVal = (((((val << 8) + val) << 8) + val) << 8) + val;
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
Int32* start = (Int32*)buf;
|
||||
Int32* end = (Int32*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = intVal;
|
||||
for (int i = 0; i < (count & 3); i++)
|
||||
buf[count - i - 1] = val;
|
||||
}
|
||||
else if (IntPtr.Size == 8)
|
||||
{
|
||||
Int64 int64Val = ((Int64)intVal << 32) + intVal;
|
||||
Int64* start = (Int64*)buf;
|
||||
Int64* end = (Int64*)(buf + count);
|
||||
while (start < end)
|
||||
*(start++) = int64Val;
|
||||
for (int i = 0; i < (count & 7); i++)
|
||||
buf[count - i - 1] = val;
|
||||
}
|
||||
else
|
||||
throw new Exception("wierd IntPtr.Size");
|
||||
}
|
||||
|
||||
private unsafe void CorrectSectors(int pass, int sector, int Sectors2Read, bool markErrors)
|
||||
{
|
||||
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace CUETools.Ripper
|
||||
string RipperVersion { get; }
|
||||
string CurrentReadCommand { get; }
|
||||
int CorrectionQuality { get; set; }
|
||||
int ErrorsCount { get; }
|
||||
BitArray Errors { get; }
|
||||
|
||||
event EventHandler<ReadProgressArgs> ReadProgress;
|
||||
|
||||
@@ -155,6 +155,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.CTDB", "..\CUETool
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProgressODoom", "..\ProgressODoom\ProgressODoom.csproj", "{8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUEPlayer", "..\CUEPlayer\CUEPlayer.csproj", "{04E59836-0C5A-4B9B-8899-848D56911758}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.CoreAudio", "..\CUETools.Codecs.CoreAudio\CUETools.Codecs.CoreAudio.csproj", "{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(TestCaseManagementSettings) = postSolution
|
||||
CategoryFile = CUETools1.vsmdi
|
||||
@@ -570,6 +574,22 @@ Global
|
||||
{8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{04E59836-0C5A-4B9B-8899-848D56911758}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user