godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.56k stars 20.28k forks source link

Microphone recording doesn't work on Linux with official builds #33184

Open Calinou opened 4 years ago

Calinou commented 4 years ago

Godot version: Git https://github.com/godotengine/godot/commit/924db5fa58ab28912857029ec8dd34fbde771550

OS/device including version: Fedora 30, PulseAudio

Issue description: Microphone recording doesn't seem to work on Linux, even though Godot appears as a capture device when running the Mic Record Demo:

image

Saving the file after recording a few seconds will write a WAV file that contains only a few seconds of silence. I made sure the microphone is not muted by recording a sample in Audacity beforehand (where it works correctly).

Steps to reproduce: Use the "Mic Record Demo" from godot-demo-projects. Click the Record button, say something, then press Stop. Save the audio to a WAV file then inspect it using a media player.


See also https://github.com/godotengine/godot-demo-projects/issues/359. This issue has been confirmed by @CombustibleLemonade in https://github.com/godotengine/godot-demo-projects/issues/359#issuecomment-547962679, so I'll add the confirmed label right away.

Edit: This issue is not exclusive to Linux and has been occurring on Windows and macOS too (both x86 and ARM).

akien-mga commented 4 years ago

Works for me on Mageia 7 using PulseAudio.

FeralBytes commented 4 years ago

Confirmed Linux Mint 19.2 Cinnamon, x64 Kernel 5.0.0-31-generic, Lenovo Laptop.

Jummit commented 4 years ago

Confirmed on Ubuntu 18.04.3 on a Lenovo Thinkpad T420.

lboklin commented 4 years ago

Confirmed on up-to-date NixOS unstable with KDE, PulseAudio.

FeralBytes commented 4 years ago

Can this get added to 3.2 milestone, and how can we help troubleshoot the problem?

Calinou commented 4 years ago

@FeralBytes Which Godot versions can you reproduce this on? Microphone support was added in 3.1.

Here, I can still reproduce this on https://github.com/godotengine/godot/commit/a10449bbbc1c04f3ca151e067974717145a396d7, which means it wasn't fixed by #34306.

lboklin commented 4 years ago

I can reproduce this with 3.1.2

FeralBytes commented 4 years ago

@Calinou 3.2 beta 4 is broken, also 3.1.1 is broken Also 3.1 Stable does not work. A what stage of 3.1 was it added at Alpha? Ah 3.1 Alpha1 works. I then tested Beta 1 and it was broken. I then worked backwards and found that even 3.1. Alpha2 was broken.

So a change between 3.1 Alpha1 and 3.1Alpha2 broke mic recording for many versions of Linux.

EDIT: Tested in both Linux Mint 19.2 and 19.3, same result.

Zolzak commented 4 years ago

@FeralBytes the change might be in the fa26a551. After reverting that in Master the recording started working for me. The changes look pretty innocent and I cannot tell just by looking what is the problem. Any thoughts @marcelofg55.

Edit: Adding this line seems to be enough fix it for me. Race condition / synchronization problem perhaps?

--- drivers/pulseaudio/audio_driver_pulseaudio.cpp  (revision 21dec856f2a7482fc69e18ffc60f64e90e10fcc5)
+++ drivers/pulseaudio/audio_driver_pulseaudio.cpp  (date 1577224764136)
@@ -669,6 +669,8 @@
            break;
    }

+   print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
+   
    pa_sample_spec spec;

    spec.format = PA_SAMPLE_S16LE;
akien-mga commented 4 years ago

I could finally reproduce this too, it seems like official builds don't work but local builds do. Likely an issue with the different PulseAudio versions used on the official buildsystem and on user systems.

akien-mga commented 4 years ago

I confirm that reverting fa26a551 "fixes" the issue, i.e. the audio recording works again, but it's cracking and of bad quality (contrarily to the current state in the master branch if you build against a recent PulseAudio, where it works and sounds good).

The official buildsystem uses Ubuntu 14.04 with libpulse-dev 4.0, which is quite old. Updating it to a newer version matching what users have on their system might help.

