修剪一个wav文件

时间:2017-02-11 00:05:58

标签: c# wpf audio trim naudio

我正在尝试使用here

中的代码修剪文件
 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);
            }
        }
    }
}

我在那里写下了什么,但是当我打开文件时我修剪了它说他已经腐败了。

此代码如何运作? while (reader.Position < endPos)始终为true,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;
            }
        }

3 个答案:

答案 0 :(得分:1)

如果bytesRequired <= 0bytesRead == 0

,您应该摆脱while循环

答案 1 :(得分: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();
        }
    }

答案 2 :(得分:0)

您使用的示例代码有些过时并且有一些错误。 这是一个更新的版本(对我来说效果很好):

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;