C# 从PCM样本创建波流

C# 从PCM样本创建波流,c#,audio,naudio,C#,Audio,Naudio,我检查了NAudio及其WaveStream相关类,但找不到基于我提供的PCM样本创建WaveStream的内置方法 理想情况下,我想这样做: byte[] samples = ... WaveFormat waveFormat = new WaveFormat(audioSampleRate, audioBitsPerSample, au

我检查了NAudio及其
WaveStream
相关类,但找不到基于我提供的PCM样本创建
WaveStream
的内置方法

理想情况下,我想这样做:

byte[] samples = ...
WaveFormat waveFormat = new WaveFormat(audioSampleRate, 
                                       audioBitsPerSample,
                                       audioChannels);
WaveStream waveStream = CreateWaveStreamfromSamples(waveFormat,
                                                    samples);
有没有办法使用NAudio实现这一点?

在Hans,Mark澄清后编辑(感谢反馈):

我需要一个可以传递给
SoundPlayer.Play的流,这不适合
WaveStream
。在我的项目中,我最终实现了下面的类,该类获取样本和
波形格式
,并可由
SoundPlayer
播放

public class MemoryWaveStream : Stream
{
    public override bool CanSeek { get { return false; } }
    public override bool CanWrite { get { return false; } }
    public override bool CanRead { get { return true; } }
    public override long Length { get { return _waveStream.Length; } }
    public override long Position { get { return _waveStream.Position; } set { _waveStream.Position = value; } }

    private MemoryStream _waveStream;

    public MemoryWaveStream(byte[] sampleData, WaveFormat waveFormat)
    {
        _waveStream = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(_waveStream);
        bw.Write(new char[4] { 'R', 'I', 'F', 'F' });

        int length = 36 + sampleData.Length;
        bw.Write(length);

        bw.Write(new char[8] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });

        waveFormat.Serialize(bw);
        bw.Write(new char[4] { 'd', 'a', 't', 'a' });
        bw.Write(sampleData.Length);
        bw.Write(sampleData, 0, sampleData.Length);
        _waveStream.Position = 0;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _waveStream.Read(buffer, offset, count);
    }

    public override void Flush()
    {
        _waveStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _waveStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        throw new NotImplementedException();
    }
}

不,一点也不像。但是,您可以创建自己的。wave\wavestream\waveilereader.cs源代码文件可能是最好的入门文档。您可以从中剥离大量内容,用正确初始化的MemoryStream替换波流。

这里有一个类,您可以根据字节数组将
MemoryStream
传递到其中。我可能会在NAudio 1.4中包含类似的内容,因为我收到很多关于如何实现这一点的支持请求

public class RawSourceWaveStream : WaveStream
{
    private Stream sourceStream;
    private WaveFormat waveFormat;

    public RawSourceWaveStream(Stream sourceStream, WaveFormat waveFormat)
    {
        this.sourceStream = sourceStream;
        this.waveFormat = waveFormat;
    }

    public override WaveFormat WaveFormat
    {
        get { return this.waveFormat; }
    }

    public override long Length
    {
        get { return this.sourceStream.Length; }
    }

    public override long Position
    {
        get
        {
            return this.sourceStream.Position;
        }
        set
        {
            this.sourceStream.Position = value;
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return sourceStream.Read(buffer, offset, count);
    }
}

是的,我做了我自己的(在内部使用MemoryStream实现流派生类,只需拍打一个Wave头),但我更喜欢内置的东西,而不是重新发明轮子。我确实提交了一个补丁-我不知道这个类对整个项目是否有用,我们将看到;-)@BrokenGlass-WaveStreams不应从其只读方法音频返回波头。
WaveFormat
waveilewriter
在写入WAV文件时使用。@Mark-我的错误。我需要一个可由SoundPlayer播放的流,因此从WaveStream派生可能不是正确的选择。我将在编辑中发布我的最终结果。感谢您提供自定义类。