Tworzę skrypt C# dla filtrów audio w silniku Unity.
Mój problem polega na tym, że po przejściu przez mój filtr wynikowy dźwięk ma spójne i częste „kliknięcia”, „wyskakiwania” lub „przeskakiwania”. Brzmi trochę jak stare radio.
Nie wiem, co to powoduje.
Oto mój kod:
public float cutoff;
public float resonance;
int sampleRate;
void Start()
{
cutoff = 200;
resonance = 1;
sampleRate = AudioSettings.outputSampleRate;
}
void OnAudioFilterRead(float[] data, int channels)
{
float c = 2 * Mathf.PI * cutoff/sampleRate;
float r = 1 / resonance;
float v0 = 0;
float v1 = 0;
for (int i = 0; i < data.Length; i++)
{
v0 = (1 - r * c) * v0 - (c) * v1 + (c) * data[i];
v1 = (1 - r * c) * v1 + (c) * v0;
data[i] = v1;
}
}
Oto dokumentacja OnAudioFilterRead().
Tutaj mam oryginalny kod dolnoprzepustowy.
Gdy odcięcie zbliża się do maksymalnej wartości (127), kliknięcia i trzaski stają się cichsze.
Jestem raczej nowy w programowaniu audio, co może być oczywiste, więc nie jestem pewien, co by to powodowało.
Czy ktoś bardziej kompetentny niż ja mógłby wyjaśnić, co robię źle?
Dzięki!
2 odpowiedzi
Rozwiązałem to. Moje zmienne c i r musiały trwać przez wywołania OnAudioFilterRead(). Uczynienie ich członkami naprawiło to. Oto mój kompletny, działający kod:
using UnityEngine;
using System.Collections;
using System;
public class LowPassFilter : MonoBehaviour {
public float cutoff;
public float resonance;
const float CUTOFF_MAX = 128.0f;
const float CUTOFF_MIN = 0.0f;
const float RESONANCE_MAX = 128.0f;
const float RESONANCE_MIN = 0.0f;
float c;
float r;
float v0;
float v1;
int sampleRate;
void Start()
{
cutoff = 20.0f;
resonance = 0.0f;
c = 0.0f;
r = 0.0f;
v0 = 0.0f;
v1 = 0.0f;
sampleRate = AudioSettings.outputSampleRate;
}
void OnAudioFilterRead(float[] data, int channels)
{
cutoff = Mathf.Clamp(cutoff, CUTOFF_MIN, CUTOFF_MAX);
resonance = Mathf.Clamp(resonance, RESONANCE_MIN, RESONANCE_MAX);
c = Mathf.Pow(0.5f, (128.0f - cutoff) / 16.0f);
r = Mathf.Pow(0.5f, (resonance + 24.0f) / 16.0f);
for (int i = 0; i < data.Length; i++)
{
v0 = ((1.0f - r * c) * v0) - (c * v1) + (c * data[i]);
v1 = ((1.0f - r * c) * v1) + (c * v0);
data[i] = Mathf.Clamp(v1, -1.0f, 1.0f);
}
}
}
Najczęstsze przyczyny kliknięć i trzasków (w kolejności „powszechności”) to:
- zła długość bufora (nałożyłeś się na bufor lub nie wypełniłeś go do granicy)
- Twoja próbka obcina się i nie obsługujesz tego tak, jak powinieneś - na przykład obliczasz wszystko w
short
s i nie przejmujesz się zawijaniem wartości - Twój algorytm DSP zachowuje się źle
- Twój algorytm jest z jakiegoś powodu zbyt wolny, a próbka dźwięku nie jest dostarczana na czas, co powoduje przerwy w dźwięku
Jedną z dobrych technik debugowania jest próba zawężenia przyczyny problemu, na przykład wstawienie zrzutu PCM bezpośrednio do procedury przetwarzającej dźwięk. W ten sposób będziesz wiedział, czy wynik twojej procedury jest OK, czy nie, i będziesz w stanie odpowiednio skoncentrować wysiłki związane z debugowaniem.
Podobne pytania
Powiązane pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.