【问题标题】:Saving each WAV channel as a mono-channel WAV file using Naudio使用 Naudio 将每个 WAV 通道保存为单通道 WAV 文件
【发布时间】:2012-08-17 23:47:04
【问题描述】:

我正在尝试将 WAV 文件(PCM,48kHz,4 声道,16 位)转换为单声道 WAV 文件。

我尝试将 WAV 文件拆分为 4 个字节数组,例如 answer,并创建了一个 WaveMemoryStream,如下所示,但不起作用。

byte[] chan1ByteArray = new byte[channel1Buffer.Length];
Buffer.BlockCopy(channel1Buffer, 0, chan1ByteArray, 0, chan1ByteArray.Length);
WaveMemoryStream chan1 = new WaveMemoryStream(chan1ByteArray, sampleRate, (ushort)bitsPerSample, 1);

我在创建 WAVE 标头时是否遗漏了什么?或者还有更多可以拆分 WAV 转换成单声道 WAV 文件 ?

【问题讨论】:

  • 当我在 Adob​​e Audition 中用我的 4 通道 WAV 文件创建单声道 WAV 文件时,我注意到比特率从 3072kbps 下降到 768kbps,这是原始比特率的四分之一。我是否需要降低比特率以及如何使用 NAudio 来降低比特率?

标签: c# audio naudio waveform wave


【解决方案1】:

基本思想是源波形文件包含交错的样本。一个用于第一个通道,一个用于第二个通道,依此类推。下面是一些未经测试的示例代码,可让您了解如何执行此操作。

var reader = new WaveFileReader("fourchannel.wav");
var buffer = new byte[2 * reader.WaveFormat.SampleRate * reader.WaveFormat.Channels];
var writers = new WaveFileWriter[reader.WaveFormat.Channels];
for (int n = 0; n < writers.Length; n++) 
{
    var format = new WaveFormat(reader.WaveFormat.SampleRate,16,1);
    writers[n] = new WaveFileWriter(String.Format("channel{0}.wav",n+1), format);
}
int bytesRead;
while((bytesRead = reader.Read(buffer,0, buffer.Length)) > 0) 
{
    int offset=  0;
    while (offset < bytesRead) 
    {
        for (int n = 0; n < writers.Length; n++) 
        {
            // write one sample
            writers[n].Write(buffer,offset,2);
            offset += 2;
        }           
    }
}
for (int n = 0; n < writers.Length; n++) 
{
    writers[n].Dispose();
}
reader.Dispose();

