BufferedWaveProvider doesnt work in Unity - c#

I am trying to implement NAudio into Unity. I managed to link the NAudio dll, but I am getting a strange error when I try to play music with NAudio BufferedWaveProvider.
If I to this:
WaveOut player;
BufferedWaveProvider buf;
AudioFileReader reader;
void Start () {
reader = new AudioFileReader(#"..\music.mp3"); // some music
player = new WaveOut();
player.Init(reader );
player.Play();
}
The music plays normal, without any problems.
But when I try use BufferedWaveProvider:
WaveOut player;
BufferedWaveProvider buf;
AudioFileReader reader;
void Start () {
reader = new AudioFileReader(#"..\music.mp3"); // some music
buf = new BufferedWaveProvider(reader.WaveFormat);
byte[] tmp = new byte[50000];
reader.Read(tmp, 0, tmp.Length); //read 50000 bytes
buf.AddSamples(tmp, 0, tmp.Length); //add bytes to buf
player = new WaveOut();
player.Init(buf); //init the WaveOut with buff
player.Play(); // play
}
It doesnt play! I debuged really a lot, and found out that the BufferedWaveProvider is using the samples (BufferedBytes are lowering), but I dont get any sound out of it!
I am using BufferedWaveProvider because of a more complex project, but its already a problem in such a simple example..
What am I missing?
Note: The same code WORKS in C# Windows Forms...

Try using WaveOutEvent instead of WaveOut, it worked at least for me in one of the projects.
As Mark pointed out:
it works because WaveOut uses Windows message callbacks by default, so if you have no gui thread (e.g. you are in a console app), then it can't be used and WaveOutEvent should be preferred

Related

Playing from wav stream

var result = service.Synthesize(
text: text,
accept: "audio/wav",
voice: "en-US_AllisonVoice"
//voice: "en-US_HenryV3Voice"
);
using (FileStream fs = File.Create(#"C:\Users\nkk01\Desktop\voice.wav"))
{
result.Result.WriteTo(fs);
fs.Close();
result.Result.Close();
}
var waveStream = new WaveFileReader(#"C:\Users\nkk01\Desktop\voice.wav");
var waveOut = new WaveOutEvent();
waveOut.Init(waveStream);
Console.WriteLine("Playing");
waveOut.Play();
Console.WriteLine("Finished playing");
Hi this is my current code which is extremely inefficient as it has to save an audio stream to a file to play it. I would like to pass the audio stream directly to my laptop's speaker using the NAudio library. I still have not managed to find a solution. It will be of great help, thanks.
i'm not familiar with naudio but as far as i can see from their git hub repo, the constructor for WaveFileReader also accepts a stream instead of a filename ...
simply try writing everything you have to a memory stream instead of a file... don't forget to reposition the memory stream before you read it ('seek' to offset 0)

How to stop MediaPlayer from starting each time?

How would I fix my MediaPlayer code, that receives bytes, than creates a temp file, that is saving input, but for each input, the player starts from the beginning, and I want it to just play. This is my code:
Java.IO.File temp = Java.IO.File.CreateTempFile("temp", "mp3");
Java.IO.FileOutputStream fos = new Java.IO.FileOutputStream(temp);
Java.IO.FileInputStream fis = new Java.IO.FileInputStream(temp);
temp.DeleteOnExit();
MediaPlayer player = new MediaPlayer();
player.SetDataSource(fis.FD);
// If set here, there is an error
//12-09 17:29:44.472 V/MediaPlayer( 9927): setDataSource(58, 0, 576460752303423487)
//12-09 17:29:44.472 E/MediaPlayer( 9927): Unable to to create media player
while (true)
{
try
{
byte[] myReadBuffer = new byte[10000]; //Input array
mmInStream.Read(myReadBuffer, 0, myReadBuffer.Length); //Reads the incoming array into myReadBuffer
fos.Write(myReadBuffer, 0, myReadBuffer.Length); //Writes it into temp file
MediaPlayer player = new MediaPlayer(); //Creates a new object
player.SetDataSource(fis.FD); // If here, it would just start from the start each time and add more // Sets the data source to temp file
player.Prepare();
player.Start();
while (true)
{
// Checks if it can release resources
if (!player.IsPlaying)
{
player.Release();
break;
}
}
}
catch (System.IO.IOException ex)
{
System.Diagnostics.Debug.WriteLine("Input stream was disconnected", ex);
}
}
I am using Xamari Forms.
Basicaly, I get an array of bytes, that I store in a temporary file, and than try to play them. I know the MediaPlayer is recreated on every loop, since there I define the data source, but if I put it outside of the loop, it would get an error(as above).
Example:
The song starts, is played for about 2s and than it starts over but is now played for 4s, and over again and now for 6s. Each time, more of the song is revealed.
If it was a string it would be like this:
123
123456
123456789
How would I make it to play continuously, but each time it would play a only the new part?
This is a logic issue. Essentially you're writing chunks to a stream, then playing that chunk, then writing more without resetting the stream, then playing from the beginning of that stream.
What you need it to do is write a chunk to your stream, play that stream, then write a new chunk to the stream and play that stream.
Move your Java.IO.FileOutputStream fos = new Java.IO.FileOutputStream(temp); inside of your outer while() loop.
The reason this works is that you're writing to your fos then playing, then writing again but not disposing of your initial buffer data. Moving fos into your while loop forces a new object to be created which will contain the new buffer data, then it will play that. There's going to be an issue with audio skipping because of the loop and having to re-load the new data to be played.
To correct the skip you'll need to load your buffer asynchronously while it's being played. You can do this with a separate thread. You might need to adjust your buffer size or set a buffer condition. MediaPlayer contains a BufferingProgress property that might help.

c# cscore how to instantly play loopback capture recorded bytes

Yo guys, its me again with my noob questions. so this time I've used cscore to record windows sounds then send the recorded bytes to another pc by sockets and let them play there.
I just could not figure out how to play the gotten bytes under DataAvailable callback...
I've tried to write the bytes gotten to a file and play that file that worked but sound is not playing correctly like there's some unexpected sounds being heard with it too.
so here's my code:
WasapiCapture capture = new WasapiLoopbackCapture();
capture.Initialize();
capture.DataAvailable += (s, e) =>
{
WaveWriter w = new WaveWriter("file.mp3", capture.WaveFormat);
w.Write(e.Data, e.Offset, e.ByteCount);
w.Dispose();
MemoryStream stream = new MemoryStream(File.ReadAllBytes("file.mp3"));
SoundPlayer player = new SoundPlayer(stream);
player.Play();
stream.Dispose();
};
capture.Start();
any help would be highly appreciated ;-;.
if you wanna hear how sound comes out by that way I would record you the result.
NOTE: if I just record sounds to a file and open later it just works perfectly but if I write and play instantly it unexpected sounds being heard.....
Use the SoundInSource as an adapater.
var capture = new WasapiCapture(...)
capture.Initialize(); //initialize always first!!!!
var soundInSource = new SoundInSource(capture)
{ FillWithZeros = true }; //set FillWithZeros to true, to prevent WasapiOut from stopping for the case WasapiCapture does not serve any data
var soundOut = new WasapiOut();
soundOut.Initialize(soundInSource);
soundOut.Play();

Play real-time sound buffer using C# Media.SoundPlayer

I have developed a system in which a C# program receives sound buffers (byte arrays) from another subsystem. It is supposed to play the incoming buffers continuously. I searched in the web and I decided to use SoundPlayer. It works perfectly in the offline mode (play the buffers after receiving them all). However, I have a problem in the real-time mode.
In the real-time mode the program at first waits for a number of buffer arrays (for example 200) to receive and accumulate them. Then it adds a wav header and plays it. However, after that for each next 200 arrays it plays repeatedly the first buffer.
I have read following pages:
Play wav/mp3 from memory
https://social.msdn.microsoft.com/Forums/vstudio/en-US/8ac2847c-3e2f-458c-b8ff-533728e267e0/c-problems-with-mediasoundplayer?forum=netfxbcl
and according to their suggestions I implemented my code as follow:
public class MediaPlayer
{
System.Media.SoundPlayer soundPlayer;
public MediaPlayer(byte[] buffer)
{
byte[] headerPlusBuffer = AddWaveHeader(buffer, false, 1, 16, 8000, buffer.Length / 2); //add wav header to the **first** buffer
MemoryStream memoryStream = new MemoryStream(headerPlusBuffer, true);
soundPlayer = new System.Media.SoundPlayer(memoryStream);
}
public void Play()
{
soundPlayer.PlaySync();
}
public void Play(byte[] buffer)
{
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(buffer, 0, buffer.Length);
soundPlayer.PlaySync();
}
}
I use it like this:
MediaPlayer _mediaPlayer;
if (firstBuffer)
{
_mediaPlayer = new MediaPlayer(dataRaw);
_mediaPlayer.Play();
}
else
{
_mediaPlayer.Play(dataRaw);
}
Each time _mediaPlayer.Play(dataRaw) is called, the first buffer is played again and again; the dataRaw is updated though.
I appreciate your help.

Looping mp3 using Naudio

I play mp3 using NAudio but I don't know how to loop the music during opening program?
IWavePlayer waveOutDevice = new WaveOut();
AudioFileReader musicBackground = new AudioFileReader(#"....mp3");
waveOutDevice.Init(musicBackground);
waveOutDevice.Play();

Categories

Resources