Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by SpencerRiedel · Jun 14, 2014 at 04:43 AM · audioperformanceupdatesyncrate

I need a way to run code much more frequently than update. Ideally, every 3 milliseconds

I'm working on an interactive music tool. The ear is much more sensitive to timing issues than the eye, and while Update's frequency of 16 milliseconds is good enough for the eye, it's far too slow for music.

Things sound "in sync" if they are within a tolerance of 5 milliseconds, water tight if they're at 3.

So far, coroutines are too expensive to reach this speed, and changing the timestep isn't an option, as it would interfere with the rest of the game. Even OnAudioFilterRead is only about 20 ms.

Is there a way to have code called at a frequency of less than 5 milliseconds?

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Jun 14, 2014 at 04:44 AM 1
Share

I don't know you can get it down to 5 milliseconds, nor how even the spacing, but InvokeRepeating() can be executed at rate faster than the frame rate, and it is more efficient that a coroutine.

avatar image Eric5h5 · Jun 14, 2014 at 04:53 AM 1
Share

Just FYI, Update doesn't have any set frequency. It's variable, depending on many factors, such as vsync, what the monitor refresh rate is if vsync is on, CPU/GPU load, etc. If you leave vsync off and the computer is fast enough for what you're doing, Update would certainly be able to hit 3ms (or lower, unless you used Application.targetFrameRate = 333 to limit it).

avatar image Nerevar · Jun 15, 2014 at 06:22 PM 1
Share

You don't need to go lower than 20ms (DSP speed = 1/outputSampleRate) though You can still reset the frequency of the DSP modifying the outputSampleRate.

avatar image SpencerRiedel · Jun 16, 2014 at 06:52 AM 1
Share

Yes, I do need a faster update, unless I can call a function every time there's new data, I need looping code that runs faster than every 20 ms.

This tool needs to be able to trigger audio on the beat, on demand. With an update of ~20ms, a beat will often be late by 10-20 ms which is unacceptable.

     public void WaitThenLoop ()
     {
 
         loopTimer = $$anonymous$$easureLoopTime();
         //If the track has segments
         if(currentTrack.Segments.Count > 0)
         {
             //gets the segment from track associated with the current state
             Segment segment = currentTrack.Segments[currentState];
             
             //If the audio is passed the current segment
             if (audio.time > segment.End) 
             {
                 //either start the segment over or jump to the next one
                 currentState = (int)cuedState;
                 audio.time = currentTrack.Segments[(int)cuedState].Start;
             }
         }    
     }

     IEnumerator AudioLoop()
     {
         while(true)
         {
 
             yield return new WaitForSeconds(0.0001f);
 
             WaitThenLoop();
 
 
         }
 
     }


avatar image Nerevar · Jun 17, 2014 at 10:32 AM 0
Share

On a good computer disabling Vsync may give you 1000fps, so that's 1ms precision on Update().It is a solution if the tool you create is for your own use because fps depend on the abilities of the computer.

There are many possibilities to generate audio on the fly with unity, but you can't update at the output sample rate ( at least not using unity), you have to create a queue of data samples to anticipate the next beats and keep the audio continuity, that's what I do to generate audio. I think audio program$$anonymous$$g tools generates buffer/chunk of audio every update, thei don't send data sample by sample.

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by YourGamesBeOver · Jun 18, 2014 at 03:09 PM

If your tool doesn't use the physics engine for anything, you could use FixedUpdate. It has a more consistent timing, and you can change the rate by going to Edit->Project Settings->Time and changing the Fixed Timestep.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SpencerRiedel · Jun 18, 2014 at 03:28 PM 0
Share

Thanks for your reply. This would most certainly work, but unfortunately the rest of the game uses physics pretty extensively.

avatar image
1

Answer by Wisteso · Jun 14, 2014 at 05:03 AM

You could try just using a C#/Mono thread... However, it seems like a bad idea to assume that you'll be able to get ~333 calculations per second. On slower hardware especially...

You'll probably also have to use busy-waiting because sleeping a thread tends to be hit and miss if you want exact timings.

My question is why dont you calculate what you need ahead of time? If you're reacting to the music (rather than generating it) you have all the data you need before-hand. If you ARE generating the music on the fly, then would it be bad to have it be smooth but lagging behind by about 30ms?

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SpencerRiedel · Jun 14, 2014 at 06:43 PM 1
Share

I'll look into mono threads. I have to believe that it is possible to get such a fast refresh since it's basically how audio program$$anonymous$$g works.

Here's the reason that calculating ahead of time isn't a solution:

Suppose I want to loop the first four measures of my song, which is from exactly 0.000 s to 4.800 s. I can know this already, and tell unity exactly what to do.

Because of how slow Update() is, when it reaches 4.800, it could jump back within 4.803, but it's more likely to jump back at 4.812. Way way mondo inaccurate for musical purposes.

It's not just that things are behind (though that is a problem) it's also that things are inconsistent.

If everything was just 30 ms behind but dead on otherwise, there wouldn't be a problem. but ins$$anonymous$$d things are 5-25 ms behind, which for musical purposes is unacceptable.

avatar image Wisteso · Jun 14, 2014 at 09:41 PM 1
Share

Using a c# thread might be best for you then. If you do busy waiting, you'll use more CPU but you'll also have more accurate sleep times. You might be able to get by with normal (not busy) waiting, but then the thread may wake up early/late (depends on the underlying OS).

You could also possibly use a bigger buffer. It sounds like you're wanting to almost do this in real time, but a lot of audio playback programs work by passing big chunks of audio data to the sound device, rather than many tiny bits. Though this would prevent the game from having instantaneous music changes based on input - it would be delayed by a maybe half a second.

Ultimately, you're talking about creating something that's typically done in native code, and not behind tons of layers of abstraction. It might be doable though. It sounds like the biggest thing to worry about is accurate wait/sleep timers, but like I said, busy waiting can help that. General idea being...

 while (DateTime.Now.Ticks < NextTime)
 {
     // comment out the line below for more expensive 
     // but more accurate ti$$anonymous$$g
     Thread.Sleep(1); 
 }

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Measuring all the Update loops combined 1 Answer

Animator.Play() in update, Performance?? 0 Answers

Tracker modules: can they send out messages? 1 Answer

Why does audio get out of sync with multiple loops playing? 1 Answer

Quadruple audio fade script not working completely. Shocker. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges