生成扫描正弦波

如何制定产生扫频正弦波的方程式。 我是信号处理新手,无法在网上发现扫描正弦波的主题。 请指出一些我可以用来生成方程并在代码中使用的来源。 谢谢。

最简单的方法是使用相位累加器 – 这是一种简单的方法,它可以确保频率变化时的相位连续性。

要生成固定频率的正弦波,您可以这样做(伪代码):

 // // A = sine wave amplitude // fs = sample rate (Hz) // f = sine wave frequency (Hz) // phi = 0; // phase accumulator delta = 2 * pi * f / Fs; // phase increment per sample for each sample output = A * sin(phi); // output sample value for current sample phi += delta; // increment phase accumulator 

对于扫频正弦波,您可以线性地提高频率,即线性上升delta

 // // A = sine wave amplitude // fs = sample rate (Hz) // f0 = initial frequency (Hz) // f1 = final frequency (Hz) // T_sweep = duration of sweep (s) // phi = 0; // phase accumulator f = f0; // initial frequency delta = 2 * pi * f / Fs; // phase increment per sample f_delta = (f1 - f0) / (Fs * T_sweep); // instantaneous frequency increment per sample for each sample output = A * sin(phi); // output sample value for current sample phi += delta; // increment phase accumulator f += f_delta; // increment instantaneous frequency delta = 2 * pi * f / Fs; // re-calculate phase increment 

gcc FILE.c -lm -o FILE编译

该程序生成单声道16位“扫频”正弦波。 作为奖励,它也展示了幅度。

 // http://www.purplemath.com/modules/grphtrig.htm #include  #include  #include  #include  #include  #include  const double radians = (M_PI * 2); typedef struct SineWave { double rate, // sample rate frequency, // oscillation Hz. amplitude, // amplitude phase, // current phase phaseStep; // phase step struct transition { double amplitude, amplitudeStep, frequency, frequencyStep; } transition; } SineWave; SineWave * sine_wave(double frequency, double amplitude, double rate) { SineWave * sw = calloc(1, sizeof(SineWave)); sw->frequency = frequency, sw->amplitude = amplitude, sw->rate = rate; return sw; } // "Fuck it" close enough comparison.. // http://stackoverflow.com/a/18975072 int double_equals(double a, double b) { return abs(a - b) < 0.001; } double sine_wave_sample(SineWave * sw) { double sample = sw->amplitude * sin(sw->phase); sw->phase += sw->phaseStep; if (sw->transition.frequencyStep) { sw->frequency += sw->transition.frequencyStep; sw->phaseStep = radians * sw->frequency / sw->rate; if (double_equals(sw->frequency, sw->transition.frequency)){ sw->transition.frequencyStep = 0; sw->frequency = sw->transition.frequency; } } if (sw->transition.amplitudeStep) { sw->amplitude += sw->transition.amplitudeStep; if (double_equals(sw->amplitude, sw->transition.amplitude)) { sw->transition.amplitudeStep = 0; sw->amplitude = sw->transition.amplitude; } } return sample; } void sine_wave_frequency_transition(SineWave * sw, double frequency, double duration) { sw->transition.frequency = frequency; sw->transition.frequencyStep = (frequency - sw->frequency) / (sw->rate * duration); } void sine_wave_amplitude_transition(SineWave * sw, double amplitude, double duration) { sw->transition.amplitude = amplitude; sw->transition.amplitudeStep = (amplitude - sw->amplitude) / (sw->rate * duration); } // test int main(int argc, char ** argv) { SineWave * mono = sine_wave(0, 0, 44100); // start with "nothing" // transition to 500 Hz by .5 seconds. sine_wave_frequency_transition(mono, 500, .5); // transition to 50% amplitude by 1 second sine_wave_amplitude_transition(mono, SHRT_MAX * .5, 1); // 1 second of samples total long long samples = mono->rate * 1; short sample; while (samples--) { sample = sine_wave_sample(mono); fwrite(&sample, sizeof(sample), 1, stdout); } return 0; }