Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

AudioClip.Create(); can't play any clips shorter than 1 second

Discussion in 'Audio & Video' started by reefwirrax, Dec 4, 2014.

  1. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    Oh sorry after many hours of running print statistics on all aspects of the audioclip.create function, and finding that it prints within the function in 10x 4096 size sample buffers, except that unity doesnt update it's frames until it has called 44100 audio samples, i coded something lame and the first half of this question i just wrote the Sample Rate wrong.

    I am still confused about the 2nd half and checking figuring out how to buffer audio.


    I took the AudioClip.Create(); script from reference

    I only changed the sample length to 4410 samples, and printed AudioClip.length.

    The sound plays the 4410 sample in a loop for one second, and the AudioClip length prints 1, i.e. 1 second.

    if i want to run a 22100 sample sound for example, for some reason the AudioClip.Create is making a sound 1 second long:

    Code (csharp):
    1.  
    2.     #pragma strict
    3.     // Creates a 1 sec long audioclip, with a 440hz sinoid
    4.     var position: int = 0;
    5.     var sampleRate : int = 0;
    6.     var frequency : float = 440;
    7.     function Start () {
    8.  
    9.        //MAKE AUDIO FILE OF 0.1 SECONDS''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    10.         var myClip = AudioClip.Create("MySinoid", 4410.0, 1, 4410.0, false, true, OnAudioRead, OnAudioSetPosition);
    11.         sampleRate = AudioSettings.outputSampleRate;
    12.         audio.clip = myClip;
    13.         print("----is length------ "+audio.clip.length);
    14.       //IT PRINTS THAT THE AUDIO CLIP LENGTH IS 1 SECOND''''''''''''''''''''''''''''''''''''''''''''''''''''
    15.         audio.Play();
    16.     }
    17.     function OnAudioRead(data:float[])
    18.     {
    19.         print ( "data.Length " + data.Length +  " pos " + position +" ms " + ( DateTime.Now.Millisecond  ) );
    20.         for (var count = 0; count < data.Length; count++)
    21.         {
    22.             data[count] = Mathf.Sign(Mathf.Sin(2 * Mathf.PI * frequency * position / sampleRate));
    23.             position++;
    24.         }
    25.     }
    26.     function OnAudioSetPosition(newPosition:int)
    27.     {
    28.         position = newPosition;
    29.     }
    30.  

    I also tried sending data from a stream computed array to the audioclip.create's PCMReaderCallback function, which prints that it runs 10 times at different DateTime.Now.Milliseconds intervals calling 4096 audiobits on every call, within a single frame. I tried to send data to it in buffer segments, to make a diffusion delay with various DSP functions, and it prints 10 times 4096 print results, but it doesnt update the frame in between the 10 data calls, so i can't stream audio to the audioclip create function in buffers smaller than 44100 float arrays, i.e. 1 second delay, because i can't update the audio sound it is reading from more often that 44100 buffer lengths, because no frame happens while audioclip create is reading it's 44100 numbers from the array, which means that i have to make multiple small audiocreate files, except it does a kind of error.
     
    Last edited: Dec 4, 2014
  2. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    Hi!

    First, in AudioClip.Create, you are passing 4410 both as clip number of samples and frequency( equivalent to sample rate here ). I guess 4410 is a typo, and you mean 44100. Then, duration will always equal numberOfSamples/frequency, so if you need a half second clip, create it with 22050 samples at 44100 Hz.

    Second, for any kind of audio manipulation, don't use the PCMReaderCallback, but OnAudioFilterRead, which runs on the audio thread and is meant for that very purpose.

    Cheers,

    Gregzo
     
  3. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    And of course, if you are generating a sine, no need to create a clip at all: just generate it in the OnAudioFilterRead callback. Be aware that it runs on the audio thread, so most UnityEngine methods will be unavailable.

    Cheers,

    Gregzo
     
  4. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    Thanks Gregzo!!! that's Soooo great. I didn't know about OnAudioFilterRead what an amazing thing for unity to write into the unityengine, very nice! omg!!!