I seem to face a problem where the use of custom filters affects the spatial dimension of a sound.
Via OnAudioFilterRead(), I try to implement some cheap-ass sample-and-hold algorithm to be able to emulate several “quality” levels of the sound file.
void OnAudioFilterRead(float[] data, int channels)
{
// Best quality: Split it into data.Length parts (don't modify)
// lowest quality: split it into 1 part
int bits = (int)Mathf.Max((int)(quality * data.Length * maxSegmentSize), 1);
int stepLength = data.Length / bits;
// Save peak for analysis
currentPeak = Mathf.Abs(data.Max());
if (enableDistortion && quality < 1.0f)
{
float currentLevel = 0.0f;
for (int i = 0; i < data.Length; ++i)
{
if (i % stepLength == 0)
{
currentLevel = data[i];
}
data[i] = currentLevel;
}
}
}
When the raw audio wave is not modified, everything’s fine. However, if the condition in line 11 is fulfilled and the wave is edited, the sound seems to ignore the previous spatial quality and occupies right and left channels equally. This is a very obvious change since the sound is rather to ones left before the filter is applied.
I am quite a noob in this area, and my question is: Shouldn’t the spatial quality stay the same regardless of the wave data that’s processed? Am I missing something here or is this some weird behavior?
I’d appreciate every kind of help or discussion. Thanks in advance!
I’m running into a similar problem. Attenuation as a function of distance seems to work, but panning stops working when using OnAudioFilterRead() to generate sound.
If the spatialization filtering has been applied before OnAudioFilterRead() by default (as suggested in one of these threads), it would be great if that could be optional. It seems that many people want to generate custom synths, etc, on game objects and have at least vanilla Unity spatialization work on those objects.
“I just discovered that panning works fine if I set the project to use the Oculus spatializer (now included with Unity) and tick the ‘spatialize’ box on the audio source. So until the bug is addressed, this might be a workable fallback solution.” - Unity 3D pan not working · Issue #112 · enzienaudio/heavy · GitHub
“That stuff has already happened when the sound reaches your audio filter. Therefore, make the AudioSource play a short looping audio clip where every sample point has a value of not 0, but 1. Make your audio filter multiply the original sample value with the one you’re generating, rather than overwriting it. That way, the Audio Source’s panning and volume will be applied, including the rolloff. The only information lost will be stereo separation, which can be reproduced in the filter itself, though it’ll take some more skills.” - OnAudioFilterRead sound spatialisation - Unity Engine - Unity Discussions
I am working through a similar problem, I’d like to use OnAudioFilterRead and the stereo pan on the AudioSource. I have done the first part of the solution posted here by @ShawnFeatherly : " make the AudioSource play a short looping audio clip where every sample point has a value of not 0, but 1" but I am confused on how to “Make your audio filter multiply the original sample value with the one you’re generating, rather than overwriting it”. I am very new and would appreciated any help you can give. Here is my current OAFR:
void OnAudioFilterRead(float [] data, int channels)
{
increment = frequency * 2.0 * Mathf.PI / samplingFrequency;
for (int i = 0; i < data.Length; i += channels) {
phase += increment;
if (myWave == Waveform.sine) {
data [i] = (float)(gain * Mathf.Sin ((float)phase));
} else if (myWave == Waveform.square) {
if (gain * Mathf.Sin ((float)phase) >= 0 * gain) {
data [i] = (float)gain * 0.6f;
} else {
data [i] = (-(float)gain) * 0.6f;
}
}
if (channels == 2) {
data [i + 1] = data [i];
}
if (phase > (Mathf.PI * 2)) {
phase = 0.0;
}
}