October 31, 2020, 04:01:03 PM

Author Topic: PlaySound causing low framerate first time a sound is played  (Read 283 times)

Offline TomToad

  • Hero Member
  • *****
  • Posts: 517
PlaySound causing low framerate first time a sound is played
« on: August 28, 2020, 09:27:54 PM »
When playing a sound first time, the framerate drops for a second.  After that, the same sound can be played multiple times without problem.  I tried delaying a few seconds to give time for  the sounds to load, but that doesn't seem to help any.
 
ANyone have a solution that doesn't involve playing all sounds before the game begins?

The example code below shows the problem in action.  The bunny and sound is from Kenney's Assets.
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Local gravity:Double = 2.0
  4. Local speed:Double = 0.0
  5. Local y:Double = 10
  6. Local image:TImage = LoadImage("bunny1_jump.png")
  7. Local JumpSound:TSound = LoadSound("drop_003.ogg")
  8. Local Channel:TChannel = AllocChannel()
  9.  
  10. Graphics 1024,768
  11. Local delta:Double
  12. Local Time:Int, OldTime:Int = MilliSecs()
  13.  
  14. While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
  15.         Time = MilliSecs()
  16.         delta = (TIme-OldTIme)/1000.0
  17.         OldTime = Time
  18.        
  19.         speed :+ gravity
  20.         y :+ speed
  21.         If y > 768-image.height
  22.                 y = 768-image.height
  23.                 speed = -50
  24.                 PlaySound(JumpSOund, Channel)
  25.         EndIf
  26.        
  27.         Cls
  28.         DrawImage image,512,y
  29.         Flip
  30. Wend
  31.  
  32.  
------------------------------------------------
8 rabbits equals 1 rabbyte.

Offline Matty

  • Hero Member
  • *****
  • Posts: 1213
    • MattiesGames
Re: PlaySound causing low framerate first time a sound is played
« Reply #1 on: August 29, 2020, 06:33:37 AM »
While not a solution that doesn't involve playing all sounds-if you do that then you can always set the volume to inaudible while doing so such that the player does not notice.

A similar thing occurs with some 3d libraries for android where the first appearance of a resource causes the app to pause while caching the resource.  In such cases spinning around the world and hiding the rendered world behind a bitmap for a second does the trick.

Offline Derron

  • Hero Member
  • *****
  • Posts: 3239
Re: PlaySound causing low framerate first time a sound is played
« Reply #2 on: August 29, 2020, 07:28:26 AM »
Uhm... for what thing we have to look for?

Jumps perfectly smooth and does play "bobb bobbb bobbb bobbb" sounds - right from the start. (Linux Mint 19, 64bit).

Can you add a "log" so we see times per "frame"? Does it happen without audio too?
What happens if you do set the audio driver manually?

SetAudioDriver(the one you use - freeaudio, soloud...)



bye
Ron

Offline Henri

  • Sr. Member
  • ****
  • Posts: 263
Re: PlaySound causing low framerate first time a sound is played
« Reply #3 on: August 29, 2020, 07:36:01 AM »
Hi,

I have a SSD drive so I couldn't re-produce your issue. I suspect that if your description is right the sound is played from the HD the first time and from memory afterwards.

There is a CueSound function though. Would that do the trick ?

-Henri
- Got 01100011 problems, but the bit ain't 00000001

Offline Derron

  • Hero Member
  • *****
  • Posts: 3239
Re: PlaySound causing low framerate first time a sound is played
« Reply #4 on: August 29, 2020, 08:50:25 AM »
I thought "LoadSound" alread loads the file into memory.

You could check it out by doing this:

loca t:TSound = LoadSound("bla.ogg")
Delay(10000)
PlaySound(t)

and while it delays... rename your bla.ogg to bla2.ogg (file handle would become invalid).


Just checked it out and ... sound still played.
And as Henri wrote: CueSound is your friend in some cases.

https://blitzmax.org/docs/en/api/brl/brl.audio/

But AllocChannel should ... do the same too, so ... maybe (and as stated already) try out a different audio backend ("Soloud")


Import audio.soloudaudio
Import audio.soloudaudiominiaudio 'miniaudio backend
'Import audio.soloudaudiosdl 'sdl backend
SetAudioDriver("Soloud")


