input stream to buffer

Feb 19, 2009 at 11:11 AM
Hi,

Im a newbie trying to program an application that has to get the audio from the microphone and send it to the a camera.

I read your example code to get the audio from the microphone but i still have many doubts, i also look for an API but i dont know where it is.

1. How can i get the number of devices i have connected to my pc? i look in "coreAudioApi" but i didnt found anything.
2. I get the audio with an event but i dont wanna save it in a file but i want to save it in a stream. How can i set the "WaveBuffer" to do that? is it possible to use a streamWriter instead?

Sorry if my questions sound too obvious.

Thanks in advance for your help.
Coordinator
Feb 24, 2009 at 10:33 AM
Hi,

What you want to do is certainly possible (although I am not sure what you mean by sending it to a camera). If you download the latest NAudio code from the Source Code tab, you will be able to use the WaveIn class to capture audio through the default input device, and the WaveFileWriter is able to write to a stream (you could use a MemoryStream for example). As for getting the number of WaveIn devices, I realised that I had not exposed this as a property, so I have now checked in a new version of WaveIn that lets you get the device count.

Mark
Feb 24, 2009 at 5:46 PM
Edited Feb 26, 2009 at 4:06 PM
Hi Mark,

Thanks for your answer, i tried but i have some problems:

I declared a memorystream with the sample information and then convert the stream to alaw,

 

Dim s As New MemoryStream(e.Buffer)
Dim a As New Wave.WaveFormatConversionStream(Wave.WaveFormat.CreateALawFormat(8000, 1), s)

 

 

 

1. But vb.net doesnt let me set a memoryStream instead of a NAudio.Wave.WaveStream. How can i do it?
2. Is there any other way of convert to alaw without setting the waveSample and the channels?

Best regards

Feb 26, 2009 at 4:03 PM
Edited Feb 26, 2009 at 4:06 PM
Hi again,

I continued developing but i couldnt convert to alaw.  I tried:

Dim

br As New BinaryReader(New MemoryStream(e.Buffer))
Dim a As New Wave.WaveFormat(br)
Dim o As New Stream(a) 

o.Read(e.Buffer, 0, e.BytesRecorded)
Dim t As New Wave.WaveFormatConversionStream(Wave.WaveFormat.CreateALawFormat(8000, 1), o) ----- I have an exception in this line

The class i created to manage the WaveStream class:

Public Class Stream
Inherits Wave.WaveStream

Private
fBuffer() As Byte
Private fOffset As Integer
Private fCount As Integer
Private fPosition As Long
Private fWaveFormat As NAudio.Wave.WaveFormat
Private fLength As Long

Public Overrides ReadOnly Property Length() As Long
Get
Length = fLength
End Get
End Property

Public
Overrides ReadOnly Property WaveFormat() As NAudio.Wave.WaveFormat
Get
WaveFormat = fWaveFormat
End Get
End Property

Public Overrides Property Position() As Long
Get
Return fPosition
End Get

Set(ByVal value As Long)
fPosition = value
End Set
End Property

Public
Overloads Overrides Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer
fBuffer = buffer.Clone
fPosition = offset
fLength = count
End Function

Public
Sub New(ByVal format As Wave.WaveFormat)
fWaveFormat = format
End Sub
End
Class

What am i doing wrong?

Coordinator
Feb 26, 2009 at 4:49 PM
If your Buffer contains a full Wave File, you can use a WaveFileReader and pass in the memory stream to the constructor.
Your example class needs to write into the buffer parameter passed into the Read method.
Try having a look at the code for the Skype Voice Changer to see how to create a custom wave stream.

Mark
Feb 27, 2009 at 7:43 AM
Hello,

I get the voice from the microphone and store it into a buffer, but what i really want to do is get the byte() and covert it to alaw or aac (i think maybe i dont really need the buffer if the event gives me already a byte()).

I read in another entry and i have a doubt the sound from the microphone is PCM format? so if i want to change to Alaw i only have to do one conversion...???.

And i had a look on the  Skype Voice Changer but there was so much code that i couldnt see nothing... so Im still thinking on how to write a class (like i did above) so i can have a WaveStream to do the conversion, but it still not working.

Thanks again.

Mar 2, 2009 at 5:44 PM
Hi,

