基于 OpenHarmony 音符检测实现原理

一、音符检测的基本原理

本文基于 OpenHarmony 开源系统提供了一种音符检测的原理方法,结合多首音乐,运用了 python 和 C++ 两种编程环境实现了预期的检出效果。旨在为振动马达(vibrator)提供音乐节奏感的触觉效果,代码所在目录 .\base\sensors\sensor\vibration_convert。

先从 python 实现说起,Librosa 关于音符检测主要用到了两个函数,一个是 onset_strength(),负责生成包含音符产生的频率突变的包络线,如蓝色线条所示。另一个是 onset_detect(),主要运用峰点检测找到每个音符的位置,如黄色线条所示。

图 1 音符检测包络图
包含有用的频率突变的包络线是音符检测的核心所在。傅里叶变换能够得到全部信号采样的频谱图,即每个频率的能量贡献,如图 2 所示。但是每个时刻频谱图却得不到,于是将全部采样分割成若干固定长度的窗口,每个窗口应用傅里叶变化,从而得到这一窗口的频率分布,水平轴为时间,纵轴为频率,颜色代表能量大小如图 3 所示。

图 2 整体频率分布图

图 3 时频图

每种乐器在音符产生时,前后时间片段的频率将会发生明显变化,如图 4 所示。于是将时频图相邻列做差分,将明显看到变化的频率。为了便于分析,只取正值,具有相同的效果,所以负值填零。一个时刻变化的频率有多个,如何取舍,有三种方法,平均数、中位数和联合,目前常用到的是中位数和平均数。至此,将得到任意时刻发生明显频率变化的单一能量,如图 1 蓝色线条所示。

图 4 时频图相邻列差分前后变化

二、音符检测的准确性

目前采用频谱光通量(相邻列差分)方法检测是业界公认且较为准确的方法,音符检出率仅为 70% 多。不准确的原因可能有乐器多且差异较大,信号衰减对性能的影响,颤音影响,峰点检测时不同参数的影响,这些主要是针对音乐的研究。

三、音符检测的程序流程

3.1 程序实现

音符检测功能核心就是频谱图和梅尔滤波器,频谱图的核心就是短时傅里叶变换,C++ 代码片段如下,

void STFT::stft(short*in,int length,double**out){int i,j;/*** Shfit & Copy***/for (j = 0; j < channels; j++) {for (i = 0; i < ol; i++) {buf[j][i] = buf[j][i + shift_size];}}// EOFif(length!=shift_size*channels){length = length/channels;for (i = 0; i < length; i++) {for (j = 0; j < channels; j++)buf[j][i + ol]=  (double)(in[i * channels+ j]);}for (i = length; i < shift_size; i++) {for (j = 0; j < channels; j++)buf[j][i + ol] = 0;}//continue}else{for (i = 0; i < shift_size; i++) {for (j = 0; j < channels; j++){buf[j][i + ol] = (double)(in[i * channels+ j]);}}}/*** Copy input -> hann_input buffer ***/for (i = 0; i < channels; i++)memcpy(out[i], buf[i], sizeof(double) * frame_size);// scaling for precisionif(opt_scale)for (i = 0; i < channels; i++)for (j = 0; j < frame_size; j++)out[i][j] /= MATLAB_scale;/*** Window ***/hw->Process(out, channels);/*** FFT ***/fft->FFT(out);
}

Mel 滤波器构造代码如下:

if fmax is None:fmax = float(sr) / 2# Initialize the weightsn_mels = int(n_mels)weights = np.zeros((n_mels, int(1 + n_fft // 2)), dtype=dtype)# Center freqs of each FFT binfftfreqs = fft_frequencies(sr=sr, n_fft=n_fft)# 'Center freqs' of mel bands - uniformly spaced between limitsmel_f = mel_frequencies(n_mels + 2, fmin=fmin, fmax=fmax, htk=htk)fdiff = np.diff(mel_f)ramps = np.subtract.outer(mel_f, fftfreqs)for i in range(n_mels):# lower and upper slopes for all binslower = -ramps[i] / fdiff[i]upper = ramps[i + 2] / fdiff[i + 1]# .. then intersect them with each other and zeroweights[i] = np.maximum(0, np.minimum(lower, upper))if norm == "slaney":# Slaney-style mel is scaled to be approx constant energy per channelenorm = 2.0 / (mel_f[2 : n_mels + 2] - mel_f[:n_mels])weights *= enorm[:, np.newaxis]else:weights = util.normalize(weights, norm=norm, axis=-1)# Only check weights if f_mel[0] is positiveif not np.all((mel_f[:-2] == 0) | (weights.max(axis=1) > 0)):# This means we have an empty channel somewherewarnings.warn("Empty filters detected in mel frequency basis. ""Some channels will produce empty responses. ""Try increasing your sampling rate (and fmax) or ""reducing n_mels.",stacklevel=2,)
return weights

