基于语音识别技术的钢琴调音软件精度研究

来源 :科技智囊 | 被引量 : 0次 | 上传用户:liouxing1984
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘  要:钢琴是一种传统演奏乐器,距今已有几百年的发展和使用历史。我国自从改革开放以来,越来越多的家庭购买了钢琴。但是钢琴调音仍然处于人工调试阶段,需要调音师的经验和手艺来判断钢琴音色是否标准,调音效果千差萬别。随着智能手机以及计算机技术发展,设计应用软件通过语音识别技术对琴键频率进行采集,采用傅里叶变换对接收到的音频进行分析,得到真实的音键频率,可以弥补人为因素对乐音调试的误差;将分析得到的琴键频率与标准乐音库进行对比,将对比后的乐音信息通过可视化界面展示出来,便于人们更加快速准确地调音。
  关键词:Visual Studio;钢琴调音;语音识别;傅里叶变换
  中图分类号:TN912.3     文献标识码:A
  Abstract:Piano is a traditional musical instrument,which has a history of development and use for hundreds of years. Since Chinese reform and opening up,more and more families have bought piano. However,the piano tuning is still in the stage of manual debugging,which requires the experience and skills of the tuner to judge whether the piano tone is standard,and the tuning effect is very different. With the development of smart phones and computer technology,the design application software collects the piano key frequency through speech recognition technology,analyzes the received music by using Fourier transform,and gets the sound key frequency approaching to the standard,which can completely make up for the error of human factors in music debugging;compares the piano key frequency obtained by analysis with the standard music library,and then compares it Through the visual interface,the music information is displayed,which is convenient for people to tune more quickly and accurately.
  Key words:Visual Studio;Piano tuning;Speech Recognition;Fourier transform
  一、项目背景
  21世纪,人们更加注重于对精神的追求,钢琴的发展和普及恰好可以为现代人们带来精神上的快乐和满足[1]。钢琴的音质长期受到各种外在环境因素的影响,使得钢琴发音不准,严重干扰钢琴演奏的稳定性和演奏效果,因此必须在钢琴使用前进行准确的调音。近些年由于演奏钢琴人数的增加,传统的钢琴调音过于复杂化和机械化,现有的调音模式始终满足不了大众的调音需求[2]。因此,需要一款方便、快捷、准确、实用的调音装置或者软件工具来帮助解决调音的音准问题。
  设计一种钢琴调音软件,可以实现智能化精密测量,高效地协助调音师完成钢琴调音工作,避免了人为调音的不足,满足了实际工作的要求。调音软件也适用于其他乐器的调音,使调音工作不再枯燥烦琐。
  二、技术方案
  (一)音频识别技术构建模型
  将模拟的音频信号进行采样得到波形数据之后,要输入到特征提取模块,提取出合适的声学特征参数供后续声学模型训练使用。好的声学特征应当考虑以下三个方面的因素:第一,应当具有比较优秀的区分特性,以使声学模型不同的建模单元可以方便准确地建模;其次,特征提取也可以认为是音频信息的压缩编码过程,既需要将信道、环境噪音的因素消除,保留与内容相关的信息,又需要在不损失过多有用信息的情况下使用尽量低的参数维度,便于高效准确地进行模型的训练;最后,需要考虑鲁棒性,即对环境噪声的抗干扰能力[3-4]。
  如今主流语音识别系统都采用隐马尔科夫模型(HMM)作为声学模型,这是因为HMM具有很多优良特性。HMM的状态跳转模型很适合人类语音的短时平稳特性,方便对不断产生的观测值(语音信号)进行统计建模;与HMM相伴生的动态规划算法可以有效地实现对可变长度的时间序列进行分段和分类的功能;HMM的应用范围广泛,只要选择不同的生成概率密度,离散分布或者连续分布,都可以使用HMM进行建模。其原理框架如下图1中所示。
  钢琴键频率是指钢琴上琴键所产生的声音频率,以赫兹(Hz)为单位。现代的钢琴上共有88至108键。88键钢琴的第49键,即第5个A(亦称A4)一般被用作调音标准。现行的标准是440Hz,亦称A440。钢琴的琴键号和频率对应关系如下表1。本项目对音频信号建模,标准频率模型即为该表。
  (二) FFT(Fast Fourier Transform)算法原理
  FFT是一种基于离散傅里叶变换(DFT)的高效傅里叶算法,被人们广泛称为快速傅里叶变换[5-6]。该方法主要基于Fourier的傅里叶函数变换,在时域上的任何傅里叶函数都必须是完全可以整数表示的,它可以构成由一个正交余弦阵列函数所组合构成的无穷数量级数。Fourier函数定义为:时域上的一个信号x(t)会对应于频域f上的另外一个信号 X(f)。即X(f)=dt。   通过Fourier变换后,可以得出信号的离散频谱,从而精确地求出信号的离散频率。实际应用时,计算得到离散信号周期x(t)的离散采样值,即x(nt),t代表离散采样信号的周期。通过计算离散采样的值x(nt),可以精確地计算出离散信号周期x(t)的离散频谱。
  麦克风记录声音时,只能获取不同时刻的电压变化值,这是多种声音频率的总和。利用傅里叶变换将多个不同频率的音频分别提取出来,将语音信号转化为电脑可识别的数字信号,其中傅里叶变换还可将混合的复杂音波分别提取出单一的音频信号。本项目通过快速傅里叶变换的算法获取采样音频的能量值。
  三、程序的实现
  本项目运行环境为微软公司的Visual Studio 2017(VS),采用C语言和Windows编程来实现钢琴调音的基本功能。首先建立一个控制台项目文件,新建项目完成后,将后缀名称.cpp改为.c。为了更加方便地调试程序,手动添加一个FFT算法.c文件。完成总体框搭建以后,只需向项目文件中添加代码即可,采用多文件联合编程的思想,可以更加快速有效地实现程序的功能。
  (一)整体思路
  软件的工作流程如下图2所示。
  频率识别需要对外部声音进行采集,添加导入winmm.lib库,可以进行Windows多媒体编程。因为还需调用接口函数和添加mmsystem.h头文件来实现声音的输入输出。mmsystem.h中包含了多媒体的大多数接口,可以简化程序。主程序包含了1个main函数和5个可调用函数,将钢琴音键和对应频率值设为全局变量,定义为结构体数组。钢琴各按键频率,为测试方便,本项目定义了70个(可以在堆栈空间中开辟88个。)
  struct MusicNote
  {
  char noteName[10];
  double frequence;
  }
  note[VOLUMESIZE]={{“1”,27.5},{“2”, 29.1},{“3”, 30.8},{“4”, 32.7},{“5”, 34.6},{“6”, 36.7 7”, 38.8},{“8”, 41.2},{“9”, 43.6},{“10”,46.2},{“11”,48.9},{“12”, 51.9},{“13”, 55.0},{“14”, 58.2},{“15”, 61.7},{“16”, 65.4}, {“17”, 69.2}, {“18”, 73.4}, { “19”, 77.7}, {“20”, 82.4}, {“21”, 87.3},{“22”, 92.4}, {“23”, 97.9}, {“24”, 103.8},{“25”, 110.0},{“26”,116.5},{“27”,123.4},{“28”,130.8},{“29”,138.5},{“30”,146.8},{“31”,155.5},{“32”,164.8},{“33”,174.6},{“34”,184.9},{“35”,195.9},{“36”,207.6},{“37”,220.0},{“38”,233.0},{“39”,246.9},{“40”,261.6},{“41”,277.1},{“42”,293.6},{“43”,311.1},{“44”,329.6},{“45”, 349.2},{“46”, 369.9},{“47”, 391.9}, {“48”, 415.3}, {“49”, 440.0},{“50”,466.1},{“51”,493.8},{“52”,523.2},{“53”,554.3},{“54”,587.3},{“55”,622.2}, {“56”,659.2},{“57”,698.4},{“58”,739.9},{“59”,783.9},{“60”,830.6},{“61”,880.0},{“62”,932.3},{“63”,987.7},{“64”,1046.5},{“65”,1108.7},{“66”,1174.6},{“67”,1244.5},{“68”,1318.5},{“69”,1396.9}, {“70”, 1479.9}};
  (二)设计过程
  1.调用Record()函数,实现PCM(脉冲编码调制)声音采集,将生成的录音文件保存于D盘的根目录下。保存的文件采用二进制进行存储,读取函数时也要进行相应的二进制读取。定义音频流格式的数据结构WAVEFORMATEX waveform和输入设备HWAVEIN hWaveIn,输入设备的初始值为0。采集音频时,需要包含数据缓存结构体LPWAVEHDR pWaveHdr以及采集时的数据缓存PBYTE pBuffer,数据缓存的类型为PBYTE,数据定义格式均为Windows核心编程内容。
  WAVEFORMATEX waveform;        //采集音频格式,结构体
  HWAVEIN hWaveIn = 0;          //输入设备
  LPWAVEHDR pWaveHdr = NULL;    //采集音频时,包含数据缓存结构体
  PBYTE pBuffer = NULL;          //采集音频时的数据缓存
  MMRESULT error = 0;           //枚举型数据变量
  double i = 4000000000;     //循环变量,用于录音需要的一段时间
  FILE *fp = NULL;   char directory[50] = “d:\\shengyin.pcm”;
  waveform.wFormatTag = WAVE_FORMAT_PCM;    //音频格式为PCM
  waveform.nChannels = 1;      //采样声道数(2声道)
  waveform.nSamplesPerSec = 8000; //采样率(采样率,16000Hz)
  waveform.wBitsPerSample = 16; //采样精度(采样比特,16bits)
  waveform.nBlockAlign = 2;    //数据块大小
  waveform.nAvgBytesPerSec = 16000;  //每秒采集的数据字节数
  waveform.cbSize = 0;        //额外描述信息块大小
  定义好基本类型数据,开辟录音所需空间和数据缓存结构体空间:
  pBuffer = (PBYTE)malloc(10 * waveform.nAvgBytesPerSec);
  pWaveHdr = (PWAVEHDR)malloc(sizeof(WAVEHDR));
  设置录音时间为10秒,如果开辟堆栈空间错误,将其置0,程序退出。
  if (pBuffer == NULL)
   {printf(“[record]pBuffer malloc error!\n”);   exit(0);}
  打开录音设备:
  error = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, 0, 0, CALLBACK_NULL);
  为录音设备准备一个缓冲区:
  error = waveInPrepareHeader(hWaveIn, pWaveHdr, sizeof(WAVEHDR));
  向录音设备输入一个缓冲区:
  error = waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR));
  啟动录音:
  error = waveInStart(hWaveIn);
  用一个while循环来记录时间:
  while (i > 0)
  {i--;}
  用于录音的缓存判断和函数结束:
  waveInStop(hWaveIn);
  waveInReset(hWaveIn);
  fp = fopen(directory, “wb”);
  if (fp == NULL)
   {printf(“[record]打开失败!\n”);
   free(pWaveHdr);
   pWaveHdr = NULL;
   free(pBuffer);
   pBuffer = NULL;
   exit(0);}
  将文件以二进制形式写入:
  fwrite(pBuffer, pWaveHdr->dwBytesRecorded, 1, fp);
  函数结尾需要关闭文件和释放堆栈空间:
  fclose(fp);
  free(pWaveHdr);
  pWaveHdr = NULL;
  free(pBuffer);
  pBuffer = NULL;
  2.调用getValue()函数,从录音文件中提取数据点。
  二进制形式打开录音文件:
  FILE *fp = NULL;
  char directory[50] = “d:\\shengyin.pcm”;
  fp = fopen(directory, “rb”);
  查找文件并计算大小:
  fseek(fp, 0, SEEK_END);
  length = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  读取数据点操作:
  fread(&datatmp, 1, sizeof(datatmp), fp);
  *(data + i) = datatmp;
  因录音不能在开始时马上进行,需要对数据进行筛选操作,要先跳过前面10000个点左右,时间为大于1秒的准备时间:
  for (i = 0; i < 8000; i++)
  {fread(&datatmp, 1, sizeof(datatmp), fp);}
  3.调用getFFTEnergy()函数,从提取的数据进行傅里叶变换,得到各音频的能量值。
  定义采集数据值为双精度double类型:
  double pr[DATASIZE], pi[DATASIZE], fr[DATASIZE], fi[DATASIZE];
  以原始数据作为实部,虚数部分为0.0,fr表示为傅里叶变换后的实部,fi为傅里叶变换后的虚部。
  调用傅里叶变换函数:
  kfft(pr, pi, DATASIZE, 12, fr, fi, 0, 1);   得到能量的返回值:
  *(data + i) = pr[i];
  4.调用getFrequence()函数,计算出音频的频率值。
  设置能量的频率、坐标和能量最大值:
  double locate = 0;
  int i;
  double frequence;
  double max;
  max = *data;
  求出能量最大值对应的横坐标:
  for (i = 0; i < (DATASIZE / 2); i++)
  {if (*(data + i) > max)
  {max = *(data + i);
  locate = i;}}
  计算出其频率值:
  frequence = locate * (8000.0 / DATASIZE);
  5.调用showVolume()函数。根据频率,在音高频率对照表中,查看对应的音符并显示结果。
  函数开始时打印出标准钢琴70个键的参照表:
  printf(“%s:%fHz\n”, note[i].noteName, note[i].frequence);
  输出当前音键的频率值:
  printf(“当前频率值:%f\n”, fre);
  输入的音律太高或音律太低,提示出现错误,并重新进行下一轮的声音读取操作:
  if (fre <= note[0].frequence)
  {Low = note[0].frequence - fre;
  printf(“音律太低,请重新录入\n”);}
  else if(fre >= note[69].frequence)
  {Heigh = fre - note[69].frequence;
  printf(“音律太高,请重新录入\n”);}
  如果频率在相应合理的范围,显示出对应高出或低于标准频率的频率值,误差在5Hz以内时,提示调音较为合理:
  if (note[choose].frequence < fre)
  {printf(“当前频率高于標准频率,高了%fHz\n”, fre - note[choose].frequence);
  while ( fre - note[choose].frequence<Wucha )
  {printf(“误差在0至5Hz之间,调音基本完成\n”);
   break;}}
  else
  {printf(“当前频率低于标准频率,低了%fHz\n”, note[choose].frequence - fre);
   while(note[choose].frequence-fre < Wucha)
  {printf(“误差在0至5Hz之间,调音基本完成\n”);
  break;}}
  (三)测试案例
  1.当在一个相对安静的环境下时,接收到的声音频率为0,低于钢琴所发出的最低频率,则会出现相应提示如下,测试结果达到预期目标。
  2.当在一个相对频率较高的环境下时,接收到的频率远高于对照表中的数据,则会出现相应提示如下,测试结果达到预期目标。
  3.测试任意钢琴的频率按键。
  (1)选择52号琴键为低音键(一组7个音键中Do键),对应的标准频率为523.2Hz,测试结果如下:
  与标准频率相差仅为0.23Hz,达到了预期调音目标。
  (2)选择63号高音键Xi,对应标准频率为987.7Hz,测试结果如下:
  与标准频率仅相差0.58Hz,达到了预期效果。
  (四)误差分析
  选取部分钢琴琴键,测出调音后的频率,与标准音频值做比对,检验软件准确度。测量结果如表2所示。52、54、56、57、59、61、63键号分别对应钢琴键号中的C5、D5、E5、F5、G5、A5、B5。
  从表2数据可以看出,测得误差与标准值基本控制在1Hz左右,误差百分比在0%~0.5%之间,测量精度相对较高,完全可以担任调音工作。
  调音中的误差主要来源于以下几个方面:
  1.系统声卡将声音文件转化为二进制文件进行保存时,声音信号转化为数字信号,会出现失真和数据丢失的情况;将二进制文件转化为音频文件时又会出现音质损失。
  2.不存在绝对安静的环境,环境因素会对频率检测出现影响,有一些杂音会通过麦克风进入声卡,导致有时测量相对误差较大。
  
  四、总结
  本项目通过Visual Studio平台进行了整体项目搭建,对每一个重要功能函数进行了详细分析和开发应用,根据程序测试案例进行分析数据,最后对比分析出结果。通过快速离散傅里叶变换计算得出的频率值与钢琴调音时弹奏出的频率值基本吻合,该软件可以初步满足对钢琴调音的需求。
  参考文献:
  [1]林琳娜.浅谈钢琴中的“律”及“调试”[J].科技信息,2011(20):259.
  [2]崔笑.钢琴调音仪的研究及实现[D].成都:电子科技大学,2014.
  [3]柯鑫.基于Web客户端和语音识别的智能家居交互系统设计[D].武汉:华中科技大学,2019.
  [4]林圣晔.语音识别技术[J].数码设计(下),2019(04):182-183.
  [5]徐健,李晓慧.一种基于FFT的高分辨率音频频率测量方法[J].电子质量,2020(02):11-14.
  [6]张嘉.基于ARM的钢琴调校装置的研发[D].哈尔滨:哈尔滨理工大学,2013.
