Создание WaveStream из образцов PCM - PullRequest
3 голосов
/ 24 ноября 2010

Я проверил NAudio и его WaveStream связанные классы, но не смог найти встроенный способ создания WaveStream на основе предоставленных мною примеров PCM.

В идеале я хотел бы сделать что-то вроде этого:

byte[] samples = ...
WaveFormat waveFormat = new WaveFormat(audioSampleRate, 
                                       audioBitsPerSample,
                                       audioChannels);
WaveStream waveStream = CreateWaveStreamfromSamples(waveFormat,
                                                    samples);

Есть ли способ сделать это с помощью NAudio?

Редактировать после уточнения от Ганса, Марк (спасибо за отзыв):

Мне нужен был поток, который я мог бы передать SoundPlayer.Play, это не очень хорошо сочетается с WaveStream. В моем проекте я реализовал следующий класс, который берет сэмплы и WaveFormat и может быть воспроизведен с помощью 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();
    }
}

Ответы [ 2 ]

5 голосов
/ 25 ноября 2010

Вот класс, в который вы можете передать 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);
    }
}
2 голосов
/ 24 ноября 2010

Нет, ничего подобного.Однако вы можете создать свой собственный.Вероятно, лучше всего начать с файла исходного кода wave \ wavestream \ wavefilereader.cs.Куча вещей, которые можно извлечь из него, замените waveStream на правильно инициализированный MemoryStream.

...