синусоида, которая медленно увеличивает частоту от f1 до f2 в течение заданного времени

Я пишу программу c для генерации синусоидальной волны, которая медленно нарастает частоту от f1 до f2 в течение заданного интервала времени.

Я написал эту программу на c для увеличения частоты от 0 до 10 Гц, но проблема в том, что частота изменяется после завершения 360 градусов. Если я попытаюсь изменить частоту от 0 до 360 градусов, переход будет не плавным, а резким.

Это уравнение sin, которое я использовал y = Amplitude * sin (freq * 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. Как плавно изменить частоту в течение заданного периода времени?
  2. я должен искать преобразования Фурье?

person katta    schedule 26.06.2012    source источник
comment
Чтобы сгенерировать реальную частоту синусоидальной волны желаемой Гц, используйте счетчики и таймеры. Используя формулу sin, генерируемая частота зависит от скорости выполнения программы.   -  person katta    schedule 06.11.2013


Ответы (4)


если вы хотите, чтобы угловая частота (w = 2 pi f) изменялась линейно со временем, тогда dw/dt = a и w = w0 + (wn-w0)*t/tn (где t изменяется от 0 до tn, w изменяется от w0 до wn). фаза является интегралом этого, поэтому phase = w0 t + (wn-w0)*t^2/(2tn) (как говорит Оли):

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

(где интервал равен tn, а дельта равен t / tn).

вот результат для эквивалентного кода Python (1-10 Гц за 5 секунд):

1–10 Гц за 5 секунд

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 кстати, если вы слушаете это (или смотрите на это - все, что связано с человеческим восприятием), я подозреваю, что вам нужно не линейное увеличение, а экспоненциальное. но это другой вопрос ...

person andrew cooke    schedule 26.06.2012
comment
фантастика!! Это сработало отлично. когда n_step очень велико, фаза - = 2 * PI почти равна нулю, поэтому sin (0) равна 0. phase - = 2 * PI вызывает начало синусоидальной волны с отрицательными значениями. Приведенный выше график верен, когда цикл while закомментирован. Не могли бы вы указать мне источник, где вы читали об этом. Я терял волосы на этом пару дней, и вы спасли меня. Большое вам спасибо. Я читал об экспоненциальном росте, но не мог понять, может попросить вас объяснить интуитивно. - person katta; 27.06.2012
comment
исправлена ​​проблема (float) в коде c, спасибо. не понимаю комментарий о фазе, но он там только в том случае, если вы хотите, чтобы он всегда находился в диапазоне 0–2PI. Я нигде этого не читал - я просто проработал это - но, насколько я могу судить, это то же самое, что и запись в Википедии (на которую я ссылался, и я проверил позже). - person andrew cooke; 27.06.2012
comment
кроме того, вместо повторного вычитания вы можете выполнить более прямой расчет. что-то вроде int n = phase / (2 * PI); phase -= n * 2 * PI. - person andrew cooke; 27.06.2012
comment
@andrew Cooke, вы правы, я не понял цикла while. альтернативный способ реализации цикла while: 'phase = fmod (phase, (2 * PI));' - person katta; 28.06.2012
comment
да (не был уверен, существует ли fmod tbh). - person andrew cooke; 28.06.2012
comment
@andrewcooke - ... экспоненциальный. но это другой вопрос, какой вопрос был поднят. - person Robᵩ; 04.11.2013

Как плавно изменить частоту в течение заданного периода времени?

Для гладкой синусоиды требуется непрерывная фаза. Фаза является интегралом частоты, поэтому, если у вас есть линейная функция для частоты (то есть увеличение с постоянной скоростью от f1 до f2), тогда фаза будет квадратичной функцией времени.

Вы можете разобраться в математике с помощью ручки и бумаги, или я могу сказать вам, что результирующая форма волны называется линейное чириканье.

Стоит ли мне искать преобразования Фурье?

Преобразование Фурье линейного чирпа само по себе является линейным чирпом, поэтому, вероятно, нет.

person Oliver Charlesworth    schedule 26.06.2012

Это должно быть довольно просто. Вместо того, чтобы думать о варьировании частоты, подумайте о том, чтобы заставить объект вращаться все быстрее и быстрее. Угловое расстояние, которое он прошел, может быть X через N секунд, но будет больше, чем 2X (возможно, 4X) через 2N секунд. Поэтому придумайте формулу для углового расстояния (например, альфа = k1 * T + k2 * T ** 2) и возьмите синус этого углового расстояния, чтобы найти значение сигнала в любой момент T.

person Hot Licks    schedule 26.06.2012

person    schedule
comment
Не совсем. Хотя это гладко и будет хорошо смотреться на графическом калькуляторе, быстрой демонстрации достаточно, чтобы проиллюстрировать ошибку. Использование этого кода для генерации звука, окруженного звуками начальной и конечной частоты, показывает, что он не заканчивается в нужном месте. Синус (startFreq, 1 секунда), развертка (startFreq, endFreq, 1 секунда), Sine (endFreq, 1 секунда), затем, если хотите, проведите некоторый спектральный анализ. Мой спектральный анализ (Cool Edit Pro 2) показывает, что он достигает 650 герц или около того. - person lmat - Reinstate Monica; 05.04.2014
comment
Что вы вводили, когда спектральный анализ показал 650 герц? Моя функция может быть неточной, но я уверен, что ее результат зависит от ее ввода. Кстати, этот метод пришел из моего программного синтезатора, и он хорошо звучит и хорошо выглядит. - person MusiGenesis; 05.04.2014
comment
@MusicGenesis Извините, я забыл указать вам параметры! Я сделал синусоидальную развертку от 220 до 440 Гц. Как я уже сказал, развертка заканчивается около 650 Гц до того, как воспроизводится синусоидальный сигнал 440 Гц. - person lmat - Reinstate Monica; 08.04.2014