SAM格林:你好,大家好。 欢迎来到我们的研讨会。 我叫山姆。 休·扎布里斯基:我休。 SAM格林:我们今天要谈 关于JavaScript和Web音频API。 刚开始出来,这是一个大纲 我们的研讨会议程。 我们将先来谈谈 为什么你应该有兴趣的网站 音频API,这是为什么的JavaScript 你需要它的语言, 再谈谈的JavaScript essentials--这么喜欢, 指导您完成一些 语言的基本知识, 再谈谈 在较高水平的音频的API。 然后,休将谈论一些 音频制作的阶段 然后演示该真棒序 项目他建立并显示你的代码。 然后,我们将有时间 在最后的人的问题 谁在这里居住。 休·扎布里斯基:酷。 SAM格林:酷。 休·扎布里斯基:酷。 我将备份。 SAM格林:那么,首先第一件事情。 所以,伟大的事情之一 关于网络音频API 是,有不需要的设置。 它配备内置在 大部分现代浏览器, 包括Chrome浏览器,封边,整体 一堆others--所有的人 那大部分 人们今天使用。 所以没有成立, 除了刚开 Web服务器去,为 你就可以开始工作 您的项目,这是伟大的。 我们建议漂亮 巨资您考虑 使用Chrome浏览器 JavaScript的Web开发, 只是因为它的开发者 工具是真正的强者。 由于正是我们所说的一个例子 说打开你的JavaScript console--如果你去到Chrome浏览器 而且你看任何网页, 你左击 检查元素,然后 你去这个小下拉 在这里,你点击控制台, 你会看到打开了看起来 很多喜欢在命令提示符下,你 在你的Mac可能会看到,或者在标识。 就这样,我们就可以 输入命令在这里,就像清除, 和其它命令那样。 我们可以创建变量,如 我们将在JavaScript中看到。 所以什么我们可以做的 JavaScript中,我们可以通过控制台执行, 这就是一个超级方便的方法 开始的API玩弄 并获得舒适 JavaScript的了蝙蝠的权利。 无需成立, 这是非常好的。 凉。 真棒。 所以,只是一件事的补充。 如果您有任何questions--有 你们中许多人谁不住在这里, 随时以电子邮件us--这些 是我们的电子邮件地址。 如果您有问题 你不想问我们, 就像,哦,我有一个bug 在我的代码,或东西 这是一个更具体一点, 也许首款谷歌它。 有很多伟大的资源 关于网络音频API在那里。 这是真的很好 记录和它的存在 使用一吨的人 工业和人谁是刚刚 建立有趣的东西留给自己。 所以应该有很多 资源在那里。 真棒。 酷,那么,为什么网络音频API? 此图是一点点 的使用方法的演变 声音在网络上在持续增长。 BGSOUND像原始的HTML标签 Internet Explorer使用的支持。 它只能用于非常基本的声音, 功能不是很强大的, 你不能这样做 复杂的排序, 或控制时,声音开始 停了下来非常强劲。 所以,这不是特别 发达。 那之后,闪存 来到along--其中, 我敢肯定,你们都熟悉 与Flash--也许不是它是如何工作的, 但你肯定看到了。 你必须更新您的Flash 插件,所有的那种东西, 那肯定扩大了范围 功能是可用。 但是,让用户安装 插件是肯定 一个缺点,包括Flash 在应用程序中,对不对? 因为那时你依赖 用户会并发现这个插件, 而且很可能被打开 关闭的这个额外的步骤 他们要好好利用您的应用程序。 然后可能有一个更新 那会破坏你的整个应用程序, 并且它最终是一个梦魇 对于开发者也。 所以这是一个路障。 并在那之后走过来, 在HTML音频标签, 是更现代的HTML--一种特性,它 当然允许有更多的东西, 但即使是事情可以做 有一点点有限的刚 作为事情的结果 该HTML是可以胜任的。 所以当JavaScript的 API时,网络音频的API, 成为标准 跨浏览器的做法, 真正扩大了集 对开发者的机会 真正进入建设 很酷的东西的网页。 很长一段时间曾有 一直很强大的工具 原生音频应用, like--殊不知GarageBand中, 然后明明有更 专业音频混合应用, 而这样的东西。 但是,没有一个 真正的好Cloud--不 云计算,是啊,我猜 Cloud--基于网络的平台 这将让开发者 构建人申请 做混音。 当他会告诉你 后,网络音频API 允许真厉害 东西发生真正简单, 这是很酷。 所以这是该指令,你为什么 应该注意研讨会的休息, 基本上。 而现在,我要谈谈 一些JavaScript--只是基本要素 的语言,以便 我们可以将在同一页上 当我们谈论的 API有点晚。 凉。 所以,这是一个概要。 我忘了这是在这里。 是啊。 休·扎布里斯基:有两个幻灯片在这里。 SAM格林:这是汇总 的一些限制 其他具有约束力,老办法。 然后现在,我们有这些东西。 凉。 真棒。 因此,JavaScript的要领。 首先第一件事情,有一个 漂亮显著差异 在JavaScript与在 像C语言,在路上 该变量的创建。 因此,在C,我们已经习惯了有 输入我们的变量,对不对? 我的意思不是喜欢的类型 键入这些,我的意思是类型 就像给它们分配一个类型 - 意思 就像,一个int,一个float,一个char。 在C语言中,我们真的用 不必创建一个变量 然后坚持这种类型的 我们使用该变量整个时间。 并且不一定是差, 但它可能很难使用。 其中一个很酷的功能 JavaScript的是 该变量是什么所谓 “动态类型”,这 意味着我可以创建一个 与语法的变量, VARx前提等于5,例如。 这种独创 一个整数变量 - 正下方 引擎盖somewhere--但我 可以改变的变量 指一个串 没有做任何事情一样 创建一个新的变量。 我不需要担心 有关类型变化。 JavaScript的人都知道类型的 改变,并且动态地发生这种情况。 所以,有优惠 而缺点是, 谁在担任人 JavaScript的一段时间可能知道。 有些时候, 你可能会意外地 改变一个变量的类型和 不处理这种类型的变化, 然后你的JavaScript 可以crash--或异常 被抛出,因为你将有 错误的类型,当你想到一种类型。 凉。 因此,scoping--这就好比,如果我们 记得最初几周在使用过程中, 指的是如何看见一个变量 是和在代码的什么区域。 所有这一切看起来非常相似, 它看起来C.方式 所以变量一般范围 在一个函数中大括号内, 然后还有 全球范围的变量 are--如果你写一个变量 一个功能以外, 这将是在整个文本中可见。 之间的一个区别 的JavaScript和C,特别是 是,如果你声明一个全局 在文本文件中变量的任何地方 它在任何函数可见 内的文本文件。 这是正确的,对不对? 休·扎布里斯基:是的。 SAM格林:所以这也是一个小 位时髦相比,C, 我们一直有我们的 上述地方变量定义 他们使用。 这不是真实强制一条规则 了,所以,有一点点不同。 而且目的也只是再次强调, 全局与局部variables-- 非常类似于C.你可以有 两个变量具有相同名称, 并有他们的一个名字被隐藏 由一个局部变量,如果其中一 是全球性的。 因此,类似那种 的问题,你们中的一些 可能已在一些碰上 您的问题至今集。 酷,所以这是变量。 控制流程,意思一样, 如果-else--逻辑stuff--和循环。 所以下手,这就是的if-else 声明看起来像在JavaScript中。 的各种事物的位置 上的线并不重要。 这只是其中一项公约 为方式,我们的结构代码。 就像在C,我们有一个 “的话,”一个括号声明。 这不是我的意思做。 我再次做到了。 休·扎布里斯基:试图退出? SAM格林:不,我 只是想进行放大。 不要紧 因此,我们有一个“如果”语句,并 我们有一个条件在它的内部 计算结果为真或假, 并且确定是否 我们进入代码块。 同样地,我们有一个else-if和 一个else,就像我们在C.使用 你也应该很舒服 马上与循环蝙蝠, 因为他们也期待 很像C相。 但是,你会再次发现,我们 有不是int初始化, 我们有变种的初始化。 我猜你有 要小心,使 确保您不会更改值 我从一个int为字符串, 例如,因为那将 导致怪异的行为,你可能不 期望。 但是,这应该是 很熟悉,也是如此。 因此,这就是事情开始 得到一点点疯狂的JavaScript 人谁是从去 C的背景有功能 在JavaScript中,并有一个办法 声明函数,看起来 排序的类似于C,和 然后还有另外一个, 看起来种不同。 第一个版本, 我们可以在这里看到, 是一种类似C,其中, 我们说,这是一个函数, 给它一个名字,给 参数的数量, 的功能,然后将内容 去那些大括号内。 我们将看到的一个例子 在短短的第二个参数。 而在下一行,我们看到,哦, 这里有一个变量叫“myFunction的,” 我们等于给这 通用件事 - function--的 似乎没有有什么事情。 之所以说是不同的 比C是JavaScript的 是所谓功能性语言, 或具有功能元件,这意味着 其功能实际上是价值观。 这意味着,我们可以设置 一个变量等于一个功能 然后移动的功能 各地,把它作为一个参数, 做各种东西, 像与功能。 另一件事note-- 函数都写 具有一定数目的参数。 我们将看到一个函数的例子 对下一张幻灯片的参数。 但是,JavaScript就无法 骂你,如果你尝试 使用带有一个功能 错误的参数数目。 它只会尽力让 这样做,这意味着如果你通过了, 你调用一个函数需要一个 不带参数,所有的说法, 会发生的事情是,它会尽力 尝试并执行该代码, 并且如果最终运行 到一个异常或错误, 它会抛出异常,只是不停 going--这只是的方法之一 该JavaScript的工作。 是啊。 听众:如果发生了什么 有太多的争论? SAM格林:所以 问题是,会发生什么 如果有太多的争论? 得到的答复是, JavaScript的只是 忽略那些是 之后,那些预计。 它会尝试执行功能 称,如果它只是前两个。 对? 休·扎布里斯基:是的,是的。 同样地,如果有 太少的参数, 正中下怀它给空所有 参数它不具有任何值 对于。 SAM格林:可 其实很方便,如果你 想要写一个函数, 采用可变数量的参数。 您可以设置默认值 的函数的定义, 而且它也可以忽略的事实 该输入的不存在。 所以,我想谈一点点 更多关于这最后一颗子弹 点,这是功能值。 这是一个例子,是 有点令人兴奋 如果你只是读它,不要以为 这是怎么回事就一秒钟。 那么,让我们来看看刚刚在 这里的第一行。 我们有这个变量,F1,我们说 是一个函数,做这件事情。 和功能的内容 被CONSOLE.LOG('你好')。 你能想到的console.log作为中 JavaScript的等效printf函数。 所以会发生什么,如果我们 在我们的浏览器运行这段代码, 它会打印出一个字符串。 我可以证明这一点。 听众:通过日志,但是,这是否 意味着它是被记录的地方? SAM格林:是的。 所以,我会告诉你发生了什么事情要发生。 所以现在的问题是,是什么日志是什么意思? 休·扎布里斯基:所以的console.log 就像printf进行C. SAM格林:那么的console.log 是如printf, 所以,如果我有这样的console.log('你好'), 我称之为,字符串“hello” 被打印到控制台。 这是控制台。 这就像printf的,在这里 它打印到标准输出。 我们会在一分钟内看到, 但其实这是 参照控制台对象, 并调用对象的方法。 这会更有意义 在一分钟的时候,我们 去谈论 在JavaScript对象, 但我想我只想提及。 休·扎布里斯基:我们 在C中使用,right-- 我们平时写一个大的程序 在主做任何事情。 但是,什么是很酷的JavaScript是你 有这样的解释说 运行在实时,所以它 通过线仅需线, 它可以只解释了当场。 它跟踪 之前已经运行的东西, 所以这是一个非常有用的工具 使用的console.log,或控制台, 通常,对于刚刚打 周围的JavaScript。 SAM格林:那么回到这个 example--代码的第二线 这里是非常令人难以置信的在我的脑海。 我第一次读到这一点, 这就像,这是怎么回事? 那么是什么发生的事情是,这 函数声明说, 我有一个功能叫做F2 该公司预计,有一个参数,女, 然后调用 函数f,其 传递给它作为参数 不带参数本身。 所以,这可能是令人困惑的。 如果我们了解这是F2采用F1 作为参数,然后F2内, ˚F得到called--此装置 这行代码, 这两条线后, 码,结果在“你好” 被打印到控制台。 我们可以通过这一事实 围绕功能作为值 最终被一个最 JavaScript的强大功能 作为一种编程语言。 所有的外 真棒的事情可以做, 正如的一个特征 在的方式而言语言 它使事情变得简单 编程,并允许 对于事情是不是特别 非常适合的网络, 函数式编程和功能 的JavaScript编程方面 是一个最 强大的概念, 在JavaScript--存在,如果你问我。 凉。 所以,接下来的事情。 除了是功能性的, 还有的JavaScript元素 这是面向对象的, 这是的极一 流行的时髦词在计算机科学。 面向对象编程 是一个非常流行的东西。 JavaScript有一个版本是, 在那里我相信每一个价值也 一个对象,这意味着每个对象 包装在一起值的一些数字。 因此,对于值是简单的,像 的整数,像VARx前提等于5, 该对象只是包装的一个值。 但是,我们也可以设想一种情况 where--我们可以想想C中的情况下, 我们想要做的 一些与结构, 例如,一个包装数 值加在一起,使 它很容易通过周围的事物。 这时候,一个对象是在JavaScript中。 重要的是要记住很重要 当我说的物体包裹 一些值的数量一起, 该功能也 值,这意味着函数可以 也可以是JavaScript对象的内部。 这是很重要的原因 是这样的,而我们常 想调用的方法 一个对象,它是在 从其他一个流行术语 流行的面向对象的语言, 的区别之一在这里的是, 所有的方法是在JavaScript 被存储的对象的内部的值 这可能执行一些action-- 使用其他值是内 该对象的,但不一定。 所以你可以想像一个情况,我 猜在一个疯狂的方式一点点, 在那里你叫了一个方法 对象在另一对象,例如。 所以,这是一个有点古怪的那样。 而且你还可以改变方法 了与某个对象相关联 通过分配的方法 新功能,这也是 从其他相当不同 面向对象的语言,在这里 一旦我们声明一个对象 并创建实例, 我们不能改变的是方法 与该对象不再相关联。 所以,这是相当不同的。 凉。 因此,这里有一个例子,首先, 在动作中的对象。 这就是被称为 一个通用的对象, 意味着它不具有任何 具体名称,不具有类, 它的价值只是一些包装。 这看起来是这样,我们有 此外对花的牙套这里 指示给JavaScript 说,这是一个目的。 它里面的值 在里面的每个值 对象应 被包裹起来。 与该对象的内部, 然后,我们有键值对, 其中的关键是指名称 物体内的值的, 另side-- 结肠这里 - 相反 是实际值 应当被存储。 所以,你在这里看到,我们有一个 关键称为FN与价值SAM, 其次是一个逗号, 话说到下一个条目。 然后,一个叫LN关键, 有一个绿色的价值, 其次是一个逗号, 其次是“印” 这将有一个函数值 那会做这行的代码。 让我们退后一步, 解开什么是怎么回事。 所以这是一个有点复杂, 和我们看到新的东西 首次。 而“这个”关键字是新事物 我们看到在这里,这是什么呢 是,是指当前 对象范围,对不对? 所以,当我们说,这 点回来的路上 这整个object-- 当我们做this.fn, 我们将一路回去 这个对象,到FN值 并获得SAM,把它所有的方式 回来了,把它贴在这里,然后继续前进。 听众:因此,与检索,是 因为参数的做完 定义? SAM格林:所以现在的问题是,是 因为参数的检索完成 定义? 是的,绝对。 这是怎么回事在这里发生的是, 这点说给JavaScript, 好吧,我得到一些价值 从我自己这个对象。 然后它会寻找一个条目 所谓的FN,如果它发现它, 它会返回value--是这样,它的SAM。 但是,我也可以键入 这是不是在这里定义的东西, 然后它只是 返回undefined--这 是一个东西,JavaScript可以 这样做,它也有一些好处, 但它的also--如果你犯了一个错字, 它会导致奇怪的错误。 因此,它会只是试图找到 不管你告诉它找到 而且它不会 抱怨,如果没有找到它。 它只想说,我没有 找到它,然后继续前进。 因此,这将是不确定的, 加空白,再加上姓氏。 是啊。 然后我们可以看到,如果我们 可以再下去access-- 我们呼吁tf.print()括号。 这将调用打印 不带参数的功能,对不对? 但是,如果我们刚才说tf.print() 分号,没有括号, 所有可能做的就是拉 从该值的功能, 但实际上没有把它称为。 凉。 休·扎布里斯基:宜 我们做一个对象? SAM格林:是的,让我们做到这一点。 因此,我可以将这个 例如控制台。 我们可以想像,我有一个对象。 因此,这是一个简单的对象。 这是一个对象,包含两个 有两个键的值,两个关键的价值 对。 所以,我就可以访问存储的价值 这个对象做x.x1内, 例如,我也得到1回。 同样,x.x2,拿到值回。 而现在的很酷的事情是,我可以 实际上添加的东西到该对象 我已经创造了它之后。 所以你可以想象,让我们 说我有一个功能。 休·扎布里斯基:你 要做按住Shift-Enter键。 SAM格林:哦,这很烦人。 那有什么不一样? 哦。 开始了。 凉。 所以,我刚才创建 这个函数f,即 是要去到目前 对象和打印this.x1。 所以,如果我只是调用F通过 本身,没有什么是怎么回事 发生的,正确的,因为没有X1 场中它指的是对象。 但是,如果我说,x.f = F,然后我 调用x.f(),我要拿回1。 也就是说f函数是现在 与对象x关联, 其中有一个关键称为X1 用值1相关联的, 所以当我们调用this.x1,它的 要查找的寻找 和能够打印的值出去。 所以,这只是一个例子 那种疯狂的事情 您可以在JavaScript对象做。 因此,该版本是 通用版,意义 我们已经创建了使用该对象 括号notation--括号符号, rather--这就是 如果我们只是想方便 特定对象的一个​​实例,但 如果我们希望有一个以上的是什么 的同一种? 和这个问题的答案 问题是,有事情 所谓的类在JavaScript中也是如此。 我们可以创建一个函数, 做某种形式的初始化 为异物, 我们会说,喜欢, 我的分类 - 这样的名字 可重复使用的object--的 等于功能设置起来。 那么,这将是等同 要创造一个对象, 将只是喜欢, 大括号,STR,结肠, 这是一个字符串, 分号,大括号。 这将是通用 我们初始化对象, 与一个区别在于对 下一行,我们创建了一个原型,这 意味着它是一个默认的键 我们加入到我们的对象, 在这里有列出的值。 意思是说,当我创建一个新的 此MyClass的实例对象, 这将有预建的内 它的值称为海峡和另一个值 叫myPrint,这是 将是一个函数。 真棒。 大。 因此,最后一件事 说关于JavaScript 是,它是什么真正有用的 被称为异步操作。 异步意味着我们 可以等待一些操作 完成之前,我们将 ,但在我们等待继续前进 再有事情发生以后。 而我的意思是,你 可以想象的情况下 你发送一个请求 某些网络服务器的地方, 并且它会送你回 一些数据大块,对不对? 并且用户可以等待在 同时要做到这一点, 并没有什么可以 事情在那个时候。 但是,这不是一个伟大的设计,对吧? 你不想在网页冻结。 如果什么用户想要 点击下拉菜单? 这是不是一个伟大的设计模式。 相反,基本上是什么 JavaScript本身是说, OK,异步执行此操作。 于是想,等的背景下, 然后当操作完成后, 调用回调function-- 调用一些功能, 做一些action--信号的 操作我们在等待结束 结束了。 这就是超级强大的理由是, 我们可以做一些事情,传递参数, 做一些事情,然后等待 事情发生。 然后,一旦某事 完成后,我们可以调用一个回调。 这是非常方便的,因为它可以让 我们做的事情与网络音频API, 例如,像负载的 从远程服务器的音频文件 而不必等待 整个音频文件被加载, 这将是真的 糟糕的用户体验。 凉。 最后夫妇注意到有关 调试,因为这 是你不得不做的事 作为项目的一部分,有保证。 我提到的JavaScript控制台。 这是一个非常有用的功能 所有现代浏览器, 我们真的希望您积极地 舒适的使用您的控制台, 如果你想获得擅长的JavaScript。 这是超级方便的 调试,但它也 为搞清楚真正有用 如何使用API​​。 它允许真 简单的实验 无需键入一些 代码,然后编译它。 你不必做的所有这些步骤。 你可以只写 一些代码成一条线, 然后得到即时反馈 不论该行代码 worked--非常方便。 而且,只是一个技术note-- JavaScript控制台是一个例子 一个REPL--所以这是R-E-P-L,REPL的, 它代表读,评估, 打印循环。 你要输入一些东西 在,它会读取你键入的, 它会评估它,它会打印 输出,然后它会重新开始。 这可以让你快速进入 圈迭代,这是真的很酷。 我想真正的最后note--这 是实际的最后一个音符,是的。 我们如何真正使用JavaScript? 因此,首先,我们可以导入 使用脚本标记它 在一个HTML的顶部或底部file-- HTML文件的内的任意位置, 真。 而script标签内,也有 两个子方式进口的JavaScript。 第一个是由具有 独立的JavaScript文件 我们进口的全部内容,或 由具有像脚本代码的区域 开始,然后 反斜线脚本结束。 然后,我们只是写 JavaScript的HTML文件中。 这些都是两种方式。 你不能HTML里面有它。 听众:是其中一个比另一个更好呢? SAM格林:问题是, 比其它更好。 所以,是的,作为一个编码风格的做法, 而且它像一个设计实践。 有两个原因 为什么它可能会更好。 第一个是,它使你的代码 很多更具可读性,如果所有的HTML的 是在一个地方,所有的CSS是在 另外一个地方,所有的JavaScript 处于第三位。 对? 我认为,我们应该已经讲过 关于它在sections--像CSS--什么 这is--和它去 常在另一个文件。 因此,相似类型的概念在这里。 你也可以想像的JavaScript 将在一个以上的重复使用 HTML页,或者一个 许多HTML页面, 并具有JavaScript的 重构为一个 文件可以导入 一成多的地方 允许代码是 这样更易于维护。 你可以想象使一个 改变给JavaScript 而不必更改它 在100种不同的文件。 相反,我们可以直接改变它 在一个,这是道路更加强大。 难道我回答你的问题? 凉。 我们还可以输入到调音台, 正如我们之前提到过。 再次,最后一个note-- 网络音频是内置的, 不需要加载任何东西。 凉。 是否有任何问题,你有没有 关于JavaScript的任何问题, 之前,我们继续前进? 听众:[听不清] SAM格林:好吧,冷静。 所以,现在他要谈的API。 休·扎布里斯基:酷。 谢谢,山姆。 SAM格林:当然。 休·扎布里斯基:真棒,所以 我们将通过JavaScript前进。 因此,我们已经谈了一些 JavaScript的要领, 而这些都是变量,函数, 对象,函数变量, 异步加载。 这些都是所有的东西,你会 看,所使用的网络音频。 因此,我们要好好谈谈 关于它首先在一个较高的水平。 这是一个API,所以它的东西 这是内置,如山姆说, 对进入的JavaScript 您在控制台中使用。 它实际上就像C ++代码 这是真的内置Chrome浏览器 和Firefox,而所有这些浏览器。 因此,与网络的主要思路 音频是,你有 这种管道音频的,对不对? 所以你的音频数据 进来以某种形式。 有一种三个主要forms-- 你有振荡器,它 创建一个正弦波,余弦波, 我们将看到如何工作的。 另一种非常常见的一种, 当然,是一个MP3。 因此,也许你开始 一首歌曲,然后你 想要做一些过滤 该输出 that--这可能是一个可能来源。 然后一个非常酷 一个是麦克风。 所以,你可以使用一些很 在JavaScript的基本通话费 以访问的 麦克风,并且因此,如果您 想使一个应用程序 就像一个音调检测, 例如,取入 你的声音和数字出 在pitch--非常简单的方法来表示。 只是一种可以读取它 在,计算出的频率, 然后输出一个数字。 所以我们会看到如何工作的,以及。 目的地是基本上 其中音频数据被输出。 因此,总的来说,这是像 您的笔记本音箱。 其他选项都喜欢 一个ScriptProcessorNode-- 我们会在一个节点 second--但基本上, 要么你把声音了 通过计算机通过扬声器, 或者你是那种记录,所以 你存储为音频数据。 因此,如果有人创建也许 音乐在你的应用程序,然后 你想记录这一点,也许像 它出口到SoundCloud,为example-- 这将是做到这一点的方法之一。 所有的有趣的东西, 我们将谈论, 这两个点之间发生, 其中我们在音乐加载 然后输出它。 所以,我要谈的五个 音频制作的第二阶段。 我们有这个东西叫做 一个AudioContext,这 这是我们在这里看到的小包装。 基本上什么AudioContext is--如果我们 去JavaScript控制台现在, 我们可以立即创建一个。 REPL的只是一个例子,对不对? 我们正在看, 评估和它打印。 AudioContext是一个全球性的状态。 这是一个结构,它是一个对象 在这里,它使信息 的事情,是怎么回事 有关音频屏幕。 一个例子是当前时间。 这告诉你的号码 几秒钟,非常精确, 由于网页加载。 所以这是一个非常有用的 小属性,您可以使用。 它的读取only--我觉得其实 你可以尝试设置一个值。 它会告诉你设置它, 然后,如果你打印出来 again--它其实并没有那么回事。 所以有只读 性能在JavaScript中。 这是,如果真的有用 有种你同步 很多不同的 信息,当你 种播放不同的声音。 另一种真正有用的 是上下文目的地。 肯定地说,如果你有兴趣,可以 在你自己的控制台右侧尝试这种 现在。 所以这是一个AudioDestinationNode。 基本上,这是什么说的是, 哪里是输出去? 因此,这里有两个真正的选择。 通常默认 只是你的音箱, 所以AudioDestinationNode 基本上只是说: 有零输出到声音 进来,发送到扬声器。 所以一般情况下,你不 有与玩。 如果你有兴趣在实际使用 的ScriptProcessorNode用于记录, 肯定拍我的 电子邮件后来因为这是 稍微复杂一点。 但是总体来说,你只是种 的输出声音以某种形式。 太酷了,我们跳回到这里。 听众:我很抱歉。 休·扎布里斯基:是的。 听众:我知道你说说话 你以后有关记录。 你能接口与Pro Tools? 休·扎布里斯基:与Pro Tools? 让我们来看看。 我不认为如此。 因此,客户端之间去, 这是JavaScript 控制台和您的实际 计算机,一般是 东西是一种 的禁区,如果你 会的,实物的the--性质 它是一种设计的东西, 但你尽量保持浏览器的独立 从用户的实际的计算机。 一般情况下,唯一你能 访问是麦克风或照相机。 你不能够,我 不要以为,使用专业工具。 但是,如果您创建 在Pro Tools轨道, 出口,您还可以加载 在这里,过滤它,例如, 过程,并记录到一个 音频Destination--或no--一球 处理器节点。 然后从那里,你可以 导出到SoundCloud,你 可以通过电子邮件发送,或 无论你想从那里。 但有一种轻微的障碍 让音乐在您的计算机上的 ,使在线音乐。 SAM格林:这就是 不是唯一的,以此API。 这是Chrome浏览器的安全功能,和 我认为,所有其他现代的浏览器。 浏览器是自包含的。 因此,例如,一个网页不能 使用JavaScript把声音 关于您的扬声器,例如。 或者无法关闭计算机。 而且没有中间点 这两件事情之间,正确的, 所以要么你有一个 完全抽象, 或者你打开 让安全漏洞 心怀不轨程序员做 任何他们想要与你的笔记本电脑。 这就是为什么Chrome是自包含的。 休·扎布里斯基:是的。 那有意义吗? 冷静,冷静。 我正要 示出的一个的例​​子。 这是相当多的 至于你,无论从 的访问用户的计算机。 如果您有一个USB键盘插上, 你可以使用一种叫做网络 MIDI API,我们不会哪 真正谈论在这里, 但是这又是一个API,它是 再建成至少Chrome--, 这就是为什么我们爱Chrome-- 我认为Firefox或Safari浏览器, 这是一件容易的事情 google--不同的浏览器有 针对这不同的支持 API的他们已经实施。 但是,如果你想在键盘插头 并与信息化工作, 那种送键盘 转移到计算机的信息 然后使用该网络,这个API 在这里你会工作的。 凉。 好。 因此,快速移动就在这里。 我们如何做的时间呢? 扬声器1:约15。 休·扎布里斯基:15分钟离开? 嗯不错。 因此,我们将在这里跑在前面。 所以基本上,主要点 这一思想作为管道 的是,在管道中的每个步骤 是一系列的音频节点。 我们的源代码,让我们说,是一个振荡器。 我们需要创建一个振荡器节点。 而这仅仅是一种 小function--的 而且它们都基于了 这里的音频上下文。 听众:当它说 振荡器,意味着什么 它实际上是从字面上去 两个不同的磁极来回? 休·扎布里斯基:不,这就像 的数字表示。 它实际上是用C ++实现的。 我居然不知道规格 它是如何实际上实现的, 但是这一切正在为二进制数据。 事实上,是的。 这将是说,我可以 实际上,如果你有兴趣, 我可以给你多一点 有关如何波形信息 被保持具有数字格式。 嗯不错。 因此,我们产生像正弦波音调 波浪或类似的东西,也许 440赫兹。 我们创建了一个振荡器。 如果我们要设置音量,我们 连接任何一个GainNode, 这是我们可以做.creategain。 这台音量。 您可以传递到任何 其他选项 - 好, 所以音频缓冲器源 节点下,您可能 存储你已经装入了一个MP3。 双二阶滤波器进行滤波,如果 要采取一切的基础出 一首歌,或者类似的东西。 上帝保佑你想利用 基地出一首歌。 和AudioDestination节点是,再次, 喜欢在那里我们的定稿是。 如果你在看到曾经兴趣 所有不同的可能的选项, 刚去的标签,让 自动完成上来。 而如果你创建,你会看到所有的 不同的东西,你可以创建。 您可以创建动态 脚本处理器, 我甚至不知道那是什么 是,用于混合通道的合并 和信道分离器和所有。 凉。 所以,这只是一个 例如一个管道。 因此,我们有三个来源进入。 也许这些都是波形, 也许这些都是MP3格式。 一个人的经历 过滤器,另一个人的 越来越扭曲的另一个 一个人的平移左右。 你可以做各种各样的事情, 他们都获得混合在了一起, 然后走出来的声音 在最后,作为目标。 这是什么更多的例子 复杂的网络音频代码如下所示。 你创造的所有这些 不同的对象右这里 - 我不知道这一点。 不,它不进行放大。 好。 SAM格林:你做控制,向上卷动。 休·扎布里斯基:控制Scroll-- SAM格林:不,不。 控制 - 休·扎布里斯基:哦,控制,滚动? 哦,疑难杂症。 是啊。 哇,没了,没了。 好。 我不会那么做的。 所以是的,在这第一 在此部分中,您将看到 我们正在创建所有这些不同的 结出的背景下。 我们只是拼凑他们 一起在第二部分 通过该功能被称为连接。 这是一个非常关键的 功能的网络音频。 它只是意味着一旦你做到 一些与在一个节点的声音, 其传递到下一个节点。 因此,我们有源,它 连接到分析装置, 分析仪做一些事吧, 它去失真,等等, 及到目的地 底部就在这里。 凉。 好了,我们会继续前进。 再次pipeline--,这些 是最常见的管道, 所以我们谈论这些事情像 失真,平移,这一切的东西。 如果你真的有兴趣 在使用的东西Pro Tools中, 这些可能是你的兴趣。 如果没有,也许你只是 要播放的声音, 或者你只是想 上设置声音的音量。 这些都是最常见的两种排序 在音频制作流程。 此外,该方法可以把它 作为一个oscillator--所以,让我们 做的是,试玩就在这里。 因此,我们要创建一个 在这里简单的音频范围内, 从我们要去 打造我们的振荡器。 所以这是,再次,我们只是 要调用Create振荡器。 我们将在设定的频率 即,440赫兹,大家的喜爱。 然后,我们连接的目的地 point--这是扬声器,所以 上下文目的地。 最后,我们只是说,开始零 从现在开始秒,我们有健全的? [铃声] 休·扎布里斯基:在这里,我们走了。 这只是一个正弦波。 嗯不错。 然后我们就会停止。 听众:哪里做 这些反馈信息从何而来? 休·扎布里斯基:反馈? 呵呵,可能是我们的话筒。 所以啊,这是你怎么做。 而实际上,如果我有 不停地运行它,你 可以有频率 价值,因为它的运行, 所以这是一个有趣的事情打转转。 凉。 这始终是一个可爱的人提出。 SAM格林:我们没有 想想,我们什么? 休·扎布里斯基:是啊, 这是一个讨厌的。 因此,缓冲loading--我将展示一个 例的,在最后。 这是加载MP3。 和麦克风,你只使用一个函数 所谓Navigator.getUserMedia() 请求访问的用户的 麦克风的信息。 这里的筛选,我会 只要继续从这个活动。 这是一个相当高的水平, 但过滤器只是让你 [哔哔] 过滤还允许你 创建像粉红色 噪声,褐色噪声,白噪声。 如果你想创建纯噪音,这 有些人喜欢摆弄, 您可以使用网络音频 过滤做到这一点。 音频Panning--所以想象 如果你正在写一个游戏 和你想要的声音 听起来像它的到来一样, 在屏幕上拍摄的,你 可以使用音频的声像 造成这种锥形的, 这like--它很mathy, 但实际上它是真的 冷静,如果你得到它的工作, 并有一些好 它的教程,我可以送你。 基本上,你可以种 中创建的声音 的东西在一个3D的方式去用。 如果你有一个DJ的兴趣,你可以 启动混合和交叉淡入淡出的歌曲。 这仅仅是一些非常基本的 代码,基本上是我以前那样。 此设置的音量 振荡器,所以我们创建了振荡器 它创建波形。 我们创建了GainNode, 我们设定频率, 然后连接振荡器到 GainNode,然后基本上改变 多少信号被允许通过。 但实际上,它是一个数字 的东西,所以它更just--呀。 这不是实际发生, 但是这是在现实生活中发生的事情 有增益。 听众:--quantization 体积参数? 休·扎布里斯基:对不起? 听众:它是一个 量化量参数? 休·扎布里斯基:是的。 这是一件事我真的很 在我的知识短少的, 如何获得工作在一个数字化水平。 我知道实际 信号,它基本上 控制多少你 放大信号。 所以,是的。 我给你的更多信息 ,因为我很好奇竟 更多地了解这一点。 但基本参数 是,一个是fold-- 响亮signal--和零是没有 信号,否则你将听不到任何声音。 我们将跳过演示时间,由于 这基本上是我以前那样。 再次,Context.Destination 是音频目标节点。 真棒,确定。 所以我打算做一个快速的两张demo。 我们如何做的时间呢? 扬声器1:约10分钟。 休·扎布里斯基:10分钟? 大! 真棒。 所以第一个我要去 确实,这就是所谓的我最喜爱的歌曲。 所以,这只是一个 小HTML的JavaScript。 我们将有两个按钮 在页面上播放我最喜欢的歌 并停止我最喜爱的歌曲。 我会改变这一点。 听众:盖你的麦克风。 休·扎布里斯基:是的。 而我在这里已经加载 这basically--脚本 这是真正有用的 加载一个MP3, 所以这只是让 加载速度更快MP3音乐的方式。 这基本上只是一个包装。 它只是使的过程 载入中的MP3快得多, 否则,你使用的HTTP请求, 有点像我们在做什么 在当前件套服务器。 这真是难看,你 不想做。 原来这家伙,鲍里斯的SMU,写了一个非常 有用的小工具,称为BufferLoader。 你所要做的只是把它传递的 情况下,你传递一个列表中 - 或者,是的,它是在JavaScript中的列表? SAM格林:数组。 休·扎布里斯基:哦,这是 一个数组,这是正确的。 这是路径的数组 不同的文件。 然后你将它传递的功能。 这是我们在谈论回调 有关与异步加载。 这将被称为 一旦加载的文件。 而该函数被调用时, 该文件的装载需要作为外围 加载缓冲器阵列。 因此,发生在这里。 基本上,BufferList是 将是1 value-- 或者这将是一个数组 长度之一,即具有在其在索引 零,MP3的整个加载的文件。 所以,当我完成我做什么 加载,我只是 创建一个缓冲源,它 是音频缓冲器源节点。 下一步骤是我在加载 source.buffer为满载缓冲区 从BufferList-- 它的很多buffers--的 然后您连接音频 缓冲到目的地。 那么它会做 只是简单地把MP3 直通到输出, 并立即开始它 在得到这个电话。 酷,让我们看看 这一点在行动。 我的[听不清]在这里,让我们来看看。 所以我只是要 启动一个基本的服务器。 在这个时候, 你需要做的,如果你 使加载文件的请求。 我要开始一个基本的服务器。 这基本上是整个 PSET现在在同一行, 但它只是开始 在端口80/80的服务器。 所以,我们去在这里,我们 要装载80/80, 我们要去我最喜爱的歌曲。 所以,如果我打“玩我 最喜欢的歌“现在, 这将载入我 最喜欢的歌曲,玩它 - [MUSIC - 老鹰,“生活在快  车道”] 可呈现恰好是“生活 快车道“由老鹰。 现在,我可以打“阻止我 最喜欢的歌“和重播。 [MUSIC - 老鹰,“生活在快  车道”] 如果我走了过来安慰,因为 我在这里用了一个全局变量 保持这个值的轨道,它实际上 在控制台现在被认可。 因此,它自动创建了我。 所以,这就是在玩,现在, 我可以简单地调用source.stop() 在这一点。 那么,你知道吗? 只是让你们听说过这个 song--你可能会认识到这首歌。 [MUSIC - RICK ASTLEY,“从未去放弃  您“] [MUSIC - 老鹰,“生活在快  车道”] 现在,我们已经全部被Rickrolled。 OK,伟大的,继续前进。 凉。 因此,这基本上是一个例子 只是你怎么可以加载一个MP3 file-- [MUSIC - 老鹰,“生活在快  车道”] - 并且播放,停止和启动它。 我可以做了很多[听不清] 最后一个,我会做的是, 我会告诉你一个[听不清]。 [音乐播放] 这就像,ogg.wave.mp3。 我想,如果我没有记错, 我碰到的一些问题。M4A, 但我不知道这一点。 我想mp3.wave-- [MUSIC - RICK ASTLEY,“从未去放弃  您“] 太好了。 我不应该说。 总之,你好。 因此,我们有这个开放。 所以,现在我要做的就是,我基本上创造 一个基本的语法创建的音乐。 所以,如果我做这样的事情,加上G4 1 2,这是什么意思的是, 加上钢琴音符,G4, 这是第四ģ 上从底部钢琴。 因此,这是一种MIDI讲, 因此,对于那些谁是音乐的基础, 这仅仅是MIDI音符。 听众:这是对G 中部C,对不对? 休扎布里斯基:这是对G 中C,这是正确的。 听众:中部以上C. 休·扎布里斯基:是的。 事实上,是的。 我想我曾作过 它酮[听不清] 所以这可能是上面一个八度。 所以,让我们来看看。 如果我打Play-- [重复性PIANO注] --we're会听到的。 这个想法是,它的运作 就像一个命令行会, 所以,如果我有涨有跌 我的键盘上,你 可以回到以前的 命令,这是非常有用的。 而下面是我的曲目列表, 这是在环路中的所有运行。 听众:你假设 88键的键盘上,对吧? 休·扎布里斯基:问题是, 我会假设一个88键的键盘, 是的,我是。 我所做的是我 基本上花了88个样本 的钢琴,一个用于每个音符。 所以每次时间 听到一记从现在开始, 这实际上是一个循环,看起来 like--这是越来越演奏循环, 所以对于每一个音符,这是在运行。 会发生什么事是,我 再创建一个缓冲区, 我创建了一个增益节点设置音量。 这只是一个非常 的说我复杂的方法 存储在source.buffer缓冲区。 我给它的增益,我 它连接到增益, 增益被连接到 输出,然后我玩。 所以这是一种过程 采取在缓冲源。 听众:你能采取实际的 燥声,使之湿润[听不清]? 休·扎布里斯基:可以,是的。 有再动词,有 延时,失真。 你基本上可以把任何东西在 之间的夹层of--好, 管道是一个更好的比喻, 但你可以添加任何东西。 凉。 所以,我会完成演示 在这里给你的感觉 时代的只是数量之多,你 可以运行功能的一次。 所以,我要删除此。 我要创造一个发电机that-- 基本上是什么does--这是真的 一种复杂syntax--,但它的 要在飞行中产生的笔记, 和刚开始玩 他们,因为它评估它们。 [插入PIANO] 因此,我们可以只是做一个小的音乐在这里。 [插入PIANO] 那么这个命令 确实,例如,是 它需要这三个音符为 钢琴,然后把他们的B3。 这个语法可能使 多一点意义 那些谁拥有 背景音乐在这里。 我可以添加一个大鼓。 我可以 - [插入仪器] --just玩弄了。 所以,你可以make-- [插入仪器] 一个人的多一点讨厌。 [插入仪器] 因此,它随机增加了一个干钹 在每16个音符,用16% [听不清]。 [插入仪器] 是啊,所以这个方法 works--它总是在4:4。 [插入仪器] 是啊,所以四季度和16/8。 [插入仪器] 所以平均起来,你会得到60% 命中的16分音符。 不管怎么说,这只是 那种炫耀 有些事情可以 建立与网络音频API。 这真是强大,它的真快, 你可以做很多很酷的事情 用它。 如此反复,您有任何疑问, 电子邮件myself-- Hugh--或山姆, 和诚实,谷歌 一吨的良好资源。 最后还有什么问题? 是啊。 听众:所以,你可以访问 内置麦克风。 如果你想什么 使用更好的麦克风? 休·扎布里斯基:如果你想 使用更好的麦克风? 如此反复,这是部分 Chrome浏览器之间的抽象 和计算机的其余部分。 除非它是可以通过 一个API,如Web MIDI API, 你也许可以找到一些黑客, 但一般不是切实可行的。 SAM格林:您可以also-- 所有的浏览器都知道 是你的默认麦克风 是,并且它访问。 所以,如果你有一个麦克风,你可以 设置为计算机的默认麦克风, 您可以访问这种方式 它可能会工作。 休·扎布里斯基:这是一个很好的点。 我从来没有尝试过,但 你也许可以来样 of--如果您重定向输入扬声器, 你也许可以做到这一点,是的。 最后还有什么问题? 凉。 好感谢你们 这么多的收看。 我休。 SAM格林:我是萨姆。 休·扎布里斯基:这是CS50。