Search Unity

Cannot get data from streamed audio sample ... but the sample is NOT streamed!

Discussion in 'Scripting' started by cecarlsen, Apr 1, 2012.

  1. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Hi Everyone (preferably Søren)

    I do this:

    Code (csharp):
    1.  
    2. IEnumerator Start()
    3. {
    4.     string path = "File://" + Application.dataPath + "/Test Files/EA0101_Loop_6strings.wav";
    5.     WWW download = new WWW( path );
    6.     yield return download;
    7.     bool threeD = false;
    8.     bool stream = false;
    9.     AudioClip clip = download.GetAudioClip( threeD, stream, AudioType.WAV );
    10.     float[] samples = new float[ clip.samples * clip.channels ];
    11.     clip.GetData( samples, 0 );
    12. }
    And I get this error:
    "Cannot get data from streamed sample"

    Why? Oh Why?

    Carl Emil
     
    Last edited: Apr 4, 2012
  2. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Anyone?
     
  3. rcomsa

    rcomsa

    Joined:
    Dec 19, 2011
    Posts:
    3
    I'm having this problem as well. Specifically telling the GetAudioClip function that I don't want a streaming clip and it tells me that it is streaming when I try and get its data. Same error: Cannot get data from streamed sample.

    Anyone out there with any suggestions?

    Also, Carl, isn't it poor practice to loop over www.isDone? I believe the documentation says that you should always yield on return like:

    WWW download = new WWW(path);
    yield return www;

    Don't think thats the problem here, but it might solve a problem for you down the road by changing to yield.
     
  4. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Thanks for the yield tip. I changed it in the example.

    The problem is still an unsolved mystery.
     
  5. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    This is still troubling me. Can anyone test the code above and confirm that there is an issue?

    Cheers
    Carl Emil
     
  6. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Let me rephrase:

    Does AudioClip.GetData() consider all audio clips loaded with WWW streamed, even though they are loaded from the hard disk with the flag 'stream' disabled?
     
  7. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Really ... no one has this problem?
     
  8. AnssiK

    AnssiK

    Joined:
    May 11, 2012
    Posts:
    2
    I'm experiencing the same problem, using essentially identical code to Carl's.
    GetData works fine if the clip represents an audio asset that is part of the Unity project and has Load Type set to "Load into memory," but does not work with audio clips loaded dynamically using WWW class.
     
  9. AnssiK

    AnssiK

    Joined:
    May 11, 2012
    Posts:
    2
    To clarify: I'm using Unity version 3.5.1.f2 on MacBook Pro and of course set the stream flag of GetAudioClip to false.
     
  10. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    This is still a show stopper for me. If anyone cares to confirm the issue I would greatly appreciate it.
     
  11. jack_rabbit

    jack_rabbit

    Joined:
    Jun 12, 2012
    Posts:
    4
    Got the exact same problem.

    I've even tried getting the byte array from WWW.bytes and converting it into a float array, since I noticed that the number of samples is exactly 1/4 of the number of bytes (so I though since there are 4 bytes in a float I may give it a try). Didn't work either.

    I desperately need this to work!!

    Edit: I kind of forgot about having stereo sound and 16bit wav files. When I convert 2 bytes into a number I get an array which is the same length as the one GetData gives me if I load the same sound file as an asset in unity (once I've taken away the wav header from the raw byte array). Looks like I may be on to something here. Will upload the code once I get this dirty, dirty hack to work.
     
    Last edited: Jun 12, 2012
  12. jack_rabbit

    jack_rabbit

    Joined:
    Jun 12, 2012
    Posts:
    4
    DISCLAIMER: This is dirty.. real dirty.

    Right, I kind of have a workaround, but it requires you knowing what music format you are dealing with:
    Get the data from the WWW instance using "myWWW.bytes". This gives you the byte array of raw data from the file reader. From there you can then get rid of the header by eliminating first 44 bytes in case of WAV files. Then you have to convert the data from bytes to something useful. In case of 16 bit, stereo WAVs you have to iterate through the byte array and combine two bytes to a short, using System.BitConverter.ToInt16().

    This sadly didn't give me the floats GetData would return, but I couldn't figure out how on earth that is formatted. Since I'm consistently using this data though, it doesn't really matter. I've successfully performed an FFT on it, which looks alright. It's my first time doing and dsp though, so I have no idea if it's perfect.

    Code (csharp):
    1.  
    2.     float[] byteArrayToFloatArray(byte[] inputData) {
    3.        
    4.         float[] outData = new float[inputData.Length / 4];
    5.        
    6.         int k = 0;
    7.         for(int i = 0; i < inputData.Length; i+=4) {
    8.             float left = System.BitConverter.ToInt16(inputData,i);
    9.             float right = System.BitConverter.ToInt16(inputData,i+2);
    10.             outData[k] = left + right; // I want mono for FFT
    11.             k++;
    12.         }
    13.        
    14.         return outData;
    15.     }
    16.  
     
    Last edited: Jun 13, 2012
  13. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Thanks for giving it a shot. I hope that Unity will fix this very soon. I've needed this feature for nearly half a year.
     
  14. Evil-Dog

    Evil-Dog

    Joined:
    Oct 4, 2011
    Posts:
    134
    Yeah I'm facing this issue as well. I'm dissapointed the thread ends here with no solution. It worked when I had waves in the asset bundles, but compressed sounds in the asset bundles give me the errors.
     
    Last edited: Jul 1, 2012
  15. Evil-Dog

    Evil-Dog

    Joined:
    Oct 4, 2011
    Posts:
    134
    Anyone? Unity people? is Unity 4 gonna fix that? It's pretty important that fully loaded sounds are not regarded as stream.
     
  16. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Hell yeah! Unity 4 fixed the issue! =D
     
  17. Evil-Dog

    Evil-Dog

    Joined:
    Oct 4, 2011
    Posts:
    134
    YEEESSSSS!!!!!!!!!!!!!!!!! You made my day man!
     
  18. BazLevelUp

    BazLevelUp

    Joined:
    Jun 27, 2012
    Posts:
    36
    Does that means I HAVE to upgrade to Unity 4 to test if it's working?
     
  19. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    No
    Just wait for the Unity 4 release and test it in the free version assuming you qualify for the free and are not legally required to get pro naturally
     
  20. themushroomsound

    themushroomsound

    Joined:
    Oct 17, 2012
    Posts:
    1
    I was hoping it would, but I get the same issue with Unity 4.
    Basically I'm trying to feed audio data from a series of AudioClips to OnAudioFilterRead so I can read a playlist without gaps (haven't found another way yet).

    There's my code :
    Code (csharp):
    1.  
    2. //#pragma strict
    3.  
    4. var audioClips : AudioClip[];
    5. private var audioSamples;
    6. private var currentClip : int = 0;
    7. private var readOffset : int = 0;
    8.  
    9. function Start () {
    10.    
    11.     audioSamples = MultiDim.JaggedFloat(audioClips.length);
    12.     for(var i : int = 0; i < audioClips.length; i++) {
    13.         var nbSamples : int = audioClips[i].samples * audioClips[i].channels;
    14.         audioSamples[i] = new float[nbSamples];
    15.         audioClips[i].GetData(audioSamples[i] as float[],0);
    16.     }
    17. }
    18.  
    19. function Update () {
    20.  
    21. }
    22.  
    23. function OnAudioFilterRead(data:float[], channels:int) {
    24.  
    25.     var bufferLength : int = data.length;
    26.     var sourceLength : int = audioSamples[currentClip].length;
    27.     var index : int = 0;
    28.    
    29.     for(var i : int = 0; i < bufferLength; i++) {
    30.         if(i + readOffset == sourceLength) {
    31.             currentClip = currentClip < audioClips.length - 1 ? currentClip + 1 : 0;
    32.             sourceLength = audioSamples[currentClip].length;
    33.             readOffset = -i;
    34.             Debug.Log("looping - i:" + i + ", offset:" + readOffset);
    35.         }
    36.         index = i + readOffset;
    37.         data[i] = audioSamples[currentClip][index];
    38.     }
    39.    
    40.     readOffset += bufferLength;
    41. }
    Now that works fine with .wav, but when I convert the clips to .ogg I get that "Cannot get data from streamed sample" error. :(
     
  21. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    It still works for me both for OGG and WAV (Unity 4.0.0f7)

    Code (csharp):
    1. string path = "File://" + Application.dataPath + "/X_TESTS/Audio GetData and WWW/instrument1.ogg";
    2. WWW download = new WWW( path );
    3. yield return download;
    4. bool threeD = false;
    5. bool stream = false;
    6. AudioClip clip = download.GetAudioClip( threeD, stream, AudioType.OGGVORBIS );
    7. float[] samples = new float[ clip.samples * clip.channels ];
    8. clip.GetData( samples, 0 );
    9. for( int s=0; s<100; s++ ) Debug.Log( samples[s] );
     
  22. terraformer

    terraformer

    Joined:
    Aug 22, 2012
    Posts:
    6
    As far as I know: the audio format depends on the platform (for mobile, use MP3, for PC and Mac standalone use OGG. Set platform in File / Build settings)
     
  23. wondersonic

    wondersonic

    Joined:
    Jan 8, 2012
    Posts:
    62
    I had the same problem, but succeed by setting the property of the imported audio clip to "Decompress in memory". (file is an mp3 on the PC platform).
     
  24. gaborszauer

    gaborszauer

    Joined:
    Nov 12, 2013
    Posts:
    1
    Like wondersonic said, it has to do with how the import settings are setup.

    I do ogg "Decompress In Memory", and GetData works.
    Useful for downloading an asset bundle and saving it as a wav.