Getting Microphone Input
To have microphone audio input in Godot:
- Go to Project -> Project Settings -> General -> Application -> Audio and make sure "Enable Audio Input" is On.
- Go to the Audio panel (on the bottom of the Godot editor by default), and add a new Audio bus with a Record effect (
- Add an
AudioStreamPlayer to the scene tree. Set the Stream attribute to a New
AudioStreamMicrophone, and the Bus attribute to the Audio bus you created. We also want it to be playing, so put set the Autoplay attribute On.
If everything is working, the game should be playing whatever is listening from microphone. Once you have made sure it is working, mute the Audio bus.
The official demo project mic_record shows how to record and play the audio, and how to save it to a file. We don't need any of that.
No code required.
By the way, Godot includes other useful effects including equalizers and a pitch shifter.
What is Pitch?
What we refer as pitch is the audio frequency. However, is there a particular pitch for an audio signal?
We need to consider that real audio is a mix of multiple frequencies.
Even an instrument playing a single node will have a fundamental frequency, and overtones which are weaker than the fundamental. (See Harmonic). Thus, we would want the stronger frequency.
Well, turns out we cannot get a specific frequency anyway. The best we can do is get frequency range. So pick reasonable ranges to query. Perhaps based on musical notes (you would want the nominal frequency of the note at the center of the range).
The problem is that the more certain we are of the instant in time we want to measure, the less certain we are about the frequency of the audio. Yes, that is the uncertainty principle. It emerges from the Fourier transform we need to do to get the frequencies.
And I'm not going to explain that, instead I'll recommend the video But what is the Fourier Transform? A visual introduction. by 3Blue1Brown, and its follow-up video he more general uncertainty principle, beyond quantum. Also remember we have audio samples to work with, not a function.
As it turns out, we don't need any library to do a Fourier Transform in Godot, because it already has the means to do an spectral analysis.
To do that add a SpectrumAnalyzer effect (
AudioEffectSpectrumAnalyzer) to the Audio bus you want (the same with the Record effect, in this case). It will do a Fast Fourier transform for us.
You can retrieve an
AudioEffectSpectrumAnalyzerInstance from code using
AudioServer.get_bus_effect_instance, and call
get_magnitude_for_frequency_range on it.
The method takes a frequency range and returns a
Vector2 (as far as I can tell - this is not documented at the time of writing - these are the left and right stereo components※, for a fair combination use the
length of the vector) in linear energy scale (you can use
linear2db to get decibels).
To get the stronger frequency range, we call the method on a loop changing the frequency ranges, and pick the maximum.
The method is also useful for audio visualization.
※: Yes, a Fourier Transform has a real an an imaginary part. However, after having a look at the source code, I don't think that is what is going on. The source for method (here) uses a
fft_history array. Which we see (here) converted to audio frames. Which have
r (as defined here). Unless that means "limaginary" and "real", I think they are "left" and "right".