Skip to content

Commit acca61d

Browse files
committed
Documentation for RawSourceWaveStream
1 parent 36bc4c3 commit acca61d

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

Docs/RawSourceWaveStream.md

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Using RawSourceWaveStream
2+
3+
`RawSourceWaveStream` is useful when you have some raw audio, which might be PCM or compressed, but it is not contained within a file format. `RawSourceWaveStream` allows you to specify the `WaveFormat` associated with the raw audio. Let's see some examples.
4+
5+
## Playing from a Byte array
6+
7+
Suppose we have a byte array containing raw 16 bit mono PCM, and want to play it.
8+
9+
For demo purposes, let's create a 5 second sawtooth wave into the `raw`. Obviously `SignalGenerator` would be a better way to do this, but we are simulating getting a byte array from somewhere else, maybe received over the network.
10+
11+
```c#
12+
var sampleRate = 16000;
13+
var frequency = 500;
14+
var amplitude = 0.2;
15+
var seconds = 5;
16+
17+
var raw = new byte[sampleRate * seconds * 2];
18+
19+
var multiple = 2.0*frequency/sampleRate;
20+
for (int n = 0; n < sampleRate * seconds; n++)
21+
{
22+
var sampleSaw = ((n*multiple)%2) - 1;
23+
var sampleValue = sampleSaw > 0 ? amplitude : -amplitude;
24+
var sample = (short)(sampleValue * Int16.MaxValue);
25+
var bytes = BitConverter.GetBytes(sample);
26+
raw[n*2] = bytes[0];
27+
raw[n*2 + 1] = bytes[1];
28+
}
29+
```
30+
31+
`RawSourceWaveStream` takes a `Stream` and a `WaveFormat`. The `WaveFormat` in this instance is 16 bit mono PCM. The stream we can use `MemoryStream` for, passing in our byte array.
32+
33+
```c#
34+
var ms = new MemoryStream(raw);
35+
var rs = new RawSourceWaveStream(ms, new WaveFormat(sampleRate, 16, 1));
36+
```
37+
38+
And now we can play the `RawSourceWaveStream` just like it was any other `WaveStream`:
39+
40+
```c#
41+
var wo = new WaveOutEvent();
42+
wo.Init(rs);
43+
wo.Play();
44+
while (wo.PlaybackState == PlaybackState.Playing)
45+
{
46+
Thread.Sleep(500);
47+
}
48+
wo.Dispose();
49+
```
50+
51+
## Turning a raw file into WAV
52+
53+
Suppose we have a raw audio file and we know the wave format of the audio in it. Let's say its 8kHz 16 bit mono. We can just open the file with `File.OpenRead` and pass it into a `RawSourceWaveStream`. Then we can convert it to a WAV file with `WaveFileWriter.CreateWaveFile`.
54+
55+
```c#
56+
var path = "example.pcm";
57+
var s = new RawSourceWaveStream(File.OpenRead(path), new WaveFormat(8000,1));
58+
var outpath = "example.wav";
59+
WaveFileWriter.CreateWaveFile(outpath, s);
60+
```
61+
62+
Note that WAV files can contain compressed audio, so as long as you know the correct `WaveFormat` structure you can use that. Let's look at a compressed audio example next.
63+
64+
## Converting G.729 audio into a PCM WAV
65+
66+
Suppose we have a .g729 file containing raw audio compressed with G.729. G.729 isn't actually a built-in `WaveFormat` in NAudio (some other common ones like mu and a-law are). But we can use `WaveFormat.CreateCustomFormat` or even derive from `WaveFormat` to define the correct format.
67+
68+
Now in the previous example we saw how we could create a WAV file that contains the G.729 audio still encoded. But if we wanted it to be PCM, we'd need to use `WaveFormatConversionStream.CreatePcmStream` to look for an ACM codec that understands the incoming `WaveFormat` and can turn it into PCM.
69+
70+
Please note that this won't always be possible. If your version of Windows doesn't have a suitable decoder, this will fail.
71+
72+
But here's how we would convert that raw G.729 file into a PCM WAV file if we did have a suitable decoder:
73+
74+
```c#
75+
var inFile = @"c:\users\mheath\desktop\chirpg729.g729";
76+
var outFile = @"c:\users\mheath\desktop\chirpg729.wav";
77+
var inFileFormat = WaveFormat.CreateCustomFormat(
78+
WaveFormatEncoding.G729,
79+
8000, // sample rate
80+
1, // channels
81+
1000, // average bytes per second
82+
10, // block align
83+
1); // bits per sample
84+
using(var inStream = File.OpenRead(inFile))
85+
using(var reader = new RawSourceWaveStream(inStream, inFileFormat))
86+
using(var converter = WaveFormatConversionStream.CreatePcmStream(reader))
87+
{
88+
WaveFileWriter.CreateWaveFile(outFile, converter);
89+
}
90+
```
91+
92+
If it was a format that NAUdio has built-in support for like G.711 a-law, then we'd do it like this:
93+
94+
```c#
95+
var inFile = @"c:\users\mheath\desktop\alaw.bin";
96+
var outFile = @"c:\users\mheath\desktop\alaw.wav";
97+
var inFileFormat = WaveFormat.CreateALawFormat(8000,1);
98+
using(var inStream = File.OpenRead(inFile))
99+
using(var reader = new RawSourceWaveStream(inStream, inFileFormat))
100+
using(var converter = WaveFormatConversionStream.CreatePcmStream(reader))
101+
{
102+
WaveFileWriter.CreateWaveFile(outFile, converter);
103+
}
104+
```

