当振幅是1.0 ,频率是1.0(频率指一秒钟震几次)。正弦波公式及其图像为
y
=
sin
(
2
π
x
)
y = \sin \lparen 2 \pi x \rparen
y=sin(2πx)
// webrtc/modules/audio_mixer/sine_wave_generator.h
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_MIXER_SINE_WAVE_GENERATOR_H_
#define MODULES_AUDIO_MIXER_SINE_WAVE_GENERATOR_H_
#include
#include "api/audio/audio_frame.h"
#include "rtc_base/checks.h"
namespace webrtc {
class SineWaveGenerator {
public:
SineWaveGenerator(float wave_frequency_hz, int16_t amplitude)
: wave_frequency_hz_(wave_frequency_hz), amplitude_(amplitude) {
RTC_DCHECK_GT(wave_frequency_hz, 0);
}
// Produces appropriate output based on frame->num_channels_,
// frame->sample_rate_hz_.
// 通过这个函数生成正弦波
void GenerateNextFrame(AudioFrame* frame);
private:
float phase_ = 0.f;
// 正弦波频率
const float wave_frequency_hz_;
// 振幅
const int16_t amplitude_;
};
} // namespace webrtc
#endif // MODULES_AUDIO_MIXER_SINE_WAVE_GENERATOR_H_
// webrtc/modules/audio_mixer/sine_wave_generator.cc
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_mixer/sine_wave_generator.h"
#include
#include
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
constexpr float kPi = 3.14159265f;
} // namespace
void SineWaveGenerator::GenerateNextFrame(AudioFrame* frame) {
RTC_DCHECK(frame);
// 获取用来保存数据的指针地址(一段Buffer)
int16_t* frame_data = frame->mutable_data();
// samples_per_channel_ 表示每个声道采样多少个样本
for (size_t i = 0; i < frame->samples_per_channel_; ++i) {
// 计算每个声道(Channel)的样本值
for (size_t ch = 0; ch < frame->num_channels_; ++ch) {
// 比如双声道(两个Channel),i = 0时就是frame_data[0] 和frame_data[1]
// frame_data[ 2 * 0 + 0 ] --> Frame_data[0]
// frame_data[ 2 * 0 + 1 ] --> Frame_data[1]
// amplitude_ 指振幅,sinf(phase_) 是对 phase_ 其sin函数值
frame_data[frame->num_channels_ * i + ch] =
rtc::saturated_cast<int16_t>(amplitude_ * sinf(phase_));
}
// 这段是重点。 phase_ 就是正弦函数中的 变量值。
// wave_frequency_hz_ 表示采样频率
// Kpi 为π
// 2∗ Kpi * wave_frequency_hz_ 是一个完整点的采样周期。
// frame->sample_rate_hz_ 这个参数表示采样率
// 采样率理解为在一个采样周期内,采多少个点。
// 所以每个点的步长,例如 [ 0 0.1 0.2 ... 1.0 ], 0.1就是步长。
// 采样的步长应为 采样周期 / 采样率。
phase_ += wave_frequency_hz_ * 2 * kPi / frame->sample_rate_hz_;
}
}
} // namespace webrtc
// The audio level ranges linearly [0,32767].
// audio_level 振幅
// duration_ms 时间
// sample_rate_hz 采样频率
// num_channels 通道数
std::unique_ptr<AudioFrame> CreateAudioFrame1kHzSineWave(int16_t audio_level,
int duration_ms,
int sample_rate_hz,
size_t num_channels) {
// 根据采样频率,计算样本数
size_t samples_per_channel = sample_rate_hz / (1000 / duration_ms);
// 创建对象,保存样本数据
std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
// 给audioFrame设置相关参数
std::unique_ptr<AudioFrame> audio_frame = std::make_unique<AudioFrame>();
audio_frame->UpdateFrame(0 /* RTP timestamp */, &audio_data[0],
samples_per_channel, sample_rate_hz,
AudioFrame::SpeechType::kNormalSpeech,
AudioFrame::VADActivity::kVadUnknown, num_channels);
// 生成频率是1000(1kHZ)的正弦波
SineWaveGenerator wave_generator(1000.0, audio_level);
wave_generator.GenerateNextFrame(audio_frame.get());
return audio_frame;
}