이것은 내가 Nils의 아이디어에서 영감을 얻은 것입니다. 다른 사람에게 유용 할 경우에 대비하여 여기에 붙여 넣으십시오. 간단히 말해서 상자 크기는 마지막 샘플의 위상 변화를 분석적으로 커널 크기 (또는 컷오프)로 사용하여 톱니파를 필터링합니다. 그것은 아주 잘 작동하고, 가장 높은 음표에는 약간의 소리가 나는 앨리어싱이 있지만, 정상적으로 사용하면 소리가 훌륭합니다.
에일리어싱을 줄이려면 커널 크기를 약간 늘려서 2 * phaseChange로 설정하면됩니다. 예를 들어 가장 높은 주파수를 잃어 버리더라도 좋을 것입니다.
비슷한 주제에 대해 SP를 검색 할 때 발견 된 또 다른 좋은 DSP 리소스는 다음과 같습니다. The Synthesis ToolKit in C++ (STK). 유용한 DSP 툴을 많이 가지고있는 클래스 라이브러리입니다. 그것은 심지어 대역 제한 파형 발생기를 사용할 준비가되어 있습니다. 그들이 사용하는 방법은 내가 첫 번째 게시물에서 설명한 것처럼 sinc를 통합하는 것입니다.
float getSaw(float phaseChange)
{
static float phase = 0.0f;
phase = fmod(phase + phaseChange, 1.0f);
return getBoxFilteredSaw(phase, phaseChange);
}
float getPulse(float phaseChange, float pulseWidth)
{
static float phase = 0.0f;
phase = fmod(phase + phaseChange, 1.0f);
return getBoxFilteredSaw(phase, phaseChange) - getBoxFilteredSaw(fmod(phase + pulseWidth, 1.0f), phaseChange);
}
float getBoxFilteredSaw(float phase, float kernelSize)
{
float a, b;
// Check if kernel is longer that one cycle
if (kernelSize >= 1.0f) {
return 0.0f;
}
// Remap phase and kernelSize from [0.0, 1.0] to [-1.0, 1.0]
kernelSize *= 2.0f;
phase = phase * 2.0f - 1.0f;
if (phase + kernelSize > 1.0f)
{
// Kernel wraps around edge of [-1.0, 1.0]
a = phase;
b = phase + kernelSize - 2.0f;
}
else
{
// Kernel fits nicely in [-1.0, 1.0]
a = phase;
b = phase + kernelSize;
}
// Integrate and divide with kernelSize
return (b * b - a * a)/(2.0f * kernelSize);
}
1 년 전이 질문에 대한 답변을 얻었지만이 문제에 걸림돌이있는 사람은 친숙하고 유능한 [DSP 및 플러그인 개발] (http://www.kvraudio.com/ –