onda sinusoidal que aumenta lentamente la frecuencia de f1 a f2 durante un tiempo determinado

Estoy escribiendo un progtwig de CA para generar una onda sinusoidal que aumenta lentamente la frecuencia de f1 a f2 durante un intervalo de tiempo.

He escrito este progtwig c para boost la frecuencia de 0 a 10 Hz, pero el problema es que la frecuencia cambia después de completar 360 grados. Si trato de cambiar la frecuencia entre 0 y 360 grados, la transición no es suave y es abrupta.

Esta es la ecuación del pecado que he usado y = Amplitud * sin (fase freq *)

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. ¿Cómo cambio la frecuencia sin problemas durante un período de tiempo determinado?
  2. ¿Debería estar investigando las transformaciones de Fourier?

si quiere que la frecuencia angular (w = 2 pi f) varíe linealmente con el tiempo, entonces dw/dt = a y w = w0 + (wn-w0)*t/tn (donde t va de 0 a tn , w va de w0 a wn ). fase es la integral de eso, entonces phase = w0 t + (wn-w0)*t^2/(2tn) (como dice 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)); } } 

(donde el intervalo es tn y delta es t / tn).

aquí está la salida para el código python equivalente (1-10Hz durante 5 segundos):

1-10 Hz durante 5 segundos

 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 incidentalmente, si estás escuchando esto (o mirándolo, cualquier cosa que implique la percepción humana), sospecho que no quieres un aumento lineal, sino uno exponencial. pero esa es una pregunta diferente …

¿Cómo cambio la frecuencia sin problemas durante un período de tiempo determinado?

Una sinusoide suave requiere una fase continua. La fase es la integral de la frecuencia, por lo que si tiene una función lineal para la frecuencia (es decir, un aumento de la velocidad constante de f1 a f2), entonces la fase será una función cuadrática del tiempo.

Puedes calcular las matemáticas con lápiz y papel, o puedo decirte que la forma de onda resultante se llama chirrido lineal .

¿Debería estar investigando las transformaciones de Fourier?

La transformada de Fourier de un chirrido lineal es en sí misma un chirrido lineal, por lo que probablemente no.

Debería ser bastante simple. En lugar de pensar en variar la frecuencia, piense en hacer que un objeto gire más y más rápido. La distancia angular que ha recorrido podría ser X después de N segundos, pero será más de 2X (tal vez 4 veces) después de 2 segundos. Así que proponga una fórmula para la distancia angular (por ejemplo, alfa = k1 * T + k2 * T ** 2) y tome el seno de esa distancia angular para encontrar el valor de la forma de onda en cualquier momento 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); } }