如果想做一个网页端的小钢琴,可能最先想到的都是用很多个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代表了声音的频率,确定了波形和频率,即可确定某个声音。

在这里补充一下乐理基础:

  1. 频率为波形的一个最小重复单元的长度,单位为Hz
  2. 第一国际音高为机械波440Hz,对应中音la,高音la为440折半,220,低音la为880(这里的高和低特指的是高八度和低八度),不过纯数字算出来的频率会让人听上去音调偏低
  3. 按照第一国际音高,从低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获取振荡器并封装成光遇钢琴的样子相关推荐

  1. 通达信行情数据获取--python_利用 Python 获取余额宝历史收益数据

    最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...

  2. 利用 Python 获取余额宝历史收益数据

    最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...

  3. php取网盘真实链接,利用蓝奏做个人小文件网盘和获取真实下载地址

    原标题:利用蓝奏做个人小文件网盘和获取真实下载地址 之前已经有人分享过蓝奏云盘直链获取教程和源码,但是或已经失效,或只能用于电脑. 按照之前网友分享的思路,对蓝奏的手机端页面进行分析: 分享的网盘链接 ...

  4. python做一个小游戏_利用python做个小游戏

    从本期开始,我们将利用几天的时间用python来做个小游戏,当然,在做小游戏之前,我们必须学会一个做小游戏的第三方库--pygame.可能有人会说,python不擅长或者说不适合用来做游戏,的确是这样 ...

  5. 微信小程序利用云函数获取小程序码(二维码) 将buffer流转换为图片

    最近在做毕设,有一个获取小程序码绘制分享海报的需求,因为需要小程序码的数量较多的业务场景,所以只能采用后端生成返回给前端调用或者云开发调用. 生成小程序码的两种方式 HTTPS调用 需要后端生成返回给 ...

  6. 【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音

    根据钢琴音调频率对照表,使用sin函数构造对应频率正弦波数据模拟各琴键声音,实现简易钢琴效果,结果写入wav文件中. 目录 程序效果 实现过程 样例代码 测试用例 参考资料 程序效果 截图1:键位图 ...

  7. php 动态多维数组长度,怎么在php中利用count获取多维数组的长度

    怎么在php中利用count获取多维数组的长度 发布时间:2021-01-05 16:38:55 来源:亿速云 阅读:80 作者:Leah 今天就跟大家聊聊有关怎么在php中利用count获取多维数组 ...

  8. 小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)

    小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像) 微信小程序生成特色头像,海报等是比较常见的.下面我来介绍下实现该类小程序的过程. 首先选择前端来通过 canvas 绘制.这样比较节 ...

  9. 微信小程序利用echarts实现中国任意行政区域地图

    微信小程序利用echarts实现中国任意行政区域地图 前言 实现 克隆代码 集成 点击事件 点击跳转 代码改造 尾巴 前言 最近微信小程序中需要绘制地图,然后点击地图可以跳转到下一层级.研究了一番,选 ...

最新文章

  1. mac mysql5.7 my_【mysql】Mac下安装mysql5.7 完整步骤,大坑已解决
  2. Mysql中对table的操作问题
  3. 计算机office软件改为中文,计算机预装正版Office如何更改为64位程序
  4. Java实现的有道云笔记图片批量下载工具
  5. Ubuntu 查看磁盘空间 及目录容量
  6. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。...
  7. 一文搞懂 Spring JPA
  8. 如果有什么想不开或者放不下的话,看看这里吧!(摘于网络)
  9. android mvvm_Android MVVM设计模式
  10. 一招教你解决Rational rose画时序图(Sequence diagram)时找不到参与者(Actor)的尴尬现场
  11. docker修改服务器防火墙,docker宿主机iptables配置
  12. 老罗如果输了整个民族都输了
  13. jQuery(简介、特点、使用方法、【重点】jQuery的选择器:是jQuery的灵魂、jQuery的属性:操作标签的属性)
  14. INO(Initial NFT Offering )
  15. php 反垃圾评论,php-无需使用验证码即可阻止评论垃圾邮件
  16. 【数据结构】栈的简单理解以及对栈的基本操作
  17. python kmean 多维_绘制多维Kmeans集群NLP python
  18. android 联通时间同步,NTP时间同步技术在中国联通信息化中的应用
  19. php银行卡账户类型查询接口
  20. 无源域适应(SFDA)方向的领域探究和论文复现(第一部分)

热门文章

  1. java字母反过来_java实现字符串(数字、字母、汉字)的反向输出
  2. java 订单管理的项目流程,基于jsp的订单管理系统-JavaEE实现订单管理系统 - java项目源码...
  3. 【实验三/四 面向对象程序设计/语言基础与面向对象】
  4. Ubuntu 16.04 ZR300驱动安装
  5. Socket编程--自己动手的HTTP代理服务器
  6. 直播平台源码搭建教程直播原理与web直播实战
  7. #2摄影测量学—基础概念和透视变换
  8. 计算机网络联网方法实验报告,计算机网络实验报告报告方案.doc
  9. [article][几米的画]寂寞的样子
  10. 洛谷1462 通往奥格瑞玛的道路 二分+spfa