NAudio.sln

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{BA7F6DBB-9
4545
Docs\PlayAudioFileWinForms.md = Docs\PlayAudioFileWinForms.md
4646
Docs\PlayAudioFromUrl.md = Docs\PlayAudioFromUrl.md
4747
Docs\PlaySineWave.md = Docs\PlaySineWave.md
48+
Docs\RawSourceWaveStream.md = Docs\RawSourceWaveStream.md
4849
Docs\RecordWavFileWinFormsWaveIn.md = Docs\RecordWavFileWinFormsWaveIn.md
4950
Docs\WasapiLoopbackCapture.md = Docs\WasapiLoopbackCapture.md
5051
Docs\WasapiOut.md = Docs\WasapiOut.md

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ NAudio comes with several demo applications which are the quickest way to see ho
7373
- [Mix Two Audio Files to WAV](Docs/MixTwoAudioFilesToWav.md)
7474
- [Convert an MP3 to WAV](Docs/ConvertMp3ToWav.md)
7575
- [Encode to MP3 and other formats using MediaFoundationEncoder](Docs/MediaFoundationEncoder.md)
76-
- [eMore examples](http://markheath.net/post/naudio-mediafoundationencoder)
76+
- [More examples](http://markheath.net/post/naudio-mediafoundationencoder)
7777
- [Understand how to convert between any audio formats you have codecs for](http://www.codeproject.com/Articles/501521/How-to-convert-between-most-audio-formats-in-NET)
7878
- [Trim a WAV File](http://mark-dot-net.blogspot.com/2009/09/trimming-wav-file-using-naudio.html)
7979
- [Merge MP3 Files](http://mark-dot-net.blogspot.com/2010/11/merging-mp3-files-with-naudio-in-c-and.html)
@@ -92,6 +92,7 @@ NAudio comes with several demo applications which are the quickest way to see ho
9292
- [Resample Audio](http://mark-dot-net.blogspot.co.uk/2014/05/how-to-resample-audio-with-naudio.html)
9393
- [Input driven Audio Resampling](http://markheath.net/post/input-driven-resampling-with-naudio-using-acm)
9494
- [Enumerate Media Foundation Transforms](Docs/EnumerateMediaFoundationTransforms.md)
95+
- [Using RawSourceWaveStream](Docs/RawSourceWaveStream.md)
9596

9697

9798
### Recording

0 commit comments

Comments
 (0)