Swan's Quest, Chapter 1: Voices in the dark
Developer Tools 入门 8m

天鹅任务第一章:黑暗中的声音

Swan's Quest, Chapter 1: Voices in the dark

2020年6月22日

在 Apple 官方观看视频

一句话判断

Swan’s Quest 是苹果为 WWDC 2020 设计的交互式编程挑战——第一章用 AVFoundation 让你的设备「听懂」特定频率的声音,是一个巧妙地引导你学习音频编程的解谜游戏。

这场 Session 讲了什么

Swan’s Quest 是 WWDC 2020 的特殊活动,一个横跨四天的编程冒险游戏。玩家需要在 Swift Playgrounds 中完成一系列编程挑战,每个挑战对应一个 iOS 技术领域。

第一章「黑暗中的声音」的挑战是:用 AVAudioEngine 监听麦克风输入,检测特定频率的声音,然后用检测到的频率作为「密码」来解锁下一关。你需要理解音频频谱分析的基本概念,使用 AVAudioEngineinstallTap 来捕获音频缓冲区,然后分析频率分量。

整个体验设计得很有趣——你写的代码会响应外部世界的声音(甚至可以对着手机吹口哨),这种交互感是传统教程做不到的。

值得深挖的点

音频频率检测的实现思路

核心是用 AVAudioEngine 的输入节点采集音频,通过 FFT(快速傅里叶变换)将时域信号转换为频域信号,找到能量最集中的频率分量。苹果在 Playground 中提供了部分辅助代码,但核心的频率检测逻辑需要你自己实现。

代码片段

import AVFoundation

// 基础的音频频率检测
class AudioDetector {
    let engine = AVAudioEngine()
    
    func startListening() {
        let inputNode = engine.inputNode
        let format = inputNode.outputFormat(forBus: 0)
        
        // 安装音频采集节点
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) { buffer, time in
            // 获取音频数据
            let channelData = buffer.floatChannelData?[0]
            let frameLength = Int(buffer.frameLength)
            
            // 分析频率(简化版本)
            // 实际需要用 FFT 或 vDSP 进行频谱分析
            self.analyzeFrequency(data: channelData!, frameLength: frameLength)
        }
        
        try? engine.start()
    }
    
    func analyzeFrequency(data: UnsafePointer<Float>, frameLength: Int) {
        // 计算音频信号的频率分量
        // 简化示例:计算 RMS 能量来判断是否有声音
        var sum: Float = 0
        for i in 0..<frameLength {
            sum += data[i] * data[i]
        }
        let rms = sqrt(sum / Float(frameLength))
        
        if rms > 0.1 {
            print("检测到声音,音量: \(rms)")
        }
    }
}

最佳实践

  1. 先跑通 Playground 再研究原理。Swan’s Quest 的乐趣在于动手,不要一开始就深究 FFT 的数学原理。先把代码跑起来,看到结果后再回头看为什么。
  2. 用真实的乐器或声音源测试。手机播放一个纯音(可以用在线频率发生器),比吹口哨更容易触发检测。

还有什么值得关注

  • 完成第一章后会在 Swift Playgrounds 中解锁第二章的内容。
  • 苹果在 Playground 的提示系统中嵌入了教学链接,点击可以跳转到相关的 WWDC Session。
  • 这个系列的四章分别覆盖了:音频、UI、绘图和序列化,每一章都是独立的编程挑战。
WWDC 2020