加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
sound.cpp 3.44 KB
一键复制 编辑 原始数据 按行查看 历史
NKEO2333 提交于 2024-08-22 23:20 . 添加心率界面
#include "sound.h"
sound::sound()
{
}
#define BUFFER_SIZE 1024
unsigned int buffer_time = 1000000; // 设置缓冲区时间为 1000 ms
unsigned int period_time = 100000; // 设置周期时间为 100 ms
// 计算 RMS (均方根)
double sound:: calculate_rms(const int16_t *buffer, size_t len)
{
double sum = 0.0;
for (size_t i = 0; i < len; ++i)
{
sum += buffer[i] * buffer[i];
}
return sqrt(sum / len);
}
// 计算 dB (分贝)
double sound::calculate_db(double rms, double reference)
{
reference = 32768.0;
return 20.0 * log10(rms / reference);
}
void sound::main_sound()
{
snd_pcm_t *capture_handle;
snd_pcm_hw_params_t *hw_params;
int16_t buffer[BUFFER_SIZE];
unsigned int rate = 44100; // 采样率 44100 Hz
int err;
// 打开默认音频设备进行捕获
if ((err = snd_pcm_open(&capture_handle, "hw:0,1", SND_PCM_STREAM_CAPTURE, 0)) < 0)
{
std::cerr << "Cannot open audio device (" << snd_strerror(err) << ")" << std::endl;
return ;
}
// 设置音频设备硬件参数
snd_pcm_hw_params_alloca(&hw_params);
snd_pcm_hw_params_any(capture_handle, hw_params);
snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate, 0);
snd_pcm_hw_params_set_channels(capture_handle, hw_params, 1); // 单声道
snd_pcm_hw_params_set_buffer_time_near(capture_handle, hw_params, &buffer_time, 0);
snd_pcm_hw_params_set_period_time_near(capture_handle, hw_params, &period_time, 0);
if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0)
{
std::cerr << "Cannot set hardware parameters (" << snd_strerror(err) << ")" << std::endl;
return ;
}
// 准备捕获
if ((err = snd_pcm_prepare(capture_handle)) < 0)
{
std::cerr << "Cannot prepare audio interface for use (" << snd_strerror(err) << ")" << std::endl;
return ;
}
// 累积音频数据,直到积累了1秒的数据
std::vector<int16_t> accumulated_data;
size_t samples_per_second = rate; // 1秒内的样本数
while (true)
{
err = snd_pcm_readi(capture_handle, buffer, BUFFER_SIZE);
if (err == -EPIPE)
{
// 处理缓冲区溢出
snd_pcm_prepare(capture_handle);
std::cerr << "Buffer overrun occurred" << std::endl;
}
else if (err < 0)
{
std::cerr << "Read from audio interface failed (" << snd_strerror(err) << ")" << std::endl;
break;
}
else
{
// 将读取的数据累积到向量中
accumulated_data.insert(accumulated_data.end(), buffer, buffer + err);
// 如果累积的数据达到1秒,则处理数据
if (accumulated_data.size() >= samples_per_second)
{
double rms = calculate_rms(accumulated_data.data(), accumulated_data.size());
double db = calculate_db(rms);
qDebug()<<db<<"111111111";
sound_db = db;
std::cout << "RMS: " << rms << ", dB: " << db << std::endl;
// 清空累积的数据,准备下一次读取
accumulated_data.clear();
break;
}
}
}
// 关闭音频设备
snd_pcm_close(capture_handle);
return ;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化