bye
Ron

Offline TomToad

  • Hero Member
  • *****
  • Posts: 517
Re: PlaySound causing low framerate first time a sound is played
« Reply #5 on: August 29, 2020, 09:12:09 AM »
What happens if you do set the audio driver manually?

SetAudioDriver(the one you use - freeaudio, soloud...)

Seems to be a driver issue.  Problem exists when using "DirectSound" but goes away with any other driver.  Even "FreeAudio DirectSound" works ok.

Thanks :)
------------------------------------------------
8 rabbits equals 1 rabbyte.

Offline GfK

  • Full Member
  • ***
  • Posts: 154
Re: PlaySound causing low framerate first time a sound is played
« Reply #6 on: August 30, 2020, 12:21:19 PM »
Pretty sure this is a long-standing Blitzmax issue.  I think what's happening is that when you use LoadSound(), DirectSound, FreeAudio etc doesn't decompress the OGG file until you actually try to play it the first time, hence the slight delay.

I always used OpenAL with BlitzMax.  You can check what drivers you have available by checking the contents of AudioDrivers().
Intel I9-9900K 3.6-5.0GHz | GeForce RTX2070 8GB | 32GB RAM | 500GB NVMe M.2 SSD | 1TB HDD | Windows 10 x64.
MSI Apache Pro | I7-7700HQ | GeForce GTX1060 3GB | 8GB RAM | 128GB SSD | 1TB HDD | Windows 10 x64.

Offline Derron

  • Hero Member
  • *****
  • Posts: 3239
Re: PlaySound causing low framerate first time a sound is played
« Reply #7 on: August 30, 2020, 12:55:09 PM »
With Soloud you could even "stream" the audio.


@GfK:
Did not check it indepth but If a am right, then default (freeaudio etc) is that ogg files get decoded in "LoadAudio", not when actually playing the audio.

If unsure, just add 10 of "loadsound()" with your favorite ogg/mp3 files ... and measure how long it takes - if it is decoded "on playback", there should be <1ms for all of the files.


I think it is more plausible that the directsound thing requires some init which is does not when "initializing" is done from the backend of BlitzMax / "brl drivers".


Meanwhile (if not wanting to change backend audio driver) pne could ... create a "silent" audio file ... incbin it and play this file then right on start. So "later" there can be no hickup.

bye
Ron

Offline fielder

  • Jr. Member
  • **
  • Posts: 91
Re: PlaySound causing low framerate first time a sound is played
« Reply #8 on: September 01, 2020, 08:19:17 AM »
are you sure that the sound is played JUST 1 time? and not 5-6 times (just looking code)
usually on my games i place a timer sound to prevent that the same sound can't be played again before 500millisecs

Offline Derron

  • Hero Member
  • *****
  • Posts: 3239
Re: PlaySound causing low framerate first time a sound is played
« Reply #9 on: September 01, 2020, 09:43:33 AM »
If each bullet you fire should play a sound, then you should not limit it.
But if each startAttack does plays a sound and startAttack is called on each keyhit, then yes, play only if channel is free again.

Bye
Ron

Offline TomToad

  • Hero Member
  • *****
  • Posts: 517
Re: PlaySound causing low framerate first time a sound is played
« Reply #10 on: September 01, 2020, 03:36:17 PM »
Done a bit of experimenting with this.  First, I only have problems with the default "DirectSound" driver.  Other drivers do not exhibit this problem.  It is not a compression thing as it makes no difference whether I use an .ogg or a .wav file.

The delay happens within PlaySound or ResumeChannel.  If I set a timer before the call and right after the call, I find a delay of about 250-500 milliseconds.  It has nothing to do with loading, initializing, nor decompressing the sound, because when I add a delay between loading/cuing sounds and playing the sound, there still is a delay.

This only occurs on the very first playing of a sound.  Subsequent plays are instant regardless of sound or channel.  This makes me think that DirectSound is loading/initializing only when the first sound needs to play creating the delay.

Solution is 1) use a driver other than DirectSound or 2) play a blank sound or a sound that can be delayed a bit (such as intro music) first.


------------------------------------------------
8 rabbits equals 1 rabbyte.

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal