mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Removed AudioEncoderSettings/AudioDecoderSettings classes, all of their functionality is now in IAudioEncoderSettings/IAudioDecoderSettings interfaces.
This commit is contained in:
160
CUETools.Codecs.WMA/AudioEncoder.cs
Normal file
160
CUETools.Codecs.WMA/AudioEncoder.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using WindowsMediaLib;
|
||||
using WindowsMediaLib.Defs;
|
||||
|
||||
namespace CUETools.Codecs.WMA
|
||||
{
|
||||
public class AudioEncoder : IAudioDest
|
||||
{
|
||||
IWMWriter m_pEncoder;
|
||||
private string outputPath;
|
||||
private bool closed = false;
|
||||
private bool fileCreated = false;
|
||||
private bool writingBegan = false;
|
||||
private long sampleCount, finalSampleCount;
|
||||
|
||||
public long FinalSampleCount
|
||||
{
|
||||
set
|
||||
{
|
||||
this.finalSampleCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get { return this.outputPath; }
|
||||
}
|
||||
|
||||
EncoderSettings m_settings;
|
||||
|
||||
public IAudioEncoderSettings Settings => m_settings;
|
||||
|
||||
public AudioEncoder(string path, EncoderSettings settings)
|
||||
{
|
||||
this.m_settings = settings;
|
||||
this.outputPath = path;
|
||||
|
||||
try
|
||||
{
|
||||
m_pEncoder = settings.GetWriter();
|
||||
int cInputs;
|
||||
m_pEncoder.GetInputCount(out cInputs);
|
||||
if (cInputs < 1) throw new InvalidOperationException();
|
||||
IWMInputMediaProps pInput;
|
||||
m_pEncoder.GetInputProps(0, out pInput);
|
||||
try
|
||||
{
|
||||
int cbType = 0;
|
||||
AMMediaType pMediaType = null;
|
||||
pInput.GetMediaType(pMediaType, ref cbType);
|
||||
pMediaType = new AMMediaType();
|
||||
pMediaType.formatSize = cbType - Marshal.SizeOf(typeof(AMMediaType));
|
||||
pInput.GetMediaType(pMediaType, ref cbType);
|
||||
try
|
||||
{
|
||||
var wfe = new WaveFormatExtensible(m_settings.PCM);
|
||||
Marshal.FreeCoTaskMem(pMediaType.formatPtr);
|
||||
pMediaType.formatPtr = IntPtr.Zero;
|
||||
pMediaType.formatSize = 0;
|
||||
pMediaType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(wfe));
|
||||
pMediaType.formatSize = Marshal.SizeOf(wfe);
|
||||
Marshal.StructureToPtr(wfe, pMediaType.formatPtr, false);
|
||||
pInput.SetMediaType(pMediaType);
|
||||
m_pEncoder.SetInputProps(0, pInput);
|
||||
}
|
||||
finally
|
||||
{
|
||||
WMUtils.FreeWMMediaType(pMediaType);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.ReleaseComObject(pInput);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (m_pEncoder != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(m_pEncoder);
|
||||
m_pEncoder = null;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!this.closed)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.writingBegan)
|
||||
{
|
||||
m_pEncoder.EndWriting();
|
||||
this.writingBegan = false;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (m_pEncoder != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(m_pEncoder);
|
||||
m_pEncoder = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
if (this.outputPath == null)
|
||||
throw new InvalidOperationException("This writer was not created from file.");
|
||||
|
||||
if (!this.closed)
|
||||
{
|
||||
this.Close();
|
||||
|
||||
if (this.fileCreated)
|
||||
{
|
||||
File.Delete(this.outputPath);
|
||||
this.fileCreated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(AudioBuffer buffer)
|
||||
{
|
||||
if (this.closed)
|
||||
throw new InvalidOperationException("Writer already closed.");
|
||||
|
||||
if (!this.fileCreated)
|
||||
{
|
||||
this.m_pEncoder.SetOutputFilename(outputPath);
|
||||
this.fileCreated = true;
|
||||
}
|
||||
if (!this.writingBegan)
|
||||
{
|
||||
this.m_pEncoder.BeginWriting();
|
||||
this.writingBegan = true;
|
||||
}
|
||||
|
||||
buffer.Prepare(this);
|
||||
INSSBuffer pSample;
|
||||
m_pEncoder.AllocateSample(buffer.ByteLength, out pSample);
|
||||
IntPtr pdwBuffer;
|
||||
pSample.GetBuffer(out pdwBuffer);
|
||||
pSample.SetLength(buffer.ByteLength);
|
||||
Marshal.Copy(buffer.Bytes, 0, pdwBuffer, buffer.ByteLength);
|
||||
long cnsSampleTime = sampleCount * 10000000L / Settings.PCM.SampleRate;
|
||||
m_pEncoder.WriteSample(0, cnsSampleTime, SampleFlag.CleanPoint, pSample);
|
||||
Marshal.ReleaseComObject(pSample);
|
||||
sampleCount += buffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user