- Home /
Why is the data I pass into OnAudioFilterRead() resulting in glitchy audio?
I am trying to read data from an AudioClip using GetData(), and play it using OnAudioFilterRead().
However, the audio that I am hearing has the wrong pitch/speed + distortion.
Here's my project (Google Drive), and below is the code in question:
using UnityEngine;
using System.Collections;
public class myPlay : MonoBehaviour
{
//I have an AudioSource that I can use to start/stop audio...
public AudioSource myAudioSource;
//I have an AudioClip that I want to play...
public AudioClip myAudioClip;
//myBuffer will containt the sample values that are to be played by OnAudioFilterRead()...
float[] myBuffer;
//_N is the offset for AudioClip.GetData()...
int _N;
//_Buffer determines if it is time to load new sample values into myBuffer...
bool _Buffer;
void Start()
{
//I want to start at the first sample...
_N = 0;
//Determine outputSampleRate based on sample frequency of AudioClip...
AudioSettings.outputSampleRate = myAudioClip.frequency;
//Initialize myBuffer...
myBuffer = new float[2048];
//Load sample values from myAudioClip into myBuffer...
myAudioClip.GetData(myBuffer, _N);
//Raise _N, to update offset...
_N += 2048;
//Set _Buffer to false so it'll go through OnAudioFilterRead() before loading in a new set of sample values...
_Buffer = false;
//Start audio...
myAudioSource.Play();
}
void Update()
{
//If it is time to load in new samples values...
if (_Buffer)
{
//Load sample values from myAudioClip into myBuffer...
myAudioClip.GetData(myBuffer, _N);
//Raise _N, to update offset...
_N += 2048;
//Set _Buffer to false, to make sure it'll go through OnAudioFilterRead before loading in a new set of samples values...
_Buffer = false;
}
}
void OnAudioFilterRead(float[] data, int channels)
{
//Move all sample values contained in myBuffer tot data...
for (int a = 0; a < 2048; a++)
{
data[a] = myBuffer[a];
}
//Set _Buffer to true, so a new set of sample values will be loaded into myBuffer...
_Buffer = true;
}
}
Why 2048? You should use data.Length ins$$anonymous$$d. Also be prepared for the number of channels to vary.
Thank you for your response!
If I Debug.Log(data.Length) it gives me 2048. I believe this is the standard buffer size for 44.100 files. Is there a way to get the buffer size before OnAudioFilterRead() is called, so I can correctly size myBuffer[] based on the file I'm trying to play?
Is the interleaving of the channels different in the AudioClip than it is in OnAudioFilterRead()? How should I prepare for a varying number of channels?
I changed: _N += data.Length, into: _N += 1024, and now it seems to work.
But, I don't get exactly how/why.
There are still some audible glitches now and then, but the pitch/playback speed is now correct, and the constant distortion is gone.
Here's my code:
using UnityEngine;
using System.Collections;
public class myPlay : $$anonymous$$onoBehaviour
{
public AudioSource myAudioSource;
public AudioClip myAudioClip;
float[] myBuffer;
int _N;
bool _Buffer;
void Start()
{
_N = 0;
AudioSettings.outputSampleRate = myAudioClip.frequency;
myBuffer = new float[2048];
myAudioClip.GetData(myBuffer, _N);
_Buffer = false;
myAudioSource.Play();
}
void Update()
{
if (_Buffer)
{
myAudioClip.GetData(myBuffer, _N);
_Buffer = false;
}
}
void OnAudioFilterRead(float[] data, int channels)
{
if (!_Buffer)
{
for (int a = 0; a < data.Length; a++)
{
data[a] = myBuffer[a];
}
_N += 1024;
_Buffer = true;
}
}
}
Answer by Sylafrs · Nov 06, 2015 at 10:52 AM
I guess it's a little too late, but the issue might come from the channels :)