Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide example showing how to play notes with NAudio #32

Open
jeffoulet opened this issue Feb 8, 2023 · 10 comments
Open

Provide example showing how to play notes with NAudio #32

jeffoulet opened this issue Feb 8, 2023 · 10 comments

Comments

@jeffoulet
Copy link

Hi,

Sorry, my request might sound like a very stupid one, and maybe this is not the correct place to ask, but I'm struggling to actually play the waveform generated by Meltysynth.

What I'm trying to do:

  • generate a midi file in memory
  • render it with Meltysynth into a memory stream
  • finally play the stream

What I've achieved so far:

private static void PlayMeltysynthChord()
		{
			var sampleRate = 44100;
			var synthesizer = new Synthesizer(@"..\Resources\Raw\Abbey-Steinway-D-v1.9.sf2", sampleRate);

			synthesizer.NoteOn(0, 60, 100);
			synthesizer.NoteOn(0, 63, 100);
			synthesizer.NoteOn(0, 66, 100);

			var mono = new float[3 * sampleRate];
			synthesizer.RenderMono(mono);

			var byteArray = new byte[mono.Length * 4];
			Buffer.BlockCopy(mono, 0, byteArray, 0, byteArray.Length); 

			var wav = new WavePcmFormat(byteArray, numChannels: 1, sampleRate: (uint)sampleRate, bitsPerSample: 16);
			var rawDataWithHeader = wav.ToBytesArray();

			var stream = new MemoryStream(rawDataWithHeader);

			var player = new System.Media.SoundPlayer(stream);
			player.Play();
		}

The 'WavePCMFormat' method inserts the .wav header to the data. The result I get is a few seconds of white noise, so I assume there is something wrong in the transformation of the rendered PCM to the .wav stream.

Any help is welcome... Thanks in advance

@jeffoulet jeffoulet changed the title Provide xample showing how to play notes with NAudio Provide example showing how to play notes with NAudio Feb 8, 2023
@sinshu
Copy link
Owner

sinshu commented Feb 9, 2023

You are rendering the waveform to a float array. Since float is 32bit, it's not compatible with bitsPerSample: 16. You should use RenderMonoInt16 and a short array.

By the way, if you want to play a MIDI file, I strongly recommend to use NAudio.Wave.WaveOut or another callback based playback. A fire-and-forget playback like System.Media.SoundPlayer is not suitable for playing a long MIDI file, because it needs a lot of memory to store the whole waveform.

Isn't the existing NAudio example suitable for your application? Is there a special reason to use System.Media.SoundPlayer? If you could be a bit more specific about what you want to do, I might be able to help 🙂

@rjjaret
Copy link

rjjaret commented Aug 11, 2023

You are rendering the waveform to a float array. Since float is 32bit, it's not compatible with bitsPerSample: 16. You should use RenderMonoInt16 and a short array.

By the way, if you want to play a MIDI file, I strongly recommend to use NAudio.Wave.WaveOut or another callback based playback. A fire-and-forget playback like System.Media.SoundPlayer is not suitable for playing a long MIDI file, because it needs a lot of memory to store the whole waveform.

Isn't the existing NAudio example suitable for your application? Is there a special reason to use System.Media.SoundPlayer? If you could be a bit more specific about what you want to do, I might be able to help 🙂

Hello Sinshu,

Since WaveOut is only available for PC, can you recommend a similar approach for Mac?

Thanks!

@sinshu
Copy link
Owner

sinshu commented Aug 12, 2023

@rjjaret
If you want to play MIDI files, please try one of the following examples.
https://github.com/sinshu/meltysynth#examples

For instance, SFML.Net supports Mac, so I believe it should function on a Mac as well.

@rjjaret
Copy link

rjjaret commented Aug 14, 2023

I want to play a stream, similar to what is being done in the Windows example above. They're originally using System.Media.SoundPlayer, and you suggested WaveOut. But WaveOut is only for PC.

I haven't seen anything quite like that for Mac in the examples, but I'll give another look. Please suggest a place if you know of one.

Alternatively, if there's a way to play a series of midi notes, without saving to file first, that would achieve what I need too.

Thanks!
Rob

@sinshu
Copy link
Owner

sinshu commented Aug 14, 2023

@rjjaret
Did you try the SFML.Net example?

@markheath
Copy link

I have just made a demo showing how to play notes triggered from a MIDI keyboard with NAudio and MeltySynth which I plan to show at my talk about NAudio at the Copenhagen Developer Festival next week. It's the first time I've tried MeltySynth and I have to say it's amazing! Brilliant job, and I was very impressed at how easy it was to integrate with NAudio.

I'll post an example on my blog hopefully in the next week and I'll try to remember to link to it here as well.

@sinshu
Copy link
Owner

sinshu commented Aug 23, 2023

@markheath
Very nice! I'm looking forward to the blog post 😎

@markheath
Copy link

Blog post is up: https://markheath.net/post/naudio-midi-playback-soundfont-meltysynth
Will try to get the sample project onto GitHub as well soon

@sinshu
Copy link
Owner

sinshu commented Sep 1, 2023

@markheath
Thank you for sharing information 👍

@chaojian-zhang
Copy link

chaojian-zhang commented Oct 13, 2023

@jeffoulet You can look at my provided code sample for playback MIDI using NAudio below.
It's minimalist and fully functional (but consumes lots of memory).

#41 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants