문제

소프트웨어 신디사이저를 작성하고 있으며 44.1 kHz 샘플 리테이션에서 실시간으로 밴드로드 된 별명 자유 파형을 생성해야합니다. 톱니 파형은 두 개의 톱니를 함께 혼합하여 펄스 웨이브를 생성 할 수 있기 때문에 지금은 반전 및 위상이 이동했습니다.

지금까지 나는 다음과 같은 접근법을 시도했습니다.

  1. 시작시 다른 대역계 주파수에서 한 사이클을 완전히 계산 한 다음 가장 가까운 두 가지를 다시 혼합 한 후 다시 연주합니다. 괜찮다고 생각하지만 그다지 우아하지는 않습니다. 많은 샘플이 필요하거나 그 사이의 "갭"이 들릴 것입니다. 보간 및 믹싱도 CPU 집약적입니다.

  2. DC 보상 된 Sinc 펄스의 기차를 통합하여 톱니 파를 얻습니다. DC 보상을 정확히 올바르게 얻지 못하면 파도가 0에서 벗어나는 것을 제외하고는 훌륭하게 들립니다 (정말 까다로운 것으로 나타났습니다). Integrator에 약간의 누출을 추가하여 DC 문제를 줄일 수 있지만 낮은 주파수를 잃게됩니다.

그래서 내 질문은 : 이것이 평범한 방법은 무엇입니까? 제안 된 솔루션은 CPU 측면에서 효율적이어야합니다. 한 번에 많은 목소리에 대해 실시간으로 수행해야하기 때문입니다.

도움이 되었습니까?

해결책

대역으로 된 파형 생성에 접근하는 방법에는 여러 가지가 있습니다. 평소와 같이 품질에 대해 계산 비용을 거래 할 것입니다.

이 사이트를 여기에서 살펴 보는 것이 좋습니다.

http://www.musicdsp.org/

아카이브를 확인하십시오! 좋은 재료로 가득합니다. 방금 키워드 "Bandlimited"를 검색했습니다. 팝업되는 자료는 적어도 일주일 동안 바쁘게 지냅니다.

BTW- 그것이 당신이 찾고있는 것인지 모르겠지만, 몇 년 전에 별명이 줄어 들었습니다 (예 : 실제로 대역 제한되지 않음). 방금 마지막 샘플 위치와 현재 샘플 위치 사이의 적분을 계산했습니다. 전통적인 신디-파형의 경우, 단수화 (예 : 톱니가 리셋 될 때)에서 통합 간격을 분할하면 쉽게 수행 할 수 있습니다. CPU 부하는 낮았으며 품질은 내 요구에 맞게 수용 가능했습니다.

나는 같은 드리프트 프로젝트를 가지고 있었지만 적분에 매우 낮은 컷오프 주파수로 고역 통과를 적용하면 그 효과를 제거했습니다. 실제 아날로그 신생은 어쨌든 SubHertz 지역으로 내려 가지 않으므로 많이 놓치지 않을 것입니다.

다른 팁

대역 제한 파형을 생성하는 빠른 방법은 대역 제한 단계 (BLEP)를 사용하는 것입니다. 대역 제한 단계 자체를 생성합니다.

enter image description here

그리고 그것을 웨이브 가능에 보관 한 다음 각 전환을 대역 제한 단계로 바꾸어 다음과 같은 모습을 만듭니다.

enter image description here

연습을 참조하십시오 밴드 제한 사운드 합성.

이 BLEP는 비정규 (미래로 확장됨)이므로 실시간 파형을 생성하기 위해 A라고하는 최소상 대역 제한 단계를 사용하는 것이 좋습니다. Minblep, 주파수 스펙트럼이 동일하지만 과거로 만 확장됩니다.

Minbleps는 아이디어를 더욱 가져 와서 창으로 된 SINC를 취하고 최소 위상 재구성을 수행 한 다음 결과를 통합하여 테이블에 저장합니다. 이제 발진기를 만들려면 파형의 각 불연속에 minblep를 삽입합니다. 따라서 정사각형 파의 경우 파형이 뒤집히는 Minblep를 삽입하면 톱 파의 경우 값이 뒤집히는 최소 블리프를 삽입하지만 램프를 정상적으로 생성합니다.

이것은 내가 Nils의 아이디어에서 영감을 얻은 제가 생각해 낸 것입니다. 다른 사람에게 유용 할 경우 여기에 붙여 넣습니다. 마지막 샘플의 위상 변경을 커널 크기 (또는 컷오프)로 사용하여 분석적으로 톱니 파를 필터링합니다. 그것은 상당히 잘 작동하며, 가장 높은 음표에는 가청 별명이 있지만 정상적인 사용은 훌륭하게 들립니다.

별명을 줄이기 위해 커널 크기를 더 많이 증가시킬 수 있으므로 비트*PhaSechange는 예를 들어 가장 높은 주파수를 잃어 버리지 만 2*PhaSechange도 좋습니다.

또한 여기에 유사한 주제에 대해 SP를 탐색 할 때 찾은 또 다른 좋은 DSP 리소스가 있습니다. C ++ (STK)의 합성 툴킷. 유용한 DSP 도구가 많이있는 클래스 라이브러리입니다. 심지어 Bandlimited 파형 발전기를 사용할 준비가되었습니다. 그들이 사용하는 방법은 첫 번째 게시물에서 설명한 것처럼 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);
}

블릿에서 DC 오프셋 - 간단한 하이 패스 필터로 줄일 수 있습니다! - DC 차단 캡을 사용하는 실제 아날로그 회로와 매우 유사합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top