【讨论】:

    【解决方案2】:

    根据 Mark Heath 的回答,我在一个包含 32 个通道的 32 位浮动 WAV 上苦苦挣扎,并通过简化他的建议来设法让它工作。我猜这个和平代码也适用于四声道音频 WAV 文件。

        var reader = new WaveFileReader("thirtytwochannels.wav");
        var writers = new WaveFileWriter[reader.WaveFormat.Channels];
        for (int n = 0; n < writers.Length; n++)
        {
            var format = new WaveFormat(reader.WaveFormat.SampleRate, 16, 1);
            writers[n] = new WaveFileWriter(string.Format($"channel{n + 1}.wav"), format);
        }
    
        float[] buffer;
        while ((buffer = reader.ReadNextSampleFrame())?.Length > 0)
        {
            for(int i = 0; i < buffer.Length; i++)
            {
                // write one sample for each channel (i is the channelNumber)
                writers[i].WriteSample(buffer[i]);
            }
        }
    
        for (int n = 0; n < writers.Length; n++)
        {
            writers[n].Dispose();
        }
        reader.Dispose();
    

    【讨论】:

      【解决方案3】:

      这是我使用的一种方法,你可以设置输出单声道格式,例如BitsPerSample、SampleRate

      using NAudio.Wave;
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      
      namespace DataScraper.TranscriptionCenter
      {
          public class MP3ToWave
          {
              /// <summary>
              /// Converts an MP3 file to distinct wav files, using NAudio
              /// They are saved in the same directory as the MP3 file
              /// </summary>
              /// <param name="MP3FileIn">The MP3 file</param>
              /// <returns>Returns the WAV files</returns>
              public static string[] MP3FilesToTranscriptionWaveFiles(string MP3FileIn)
              {
                  FileInfo MP3FileInfo = new FileInfo(MP3FileIn);
                  if (MP3FileInfo.Exists == false)
                      throw new Exception("File does not exist? " + MP3FileIn);
                  Mp3FileReader readerMP3 = null;
                  WaveStream PCMStream = null;
                  WaveFileReader readerWAV = null;
                  List<string> ListFilesOut = null;
                  WaveFileWriter[] FileWriters = null;
                  MemoryStream TempStream = null;
                  WaveFormatConversionStream WaveFormatConversionStream_ = null;
                  WaveFormat SaveWaveFormatMono = new WaveFormat((16 * 1000), 
                          16, 
                          1);
                  try
                  {
                      readerMP3 = new Mp3FileReader(MP3FileInfo.FullName);
                      PCMStream = WaveFormatConversionStream.CreatePcmStream(readerMP3);
                      WaveFormatConversionStream_ = new WaveFormatConversionStream(new     WaveFormat(SaveWaveFormatMono.SampleRate, 
                          SaveWaveFormatMono.BitsPerSample, 
                          PCMStream.WaveFormat.Channels),
                          PCMStream);
                  
                      //Each filepath, each channel
                      ListFilesOut = new List<string>    (WaveFormatConversionStream_.WaveFormat.Channels);
                  
      
                      //Each is a wav file out
                      for (int index = 0; index <     WaveFormatConversionStream_.WaveFormat.Channels; index++)
                  {
                      ListFilesOut.Add(MP3FileInfo.Directory.FullName + "\\" + Path.GetFileNameWithoutExtension(MP3FileInfo.Name) + "_" + index.ToString() + ".wav");
                  }
      
                  //Initialize the writers
                  FileWriters = new WaveFileWriter[WaveFormatConversionStream_.WaveFormat.Channels];
                  for (int index = 0; index < WaveFormatConversionStream_.WaveFormat.Channels; index++)
                  {
                      FileWriters[index] = new WaveFileWriter(ListFilesOut[index], SaveWaveFormatMono);
                  }
      
      
                  TempStream = new MemoryStream(int.Parse("" + WaveFormatConversionStream_.Length));
                  WaveFileWriter NewWriter = new WaveFileWriter(TempStream, WaveFormatConversionStream_.WaveFormat);
                  byte[] BUFFER = new byte[1024];
                  int ReadLength = WaveFormatConversionStream_.Read(BUFFER, 0, BUFFER.Length);
                  while (ReadLength != -1 && ReadLength > 0)
                  {
                      NewWriter.Write(BUFFER, 0, ReadLength);
                      ReadLength = WaveFormatConversionStream_.Read(BUFFER, 0, BUFFER.Length);
                  }
                  NewWriter.Flush();
                  
                  
      
                  TempStream.Position = 0;
                  readerWAV = new WaveFileReader(TempStream);
                  
                  float[] buffer = readerWAV.ReadNextSampleFrame();
                  
                  while(buffer != null && buffer.Length > 0)
                  {
                      for(int i = 0; i < buffer.Length; i++)
                      {
                          FileWriters[i].WriteSample(buffer[i]);
                      }
                      buffer = readerWAV.ReadNextSampleFrame();
                  }
              }
              catch (Exception em1)
              {
                  throw em1;
              }
              finally
              {
      
                  
                  try
                  {
                      //Flush each writer and close
                      for (int writercount = 0; writercount < FileWriters.Length; writercount++)
                      {
                          FileWriters[writercount].Flush();
                          FileWriters[writercount].Close();
                          FileWriters[writercount].Dispose();
                      }
                  }
                  catch
                  {
      
                  }
      
                  try { readerWAV.Dispose(); readerWAV = null; }
                  catch { }
      
                  try { WaveFormatConversionStream_.Dispose(); WaveFormatConversionStream_ = null; }
                  catch { }
      
                  try { PCMStream.Dispose(); PCMStream = null; }
                  catch { }
      
                  try { readerMP3.Dispose(); readerMP3 = null; }
                  catch { }
      
                  try
                  {
                      TempStream.Close(); TempStream.Dispose();
                  }
                  catch
                  {
      
                  }
              }
                  return ListFilesOut.ToArray();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        相关资源
        最近更新 更多