我正在尝试将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文件?
答案 0 :(得分:5)
基本思想是源波文件包含交错的样本。一个用于第一个通道,一个用于第二个通道,依此类推。这里有一些未经测试的示例代码,可以让您了解如何执行此操作。
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();
答案 1 :(得分:1)
基于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();
答案 2 :(得分:1)
这是我使用的一种方法,您可以设置输出单声道格式,例如 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();
}
}
}