【C脚本】计算PCM的DBFS(分贝全尺度)

2024-04-01 23:12

本文主要是介绍【C脚本】计算PCM的DBFS(分贝全尺度),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

DBFS是分贝全尺度(Decibels Full Scale)的缩写,是一种用于衡量音频信号强度的单位。DBFS是相对于数字音频的最大可能幅度而言的,它的取值范围通常是从0到-∞。在DBFS中,0表示音频信号的最大幅度,-∞表示完全没有信号。

计算一个24bit、大端PCM样本的DBFS

#include <stdio.h>
#include <stdlib.h>
#include <math.h>int main() {unsigned char buf[3];  // 存储大端24bit PCM样本的缓冲区float sample;          // 存储转换后的浮点数样本值float max_sample = pow(2, 23) - 1;  // 最大电平值,即所有位都为1时的值// 假设buf中存储的是大端24bit PCM样本的值buf[0] = 0x12;buf[1] = 0x34;buf[2] = 0x56;// 将24bit PCM样本转换为浮点数int sample_int = (buf[0] << 16) | (buf[1] << 8) | buf[2];  // 先将3个字节拼成一个整数if (sample_int & 0x800000) {  // 如果最高位是1,即负数sample_int |= 0xff000000;  // 则将32位整数的高8位都置为1,表示负数}sample = (float)sample_int / max_sample;  // 转换为浮点数,再除以最大电平值// 计算DBFS值float dbfs = 20 * log10(fabs(sample));  // 用对数函数计算分贝数值printf("DBFS: %.2f\n", dbfs);return 0;
}

之所以用上述方法转负数的原因参见:C语言中负数的存储

求一段PCM的平均DBFS的方法

下面的函数只统计第一个声道的DBFS,且小端数据的计算一直有问题,结果不一定是负数,不清楚是数据有问题还是方法用错了,希望大神指教,感谢。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>/* 
@param char *data PCM数据
@param int Endianness 大小端标识,大端为真、小端为假
@param int byte 字节大小,可选:2字节(16bit)、3字节(24bit)
@param int sampling_num 统计的次数
@param int channel 声道数,几声道就写几,如双声道就写2*/
double averageDBFS(char *data, int Endianness, int byte, int sampling_num, int channel) {int i;double sample = 0;double pref = pow(2, byte*8-1);int interval_bit = channel * byte;if(Endianness){// 大端if(byte==3){for(i=0;i<sampling_num;i++){int bsize = i * interval_bit;int value = (*(data+bsize) << 16) | (*(data+bsize+1) << 8) | *(data+bsize+2);if (value & 0x800000) {  // 如果最高位是1,即负数value |= 0xff000000;  // 则将32位整数的高8位都置为1,表示负数}sample += fabs(value);}}else if(byte==2){for(i=0;i<sampling_num;i++){int bsize = i * interval_bit;short int value = (*(data+bsize) << 8) | *(data+bsize+1);sample += fabs(value);}}}else{// 小端/* if(byte==3){for(i=0;i<sampling_num;i++){int bsize = i * interval_bit;int value = (*(data+bsize+2) << 16) | (*(data+bsize+1) << 8) | *(data+bsize);if (value & 0x800000) {  // 如果最高位是1,即负数value |= 0xff000000;  // 则将32位整数的高8位都置为1,表示负数}sample += fabs(value);}}else if(byte==2){for(i=0;i<sampling_num;i++){int bsize = i * interval_bit;short int value = (*(data+bsize+1) << 8) | *(data+bsize);sample += fabs(value);}} */}sample /= sampling_num;double dbfs = 20 * log10(sample / pref);return dbfs;
}

这篇关于【C脚本】计算PCM的DBFS(分贝全尺度)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/868379

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

通过Python脚本批量复制并规范命名视频文件

《通过Python脚本批量复制并规范命名视频文件》本文介绍了如何通过Python脚本批量复制并规范命名视频文件,实现自动补齐数字编号、保留原始文件、智能识别有效文件等功能,听过代码示例介绍的非常详细,... 目录一、问题场景:杂乱的视频文件名二、完整解决方案三、关键技术解析1. 智能路径处理2. 精准文件名