Trim一个wav文件
Trim a wav file
我正在尝试使用 here
中的代码 trim 一个文件
public static void TrimWavFile(string inPath, string outPath, TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000;
int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond;
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = (int)reader.Length - endBytes;
TrimWavFile(reader, writer, startPos, endPos);
}
}
}
private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos)
{
reader.Position = startPos;
byte[] buffer = new byte[1024];
while (reader.Position < endPos)
{
int bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.WriteData(buffer, 0, bytesRead);
}
}
}
}
我在里面写了准确的内容,但是当我打开文件时,我 trimmed 说他已经损坏了。
这段代码是如何工作的? while (reader.Position < endPos)
始终为真,reader.Position
不变。
编辑 1
else if() 与 else 相同,但我只是为了确定。
while (reader.Position < end)
{
int bytesRequired = (int)(end - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.Write(buffer, 0, bytesRead);
}
else if (bytesRead == 0)
{
break;
}
}
else if (bytesRequired <= 0)
{
break;
}
}
如果 bytesRequired <= 0
或者 bytesRead == 0
你应该跳出 while 循环
我找到了解决方案。完成后我不得不写writer.Dispose()。
像那样:
public static void TrimWavFile(string inPath, string outPath, TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000;
int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond;
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = (int)reader.Length - endBytes;
TrimWavFile(reader, writer, startPos, endPos);
writer.Dispose();
}
}
您使用的示例代码有点过时并且有一些错误。
这是一个更新版本(对我来说效果很好):
private void Cut()
{
var filename = @"G:\Voice\Samples\LongAudioFile.wav";
FileInfo fi = new FileInfo(filename);
var outputPath = System.IO.Path.Combine(fi.Directory.FullName, string.Format("{0}_Shorter{1}", fi.Name.Replace(fi.Extension, ""), fi.Extension));
TrimWavFile(filename, outputPath, TimeSpan.FromHours(1));
}
public static void TrimWavFile(string inPath, string outPath, TimeSpan duration)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
float bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000f;
int startPos = 0;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)Math.Round(duration.TotalMilliseconds * bytesPerMillisecond);
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = endBytes;
TrimWavFile(reader, writer, startPos, endBytes);
}
}
}
private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos)
{
reader.Position = startPos;
byte[] buffer = new byte[reader.BlockAlign * 1024];
while (reader.Position < endPos)
{
int bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.Write(buffer, 0, bytesRead);
}
}
}
}
请注意,在我的例子中,我需要获取从开始到某个点(例如:1H)的音频。
如果您想在中间某处获得特定部分,只需更改:
int startPos = 0;
至
int startBytes = (int)Math.Round(startPoint.TotalMilliseconds * bytesPerMillisecond);
startBytes = startBytes - startBytes % reader.WaveFormat.BlockAlign;
int startPos = startBytes;
我正在尝试使用 here
中的代码 trim 一个文件 public static void TrimWavFile(string inPath, string outPath, TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000;
int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond;
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = (int)reader.Length - endBytes;
TrimWavFile(reader, writer, startPos, endPos);
}
}
}
private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos)
{
reader.Position = startPos;
byte[] buffer = new byte[1024];
while (reader.Position < endPos)
{
int bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.WriteData(buffer, 0, bytesRead);
}
}
}
}
我在里面写了准确的内容,但是当我打开文件时,我 trimmed 说他已经损坏了。
这段代码是如何工作的? while (reader.Position < endPos)
始终为真,reader.Position
不变。
编辑 1 else if() 与 else 相同,但我只是为了确定。
while (reader.Position < end)
{
int bytesRequired = (int)(end - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.Write(buffer, 0, bytesRead);
}
else if (bytesRead == 0)
{
break;
}
}
else if (bytesRequired <= 0)
{
break;
}
}
如果 bytesRequired <= 0
或者 bytesRead == 0
我找到了解决方案。完成后我不得不写writer.Dispose()。 像那样:
public static void TrimWavFile(string inPath, string outPath, TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000;
int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond;
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = (int)reader.Length - endBytes;
TrimWavFile(reader, writer, startPos, endPos);
writer.Dispose();
}
}
您使用的示例代码有点过时并且有一些错误。 这是一个更新版本(对我来说效果很好):
private void Cut()
{
var filename = @"G:\Voice\Samples\LongAudioFile.wav";
FileInfo fi = new FileInfo(filename);
var outputPath = System.IO.Path.Combine(fi.Directory.FullName, string.Format("{0}_Shorter{1}", fi.Name.Replace(fi.Extension, ""), fi.Extension));
TrimWavFile(filename, outputPath, TimeSpan.FromHours(1));
}
public static void TrimWavFile(string inPath, string outPath, TimeSpan duration)
{
using (WaveFileReader reader = new WaveFileReader(inPath))
{
using (WaveFileWriter writer = new WaveFileWriter(outPath, reader.WaveFormat))
{
float bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000f;
int startPos = 0;
startPos = startPos - startPos % reader.WaveFormat.BlockAlign;
int endBytes = (int)Math.Round(duration.TotalMilliseconds * bytesPerMillisecond);
endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
int endPos = endBytes;
TrimWavFile(reader, writer, startPos, endBytes);
}
}
}
private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos)
{
reader.Position = startPos;
byte[] buffer = new byte[reader.BlockAlign * 1024];
while (reader.Position < endPos)
{
int bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired > 0)
{
int bytesToRead = Math.Min(bytesRequired, buffer.Length);
int bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
writer.Write(buffer, 0, bytesRead);
}
}
}
}
请注意,在我的例子中,我需要获取从开始到某个点(例如:1H)的音频。 如果您想在中间某处获得特定部分,只需更改:
int startPos = 0;
至
int startBytes = (int)Math.Round(startPoint.TotalMilliseconds * bytesPerMillisecond);
startBytes = startBytes - startBytes % reader.WaveFormat.BlockAlign;
int startPos = startBytes;