WWDC Quick Look 💓 By SwiftGGTeam
Swan's Quest, Chapter 2: A time for tones

Swan's Quest, Chapter 2: A time for tones

元の動画を見る

ハイライト

第 2 章の課題は、コードを使用して特定の周波数のトーンを生成し、デバイスのスピーカーから再生することです。第 1 章の「音の検出」とは異なり、この章では「音の生成」が必要です。

主要内容

Swan’s Quest の最初の章では、プレイヤーにアクセス可能なインターフェイスを紹介します。第 2 章では、トカゲと白鳥のスクロール パズルに場面が戻ります。プレイヤーは、チャレンジに合格するために、白鳥のために一連の音符を演奏する必要があります。

この点で難しいのは、サウンド ファイルを再生することではありません。このチャレンジでは、周波数に従ってトーンを生成し、それを固定リズムに従って順番に再生する必要があります。この講義では、エントリ ポイントを 2 つの API に圧縮します。ToneOutput発言することに責任を持ち、Timer音符のシーケンスを時間内に進める責任を負います。

440 Hz の中央 A が 1 つあれば簡単に鳴ります。このチャレンジを実際に完了するには、400 ミリ秒のビート ループでノートを切り替える必要があります。最後に、ToneOutput を停止し、タイマーをキャンセルして、endPerformance()スワンにショーが終わったと伝えてください。

最後のサイドクエストでも引き続き同じコードが使用されます。白鳥はハ長調スケールを与えましたが、練習問題ではそれをヘ長調スケールに変更する必要がありました。スピーチで述べられた理由は非常に具体的です。F4 から開始し、既存の周波数を再利用し、オクターブを上げる必要がある場合は周波数を 2 倍します。たとえば、A4 の 440 Hz を A5 の 880 Hz に変更します。

詳細

ToneOutput は連続サウンドの生成を担当します

01:09ToneOutputがこの挑戦の声です。プレゼンテーションでは、1 秒あたり 44,100 個のサンプルを生成し、人間の耳で連続音を聞くことができると述べています。

//  ToneOutput.swift

public class ToneOutput : AURenderCallbackDelegate {
    let sampleRate = 44100.0

    public func play(tone: Tone) { /**/ }

    public func stopTones() { /**/ }

    // ...

}

キーポイント:

  • sampleRate = 44100.0トランスクリプトでは 1 秒あたり 44,100 サンプルに相当します。
  • play(tone:)トーンに応じた信号を作成します。
  • stopTones()現在再生中のトーンを停止します。
  • このタイプは Sonic Workshop から提供され、プレイヤーが独自のプロジェクトで使用できるように Sonic Create に組み込まれています。

(01:30) パスToneOutput値はTone。ピッチとボリュームという 2 つのコア パラメータのみを公開します。

//  ToneOutput.swift

public struct Tone: Codable {
    public var pitch: Double
    public var volume: Double

    // ...
}

キーポイント:

  • pitchそれは周波数ですDouble急行。
  • volumeあまりにもDouble
  • Codableトーンを保存し、単純なデータ構造として渡します。
  • これにより、チャレンジ コードが基礎となるオーディオ サンプルを直接処理する必要がなくなります。

ミドル A を最初にプレイします

(01:45) 実行可能なコードの最初の部分は、create という 1 つのことだけを行います。ToneOutput、440 Hz、ボリューム 0.3 のトーンを構築し、再生します。

// Play a middle A

import SPCAudio

let toneOutput = ToneOutput()
let middleA = Tone(pitch: 440.0, volume: 0.3)
toneOutput.play(tone: middleA)

キーポイント:

  • import SPCAudio例に必要なオーディオの種類を紹介します。
  • ToneOutput()音声オブジェクトです。
  • Tone(pitch: 440.0, volume: 0.3)トランスクリプトでは 440 Hz の中央 A に対応します。
  • toneOutput.play(tone: middleA)プレイグラウンドから連続音を発します。

(02:21) 講義のリマインダー: Playground コードの実行が停止しない場合、このトーンは鳴り続けます。例えばDispatchQueue.main.asyncAfter400ミリ秒後に呼び出されるstopTones()

// 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()
}

キーポイント:

  • a4440Hzではまだ真ん中のAです。
  • toneOutput.play(tone: a4)まずサウンドを開始します。
  • DispatchTimeInterval.milliseconds(400)音の長さを短くしてください。
  • 閉鎖中toneOutput.stopTones()連続再生の終了を担当します。

タイマーを使用して複数の音符をつなぎ合わせる

(02:51) 単一の遅延は、トーンを停止するのに適しています。複数の音を連続して再生するには、Speech が推奨しますTimerというのは、同じロジックを一定の間隔で繰り返し実行できるからです。

// 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
}

キーポイント:

  • tones中央 A、中央 B、中央 C の周波数を保存します。
  • toneIndex配列内のどのトーンが次に再生されるかを記録します。
  • withTimeInterval: 0.4トランスクリプト内の次の音を 400 ミリ秒ごとに再生します。
  • guard toneIndex < tones.count配列の最後に到達したら、最後の分岐に入ります。
  • toneOutput.stopTones()音声出力を停止し、timer.invalidate()タイマーの繰り返しを停止します。
  • owner.endPerformance()パフォーマンスが完了し、プレイヤーが進歩したことをチャレンジ システムに伝えます。

重要ポイント

  1. スケール練習器を作る 手順: ボタンを使用してハ長調、ヘ長調などのスケールを選択し、各音を順番に演奏します。 実行する価値がある理由: セッションでは、トーン アレイ、0.4 秒タイマー、オクターブを上げるときに周波数を 2 倍にする方法について説明しました。 開始方法: まずは公式のものを再利用してくださいtones配列の合計Timer.scheduledTimer、次に、異なるスケールを異なるスケールにマッピングします。Tone(pitch:volume:)リスト。

  2. リスニング記憶チャレンジを行う 何をすべきか: 3 ~ 5 つのトーンを再生し、ユーザーに順番に繰り返してもらいます。 実行する価値がある理由: これは、Swan’s Quest の「Swan のために一連の音符を演奏する」クエストの直接の拡張です。 開始方法: を使用しますToneOutput.play(tone:)質問を再生するには、次を使用しますtoneIndex進行状況を制御し、ユーザーが完了した後にチャレンジと同様の終了ロジックを呼び出します。

  3. 周波数実験パネルを作成 機能: ピッチとボリュームの入力を提供し、ユーザーがさまざまな周波数とさまざまなボリュームの結果を聞くことができるようにします。 実行する価値がある理由:Tone公開パラメータは次のとおりです。pitchそしてvolume、周波数と音量を理解するのに最適です。 開始方法:Tone(pitch: 440.0, volume: 0.3)の 2 つの数値は制御入力によって置き換えられ、再生前に新しい数値が生成されます。Tone

  4. サイドクエストのヘルパーを作る 手順: C メジャー スケールを F メジャー スケールに書き換え、追加する必要がある B フラットをマークします。 実行する価値がある理由: トランスクリプトでは、F4 から開始し、C メジャー コードを再利用し、より高いオクターブを得るために周波数を 2 倍にする必要があるのは明らかです。 開始方法: 最初に元の再生ループを保持し、それのみを置き換えますtones配列内の周波数。より高いオクターブに遭遇した場合は、元の周波数を 2 倍します。

関連セッション

コメント

GitHub Issues · utterances