Pergunta

Eu estou escrevendo um sintetizador de software e necessidade de gerar bandlimited, formas de onda livre de alias em tempo real em 44,1 kHz samplerate. Dente de serra da forma de onda faria por agora, uma vez que se pode gerar uma onda de pulso através da mistura de duas sawtooths em conjunto, um invertido e fase deslocada.

Até agora eu tentei as seguintes abordagens:

  1. Precomputing um ciclo de amostras de forma de onda perfeitamente de banda limitada em diferentes freqüências bandlimit na inicialização, em seguida, reproduzir a dois mais próximos juntos mista. Funciona Eu acho que tudo bem, mas não se sente muito elegante. Um lote de amostras são necessários ou as "lacunas" entre eles será ouvido. Interpolação e mistura também é bastante intensivo da CPU.

  2. A integração de um trem de DC compensado pulsos sinc para obter uma onda dente de serra. Parece ótimo, exceto que a onda se afasta de zero se você não obter a compensação DC exatamente certo (o que eu encontrei para ser realmente complicado). O problema DC pode ser reduzida através da adição de um pouco de vazamento para o integrador, mas então você perde as baixas frequências.

Então, minha pergunta é: Qual é a maneira usual isso é feito? Qualquer solução sugerida deve ser eficiente em termos de CPU, uma vez que deve ser feito em tempo real, por muitas vozes ao mesmo tempo.

Foi útil?

Solução

Há uma série de maneiras de abordar a geração de forma de onda bandlimited. Você vai acabar negociação custo computacional contra a qualidade como de costume.

Eu sugiro que você dê uma olhada neste site aqui:

http://www.musicdsp.org/

Confira o arquivo! É cheio de bom material. Eu apenas fiz uma pesquisa sobre a palavra-chave "bandlimited". O material que aparece você deve manter-se ocupado por pelo menos uma semana.

Btw - não sei se é isso que você está procurando, mas eu apelido reduzida (por exemplo, não é realmente banda limitada) geração de forma de onda de um par de anos atrás. Eu apenas calculado o integral entre o passado e atual amostra posições. Para synth-ondas tradicionais você pode fazer isso bastante fácil se você dividir o seu intervalo de integração nas singularidades (por exemplo, quando o dente de serra get é o seu reset). A carga de CPU foi baixa ea qualidade aceitável para as minhas necessidades.

Eu tinha os mesmos deriva-problemas, mas a aplicação de um passa-alta com um nível muito baixo de corte de frequência sobre a integral se livrou desse efeito. Real analógico synth não descem região subhertz qualquer maneira, então você não vai perder muito.

Outras dicas

Uma maneira rápida de gerar formas de onda limitado de banda é usando passos limitados de banda (BLEPs). Você gera o próprio passo de banda limitada:

enter descrição da imagem aqui

e loja que em um wavetable, em seguida, substituir cada transição com um passo de banda limitada, para criar formas de onda que se parecem com isto:

enter descrição da imagem aqui

Veja o walk-through em Band-limitada Síntese Sonora .

Uma vez que este BLEP é não-causal (o que significa que se estende para o futuro), para gerar formas de onda em tempo real, é melhor usar o passo-fase mínima banda-limitada, chamada de MinBLEP , que tem o mesmo espectro de frequência, mas só se estende para o passado:

MinBLEPs levar ainda mais a idéia e tomar um sinc de janela, execute uma reconstrução mínimo de fases e, em seguida integrar o resultado e armazená-lo em um tabela. Agora, para fazer um oscilador você Basta inserir uma MinBLEP em cada descontinuidade na forma de onda. Assim, para uma onda quadrada que inserir um MinBLEP onde os inverte de forma de onda, por via onda inserir um MinBLEP onde o inverte valor, mas você gerar o rampa como normal.

Isto é o que eu vim com, inspirado pelas idéias Nils'. Colá-lo aqui no caso é útil para alguém. I simplesmente caixa de filtro de um dente de serra onda analiticamente usando a mudança de fase a partir da última amostra, tal como um tamanho de semente (ou corte). Ele funciona razoavelmente bem, há algum aliasing audível nos mais altos notas, mas para o uso normal soa grande.

Para reduzir aliasing ainda mais o tamanho do kernel pode ser aumentado um pouco, fazendo 2 * mudança de fase, por exemplo, sons boa também, embora você perde um pouco das mais altas frequências.

Além disso, aqui é um outro recurso bom DSP eu encontrei quando navega SP para temas semelhantes: A síntese ToolKit em C ++ (STK) . É uma biblioteca de classes que tem de monte de ferramentas DSP úteis. Ele ainda tem pronta a usar geradores de forma de onda de banda limitada. O método que eles usam é integrar sinc como eu descrevi no meu primeiro post (embora eu acho que eles fazem isso melhor do que eu ...).

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);
}

O DC offset de um blit - pode ser reduzido com um simples High Pass filtro! - muito parecido com um circuito analógico real, onde eles usam uma tampa de bloqueio DC

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top