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
0
Question by Doddler · Jul 23, 2013 at 09:42 PM · audiostreaming

OnAudioRead Buffer Changing Sizes?

For a variety of reasons on my project (the main one is having over 10000+ audio assets), I'm loading ogg files into memory from an external source, and using the NVorbis library to stream samples to unity through the callback functions available using AudioClip.Create. The code looks roughly like this:

 AudioClip InitClip(byte[] inbytes)
 {
     stream = new MemoryStream(inbytes);
     vorbis = new VorbisReader(stream, true);
     
     samplecount = (int) (vorbis.SampleRate*vorbis.TotalTime.TotalSeconds); //probably close enough
 
     return AudioClip.Create("clip", samplecount, vorbis.Channels, vorbis.SampleRate, false, true, OnAudioRead, OnAudioSetPosition);
 }
 
 void OnAudioRead(float[] data)
 {
     var f = new float[data.Length];
     vorbis.ReadSamples(f, 0, data.length);
 
     for (int i = 0; i < data.Length; i++)
     {
         data[i] = f[i];
     }
 }
 
 void OnAudioSetPosition(int newPosition)
 {
     vorbis.DecodedTime = new TimeSpan(0); //Only used to rewind the stream, we won't be seeking
 }

This actually works pretty well, in most cases it streams properly. I simply attach it to an AudioSource and it's good. The reason for the for loop in the OnAudioRead section is because while OnAudioRead is supposed to be passed a float[], it's actually getting a Single[][], which I can't pass directly to NVorbis. Copying over the buffer like this seems to resolve the issue.

Main problem though is that periodically I will receive error messages and garbled segments of audio. The error is "System.IndexOutOfRangeException: Array index is out of range. at AudioAsset.OnAudioRead (System.Single[] data)". The error to me doesn't make much sense, because there shouldn't be any way the index could be invalid.

So I rigged up the following code within OnAudioRead to test it.

 var length = data.length;
 vorbis.ReadSamples(f, 0, data.length);
 var length2 = data.length;
 
 if(length != length2)
     Debug.LogError("Warning! Buffer size changed!? Was " + length + ", now is " + length2);

Running this code, lo and behold, it would sometimes generate the error. I would get this in my error log, interspersed with IndexOutOfRangeExceptions.

 Warning! Buffer size changed!? Was 928, now is 4096
 Warning! Buffer size changed!? Was 928, now is 4096
 Warning! Buffer size changed!? Was 928, now is 4096
 Warning! Buffer size changed!? Was 4096, now is 2512
 Warning! Buffer size changed!? Was 2512, now is 4096

So the question is, why in the world would the length of the buffer be changing while I'm reading? I can't make any sense of it. In order to rule out NVorbis causing the issue, I did another test, excluding it entirely from the OnAudioRead function.

 public void OnAudioRead(Single[] data)
 {
     for (var i = 0; i < data.length; i++)
         data[i] = Mathf.Sin((float)i/100);
 }

Still periodically receiving IndexOutOfRangeExceptions. There's so little documentation on these functions that there's nothing really to help me figure out why it's not working. Locking doesn't seem to help either.

Anyone have any clue?

Comment
Add comment · Show 3
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 gregzo · Jul 23, 2013 at 09:54 PM 1
Share

Probably a typo, but I've never heard of OnAudioRead, OnAudioFilterRead is what I use. Never saw it changing data.Length, though...

avatar image Doddler · Jul 23, 2013 at 10:08 PM 0
Share

Sorry, I guess it's not too clear. It's not specifically called OnAudioRead, it's simply a callback function for AudioClip.Create to read audio data. It doesn't have to have that name, but it's referred to it like that in the documentation.

I tried using OnAudioFilterRead briefly but had issues with the frequency being screwy. I guess I can try that again.

avatar image gregzo · Jul 23, 2013 at 10:32 PM 1
Share

Hey Doddler, Indeed, the callbacks you can setup from AudioClip.Create are unreliable. Use OnAudioFilterRead for any kind of reliable access to lower level audio, or accept a higher latency and less flexibility and work with AudioCLip.GetData / SetData. Hope it helps!

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Doddler · Jul 23, 2013 at 11:02 PM

gregzo: Thanks for the tip, I'm trying to use OnAudioFilterRead but running into an issue where the audio is a bit distorted. I imagine this is because my input stream is 44100 and unity wants to use 48000 (even if the clip is set to 44100). Is there an easy way to match this, or do I need to figure out the conversion necessary?

Edit: AudioSettings.outputSampleRate = 44100; will set the output sample rate. I'm good! OnAudioFilterRead will work in place of the broken callbacks.

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 Doddler · Nov 11, 2013 at 03:21 AM 0
Share

An update incase anyone stumbles upon this issue. OnAudioRead now works, but at present AudioClip.Create will crash on mac and linux if strea$$anonymous$$g is enabled. Two steps forward, one step back. At least it's progress!

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

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I stream audio from disk? 0 Answers

Sound creation using WAV. files 1 Answer

Stream music in Unity mobile 0 Answers

Problem with streaming audio and play in trigger area 0 Answers

How to stream audio before completely downloaded? 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