Loading Clips from Disk

An alterantive to generating audio on the fly.

Presaved Data

As well as using delegates (functions) for handling the audio processing, we have the option of passing a float array when creating a audio clip. This might be better if you want to do more complicated processing on the track (but means you can’t edit it in real time).

Let’s revisit the AudioClip’s Create Method again:

  • They are declared public, so can be accessed outside the class

  • They are declared static, so we don’t need an instance of the class to use them

  • There are a lot of different method signatures (the function is 'overloaded')

We were using the version which takes two callbacks (Reader and Position) we could also use the version that doens’t need them:

// properties from before...
int sampleRate = 44100;
int lengthInSeconds = 2;

// Start Method:
void Start() {
	int lengthInSamples = lengthInSeconds * sampleRate;

	clip = AudioClip.Create("MyAudioClip", lengthInSamples, 1, sampleRate, false);
	PopulateClip(clip); // definition below

	source = GetComponent<AudioSource>();
	source.clip = clip;
}
Tip
remember what unity calls frequency is actually the Sample Rate.

Poupulating the Clip

If we are not providing callbacks where does the audio come from? Well, we have to provide it before the sample is played.

void PopulateClip(AudioClip clip) {
	float[] samples = new float[ clip.samples * clip.channels ];

	// if there is already data present, this will read it into our float array...
	clip.GetData(samples, 0);

	// TODO modify the samples

	// now we update the clip with the new audio
	clip.SetData(samples, 0);
}

Let’s use our existing SineWave code to populate the samples:

void PopulateClip(AudioClip clip) {
	float[] samples = new float[ clip.samples * clip.channels ];

	// if there is already data present, this will read it into our float array...
	clip.GetData(samples, 0);

	// assuming you have position still...
	position = 0; // remember, this isn't being updated via callback anymore...
	SineWave(samples); // should populate the whole clip...

	// now we update the clip with the new audio
	clip.SetData(samples, 0);
}
Tip
we are loading a lot of data at the start of the program, it might be a little slow to start the scene.

Loading Audio into the AudioClip

What if you wanted to use an existing audio clip (eg, one you created in an Audio Editor like Audacity?)

In Unity, you would need to place the audio clip in the 'Assets' folder (where your scripts and scene live).

Tip
it’s best to create folders to store your assets, use the Right click Menu in the Project Pane and select: Create  Folder

The AudioClip located in the Audio folder

In your script, create a new variable of the AudioClip type:

public AudioClip birdSong;

The property should then appear in the inspector pane inside unity:

The component showing the AudioClip Bird Song currently unpopulated

Drag the audioClip from the Project pane over the top of the Audio Clip in the inspector. The name of the clip should then be displayed:

The component showing the AudioClip Bird Song

Modifying the existing clip

We can then access, play and modify the clip in the same way as we have previouslly:

void Start() {
	ModifyBird(birdSong);
	source = GetComponent<AudioSource>();
}

void playAudio() {
	source.clip = birdSong;
	source.Play();
}

public void ModifyBird(AudioClip clip) {
	float[] samples = new float[ clip.samples * clip.channels ];

	// if there is already data present, this will read it into our float array...
	clip.GetData(samples, 0);

	// modify the clip however you like...
	for ( int i=0; i < samples.Length; i++ ) {
		samples[i] = samples[i] * 0.2f; // this example will reduce the volume
	}

	// now we update the clip with the new audio
	clip.SetData(samples, 0);
}