0

I get audio samples (as float array) from another method and I want to play this float array without writing any files to disk.

For this example I get samples from audio file:

var file = new AudioFileReader(stereoFile);

int startPos = 0;
int endPos = 138890;

var sampleArray = new float[endPos - startPos];

file.Read(sampleArray, startPos, sampleArray.Length);

How can I play sampleArray?

Deim
  • 111
  • 5
  • Does this answer your question? [How can I play byte array of audio raw data using NAudio?](https://stackoverflow.com/questions/28792548/how-can-i-play-byte-array-of-audio-raw-data-using-naudio) – Sinatr Feb 04 '21 at 09:36
  • @00110001 this is byte array, not float sample array. this answer not work with samples – Deim Feb 04 '21 at 09:38
  • @Sinatr unfortunately not. – Deim Feb 04 '21 at 09:39
  • 1
    Sinatr's answer should work once you have converted those floating-point samples to e.g. 16-bit signed samples. – AKX Feb 04 '21 at 09:48
  • @AKX This is possible way, but if I correctly understand this question https://stackoverflow.com/questions/18689410/convert-32-bit-float-audio-to-16-bit-byte-array this way not easyest. Maybe there's a better way to do this? – Deim Feb 04 '21 at 10:13
  • It's not really particularly _hard_ ... but you could also try if using a [float data format](https://github.com/naudio/NAudio/blob/889ec87e1e8153504de330cacb2e7ca3e6437c5a/NAudio/Wave/WaveFormats/WaveFormat.cs#L135) would work directly. – AKX Feb 04 '21 at 11:16

2 Answers2

0

I find next solution and it work for me:

        var file = new AudioFileReader(stereoFile);

        WaveFormat waveFormat = file.WaveFormat;

        int startPos = 2403;
        int endPos = 41265;

        if (startPos % 2 != 0)
        {
            startPos += 1;
        }

        if (endPos % 2 != 0)
        {
            endPos += 1;
        }

        if (waveFormat.Channels == 2)
        {
            startPos *= 2;
            endPos *= 2;
        }

        var allSamples = new float[file.Length / (file.WaveFormat.BitsPerSample / 8)];

        file.Read(allSamples, 0, allSamples.Length);

        Span<float> samplesSpan = allSamples;
        Span<float> trackSpan = samplesSpan.Slice(startPos, endPos - startPos);

^ upper code to take correct samples for tests. code below - my solution

        MemoryStream ms = new MemoryStream();
        IgnoreDisposeStream ids = new IgnoreDisposeStream(ms);

        using (WaveFileWriter waveFileWriter = new WaveFileWriter(ids, waveFormat))
        {
            waveFileWriter.WriteSamples(trackSpan.ToArray(), 0, endPos-startPos);
        }


        ms.Position = 0;
        WaveStream waveStream = new WaveFileReader(ms);
        WaveOutEvent waveOutEvent = new WaveOutEvent();
        waveOutEvent.Init(waveStream);
        waveOutEvent.Play();
Deim
  • 111
  • 5
0

RawSourceWaveStream is designed for the situation where you have audio in a byte array or MemoryStream and want to play it directly. You can learn more about it and see an example of how to use it here

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • How can i play sample array with RawSourceWaveStream? RawSourceWaveStream can work with byte[] or Stream but not with float[] – Deim Feb 05 '21 at 12:35
  • You can use the WaveBuffer class as a way to cast between the two, or use something like Buffer.BlockCopy to copy float samples into a byte[] – Mark Heath Feb 06 '21 at 16:49