开发者

Creating a WaveStream from PCM samples

开发者 https://www.devze.com 2023-01-27 00:30 出处:网络
I checked NAudio and its WaveStream related classes, but I couldn\'t find a built in way to create a WaveStream based on PCM samples that I provide.

I checked NAudio and its WaveStream related classes, but I couldn't find a built in way to create a WaveStream based on PCM samples that I provide.

Ideally I would like to do something like this:

byte[] samples = ...
WaveFormat waveFormat = new WaveFormat(au开发者_运维技巧dioSampleRate, 
                                       audioBitsPerSample,
                                       audioChannels);
WaveStream waveStream = CreateWaveStreamfromSamples(waveFormat,
                                                    samples);

Is there a way to do this using NAudio?

Edit after clarification from Hans, Mark (thanks for the feedback):

I needed a stream that I could pass to SoundPlayer.Play, this doesn't fit well with WaveStream. In my project I ended up implementing the following class which takes samples and a WaveFormat and can be played back by 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();
    }
}


Here's a class that you can pass a MemoryStream based on your byte array into if you want. I'll probably include something like this in NAudio 1.4 as I get a lot of support requests about how to do this.

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);
    }
}


No, nothing like it. You can however create your own. The wave\wavestream\wavefilereader.cs source code file is probably best to get started with. Bunch of stuff you can strip from it, replace the waveStream by a properly initialized MemoryStream.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号