Crackling noise when incorporate JUCE into GDExtension

Godot Version

Godot4.3 Stable, Windows10/11, JUCE8.0.2

Question

Hello everyone. I am currently trying to create a game-like music software using Godot.

JUCE is a very popular framework used to develop full-scale music tools. I thought that if I combined it with Godot, I could easily create the most attractive music software.

I was successful in incorporating JUCE into GDExtension and playing the sound, but when I listened closely, I noticed that the playback sound had clicking noise at intervals of several seconds to several tens of seconds. If the playback sound has the noise, it is useless as music software and has no value at all.

It seems to be a buffer-related problem, and I have been trying various things to solve this, but I am having trouble.

You can see the current noise problem in video, at 5sec, 22sec, 30sec.

Also you can look source code. (Sorry it includes Japanese because personal repository)

This noise problem did not occur when I created a minimal C++ Windows desktop app and incorporated JUCE. I also tried incorporating another audio engine “miniaudio” into GDExtension, and there was also no noise. So I think there may be some kind of compatibility issue rather than a problem with either of JUCE and Godot.


What I’ve tried so far

  • Changed the audio buffer size on the JUCE side, changed the audio device type, etc.
  • I thought that Godot and JUCE might be opening the audio device twice, so I set the audio device on the Godot side to “Dummy”.
  • Disabling all audio-related code in main.cpp of the Godot source code and recompiling it, and removing all godot modules and building it.
  • I also tried it on a PC other than the development machine (a Macbook with Windows installed), but the same problem occurred.
  • The frequency of the noise seems to have decreased significantly when I did a release build JUCE and Godot, but the noise still occurs.
  • I also tried Godot4.4 dev3 and JUCE7.0.12, but there was no change.

I’m still beginner to Godot and JUCE, and I don’t know much about the internal details yet.

  • Has Godot’s audio system been completely disabled?
  • If disabling Godot’s audio function doesn’t fix it, what else could be the cause?
  • Is there an easy way to try a minimal build that does more than just remove modules?
  • Am I using JUCE wrong in the first place?

Even if it’s not the solution itself, I’d be happy if you could give me some hints. Thank you.

Yes, I would agree it is a buffer problem. If it’s underflow-ing, it typically can be reduced by increasing the buffer size at the cost of latency, or making sure your audio thread can keep up. Overflowing, just needs to reduce processing rate.

I think Godot audio server runs on a 64 frame buffer. So I would try and match it’s rate or be within an integer multiple of it. (Unless you’re outputting another way.)

Make sure you don’t block, or lock, on the audio thread. ( Use atomics for signaling ).

I looked at your code, the only thing that looks off is you set the frequency every process call. You could make that set whenever it changes. But the problem is probably juce itself as you already have a large buffer.

Thank you for your comment. It gave me a some hints.

If both Godot and JUCE have some process that blocks or locks the audio thread and they are fighting over it, I can understand that makes problem.

According to the last table on the following site, it seems that JUCE has some process that locks the audio thread, although it is about older versions. So it is certainly possible that it is a problem with JUCE.

On the other hand, does Godot have a process that blocks or locks the audio thread?
Is it done by audio-related process and cannot be prevented by simply setting it to Dummy, Or is it possible that such blocking occurs in a process unrelated to audio?

The reason for changing the frequency is to change the pitch of the sine wave depending on the position of the mouse cursor, and it is not particularly necessary, but is this an incorrect usage?

In the end, I avoided this problem by using miniaudio instead of JUCE.
As a result, I had to make more parts from scratch, but so far there have been no problems.
Thank you.

1 Like

Sorry, I don’t get notifications if I’m not directly replied too. To answer your question about locking. I think it depends on the the audio API and if they can share hardware to processes.

I know Linux more and pulse audio allows applications to share an audio device. But to be honest I have never looked at Godot’s audio back end. But I suspect it shouldn’t fight over it as you can have many applications play out at the same time on most OS. Unless you are trying to access the hardware directly I think that would potentially lock everyone else out, not just periodic drops.

The only reason to disconnect setting the frequency every frame (in a process function ) is it may incur extra processing that could cause a dropout? That is only a guess. Although I hope that not be that case.

Anyway I’m glad you found a solution.

1 Like

Sorry, I didn’t know about the notification system. And thank you for your kind and detailed answer!

I haven’t been able to solve the problem in the title so far, but I found another solution so I thought I’d share it.
Maybe I’ll try again when I have a deeper understanding of Godot and JUCE.
Thanks!