做个小钢琴~利用AudioContext获取振荡器并封装成光遇钢琴的样子
如果想做一个网页端的小钢琴,可能最先想到的都是用很多个video标签,js直接控制这些video的播放和暂停,不过不仅很麻烦要录制每个琴键的声音,多个按键同时按下同时播放的兼容性也很拉
既然确定了不用video,那自然是用AudioContext
创建一个音频上下文了。让我们看一下MDN中怎么介绍AudioContext
:
AudioContext
接口表示由链接在一起的音频模块构建的音频处理图,每个模块由一个AudioNode
表示。音频上下文控制它包含的节点的创建和音频处理或解码的执行。
好嘛,还挺难懂。简单地说,AudioContext
创建了一条无限长的时间轴,时间轴上分布着声音信息(可以理解为频谱),并且不可以停止。我们可以通过时间点改编这些信息,从而控制频率、音色等等。
认识AudioContext
那么就来看看AudioContext
:
构造方法:直接new,接受一个参数,一般不写参数,默认就可以了
注:必须存储音频源。有 3 种主要类型的音频源。
- 振荡器: 用于产生数学计算的声音,今天的钢琴就是用振荡器
- 音频样本: 从各种文件中获取音频
- 音频流: 从网络摄像头或麦克风获取音频
属性:继承BaseAudioContext,里面比较常用的有:
属性 | 意义 |
---|---|
currentTime | 当前时间 |
state | 当前状态 |
desination | 音频播放的扬声器 |
控制音频的部分方法:
属性 | 意义 |
---|---|
AudioContext.close() | 释放AudioContext控制的资源(比如扬声器)可以理解为停止 |
AudioContext.createMediaElementSource() | 控制与标签 |
AudioContext.createMediaStreamSource() | 处理麦克风 |
AudioContext.createMediaStreamDestination() | 处理本地文件 |
AudioContext.createMediaStreamTrackSource() | 跟踪media stream |
AudioContext.getOutputTimestamp() | 返回时间戳 |
AudioContext.resume() | 暂停后的播放 |
AudioContext.suspend() | 暂停(有人翻译做挂起,不过suspend也有暂停的意思,应该更合适一些) |
于是我们可以构建出来一个利用AudioContext
的播放链:
开始播放new AudioContext => 暂停AudioContext.suspend()=> 继续播放AudioContext.resume()=>停止AudioContext.close()
并且用AudioContext.currentTime控制播放时间
获取音频源
我们之前已经提到过,AudioContext
必须要有音频源,接下来有一些定式的操作,获取音频源:
createGain()
AudioContext.createGain()
也是AudioContext
的一个方法,创建一个GainNode,控制音频的总音量
1.绑定扬声器
我们要将他绑定在一个扬声器上。使用connect
方法绑定扬声器,我们就绑定默认扬声器connect(AudioContext.desination)
2.设置音高
直接Gain.value就好了
3.动态修改音高linearRampToValueAtTime()
gain.linearRampToValueAtTime(0.6,AudioContext.currentTime + 0.01)
//在0.01s内从音高从value值变到0.6
这里提一点,linearRampToValueAtTime的参数中第二个是一个时间点,表示从现在这个点到参数中的时间点内修改音高。
综上,我们创建好了一个舒舒服服的AudioContext(似乎并不舒服)
我们获取了一个AudioContext,但只有一个AudioContext有什么用(嫌弃)
我们来给他绑定音频源。因为要做钢琴,肯定是绑定振荡器了
振荡器
振荡器由createOscillator
方法构造AudioContext.createOscillator()
即可创建。
创建完之后,需要连接上文创建的Gain,否则没有音量控制器,不会出声。连接用connect
方法,非常容易:
Oscillator.connect(Gain)
振荡器的属性type,代表了音频的波形,有这几个参数:
- sine:默认值,正弦波
- square:方形波
- sawtooth:锯齿波
- triangle:三角波
除此之外的属性frequency.value
代表了声音的频率,确定了波形和频率,即可确定某个声音。
在这里补充一下乐理基础:
- 频率为波形的一个最小重复单元的长度,单位为Hz
- 第一国际音高为机械波440Hz,对应中音la,高音la为440折半,220,低音la为880(这里的高和低特指的是高八度和低八度),不过纯数字算出来的频率会让人听上去音调偏低
- 按照第一国际音高,从低8dao,到高8dao的频率约等于[130,147,165,175,196,220,246,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1047](加粗标出了基准点)
有了频率,我们就能直接获得声音了。让我们先写几个最简单的练练手:
var son1=new AudioContext();
//创建AudioContext
var osc = son1.createOscillator()
//创建音频振荡器
var g = son1.createGain()
//获得音量控制器Gain
osc.connect(g)
//振荡器连接Gainosc.type = 'sine'//设置波形osc.frequency.value = 440//设置频率为440Hz,即中音la
g.connect(son1.destination)
//连接扬声器
g.gain.value = 1
//初始音高为1
osc.start();
//从时间轴的此时此刻当前开始发生
直接执行这段,会是一个非常刺耳的无限长的laaaaaa—————,我们再加一个截止时间
var stoptime = 1
osc.stop(stoptime);
就只响一秒了。
到这里就已经基本结束了(大概),我们来封装一下:
JS Bin - Collaborative JavaScript Debugging
代码都放这里啦
(对!就是光遇哈哈哈哈哈哈哈)
做个小钢琴~利用AudioContext获取振荡器并封装成光遇钢琴的样子相关推荐
- 通达信行情数据获取--python_利用 Python 获取余额宝历史收益数据
最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...
- 利用 Python 获取余额宝历史收益数据
最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...
- php取网盘真实链接,利用蓝奏做个人小文件网盘和获取真实下载地址
原标题:利用蓝奏做个人小文件网盘和获取真实下载地址 之前已经有人分享过蓝奏云盘直链获取教程和源码,但是或已经失效,或只能用于电脑. 按照之前网友分享的思路,对蓝奏的手机端页面进行分析: 分享的网盘链接 ...
- python做一个小游戏_利用python做个小游戏
从本期开始,我们将利用几天的时间用python来做个小游戏,当然,在做小游戏之前,我们必须学会一个做小游戏的第三方库--pygame.可能有人会说,python不擅长或者说不适合用来做游戏,的确是这样 ...
- 微信小程序利用云函数获取小程序码(二维码) 将buffer流转换为图片
最近在做毕设,有一个获取小程序码绘制分享海报的需求,因为需要小程序码的数量较多的业务场景,所以只能采用后端生成返回给前端调用或者云开发调用. 生成小程序码的两种方式 HTTPS调用 需要后端生成返回给 ...
- 【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音
根据钢琴音调频率对照表,使用sin函数构造对应频率正弦波数据模拟各琴键声音,实现简易钢琴效果,结果写入wav文件中. 目录 程序效果 实现过程 样例代码 测试用例 参考资料 程序效果 截图1:键位图 ...
- php 动态多维数组长度,怎么在php中利用count获取多维数组的长度
怎么在php中利用count获取多维数组的长度 发布时间:2021-01-05 16:38:55 来源:亿速云 阅读:80 作者:Leah 今天就跟大家聊聊有关怎么在php中利用count获取多维数组 ...
- 小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)
小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像) 微信小程序生成特色头像,海报等是比较常见的.下面我来介绍下实现该类小程序的过程. 首先选择前端来通过 canvas 绘制.这样比较节 ...
- 微信小程序利用echarts实现中国任意行政区域地图
微信小程序利用echarts实现中国任意行政区域地图 前言 实现 克隆代码 集成 点击事件 点击跳转 代码改造 尾巴 前言 最近微信小程序中需要绘制地图,然后点击地图可以跳转到下一层级.研究了一番,选 ...
最新文章
- mac mysql5.7 my_【mysql】Mac下安装mysql5.7 完整步骤,大坑已解决
- Mysql中对table的操作问题
- 计算机office软件改为中文,计算机预装正版Office如何更改为64位程序
- Java实现的有道云笔记图片批量下载工具
- Ubuntu 查看磁盘空间 及目录容量
- 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。...
- 一文搞懂 Spring JPA
- 如果有什么想不开或者放不下的话,看看这里吧!(摘于网络)
- android mvvm_Android MVVM设计模式
- 一招教你解决Rational rose画时序图(Sequence diagram)时找不到参与者(Actor)的尴尬现场
- docker修改服务器防火墙,docker宿主机iptables配置
- 老罗如果输了整个民族都输了
- jQuery(简介、特点、使用方法、【重点】jQuery的选择器:是jQuery的灵魂、jQuery的属性:操作标签的属性)
- INO(Initial NFT Offering )
- php 反垃圾评论,php-无需使用验证码即可阻止评论垃圾邮件
- 【数据结构】栈的简单理解以及对栈的基本操作
- python kmean 多维_绘制多维Kmeans集群NLP python
- android 联通时间同步,NTP时间同步技术在中国联通信息化中的应用
- php银行卡账户类型查询接口
- 无源域适应(SFDA)方向的领域探究和论文复现(第一部分)
热门文章
- java字母反过来_java实现字符串(数字、字母、汉字)的反向输出
- java 订单管理的项目流程,基于jsp的订单管理系统-JavaEE实现订单管理系统 - java项目源码...
- 【实验三/四 面向对象程序设计/语言基础与面向对象】
- Ubuntu 16.04 ZR300驱动安装
- Socket编程--自己动手的HTTP代理服务器
- 直播平台源码搭建教程直播原理与web直播实战
- #2摄影测量学—基础概念和透视变换
- 计算机网络联网方法实验报告,计算机网络实验报告报告方案.doc
- [article][几米的画]寂寞的样子
- 洛谷1462 通往奥格瑞玛的道路 二分+spfa