电商网站的意义,突发 佛山出大事,小程序推广方式,南通五建宏业建设工程有限公司网站文章目录 背景知识teoriapitchytone效果 背景知识
学过初中物理就会知道#xff0c;声音是由空气振动产生的。振动产生波#xff0c;所以声音就是不同振幅和频率的波构成的。振幅决定了声音的响度#xff0c;频率决定了声音的音高。想更进一步了解的可以访问这个网页wavefo… 文章目录 背景知识teoriapitchytone效果 背景知识
学过初中物理就会知道声音是由空气振动产生的。振动产生波所以声音就是不同振幅和频率的波构成的。振幅决定了声音的响度频率决定了声音的音高。想更进一步了解的可以访问这个网页waveforms。
学过一点基础乐理的同学就知道标准音A4的频率是440Hz也就是说每一个音其实是由它的频率决定的。在十二平均律中一个音的八度音及高八度后的音的频率是这个音的两倍。而八度音跨了12个半音所以每个半音平均相差2的1/12次方倍。例如A4音的频率是440Hz那么B4的频率就是4402^(2/12)493.88HzA和B跨两个半音。以此类推A5的频率就是4402880Hz。
我们知道吉他的六根弦分别是E2、A2、D3、G3、B3和E4。这四个音的音高可以根据上述的公示推到出来。那么当我们知道了吉他空弦的频率我们就可以根据音频判断吉他的音高是否准确。但是有什么方法可以根据音名得到频率呢
teoria
teoria是一个轻量级且快速的 JavaScript 音乐理论库包括爵士乐和古典音乐。它旨在为音乐软件提供直观的编程界面。通过以下方法获取音频
const E2 teoria.note(E2);
const fq E2.fq();
// 82.41Hz
const name E2.toString();
// E2解决了吉他空弦频率问题那么当我们拨弦后如何根据录音得到其对应的频率呢
pitchy
我们用到pitchy这个库。这个库可以根据音频计算出频率采用了Philip McLeod 和Geoff Wyvill在文章A Smarter Way to Find Pitch设计的算法。用法如下 startRecord() {const audioContext new window.AudioContext();const analyserNode audioContext.createAnalyser();navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) {// 得到音频流this.audioStream stream;audioContext.createMediaStreamSource(stream).connect(analyserNode);const detector PitchDetector.forFloat32Array(analyserNode.fftSize);const input new Float32Array(detector.inputLength);this.updatePitch(analyserNode, detector, input, audioContext.sampleRate);});},updatePitch(analyserNode, detector, input, sampleRate) {analyserNode.getFloatTimeDomainData(input);// 得到音高频率和清晰度const [pitch, clarity] detector.findPitch(input, sampleRate);// ...// 每200ms检测一次频率setTimeout(() this.updatePitch(analyserNode, detector, input, sampleRate), 200);},得到频率后我们可以设计一个标准判定这个音已经调准了例如持续2s频率与标准频率差值小于2Hz。 updatePitch() {// ... this.delta (this.pitch - this.currentNote.fq()).toFixed(2);if (Math.abs(this.delta) 2) {if (firstCorrectTimeStamp 0) {firstCorrectTimeStamp new Date().getTime();} else {// 进度条this.correctProgress (new Date().getTime() - firstCorrectTimeStamp) / 1000 / 2 * 100;// 判定为已调准if (this.correctProgress 100) {this.correctNoteList.push(this.currentNote);this.stopRecord();return;}}} else {firstCorrectTimeStamp 0;this.correctProgress 0;}// ....
}这里我设计了一个时钟样式的进度条如下图当2s时长达到进度100%。 用到了css样式的background的conic-gradient属性可以自行了解下。 如果想再完善下我们还可以在点击某个音时播放这个音的音高。如何实现
tone
这里我使用了tone这个包。Tone.js 是一个网络音频框架用于在浏览器中创建交互式音乐。 Tone.js 的架构旨在让创建基于 Web 的音频应用程序的音乐家和音频程序员都熟悉。由于直接使用默认方式的效果并不是吉他我这边在另一个网站找到了这几个音的mp3音频作为输入代码如下
playPitch(note) {this.sampler new Tone.Sampler({urls: {e2: e2.mp3,a2: a2.mp3,d3: d3.mp3,g3: g3.mp3,b3: b3.mp3,e4: e4.mp3,},baseUrl: IP,}).toDestination();Tone.loaded().then(() {this.sampler.triggerAttackRelease(note.toString(), 1);});
},效果
链接https://hougiser.gitee.io/music-score/ 欢迎沟通