大多数浏览器和
Developer App 均支持流媒体播放。
-
Swan 的征途 第 2 篇章:乐音时间
Swift Playgrounds 出品《天鹅之旅》,一款老少咸宜的四章节互动冒险游戏。在这一章中,我们的英雄需要你来帮助破解天鹅之书。唤醒你的音乐细胞——你会需要它们的。 了解如何将 Swift Playgrounds 转换成音频发生器,以帮助我们的英雄找寻缺失信息...然后进入下一节。 《天鹅之书》为 iPad 与 Mac 量身定制,其中结合了我们许多 Playground 教育体验中使用的框架与资源(如 Sonic Workshop、Sensor Arcade 与增强现实等)。要了解更多如何制作自己 Playground 的信息,请查看“为 iPad 与 Mac 创建 Swift Playground 内容”一节。 另外,别忘了去开发者论坛,分享你对我们这个支线任务的解决方法哦。
资源
相关视频
WWDC20
-
下载
(你好 WWDC 2020)
你好 欢迎参加 WWDC (Swan 的征途 第 2 篇章:乐音时间) 你好 欢迎继续观看《Swan 的征途》 我是 Rob 本次旅途第二篇章的引路人 希望此前的第一场挑战能让你乐在其中 并学习到一点关于辅助功能界面的知识 在第二篇章中 你将再度与 Lizard 为伴 让它帮助你解开 Swan 卷轴之谜 我不想剧透 但我可以告诉你 为了通过此次挑战 你需要为 Swan 演奏一系列音符
为了演奏音符 我们要向你展示两个 API 分别是 ToneOutput 和计时器 我们会对这两个 API 逐一进行详细介绍 好让你能够用出色的演奏技巧 来打动我们这位伟大的摄政王 最后 我们会以一个支线任务作为结尾 好让那些渴望更多冒险的开发者得到满足 首先 我们先来讲一讲如何演奏乐音 为了做到这一点 我们需要用到 ToneOutput 类型 我们把 ToneOutput 引入了 Sonic Workshop 和 Sonic Create 好让你能在自己的项目中使用它 让我们更深入地了解一下 ToneOutput ToneOutput 类型的 API 十分直观 可以让你用一个乐音值 来演奏程序生成的信号 它每秒能产生 44100 个样例 因此你听到的才是连续的声响 而不是一个个离散的脉冲 你需要调用主实例方法 play(tone:) 来创建信号
信号的定义也是同样直观 它包括音高 也就是频率的双精度表示 以及音量 同样也是通过双精度表示
它在实际应用中会是这个样子 在这个例子里 我们要创建一个 ToneOutput 的实例 然后给它 440 Hz 的频率 即中央 A 在 Playground 中运行这串代码 你会听到一个乐音 能让人联想到紧急广播系统的那种 如果你不让 Playground 代码停止运行 那么这个乐音会永远播放下去 我们来联系一下 Stephen 看看如何才能演奏多个音符
谢谢 Rob 如他所言 这个ToneOutput 样例会持续播放下去 直到有人让它停止播放 为了停止这个 ToneOutput 实例 我们需要调用 stopTones 这里已经把它高亮标示出来了
为了在我们这个样例中完成这项任务 我们可以调用 Dispatch.asyncAfter 让它在 400 毫秒之后调用 stopTones 这个音符会播放一小段时间 然后停止 如果你想播放多个音符 这个方法就不管用了 (计时器 可供人类阅读的 API) 我们建议使用计时器 这是一种更加直观的API 能按照预先指定的时间间隔重复某个片段 我们来更新一下这个样例 让它播放多个音符
这里我们已经补充了中央 A、中央 B 和中央 C 的频率 为了让它们能够接连播放 我们要使用计时器 我们要遍历乐音数组 让它每过 400 毫秒便播放下一个乐音 到达数组末尾时 我们要在 ToneOutput 中调用 stopTones 然后使计时器无效 这样它便会停止重复播放了
最后 你需要调用 endPerformance 好让你的功劳能够被人记得 你需要在余下的所有挑战中 使用同样的调用 来告诉 Swan 你的表演已经结束了 以上就是使用计时器来接连播放 多个不同音符的方法
谢谢 Stephen 在进一步深入讲解之前 我想提醒你的是
接下来的支线任务包含 有关本篇章挑战内容的剧透 如果你想先完成挑战 请暂停播放本视频 待你完成之后再回来 祝你好运
你准备好要进行这个支线任务了吗? Swan 的挑战是要你演奏一个 C 大调音阶 所有的频率都已经由它们提供给你了 让我们来看看你能不能调整一下 这串代码 让它改为演奏 F 大调音阶 想想看 其实很多需要的频率你都有了 首先 F 大调音阶是从 F4 开始的 你已经从 Swan 那里得到了这个音符 其次 你应该能够重用 C 大调音阶的代码 最后 如果你想升一个八度 只需将频率加倍即可 也就是说 如果想从 A4 升到 A5 你需要将 440 Hz 乘以二 得到 880 Hz (降 B 的频率) 很好 降 B 的频率也是你需要用到的
在本段视频中 我们给了你一些关于如何完成 《Swan 的征程》第二项挑战的小提示 我们向你介绍了 ToneOutput 以及如何使用 Swift Playgrounds 来根据频率播放带音调的音高 之后我们讨论了如何使用计时器 来更改音符 让它们按照指定时长播放 明天还会有一场与音符有关的挑战 内容十分精彩 千万不要错过 祝你好运 玩得开心 也欢迎你把支线任务的解法分享在论坛上 我们很想听一听
-
-
1:09 - ToneOutput.swift
// ToneOutput.swift public class ToneOutput : AURenderCallbackDelegate { let sampleRate = 44100.0 public func play(tone: Tone) { /**/ } public func stopTones() { /**/ } // ... }
-
1:30 - Inside the Tone type
// ToneOutput.swift public struct Tone: Codable { public var pitch: Double public var volume: Double // ... }
-
1:45 - Play a middle A
// Play a middle A import SPCAudio let toneOutput = ToneOutput() let middleA = Tone(pitch: 440.0, volume: 0.3) toneOutput.play(tone: middleA)
-
2:21 - Play a middle A for 0.5 seconds
// Play a middle A import SPCAudio let toneOutput = ToneOutput() let a4 = Tone(pitch: 440.0, volume: 0.3) toneOutput.play(tone: a4) DispatchQueue.main.asyncAfter(deadline: .now() + DispatchTimeInterval.milliseconds(400)) { toneOutput.stopTones() }
-
2:51 - Play more than one tone
// Play more than one tone let toneOutput = ToneOutput() let tones = [ Tone(pitch: 440.00, volume: 0.3), Tone(pitch: 493.88, volume: 0.3), Tone(pitch: 523.25, volume: 0.3) ] var toneIndex = 0 Timer.scheduledTimer(withTimeInterval: 0.4, repeats: true) { timer in guard toneIndex < tones.count else { toneOutput.stopTones() timer.invalidate() owner.endPerformance() return } toneOutput.play(tone: tones[toneIndex]) toneIndex += 1 }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。