0

I try to concatenate some data in different durations but same sample rate. I concatenate the data with MemoryStream.CopyTo(memoryStream) method.

Is there any way to play a data from a memory stream which don't have a wav header in the start?

And if not, is there any way to append a wav headers to to start after the stream was appended?

(I want to avoid generating a file in the disk..)

axcelenator
  • 1,497
  • 3
  • 18
  • 42
  • possible duplicate of [Play wav/mp3 from memory](http://stackoverflow.com/questions/6340967/play-wav-mp3-from-memory) – goobering Jun 19 '15 at 13:17
  • @goobering except their looking for naudio – kenny Jun 19 '15 at 13:18
  • Hello, the link you provided generates a class which uses a buffer that includes wav headers. My buffer doesn't contain a headers. I get this exception: > An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll Additional information: The wave header is corrupt. – axcelenator Jun 19 '15 at 13:27
  • You could create the file and just dynamically delete it afterwards? – Adam Jun 19 '15 at 13:31
  • I want to avoid that situation. I prefer disposing the stream after playing it instead of handling with files – axcelenator Jun 19 '15 at 13:33

2 Answers2

1

To do this with NAudio, just use a RawSourceWaveStream and pass in the MemoryStream containing the raw concatenated audio to its constructor. You'll also need to explicitly specify that the WaveFormat is.

memoryStream = ... // construct your audio
memoryStream.Position = 0; // rewind to beginning
var rs = new RawSourceWaveStream(memoryStream, new WaveFormat(sampleRate, 16, 1));
Mark Heath
  • 48,273
  • 29
  • 137
  • 194
0

You can write header to your stream, then play the WAV with SoundPlayer.

    //your wav streams
    MemoryStream wavNoHeader1=new MemoryStream();
    MemoryStream wavNoHeader2 = new MemoryStream();
    //result WAV stream
    MemoryStream wav=new MemoryStream();
    //create & write header
    ushort numchannels = 1;
    ushort samplelength = 1; // in bytes
    uint samplerate = 22050;
    int wavsize = (int) ((wavNoHeader1.Length + wavNoHeader2.Length)/(numchannels*samplelength));
    BinaryWriter wr = new BinaryWriter(wav);
    wr.Write(Encoding.ASCII.GetBytes("RIFF"));
    wr.Write(36 + wavsize);
    wr.Write(Encoding.ASCII.GetBytes("WAVEfmt "));
    wr.Write(16);
    wr.Write((ushort)1);
    wr.Write(numchannels);
    wr.Write(samplerate);
    wr.Write(samplerate * samplelength * numchannels);
    wr.Write(samplelength * numchannels);
    wr.Write((ushort)(8 * samplelength));
    wr.Write(Encoding.ASCII.GetBytes("data"));
    wr.Write(numsamples * samplelength);
    //append data from raw streams
    wavNoHeader1.CopyTo(wav);
    wavNoHeader2.CopyTo(wav);
    //play
    wav.Position = 0;
    SoundPlayer sp=new SoundPlayer(wav);
    sp.Play();
cyberj0g
  • 3,707
  • 1
  • 19
  • 34
  • Hello, thanks for the answer, in the top of it what is difference between uint numsamples = 44100 and uint samplerate = 22050 ? – axcelenator Jun 19 '15 at 13:40
  • Hello, I assume that the wav headers include the total length of the audio file. But my concatenated wav file is unknown at the beginning of the progress... – axcelenator Jun 19 '15 at 13:48
  • Yes, I missed that, the length of resulting WAV data should be in the header, edited my code. If you don't know size of your source streams, you probably should create some kind of buffer. – cyberj0g Jun 19 '15 at 13:53
  • How can I formulate the resulting length? And if my every sample is 2 bytes the ushort samplelength must equal 2? – axcelenator Jun 19 '15 at 15:15