How exactly does AudioClip.Create() work?

I’m using AudioClip.Create() to create procedural tones. Using the example provided it is functional and I’ve been able to implement my own tones, but I want to take it further and I’m not understanding what the callback functions are doing or why I should be using this function at all!

My first question is in regards to the ‘frequency’ argument within Create(). Why does it accept a frequency if you make the frequency yourself inside the OnAudioRead() callback function? What baffles me further is that even though I’m overriding the frequency (or so I thought) within the OnAudioRead() using a standard sine wave input for the audio data, the frequency argument seems to affect the pitch.

OnAudioRead() appears to be called 12 times when using AudioClip.Create() with the following parameters: (“Sine Tone”, 44100, 1, 44100, false, false, OnAudioRead, OnAudioSetPosition)
Is there any reason that it needs to be called 12 times? I think there’s something I don’t understand about the callbacks in general. The ‘position’ integer also makes little sense to me. What is this meant to be doing!?

Here’s the code for reference:

using UnityEngine;
using System.Collections;

public class ToneGenerator : MonoBehaviour {
	
	private AudioClip[] tones;
	private AudioSource audioSource;
	private int position = 0;
	private int sampleRate = 0;
	private float frequency = 0;

        void Start ()
	{		
		//Audio properties
		audioSource = gameObject.AddComponent<AudioSource>();
		audio.volume = 0;
		audio.loop = true;
		
		GenerateTones();
	}

    void GenerateTones () 
	{
		tones = new AudioClip[4];
		
		//Generate the tones
		sampleRate = 44100;
		
		frequency = 440f;
		tones[0] = AudioClip.Create("Saw Tone", 44100, 1, 44100, false, false, OnAudioRead, OnAudioSetPosition);
		frequency = 300f;
		tones[1] = AudioClip.Create("Saw Tone", 44100, 2, 44100, false, false, OnAudioRead, OnAudioSetPosition);
		frequency = 200f;
		tones[2] = AudioClip.Create("Saw Tone", 44100, 2, 44100, false, false, OnAudioRead, OnAudioSetPosition);
		frequency = 500f;
		tones[3] = AudioClip.Create("Saw Tone", 44100, 2, 44100, false, false, OnAudioRead, OnAudioSetPosition);
	}
	
    void OnAudioRead(float[] data) 
	{
        for(int i = 0; i < data.Length; i++)
		{
			switch (wave)
			{
			case waveType.Sine:
            	data _= Mathf.Sin(2 * Mathf.PI * frequency * position / sampleRate);_
  •  		break;*
    
  •  	case waveType.Sawtooth:*
    

data = (Mathf.PingPong(frequency * position / sampleRate, 0.5f));
* break;*
* case waveType.Square:*
data = Mathf.Sign(Mathf.Sin(2 * Mathf.PI * frequency * position / sampleRate)) * 0.5f;
* break;*
* case waveType.Noise:*
data = Mathf.PerlinNoise(frequency * position / sampleRate, 0);
* break;*
* }*
position++;
}
}

void OnAudioSetPosition(int newPosition)
* {*
position = newPosition;
}
}
Thanks for any advice or resources!

Sorry i didnt see this earlier. If you change the sample rate, it is like changing the pitch, because, the audio playback rate of audio files is normally set to 44k or 22k or whatever, so if you cram more sine dots into the same space, it will be higher.

Question1 why does it make a frequency…

the freq in audioclip.create is the number of dots per second recorded onto the audio file, in other words, it tells the audio files that it’s supposed to have 44k dots/samples per second. it’s standard audio technology.

The freq of the sine wave, is the number of wobbles per second multiploed onto the sine wave, i.e. the freq of the sine wave encoded into the 44k dots, each dot is a value of sin on a graph at 44k

i dunno why it is called 12 times, i found if i make the sample longer in seconds, it’s called more times, i get this printout from the example file: 9 reads from create function, 9 reads from play() function, and 8 reads from some other print whose line isnt declared.

perhaps its processing audio blocks.

actually i just ran the reference code with sample length 200 i.e. 20ms, and it printed 300 times.

well noticed! very bizarre.

i figure it’s something to do with audio memory blocks

i just tried a 10 second file, it did 9, 18, and 45 prints on seperate lines, but he 45 printed slowly over the course of playback.

dunny why the create stuff runs in playback! weird.

i want to use the stream option anyways.

Just use the first documented AudioClip.Create function, then the AudioClip.SetData one to populate the clip.

Here’s what I used to create an empty clip (the method I mean):

public static AudioClip AudioClipCreateEmpty(string ClipName, int Length) { 
	AudioClip AudioClipToReturn = AudioClip.Create (ClipName, Length, 1, 44100*2,false);
	return AudioClipToReturn;
}