Can't get Microphone to work properly in MonoGame 3.8.1

Hey there,

I’ve been trying to capture microphone input (Microsoft.Xna.Framework.Audio.Microphone) but after capturing the data, I can’t get it to play properly. The sound is distorted, it sounds like it’s repetitive every few milliseconds and advancing very slowly.

Basically, what I’m trying is configuring the capturing buffer, the stream, and starting the Microphone:

microphone = Microphone.Default;
microphone.BufferDuration = TimeSpan.FromMilliseconds(100);
buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
stream.SetLength(0);
microphone.Start();

Then have an event executed whenever the buffer is ready, in order to read the buffer and write it to the stream:

microphone.GetData(buffer);
stream.Write(buffer, 0, buffer.Length);

And finally, when the microphone stopped, try to instantiate a SoundEffect with the stream data and play it:

sound = new SoundEffect(stream.ToArray(), microphone.SampleRate, AudioChannels.Mono);
isound = sound.CreateInstance();
isound.Pitch = 0f;
isound.Volume = 1f;
isound.Play();

The implementation is based on a (very old, XNA) article, but I’d say it’s quite straightforward:
https://www.codeproject.com/Tips/535284/How-to-record-sound-using-XNA

It could be that some of its approach is not valid anymore though, so if someone has experience with it and could put me on the right track, that’d be great. I searched the forum and elsewhere, but unfortunately, I couldn’t find a solution or explanation on the topic.

Thanks!

Hi, just to cut time short, please follow the information on the linked post below:

:new: New Here? Read This! [Now with Menu] - General - Community | MonoGame

Specifically in 4- notably: What Platform are you targeting? as there are certain differences with OpenGL and DirectX…

Welcome back :slight_smile:

1 Like

Hi. Thanks! :slight_smile:

As for the platform I’m targeting, it’s Desktop OpenGL. Although the game should eventually be available for mobile platforms as well, so if there are significant differences regarding the microphone implementation, I’d definitely like to know. Because I thought the Microphone class and SoundEffect class were already cross platform.

1 Like

Hopefully one of the DGL devs can chime in as I am primarily a DX dev.

Hey @ShakiFanatico

Out of curiosity, I did some testing and found the same result you have. I used the tutorial you linked so I was using the same implementation.

Using MonoGame 3.8.1.303, I experienced the same issue as you.

So then I was curious if this issue existed in XNA 4.0. So I setup VS 2010 and XNA Game Studio 4.0 and tested the same exact code. The issue did not exist in XNA.

I’ll get some information recorded and submit an issue on the GitHub.

2 Likes

I’ve opened an issue regarding it here Microphone Recording and Playback Stutters in MonoGame But Not XNA · Issue #8058 · MonoGame/MonoGame · GitHub

2 Likes

The correct code, according to the documentation, is

int actualSizeOfWavData = microphone.GetData(buffer);
stream.Write(buffer, 0, actualSizeOfWavData);
3 Likes

Is it possible to get the samples of currently playing audio in a similar way? I mean using a callback function so that while playing songs and sounds we could use the data to do a visualization of the raw sound data?

XNA had the MediaPlayer.GetVisualizationData method for doing this with songs but this method is not implemented in MonoGame unfortunately.

Here are some discussions in the repo about it (spoilers, not much)

Outside of this, you can implement things like visualizations and spectographs using other third party libraries if you wanted to venture into them. NAudio is one I’ve used before, but it’s Windows only so no cross platform. There’s also the popular FMOD, but that’s a ten ton hammer type solution.

There’s also MonoSound which I’ve discovered recently but haven’t used. It does appear you can get the sample data for visualizations though with it, but again, I haven’t used it so can’t say for sure how to implement it.

2 Likes

Thanks guys, for looking into it and for opening the issue. I appreciate it. :slight_smile:

I just recently had a chance to try it again with @nkast’s suggestion (using the return value of GetData() as buffer size for writing to the stream) and that works indeed. No more stuttering, thanks a lot! :slight_smile: I saw in the opened issue that an inconsistent buffer size is mentioned and that’s the cause why an ‘invalid’ buffer is being written to the stream. That totally makes sense. For now I’m happy that the actual buffer size can be passed and it solves the issue for me. Thanks again!

4 Likes