3.2 功能流程图

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/808238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.4.12蚂蚁庄园今日答案:豆腐在烹调时容易碎有什么办法可以避免?

原文来源&#xff1a;蚂蚁庄园今日答案 - 词令 蚂蚁庄园是一款爱心公益游戏&#xff0c;用户可以通过喂养小鸡&#xff0c;产生鸡蛋&#xff0c;并通过捐赠鸡蛋参与公益项目。用户每日完成答题就可以领取鸡饲料&#xff0c;使用鸡饲料喂鸡之后&#xff0c;会可以获得鸡蛋&…

JDK版本升级后连不上MySQL数据库的问题

1. 问题描述 用户在将 JDK 版本从 8 升级到 11 后&#xff0c;发现应用无法连接到 MySQL 数据库&#xff0c;出现连接超时或连接被拒绝的错误。 例如出现如下报错信息&#xff1a; 可能原因&#xff1a; JDBC驱动版本不兼容&#xff1a; 新的 JDK 11 可能需要使用更高版本的 My…

docker一键部署GPU版ChatGLM3

一键运行 docker run --gpus all -itd --name chatglm3 -p 81:80 -p 6006:6006 -p 8888:8888 -p 7860:7860 -p 8501:8501 -p 8000:8000 --shm-size32gb registry.cn-hangzhou.aliyuncs.com/cwp-docker/chatglm3-gpu:1.0 进入容器 docker exec -it chatglm3 /bin/bash cd /…

自定义校验器

1.前端校验 <template><el-dialog:title"!dataForm.brandId ? 新增 : 修改":close-on-click-modal"false":visible.sync"visible"><el-form:model"dataForm":rules"dataRule"ref"dataForm"keyu…

Java(IO流)

IO流 用于读写文件中的数据&#xff08;可以读写文件或网络中的数据&#xff09;I&#xff1a;inputO&#xff1a;output 1.IO流的分类 1 流的方向 输入流&#xff08;读取&#xff1a;程序 -> 文件&#xff09;输出流&#xff08;写出&#xff1a;文件 -> 程序&#x…

Hello 算法10:搜索

https://www.hello-algo.com/chapter_searching/binary_search/ 二分查找法 给定一个长度为 n的数组 nums &#xff0c;元素按从小到大的顺序排列&#xff0c;数组不包含重复元素。请查找并返回元素 target 在该数组中的索引。若数组不包含该元素&#xff0c;则返回 -1 。 # 首…

前端实用文档总结

工具类 utools 快捷键 空格option 呼出颜色提取/转换json格式化工具截图markdown笔记文本差异对比svg转png正则… deepl 翻译工具 翻译工具 poe AI工具figma 原型图设计iconfont阿里巴巴图库菜鸟工具-正则表达式Mermaid在线画图&#xff0c;属于文字类画图&#xff0c;根据对应…

C++11 设计模式2. 简单工厂模式

简单工厂&#xff08;Simple Factory&#xff09;模式 我们从实际例子出发&#xff0c;来看在什么情况下&#xff0c;应用简单工厂模式。 还是以一个游戏举例 //策划&#xff1a;亡灵类怪物&#xff0c;元素类怪物&#xff0c;机械类怪物&#xff1a;都有生命值&#xff0…

深入浅析插入排序:原理、实现与应用

在众多基础排序算法中&#xff0c;插入排序以其简洁明了的逻辑和直观的实现方式&#xff0c;赢得了广大程序员的喜爱。本篇博客将带领大家深入了解插入排序的原理、详细实现步骤以及其在实际场景中的应用&#xff0c;帮助读者更好地理解和掌握这一经典排序方法。 一、插入排序…

