onde sinusoïdale qui augmente lentement la fréquence de f1 à f2 pendant un temps donné

J’écris un programme ca pour générer une onde sinusoïdale qui augmente lentement la fréquence de f1 à f2 pendant un intervalle de temps donné.

J’ai écrit ce programme c pour augmenter la fréquence de 0 à 10 Hz, mais le problème est que la fréquence change après avoir terminé 360 degrés. Si j’essaie de changer la fréquence entre 0 et 360 degrés, la transition n’est pas lisse et elle est abrupte.

C’est l’équation du péché que j’ai utilisé y = Amplitude * sin (fréq * phase)

int main(int argc, char *argv[]) { double y, freq,phase; int count; // for convenience of plotting in matlab so all the waves are spread on x axis. for (freq = 0; freq < 10; freq+=1) { for (phase = 0; phase < 360; phase++) { // phase is 360 degrees y = 3 * sin((count*6.283185)+(freq*(phase*(3.14159/180)))); printf("%f %f %f \n", freq, phase, y); } count++; } return EXIT_SUCCESS; } 
  1. Comment changer de fréquence en douceur pendant une période donnée?
  2. devrais-je me pencher sur les transformations de Fourier?

    si vous voulez que la fréquence angular (w = 2 pi f) varie linéairement avec le temps, alors dw/dt = a et w = w0 + (wn-w0)*t/tn (où t va de 0 à tn , w va de w0 à wn ). phase est l’intégrale de celui-ci, donc phase = w0 t + (wn-w0)*t^2/(2tn) (comme le dit oli):

     void sweep(double f_start, double f_end, double interval, int n_steps) { for (int i = 0; i < n_steps; ++i) { double delta = i / (float)n_steps; double t = interval * delta; double phase = 2 * PI * t * (f_start + (f_end - f_start) * delta / 2); while (phase > 2 * PI) phase -= 2 * PI; // optional printf("%f %f %f", t, phase * 180 / PI, 3 * sin(phase)); } } 

    (où intervalle est tn et delta est t / tn).

    voici la sortie pour le code python équivalent (1-10Hz sur 5 secondes):

    1-10 Hz sur 5 secondes

     from math import pi, sin def sweep(f_start, f_end, interval, n_steps): for i in range(n_steps): delta = i / float(n_steps) t = interval * delta phase = 2 * pi * t * (f_start + (f_end - f_start) * delta / 2) print t, phase * 180 / pi, 3 * sin(phase) sweep(1, 10, 5, 1000) 

    ps accessoirement, si vous écoutez ceci (ou que vous le regardez – tout ce qui implique la perception humaine), je soupçonne que vous ne voulez pas une augmentation linéaire, mais une augmentation exponentielle. mais c’est une question différente …

    Comment changer de fréquence en douceur pendant une période donnée?

    Une sinusoïde lisse nécessite une phase continue. La phase est l’intégrale de la fréquence. Par conséquent, si vous avez une fonction linéaire pour la fréquence (c’est-à-dire une augmentation constante du débit de f1 à f2), alors la phase sera une fonction quadratique du temps.

    Vous pouvez comprendre le calcul avec un stylo et du papier, ou je peux vous dire que la forme d’onde résultante s’appelle un chirp linéaire .

    Devrais-je me pencher sur les transformations de Fourier?

    La transformée de Fourier d’un chirp linéaire est elle-même un chirp linéaire, donc probablement pas.

    Cela devrait être assez simple. Plutôt que de penser à faire varier la fréquence, pensez à faire tourner un object de plus en plus vite. La distance angular parcourue peut être X après N secondes, mais sera supérieure à 2X (peut-être 4X) après 2N secondes. Créez donc une formule pour la distance angular (par exemple, alpha = k1 * T + k2 * T ** 2) et prenez le sinus de cette distance angular pour trouver la valeur de la forme d’onde à tout moment T.

     + (void) appendChirp:(int[])sampleData size:(int)len withStartFrequency:(double)startFreq withEndFrequency:(double)endFreq withGain:(double)gain { double sampleRate = 44100.0; for (int i = 0; i < len; i++) { double progress = (double)i / (double)len; double frequency = startFreq + (progress * (endFreq - startFreq)); double waveLength = 1.0 / frequency; double timePos = (double)i / sampleRate; double pos = timePos / waveLength; double val = sin(pos * 2.0 * M_PI); // -1 to +1 sampleData[i] += (int)(val * 32767.0 * gain); } }