Calinou commented 4 years ago

@akien-mga Would loading the PulseAudio library via dlopen() solve the issue? (#20978)

akien-mga commented 4 years ago

No, it's properly linked and found already.

Goutte commented 4 years ago

I can confirm @Zolzak's finding about the print_verbose(). Neither local builds of the master nor the 3.2.2-stable were giving off any sound. Now they do. Even when running Godot without --verbose.

Calinou commented 3 years ago

This was confirmed to also occur on Windows and macOS in https://github.com/godotengine/godot-demo-projects/issues/572.

akien-mga commented 3 years ago

This was confirmed to also occur on Windows and macOS in godotengine/godot-demo-projects#572.

That's a different issue though. The issue on Linux is specific to official builds, mic input works fine on local builds with a recent PulseAudio.

Separate issues should be opened for Windows or macOS issues, which are likely all separate bugs (mic input is implemented in the audio drivers so it's platform-specific).

erik-andershed commented 2 years ago

The problem is this:

The sample rate for you mic on your Mac and the Godot project need to match:

Skärmavbild 2021-10-02 kl  12 20 59 Skärmavbild 2021-10-02 kl  12 20 42
enorrmann commented 2 years ago

this still happens with 3.4.stable on linux ubuntu 21.10

mgschwan commented 2 years ago

Happens on Ubuntu 20.04.1 LTS with Godot_v3.4-stable_x11.64 The audiomixer shows that the microphone Godot is using does work but the data Godot records is silence

Calinou commented 2 years ago

@enorrmann @mgschwan Can you reproduce this if you change the microphone's sample rate in the PulseAudio configuration files, then log out and back in again? This is apparently how you workaround the issue on macOS at least.

enorrmann commented 2 years ago

@enorrmann @mgschwan Can you reproduce this if you change the microphone's sample rate in the PulseAudio configuration files, then log out and back in again? This is apparently how you workaround the issue on macOS at least.

my samplerate is 44100, with godot 3.2, in the sound panel, a new godot recording source appears and the app works ok with godot 3.4.stable, nothing appears in the recording panel, and the app "hangs" when I hit play, then the console shows

1 44100 True [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0[...]

vickylance commented 2 years ago

Its still happening in Godot 3.5 in Mac OS monterey. M1 Pro - Macbook Pro

Calinou commented 2 years ago

Its still happening in Godot 3.5 in Mac OS monterey. M1 Pro - Macbook Pro

Please open a separate issue to track the root cause on macOS, as it's likely different compared to Linux.

idg32 commented 2 years ago

i get no audio from anything recorded on windows.

Zireael07 commented 2 years ago

@idg32 this is a Linux specific issue, please open another one for Windows

fire commented 1 year ago

In https://github.com/V-Sekai/godot-speech we added code from libsamplerate to resample audio arbitrarily to 48000hz.

@enorrmann has a sample conversion problem and this relates to that.

phryk commented 1 year ago

Not sure if this is the right place for that, but I have the same problem on FreeBSD (13.1 with Godot 3.4.2 installed via pkg). pavucontrol (pulseaudio mixer) doesn't show anything in its 'Recording'-tab when Godot is ostensibly recording, tho.

Playback works fine, recording just yields a completely silent audio stream, no errors. Tested with own code as well as the mic recording demo.

Promptineer commented 1 year ago

Over 3 years later and this is still happening on Godot 4.01 stable. Recorded audio is silent every time. The length of the recording is accurate but the data is all 0s. You can clearly hear yourself with the Record bus unmuted, so imo the issue lies somewhere within the set_recording_active() and/or get_recording() functions. I tried to figure it out but I am not equipped enough to figure it out. Please help anyone :'(

mrzapp commented 1 year ago

This issue is still present, for me as well.

I can hear the feedback through the "Record" bus when unmuted, but the audio is being recorded.

On Arch Linux, kernel 6.2.9-zen1-1-zen Godot v4.0.2.stable.flathub [7a0977ce2]

Nukiloco commented 1 year ago

I was looking closely at the code and I'm no expert at C++ or threaded stuff. When set_recording_active is set to false, it never waits for the thread to finish. The code inside the thread _io_thread_process does know when to stop processing, but it seems like that function is still being called since the thread never finishes.

Also _io_thread_process really just calls _update_buffer. Though what's strange is that another function called _update also calls _update_buffer as well. I'm not sure where _update gets called from but it never checks if the recording has stopped.

Maybe I can try to clone the repo and test to see if there is any issues there.

Nukiloco commented 1 year ago

I'm not getting any results so far except that PulseAudio sometimes exit badly when I stop hitting record. There is also sometimes where audio crackles though closing and opening the game fixes it. (aka when i keep the audio bus unmuted) Data seems to be zero from the recording_data itself.

Note I'm using the mic_record demo from the godot projects demo repository as testing. I added the ensure_thread_stopped function to when the set_recording_active is set to false and break early when the loop needs to stop, though that also didn't change anything. I'm not sure where the actual microphone input data is coming from.

Is AudioEffectRecord really the right thing to use here? The documentation says to use AudioEffectCapture to capture the voice and mentions nothing about AudioEffectRecord.

Looking it up more, it seems like AudioEffectRecord is meant only for recording your voice to a file and AudioEffectCapture is used for processing your voice in real time. https://github.com/godotengine/godot/pull/52441 Though I'm not sure why AudioEffectCapture can't just be used instead to save to a file if that's what the user is going to do?

Does AudioEffectCapture work here? I haven't seen anyone mention it yet so I guess I will test it out.

andersmmg commented 1 year ago

I had this issue with earlier betas on arch Linux, but since the release it works perfectly for me. Not sure if that means it's an issue with how it works or not, maybe some sort of driver difference? Idk

MJacred commented 1 year ago

Does AudioEffectCapture work here? I haven't seen anyone mention it yet so I guess I will test it out.

What were your findings, @Nukiloco ?

@andersmmg: What did you use to record? AudioEffectRecord? Or AudioEffectCapture, like the docs say?

andersmmg commented 1 year ago

It works for me using the official audio record demo, which looks like it's using AudioEffectRecord

Nukiloco commented 1 year ago

Does AudioEffectCapture work here? I haven't seen anyone mention it yet so I guess I will test it out.

What were your findings, @Nukiloco ?

@andersmmg: What did you use to record? AudioEffectRecord? Or AudioEffectCapture, like the docs say?

I haven't tested it out yet since I been busy doing other things currently.

goatchurchprime commented 1 year ago

For me it works in linux (nixos) for v4.0.2 and 4.0.3 but then it's back to total silence on v4.1.1 when using the Audio Mic Record Demo.

v4.2.dev.4 is also silent.

The same results (for working and not working) occur when setting $AudioStreamPlayer.stream = AudioStreamMicrophone.

goatchurchprime commented 1 year ago

Using git bisect between (working) 4.0.3-stable and (not working) 4.1.1-stable and the power of the following Nix expression

nix build --impure --expr '(builtins.getFlake "github:nixos/nixpkgs/nixos-unstable").legacyPackages.x86_64-linux.godot_4.overrideAttrs { src = ./.; }' -L

I have determined that the breaking change was at: https://github.com/godotengine/godot/commit/98c655ec8db17e50afa58284b1dcad754034db4b

Unfortunately this commit doesn't look suspicious at all. Further investigation is necessary.

For the record, the bisect log is:

[julian@goatlap:~/repositories/godot]$ git bisect log
git bisect start
# status: waiting for both good and bad commits
# bad: [0bca4242392992840b0b891acde6422c49712e3e] Merge pull request #81420 from akien-mga/haiku-sayonara
git bisect bad 0bca4242392992840b0b891acde6422c49712e3e
# status: waiting for good commit(s), bad commit known
# good: [5222a99f5d38cd5346254cefed8f65315bca4fcb] Bump version to 4.0.3-stable
git bisect good 5222a99f5d38cd5346254cefed8f65315bca4fcb
# good: [92bee43adba8d2401ef40e2480e53087bcb1eaf1] Bump version to 4.0-stable \o/
git bisect good 92bee43adba8d2401ef40e2480e53087bcb1eaf1
# bad: [e95decf34369ba1bc925c59dfc2d791254bf41d9] Merge pull request #78111 from sbarkeha/master
git bisect bad e95decf34369ba1bc925c59dfc2d791254bf41d9
# good: [1ac2c537da86bd9a9234954dd4ba67e32c1b0d3a] Fix infinite loop in Build2DFaces::_find_edge_intersections
git bisect good 1ac2c537da86bd9a9234954dd4ba67e32c1b0d3a
# bad: [09d3dc86c0e740ba22caf924f8a6817c0bb2d79b] Merge pull request #77379 from bruvzg/update_ts_libs
git bisect bad 09d3dc86c0e740ba22caf924f8a6817c0bb2d79b
# bad: [645fd5ed0c1e45368b2bf8e6dbf59945f0c0843a] Merge pull request #76979 from MewPurPur/unify-audio-bus-textures
git bisect bad 645fd5ed0c1e45368b2bf8e6dbf59945f0c0843a
# good: [3e6a731904105ecb6712248106acd1c78eb2cd3c] Merge pull request #76418 from reduz/method-bind-validated-call
git bisect good 3e6a731904105ecb6712248106acd1c78eb2cd3c
# good: [4d703280d51595286d39375be0980f76d29ed97b] Merge pull request #76532 from dalexeev/tree-fix-multiline-drawing
git bisect good 4d703280d51595286d39375be0980f76d29ed97b
# bad: [a1db628eb359a24f494d03370f74bb44906277d5] Merge pull request #76856 from HolonProduction/macos-specific
git bisect bad a1db628eb359a24f494d03370f74bb44906277d5
# bad: [c80a2b4fe99dcd0bba6fc24ed2748b1474b24448] Merge pull request #76913 from akien-mga/rvo2-include-cstdint
git bisect bad c80a2b4fe99dcd0bba6fc24ed2748b1474b24448
# bad: [5271186f2f826cc6667766d9db32c1ca8b0743ec] Merge pull request #75901 from reduz/refactor-node-processing
git bisect bad 5271186f2f826cc6667766d9db32c1ca8b0743ec
# good: [bee96aa5cb2e353cbbfc1cb346cf2c27e9748746] Merge pull request #76903 from akien-mga/ci-codesp-hell
git bisect good bee96aa5cb2e353cbbfc1cb346cf2c27e9748746
# good: [31fc7a8525603e0e0b35438de4f66c73378915cc] Merge pull request #62378 from trollodel/gsoc_2022_multiwindow
git bisect good 31fc7a8525603e0e0b35438de4f66c73378915cc
goatchurchprime commented 1 year ago

I have definitely confirmed that this is the breaking commit, from two subsequent checkins in this list from around May 10

https://github.com/godotengine/godot/commits/master?after=c80a2b4fe99dcd0bba6fc24ed2748b1474b24448+1&branch=master&qualified_name=refs%2Fheads%2Fmaster

image

It's a very large commit, none of which appears to relate the the audio system, so I have no idea what's happened. https://github.com/godotengine/godot/pull/75901/commits/98c655ec8db17e50afa58284b1dcad754034db4b

akien-mga commented 1 year ago

That's a different issue from this one which was reported in 2019 then, and seemed specific to build environments / runtime environments. Could you open a new issue about the 4.1 regression with those details?

Nukiloco commented 9 months ago

More testing, i was reading through the source code and wanted to get more details. I run the test project in verbose mode, and all of the sudden, it starts to work.

For some unknown reason, verbose mode, fixes the issue? And running without verbose mode, brings the issue back.

All I can assume here and what I'm guessing, is that the verbose printing is delaying something long enough for it to work?

EDIT: Oh wait, that's what everyone above has said as well, didn't check that part, whoops.