I have continued the development.. i wrote a temp file to get a wavestream and the convert to alaw, it seems like the conversion (i get the time from the stream... wavestream.totaltime )  its ok but when i try to play the sound (to hear it on the speakers) but a exception of  wavebadformat:

 

Dim r As New Wave.WaveFileReader(auFileWriter.Filename)
D
im targetformat As New Wave.WaveFormat
targetformat = Wave.WaveFormat.CreateALawFormat(r.WaveFormat.SampleRate, r.WaveFormat.Channels)

Dim
convertedStream As Wave.WaveStream = New Wave.WaveFormatConversionStream(targetformat, r)

 

----------------- Later i have to send the stream to a server, i convert the stream to send ----- 


Dim
a As New BinaryReader(convertedStream)
Dim b As Byte()
b = a.ReadBytes(convertedStream.Length)
----------------------------

--------------- i try to play the stream....
Dim
s As New Wave.WaveOut(1, 0, Me)
s.Init(convertedStream) ----------------------------------> exception WaveBadFormat calling waveOutOpen
s.Play()


And i need to know how to create a waveStream without saving a "temporal" file....

best regards

 

Coordinator
Mar 3, 2009 at 12:49 PM
Hi there,

You should not normally try to play a compressed (e.g. A-law) wavestream. For best results, play audio in PCM.

Mark
Mar 3, 2009 at 2:10 PM
Thanks mark for your reply.

I have many problems trying to made a class inherit from WaveStream so i could you use it instead of the WaveFileReader.

The idea is to change the format without saving any file.

Any help will be greatly appreciated. Best regards
Mar 4, 2009 at 7:58 AM
Hello mark,

Sorry for going again with this, but i have to get a waveStream:

 

Private Sub grabacion(ByVal sender As Object, ByVal e As NAudio.Wave.WaveInEventArgs)
Dim f As New Wave.WaveFormat(8000, e.BytesRecorded,, 1)
Dim c As New Stream(f) ----> Stream is a class like i wrote above
c.Read(e.Buffer, 0, e.BytesRecorded) ----> i read the BytesRecorded on the event...

Now i declare a stream, so i can convert to ulaw but i get an AcmNotPossible calling acmStreamOpen exception:
Dim convertedStream As Wave.WaveStream = New Wave.WaveFormatConversionStream(Wave.WaveFormat.CreateMuLawFormat(8000, 1), c)
 

Then i have to send the sound and i need to send a byte()
Dim a As New BinaryReader(convertedStream)
Dim b As Byte()
b = a.ReadBytes(convertedStream.Length)

 

Coordinator
Mar 4, 2009 at 9:28 AM
hi,
the following line has a bug:
Dim f As New Wave.WaveFormat(8000, e.BytesRecorded,, 1)

The second  parameter is the number of bits. So if you opened WaveIn as 16 bit, that parameter should be 16. That would explain some of the errors you are getting

Mark


Mar 4, 2009 at 9:41 AM
hello mark,

Now, the waveStream goes straight but i get this exceptions when i stop the debug closing the window...

Excepción del tipo 'NAudio.MmException' en NAudio.dll
Excepción del tipo 'NAudio.MmException' en NAudio.dll
---- ERROR DE DEPURACIÓN DE ASERCIÓN ----
---- Mensaje corto de aserción ----
AcmStreamHeader dispose was not called
---- Mensaje largo de aserción ----

I dont know what is wrong, could you help me with this?

Mar 4, 2009 at 5:41 PM
Edited Mar 4, 2009 at 5:42 PM
Sorry for send so many entries... but i have another problem...

Now i can convert to alaw i wanna send the audio sample to a camera in packets of 240 bytes so i have to convert the waveStream to a byte(), i think i can use a binaryReader to do it. But the result is a byte.length=0 when i was supposed to be byte.length=convertedStream.length???

 

Dim aBuffer As Byte()
[...]
convertedStream = New Wave.WaveFormatConversionStream(Wave.WaveFormat.CreateMuLawFormat(8000, 1), strm)
br =
New BinaryReader(convertedStream)
aBuffer = br.ReadBytes(convertedStream.Length)

How can i get the byte() full of values??

Coordinator
Mar 24, 2009 at 10:46 AM
have you reset the position of strm back to the beginning?
Mar 27, 2009 at 6:52 PM
Hello mark,

what do you mean? could you show any code?