How to get more frequent audio playback_position?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By arpeggiocat

TLDR: I’d like the playback_position to update at least every 1/100th second, is this possible? Thanks!!

Hi, I have a talking 3D NPC. I have blend shapes for the mouth and gathered times for those shapes with Rhubarb

With this:

func _physics_process(_delta):
	pbTime = self.get_playback_position()
        print(pbTIme)

I get something like this:

  0
    0
    0.052245                  # same
    0.052245                  # same
    0.052245                  # same
    0.098685                  # jumps ahead
    0.098685                  # same
    0.121905                  # jumps ahead
    0.121905                  # jumps ahead
    0.168345                  #  etc .. 
    0.168345
    0.168345
    0.214785
    0.214785
    0.261224
    0.261224
    0.261224
    0.307664
    0.307664
    0.307664
    0.354104
    0.354104
    0.354104
    0.400544
    0.400544
    0.400544
    0.446984
    0.446984
    0.493424
    0.493424
    0.493424
    0.493424
    0.539864
    0.539864
    0.586304
    0.586304
    0.632744

FYI I have also tried using a .01 sec Timer to get the playback position

func _on_AudioTimer_timeout(): 
		pbTime = self.get_playback_position()
		print(pbTime)

… but the results were no better.

Thanks again!

Try to experiment with lower latency of audio playback (by decreasing buffered data length), see AudioStreamGeneratorPlayback, and push frames manually instead of _physics_process.

But remember, the smaller buffer length, the higher chances to get buffer under-over-run, which will lead to clicks and stutters (OS/hardware dependent).

Another suggested option, is to use AudioEffectSpectrumAnalyzer.

p.s. in any case I’d consider to use C++ as it’s better suited to your task (of low level) than GDScript.

sash-rc | 2020-12-24 15:21

:bust_in_silhouette: Reply From: Lopy

If you only use the time information for your mouth movement, you could get it from elsewhere, with a periodic sync if necessary. You would use OS.get_ticks_usec(). Save the time when your playback starts, and then assume that it runs at the corrects speed. If the playback is long and you fear a desync, you can always reset the time according to get_playback_position().

The physics fps can be set in Physics/Common/Physics Fps.