其他文献
摘 要:SiC具有较大的带隙宽度和优异的热稳定性,可在高功率、高温(高达600℃)和高频(高达20GHz)条件下工作,在半导体器件中有着广泛的应用。Si是常用的制作SiC薄膜的基底材料,然而,由于基底Si和SiC靶材的晶格常数存在差异,使得它们之间存在较大的晶格失配和热膨胀系数失配,影响了成膜质量,在一定程度上限制了SiC在微电子领域的应用。通过在Si与SiC之间添加AlN缓冲层可以有效地解决这一
期刊
摘要:2020年,新型冠狀病毒感染的肺炎蔓延全国,为应对新冠肺炎疫情这一突发事件,北京自然博物馆及时开展了相关线上应急科普活动,为公众传播正确的疫情防控知识。文章阐述了应急科普概念及新冠病毒下的应急科普在网络和政府方面的特点,介绍了疫情期间北京自然博物馆的线上应急科普活动,根据博物馆微信公众号的阅读量及互动情况进行分析。从受众角度看,北京自然博物馆在设计线上科普活动时,应急科普应根据受众年龄分层进
期刊
摘 要:疫苗在公共卫生领域扮演着极其重要的角色。近年来,频繁发生的疫苗事件不仅引发了公众对疫苗行业的信任危机,也暴露出我国在相关生物制品的生产和流通环节存在的潜在安全风险。风险积聚会产生动摇社会稳定和破坏社会秩序的严重后果,风险治理问题已成为当前社会面临的严峻问题。文章以长春长生疫苗事件为研究对象,从博弈视角对该事件中利益相关者及其策略选择进行分析,最终提出完善疫苗安全风险防控机制既要充分发挥核心
期刊
摘要:OBE理念強调以学生为中心,以产出为导向,为高校实践教学改革指明了方向。广州理工学院与京东华南区域分公司合作建立的“京苗班”已成立4年,文章基于“京苗班”生产实践教学活动产出、科研成果产出、学生对企业生产实践活动满意度等方面的调查研究,总结校企合作、产学研结合的经验与不足,为同行业教育教学改革提供参考。  关键词:OBE理念;产学研结合;人才培养模式  中图分类号:G642  文献标识码:A
期刊
摘要:文章在总结“十三五”经验教训的前提下,根据“十四五”规划发展方向,立足北京天文馆实际,针对北京天文馆智慧场馆建设规划,从建设目标、需求分析、总体设计以及重点举措等方面进行了详细阐述,以期为北京天文馆“十四五”智慧化建设提供借鉴。  关键词:北京天文馆;智慧场馆;需求分析;总体设计  中图分类号:G261  文献标识码:A  一、引言  近年来,从中央到地方都在持续加强对文物的保护与活化利用工
期刊
摘 要:依托广西科技工作者状况调查站点体系对广西高校、科研院所、企业、中学等单位一线科技工作者进行调查,结果显示广西科研激励存在以下问题:科技工作者对广西科研激励政策的认可度不高、对科研激励政策的认知度不高;政府、单位政策宣传力度、深度不足;单位科研奖励激励机制制度缺失;“弱势”科技工作者群体科研付出与回报不匹配,奖励资源被“压榨”情况较严重;科技工作者科技成果转移转化奖励率低等。文章根据调查结果
期刊
摘 要:科技自立就是掌握要关键核心技术,科技自强就是能够面向世界科技前沿自主领航,基础研究是支撑科技自立自强的国之柱石。结合基础研究的分类与特点,以及我国科技发展所面临的形势和任务,针对传统路径的缺失环节,文章探索了基础研究能力提升的新路径,并提出锻造战略科技力量的建议:打造多元化、多梯度的国家战略科技力量;全面布局重大科技基础设施,夯实基础研究的物质基础;鼓励企业开展应用基础研究,构建基础研究支
期刊
摘 要:科技工作者状况调查站点是中国科学技术协会为服务基层科技工作者而专门设置的组织机构。文章通过对苏州市科学技术协会调查站点的实证研究发现,该站点在网络化治理过程中表现出结构扁平、关系弱联、治理有效的特点。其网络化治理经验表现为:网状结构形成信息倍增效应,网络化平台提升信息报送效能,考核与动态调整保持系统开放性,非正式网络促进信息交流与知识共享。与此同时,调查站点仍然存在组织性质模糊、缺乏独立性
期刊
摘 要:随着我国老龄化社会的到来,日益增长的老年读者群体成为公共图书馆开展阅读推广的重要群体。笔者通过分析公共图书馆老年阅读推广活动现状,探讨推广模式新的发展趋势和方向,满足老年读者阅读需求、丰富老年人精神文化生活,为应对老龄化社会、倡导全民阅读、构建和谐社会作出积极贡献。  关键词:公共图书馆;老年读者;阅读推广  Abstract:With the advent of an aging soc
期刊
摘 要:连续波体制雷达的发射功率可在一段时间内实现功率平均分配,发射峰值功率小、环境适应性强,因此易于结构优化、电路简单。文章在STM32架构上设计了一款24GHz 毫米波调频连续波(frequency modulation continuous wave,FMCW)雷达系统。经LabView平台仿真和实物验证,最终可生成频率为100Hz,峰值为2.56V的调频连续波。该系统由于易实现、效率高,可
期刊