Страницы

Поиск по вопросам

вторник, 31 марта 2020 г.

Математические правила для генерирования звука плавно нарастающей частоты

#математика #аудио


Я пишу программу, которая генерирует WAV-файл, который содержит плавно меняющийся
звук от частоты seq1 до seq2, частотой дискретизации sampleRate = 44100 и длинной n
секунд. Необходимо найти формулу, по которой вычислять частоту текущего отрезка длинной
в одно полное колебание звука, а так же общее количество отрезков frame.  

Текущая частота - seq = k1 * x + seq1, где k1 - скорость роста частоты, x - порядковый
номер отрезка в одно полное колебание;  

Число семплов на отрезок - spt = sampleRate/seq = sampleRate/(k1*x+b);  

P.S. В принципе, можно упростить, отбросив начальную частоту, и считать по формуле
spt=(sampleRate/k1)/x  

Насколько я понимаю, количество отрезков и прирост частоты от отрезка к отрезку должно
выводиться из уравнения



Но я точно не уверен.  

Пожалуйста, помогите извлечь количество отрезков и скорость прироста частоты.

int main() {
    ofstream out("test.wav", ios::binary);

    int time = 30;
    waveHeaderInit(2, 44100, 16, time);
    waveData = new char[waveHeader.subchunk2Size];
    int sequence = 100;
    volatile float phase;
    volatile int16_t sample;

    int maxAmplitude = pow(2, waveHeader.bitsPerSample - 1) - 1;

    for (int i = 0; i < time * waveHeader.sampleRate; i++) {
        int spt = waveHeader.sampleRate / sequence;
        phase = (i % spt) / float(spt);
        sample = sin(PI*phase)*maxAmplitude;
        for (int channel = 0; channel < waveHeader.numChannels; channel++) {
            ((int16_t*)waveData)[i*waveHeader.numChannels + channel] = sample;
        }
    }

    out.write((char*)&waveHeader, sizeof(waveHeader));
    out.write(waveData, waveHeader.subchunk2Size);
    out.close();
    return 0;
}

    


Ответы

Ответ 1



Увеличивайте частоту медленно с экспоненциальной скоростью. Монотонный звук это A*sin(2Pi*B*t). Заменяем константу B на экспонету B:=C*Exp[D*t]. C*Exp[D*t0]==seq0 C*Exp[D*t1]==seq1 --- D=Ln[seq1/seq0]/(t1-t0) C=seq0*((seq0/seq1)^(t0/(t1-t0))) Получаем A*sin(2Pi*C*Exp[D*t]*t). Упрощаем t0=0, t1=T.Результат: A*sin(2Pi*seq0*((seq1/seq0)^(t/T))*t)

Комментариев нет:

Отправить комментарий