-
-
Notifications
You must be signed in to change notification settings - Fork 22.4k
Add microphone access to Input
#105244
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
base: master
Are you sure you want to change the base?
Add microphone access to Input
#105244
Conversation
Does this assume mono mic? I have a multichannel mic. Does this break our attempts to do automatic libsamplerate conversion? Added to the last question. Does make it make a promise on the structure of the audio stream so we can never break that promise? I would recommend the It can still be seen as grabbing a packed vector2 array of some fixed size How would we design a feature where the mic is injected back into the godot engine audio bus? For example we want to proxy the audio channel for voice cancellation. Tl;DR it's a promising idea. |
This assumes a stereo mic, exactly as specified in the internal microphone buffer. (On platforms that have a mono mic the samples are duplicated into the two channels.) @fire Please send details about your multichannel mic if it has more than two channels. (I have two mics on my laptop PC on either side of the camera 10cms apart, and I have plotted a visual correlation between the two channels to prove that the offsets are consistent with the speed of sound -- 8mm/sample at 44.1kHz) There could be a scenario where we have multiple independent microphones plugged into the system as inputs. Not sure what this would be good for since there's already a lot of audio equipment for dealing with that.
The twovoip library has its own resampler for robustness and isolation from the audio system, and the output is fed directly to the RNNoise and Opus libraries which require different sample rates. It's unusual for the mic to have a wildly different sample rate to the output. (The variation I have observed is below a percent.)
The audio stream can be whatever it likes internally, but
This is the minimal API for now. We can add those other functions (eg
I need to do some experiments using the Regarding voice cancellation: Isn't this about subtracting the speaker output from the microphone input to prevent feedback where you hear your own voice round tripping across the network to another player and then back to you? I imagine that would be done by running a noise-cancelling process against the captured the output stream from the Master Bus and the microphone input. |
So the current behavior is pause the entire game engine. |
No, it just returns an empty array if there are not enough samples -- same as the equivalent function in AudioEffectCapture |
You need to implement the AudioEffectCapture internal workflow then |
I don't understand. Can you explain? Also, was my answer to your previous question adequate? |
Let's get together in a voice call at some point in discord or somewhere else. |
Input
I'm afraid I cannot satisfy @lyuma's challenge of sharing code between the two functions that draw data from the AudioDriver::input_buffer. The functions are: int AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames)This:
PackedVector2Array Input::get_microphone_buffer(int p_frames)This:
Basically, my 20 line function collapses two complicated buffer copying functions (into and out of the audio system) into one very simple one. The complexity is caused by the intermediate buffer being part of the audio system. |
a1e95cf
to
47c7942
Compare
47c7942
to
3ecf06f
Compare
Here is the much simplified demo project for this feature I only just remembered to update: |
This PR is an alternative to #100508 that answers godotengine/godot-proposals#11347
We add the following four functions to the
Input
singleton to manage and access the microphone data stream independently of the Audio System.The current means of accessing the microphone data involves chaining the following units together in a sequence:
The
AudioCaptureEffect
in the middle intercepts the audio data as it flows from the source stream to the output stream copies it into a buffer.This structure is problematic because it is locking two real-time serial devices (microphone and speakers) into the same chain so that any systematic drift between them no matter how insignificant will eventually overwhelm any buffer.
Issues that this may have caused are #80173 #95120 #86428 . The problem is most consistent on Android where the microphone will either enter an endless loop or shut down after several minutes of use.
Additional changes are made to the platform implementations of
AudioDriver.input_start()
to make them safe to call multiple times, which can happen if there is more than oneAudioStreamMicrophone
present in the project.The full test of these functions are in the
godot-demo-projects/audio/mic_input
project of godotengine/godot-demo-projects#1172 . This demo includes an option to push the samples straight into anAudioStreamGenerator
to simulate a loop-back. The observed delay is about the same (1/3 seconds) as the original case of using anAudioStreamMicrophone
as input.The code that extracts the buffer is as follows:
I have tested it on Windows, Android and Linux and it is perfectly designed to work with https://github.com/goatchurchprime/two-voip-godot-4