用python 实现进销存

进销存系统是一个基本的商业管理系统&#xff0c;用于跟踪库存、销售和采购活动。以下是一个简单的进销存系统的Python实现&#xff0c;这个系统包括商品管理、采购入库、销售出库以及库存查询的功能。 首先&#xff0c;我们定义一个Product类来表示商品&#xff1a; python复…

Unity3D知识点精华浓缩

一、细节 1、类与组件的关系 2、Time.deltaTime的含义 3、怎么表示一帧的移动距离 4、Update和LateUpdate的区别和适用场景 5、找游戏对象的方式&#xff08;别的对象 / 当前对象的子对象&#xff09; 6、组件1调用组件2中方法的方式 7、在面板中获取外部数据的方法 8、序列化属…

在Windows系统中开启SSH服务

文章目录 引言I 使用Windows内置的OpenSSH服务器功能1.1 安装并启用SSH服务器1.2 配置SSH服务器的端口号II Windows的run功能III SSH的其他操作3.1 绑定本地端口3.2 本地端口转发3.3 远程端口转发3.4 后台运行3.5 不执行远程操作3.6 在Linux上创建一个git用户用于SSH访问see al…

ChatGPT智能写作:开启论文写作新视野

ChatGPT无限次数:点击直达 html ChatGPT智能写作&#xff1a;开启论文写作新视野 引言 在当今信息爆炸的时代&#xff0c;人们需要更有效的工具来帮助他们在各种领域进行写作。ChatGPT作为一项基于人工智能技术的顶尖产品&#xff0c;为论文写作提供了全新的视角和可能性。…

海外博士后政策,这些重点你不能错过!

​ ​海外高层次人才博士后专项申报政策是针对具有较高学术造诣和研究潜力的海外学者、研究人员&#xff0c;旨在吸引他们回国从事科研工作&#xff0c;推动国内科技创新发展。该政策不仅为海外人才提供了良好的职业发展平台&#xff0c;还为他们提供了丰富的科研资源和优厚…

20240408在线给加密的PDF文件解密【打印限制】

20240408在线给加密的PDF文件解密 百度&#xff1a;PDF解密 https://smallpdf.com/cn/unlock-pdf PDF解密 未选择任何文件 或拖放PDF至此处 无文件大小限制&#xff0c;无广告水印 - 这款易于使用且免费的在线密码移除工具可为您移除恼人的PDF密码。 无需注册 数秒内解锁 PDF …

【GitHub技术全面解析及游戏开发者的应用】

GitHub技术全面解析及游戏开发者的应用 GitHub作为全球最大的开源代码托管平台&#xff0c;不仅为软件开发者提供了一个强大的工具&#xff0c;也为游戏开发者带来了前所未有的便利。在游戏开发领域&#xff0c;GitHub的技术可以帮助开发者更高效地管理代码、协作开发、分享资…

CommandLineRunner实现项目启动时预处理

如果希望在SpringBoot应用启动时进行一些初始化操作可以选择使用CommandLineRunner来进行处理。 我们只需要实现CommandLineRunner接口&#xff0c;并且把对应的bean注入容器。把相关初始化的代码重新到需要重新的方法中。 这样就会在应用启动的时候执行对应的代码。 Compon…

python基础语法--输入和输出

一、 输入 input() python使用input输入变量&#xff0c;input输入的变量为字符串形式&#xff0c;可以通过其他方式转换为整型或其他类型。 &#xff08;1&#xff09;单行读入已知个数的字符串或数字 读入字符串 # 单行读入字符串a,并给出一句输入提示 a input("请…

【随笔】Git 高级篇 -- 提交的技巧(下) cherry-pick commit --amend(十九)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

Vue插件使用详细介绍

介绍​ 插件 (Plugins) 是一种能为 Vue 添加全局功能的工具代码。下面是如何安装一个插件的示例&#xff1a; import { createApp } from vueconst app createApp({})app.use(myPlugin, {/* 可选的选项 */ }) 一个插件可以是一个拥有 install() 方法的对象&#xff0c;也可以直…