文章目录

  • 音频测试
    • 1.dtmf调制成音频数据
      • test.c
      • sound forge打开
    • 2.使用fsk调成音频数据
      • test.c
  • 相关知识:
    • dtmf:
    • 响度:
    • 采样率:
    • 振幅:
    • 正弦波:
    • 振幅:
    • 正弦波:

音频测试

1.dtmf调制成音频数据

  1. 输入任意按键值,输出是该按键对应的dtmf调制的音频信号,输出结果保存到文件中。
  2. 要求dtmf使用的基波响度为-12dB,采样率为16000Hz,生成的音频长度为100ms。

test.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define FILE_NAME_SIZE_MAX  50
#define SAMPLE_RATE         16000
#define AMPLITUDE           32767
#define PI                  3.14159265358979323846
#define AUDIO_TIME_SEC_LEN  (0.1)
#define AUDIO_LOUDNESS_DBFS (-12) typedef struct {char key;int freq1;int freq2;
} dtmf_st;static const dtmf_st dtmf_table[] = {{'1', 697, 1209}, {'2', 697, 1336}, {'3', 697, 1477}, {'A', 697, 1633},{'4', 770, 1209}, {'5', 770, 1336}, {'6', 770, 1477}, {'B', 770, 1633},{'7', 852, 1209}, {'8', 852, 1336}, {'9', 852, 1477}, {'C', 852, 1633},{'#', 941, 1209}, {'0', 941, 1336}, {'D', 941, 1477}
};static const int dtmf_table_size = sizeof(dtmf_table) / sizeof(dtmf_st);int main(void) {char key = 0;short *audio_data = NULL;int num_samples = 0;int freq1 = -1, freq2 = -1;double dtmf_amp = 0;double time_in_sec = 0;double sin_wave1 = 0, sin_wave2 = 0;char filename[FILE_NAME_SIZE_MAX] = {0};FILE *fp = NULL;int i = 0;while(1) {printf("\nPlease input key:");if(scanf("%c", &key) != 1) {while(getchar() != '\n');printf("Input error! \nPlease input (0-9,A-D,#,*)\n");continue;}for(i=0;i<dtmf_table_size; i++) {if(key == dtmf_table[i].key) {break;}}if(i < dtmf_table_size) {freq1 = dtmf_table[i].freq1;freq2 = dtmf_table[i].freq2;// printf("%d %d\n",freq1,freq2);break;} else {printf("Invalid key!\n");}}num_samples = SAMPLE_RATE * AUDIO_TIME_SEC_LEN;audio_data = malloc(sizeof(short) * num_samples);if(audio_data == NULL) {goto ERROR;}dtmf_amp = pow(10, AUDIO_LOUDNESS_DBFS/20.0) * AMPLITUDE;for (int i = 0; i < num_samples; i++) {time_in_sec = i / (double) SAMPLE_RATE;sin_wave1 = sin(2 * PI * freq1 * time_in_sec);sin_wave2 = sin(2 * PI * freq2 * time_in_sec);audio_data[i] = dtmf_amp * (sin_wave1 + sin_wave2);}sprintf(filename, "key_%c.raw", key);fp = fopen(filename, "wb");if (!fp) {perror("fopen");goto ERROR;}if(fwrite(audio_data, sizeof(short), num_samples, fp) < 0){perror("fwrite");goto ERROR;}ERROR:if (fp) {fclose(fp);fp = NULL;}if (audio_data) {free(audio_data);audio_data = NULL;}return 0;
}

sound forge打开

2.使用fsk调成音频数据

使用C语言编写一段程序,程序可以实现将输入的16进制数据使用fsk调制成音频数据。

1.输入为一个16进制数,输出为一个音频文件。例如输入0x55,对应的二进制为01010101,fsk调制后的频率组合为 低频-高频-低频-高频-低频-高频-低频-高频。

2.音频采样率为16000Hz。

3.fsk调制时使用的两个信号分别为1209Hz和697Hz。

4.fsk使用的调制信号的幅值为-12dB。

5.fsk调制时每个频率的信号长度为10ms。

6.两个不同频率的信号拼接时要注意保持相位上的连续性。

在linux系统中,数据保存为raw格式

test.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <stdbool.h>#define AMPLITUDE             32767.0
#define SAMPLE_RATE           (16000.0)
#define LOW_FREQ              697
#define HIGH_FREQ             1209
#define AUDIO_LOUDNESS_DBFS   (-12.0)
#define SIGNAL_LENGTH         0.01
#define BIN_STR_SIZE_MAX      64
#define PI                    3.14159265358979323846
#define OUTPUT_FILE           "output.raw"struct wave {int freq;               double amplitude;
};
static const struct wave waves[2] = {{LOW_FREQ, pow(10, AUDIO_LOUDNESS_DBFS / 20.0)*AMPLITUDE}, {HIGH_FREQ, pow(10, AUDIO_LOUDNESS_DBFS / 20.0)*AMPLITUDE}};static const char *hex_table[] = {"0000", "0001", "0010", "0011", "0100","0101", "0110", "0111", "1000", "1001","1010", "1011", "1100", "1101", "1110","1111"};void hex_to_bin(char *hex_string, char *bin_string)
{int i = 0;char hex_digit = 0;for (i = 0; hex_string[i] != '\0'; i++) {hex_digit = hex_string[i];if (hex_digit >= '0' && hex_digit <= '9') {strcat(bin_string, hex_table[hex_digit - '0']);} else if (hex_digit >= 'A' && hex_digit <= 'F') {strcat(bin_string, hex_table[hex_digit - 'A' + 10]);} else if (hex_digit >= 'a' && hex_digit <= 'f') {strcat(bin_string, hex_table[hex_digit - 'a' + 10]);} else {printf("error invalid digit '%c'\n", hex_digit);goto ERROR;}}if (strlen(bin_string) == 0) {printf("error input is null\n");goto ERROR;}if (strlen(bin_string) % 4 != 0) {printf("error:invalid len %d\n", (int)strlen(bin_string));goto ERROR;}
ERROR:return ;
}double generate_fsk_signal(int fi,int freq,int amplitude,int num_samples,short *audio_data)
{static int pos = 0;double t = 0;for (int i = 0; i < num_samples; i++){audio_data[pos++] = (short)(amplitude * sin(2 * PI * freq * t + fi));t += 1/SAMPLE_RATE;}return (2 * PI * freq * (t+1/SAMPLE_RATE)  + fi); //相位对齐
}void generate_sin_wave(int n,char *bin_string,short *audio_data,int num_samples)
{int len = strlen(bin_string);int i=0 ,j=0;double fi = 0;int index = 0;for(i=0;i<len;i++){index = bin_string[i] - '0';if(index == 0) {fi = generate_fsk_signal(fi,waves[index].freq,waves[index].amplitude,num_samples,audio_data);} else if(index == 1) {fi = generate_fsk_signal(fi,waves[index].freq,waves[index].amplitude,num_samples,audio_data);}}
}char *get_hex_str(char *str)
{int len = strlen(str);if(str == NULL) {goto ERROR;}if (len == 0 || len > BIN_STR_SIZE_MAX / 4) {goto ERROR;}if(strstr(str,"0x") || strstr(str,"0X") ) {str += 2;}for(int i=0; i<strlen(str); i++){if(!isxdigit(str[i])){printf("error: invalid hex_string\n");goto ERROR;}}return str;
ERROR:return NULL;
}int main(int argc, char **argv)
{int i = 0, j = 0;int index = 0;int num_samples = 0;FILE *fp = NULL;int signal_length = 0;char *hex_str = NULL;double last_fi = 0;char bin_string[BIN_STR_SIZE_MAX] = {0};short *audio_data = NULL;if (argc < 2) {printf("Usage: %s hex_string\n", argv[0]);goto ERROR;}hex_str = get_hex_str(argv[1]);if(hex_str == NULL){goto ERROR;}hex_to_bin(hex_str, bin_string);num_samples = SIGNAL_LENGTH * SAMPLE_RATE;signal_length = strlen(bin_string) * num_samples;audio_data = malloc(sizeof(short) * signal_length);memset(audio_data,0,sizeof(short) * signal_length);generate_sin_wave(signal_length,bin_string,audio_data,num_samples);fp = fopen(OUTPUT_FILE, "wb");if (fp == NULL) {perror("fopen");goto ERROR;}if(fwrite(audio_data, sizeof(short), signal_length, fp) < 0) {perror("fwrite");goto ERROR;}
ERROR:if (fp) {fclose(fp);fp = NULL;}if (audio_data) {free(audio_data);audio_data = NULL;}return 0;
}

相关知识:

dtmf:

响度:

响度常用的单位是dBSPL、dBFS、dBpa、dBm0。

dB计算:对于功率,dB = 10 * lg(A/B)。对于电压或电流,dB= 20 * lg(A/B)。此处A,B代表参与比较的功率值或者电流、电压值。

以dBfs举例说明:

dBfs = 20 * lg(x/32767)。

其中32767是16bit采样精度时最大的值,x取值0 ~ 32767。所以dBfs的最大值为当x取值为32767时的值,即0dBfs。

采样率:

采样率是指对模拟音频信号进行取样的每秒次数,通常以赫兹 (Hz) 为单位表示。当我们要将模拟音频信号转换成数字形式时(例如录制音频或将其从 CD 转换成数字格式),需要对其进行采样,即在时间轴上不断地对音频信号进行抽样,获取一系列数字值。采样率越高,每秒中采集到的样本数量就越多,这可以提供更精确的音频表示,但同时也会增加所需的存储空间和处理能力。

振幅:

振幅是指波形的最大偏移量,通常用单位分贝 (dB) 或电平(以电压为单位)来表示。在音频信号中,振幅描述了声音的响度或强度。例如,在一段声音信号中,振幅越高,则声音会听起来更响亮、更强烈,振幅越低,则声音会听起来更柔和、更安静。与采样率不同,振幅是代表音频信号能量的单一数值,其大小与声音响度直接相关。

正弦波:

y = A * sin(ωt + ϕ)

其中,A代表振幅,即波形的最大偏移量;

ω代表角频率,即单位时间内的变化角度;

t代表时间;

ϕ代表初相位,即初始状态下正弦波图像的左右平移位置

φ = arcsin(y/A) - wt

每秒中采集到的样本数量就越多,这可以提供更精确的音频表示,但同时也会增加所需的存储空间和处理能力。

振幅:

振幅是指波形的最大偏移量,通常用单位分贝 (dB) 或电平(以电压为单位)来表示。在音频信号中,振幅描述了声音的响度或强度。例如,在一段声音信号中,振幅越高,则声音会听起来更响亮、更强烈,振幅越低,则声音会听起来更柔和、更安静。与采样率不同,振幅是代表音频信号能量的单一数值,其大小与声音响度直接相关。

正弦波:

y = A * sin(ωt + ϕ)

其中,A代表振幅,即波形的最大偏移量;

ω代表角频率,即单位时间内的变化角度;

t代表时间;

ϕ代表初相位,即初始状态下正弦波图像的左右平移位置

φ = arcsin(y/A) - wt

dtmf_fsk音频数据测试相关推荐

  1. 睡眠音频分割及识别问题(九)--Android下的YAMNet

    部署PANNs模型面临的问题 加载模型出错 在使用PANNs模型时,在PC端可以较好的运行,可是在Android端运行的时候,编译过程提示缺少libpytorch_jni.so文件,导致无法加载模型, ...

  2. 【电路_音频】一些关于音频功放的小秘密,你都知道吗?

    一个手机的音乐效果的好坏,取决于喇叭(包括喇叭单体.音腔结构.出音孔.防尘网等),音频功放,音效算法调试(平台音效或第三方音效等),这三者有效,合理配合,才能实现最终满意的音乐效果.本文主要从一些基础 ...

  3. Python爬虫教程,Python采集喜马拉雅音频

    目录 项目需求:抓取专辑所有音频文件. 1. 项目截图 2. 找数据 3. 项目难点讲解 4. 源代码 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪 ...

  4. 音频编解码器以50%的功耗提供两倍的音频质量

    音频编解码器以50%的功耗提供两倍的音频质量 Audio codecs deliver twice the audio quality at 50% less power Dialog的DA740x音 ...

  5. 新十年嵌入式音频的五大趋势

    新十年嵌入式音频的五大趋势 Five embedded audio trends for the new decade 很难相信正在进入一个新的十年.十年前,像Alexa这样的语音技术甚至还没有成为现 ...

  6. 人工智能在音频链中找到自己的声音

    人工智能在音频链中找到自己的声音 AI finds its voice in audio chain 硅基silicon-based麦克风的出现重塑了音频领域.但在未来几年,市场研究公司Yole Dé ...

  7. 处理器嵌入室内校正数字音频平台

    处理器嵌入室内校正数字音频平台 Processors to embed room correction digital audio platform 家庭影院的目的是给家带来一种影院般的体验.对于发烧 ...

  8. 用matlab怎么画视电阻率拟断面图,在MATLAB平台上实现可控源音频大地电磁反演数据三维可视化显示...

    第29卷 增刊 物探化探计算技术 2007年10月 收稿日期6文章编号:1001-1749(2007)增刊(1)-0068-04 在MAT LAB 平台上实现可控源音频大地 电磁反演数据三维可视化显示 ...

  9. FFmpeg学习4:音频格式转换

    前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...

最新文章

  1. [JS] 如何判断一个对象是否为空
  2. 计算机视觉与图像处理、模式识别、机器学习学科之间的关系
  3. uva 10047 the monocyle (四维bfs)
  4. 科大星云诗社动态20210210
  5. numpy genfromtxt 读取字符_numpy组队学习1: 输入输出
  6. phpcmsV9留言插件提交后返回上一页实现方法
  7. 软考信息安全工程师学习笔记四(1.4 信息安全标准化知识)
  8. DataGrid控件(可以实现不刷新增加删除等操作)
  9. java.lang.NoClassDefFoundError: weblogic/rmi/extensions/DisconnectListener
  10. web之nginx相关配置二
  11. Pyinstaller打包过程中报错“AttributeError: module 'enum' has no attribute 'IntFlag'”问题解决
  12. Linux中使用SSH服务远程连接Linux系统
  13. 2020年度全球人工智能十大事件
  14. pyTest官方手册(Release 4.2)之蹩脚翻译(6)
  15. 聚币网行情与套利分析
  16. 数据分析-思维分析逻辑day02
  17. 夏令时和时区最佳实践
  18. Web网页如何实现QQ好友,QQ空间,微博分享
  19. 【统计学】【2018.05】【含源码】时间序列:以密度预测评价方法为中心的预测与评价方法
  20. 深入学习理解(1):java:ExecutorService invokeAll 任务的批量提交invokeAll两种方法的区别

热门文章

  1. opencv flip
  2. Python数据可视化 Pyecharts 制作 Treemap 矩形树图
  3. 音频格式m4a怎么转换成mp3
  4. 论云原生架构及其应用
  5. 灯火阑珊,一夜芳醉年华:QQ空间伤感日志
  6. 游戏UI动态加载图片优化
  7. AudioContext开发后台管理系统新订单提示音(audio不能自动播放)
  8. 页面数据加载不出来、或者图面、JS、CSS加载不出来
  9. 工业产品3.12寸OLED屏调研
  10. 基于docker部署php应用