CEDEC 2016 ワークショップ VOCALOID SDK for Unity で 自由に歌わせられるアプリをつくってみよう 【補助資料】 ©2016 VOCALOID Group, Yamaha Corporation サンプルプロジェクト • 仕様 – スペースキーの押下で, 開始 & unity-chan! がジャンプ – 開始とともにボールが落下し, unity-chan! はボールをヘディングする – ヘディング位置が低すぎると失敗とし, 5連続失敗で,待機状態に戻る – 時間経過とともにゲームの速度が上がる * 本プロジェクトは「unity-chan! OFFICIAL WEBSITE」で配布されている 「SDユニティちゃん 3Dモデルデータ」をベースにしています ©2016 VOCALOID Group, Yamaha Corporation 2 サンプルプロジェクト • 改造目標 – unity-chan! がボールをヘディングする 度に ドレミファソラシド の高さで歌う – ヘディングの位置が低すぎると音を外す – 歌詞を変更することができる * 本プロジェクトは「unity-chan! OFFICIAL WEBSITE」で配布されている 「SDユニティちゃん 3Dモデルデータ」をベースにしています ©2016 VOCALOID Group, Yamaha Corporation 3 VOCALOID プラグインの基本的な使い方 • • YVF クラス (static) が API を包含 プラットフォームごとの namespace 下に,それぞれ YVF クラスがある #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN" using Yamaha.VOCALOID.Windows;" #elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX " using Yamaha.VOCALOID.OSX;" #elif UNITY_IOS" using Yamaha.VOCALOID.iOS;" #endif" " using UnityEngine;" using System.Collections;" " public class Example : MonoBehaviour {" " void Start () {" // API はすべて static にアクセス." YVF.YVFStartup("personal", Application.streamingAssetsPath + "/VOCALOID/DB_ini");" } " }" * 簡素化のため,スライド上のサンプルコードはサンプルプロジェクトでの書き方と一致しない場合があります ©2016 VOCALOID Group, Yamaha Corporation 4 VOCALOID プラグインの基本的な使い方 • 多くの API は,戻り値としてメソッドの実行結果を表す enum を返す – YVFResult (情報取得系以外のほぼすべての API の戻り値) – YVFFindResult (情報取得系 API の戻り値) • YVFFind~() • YVFNext~() YVF.YVFResult result = YVF.YVFStartup("personal", path);" " // 結果に応じて必要な処理をする if (result == YVF.YVFResult.Success) {" print("正常終了");" " } else if (result == YVF.YVFResult.InvalidString) {" print("入力文字列が不正");" // TODO" } ©2016 VOCALOID Group, Yamaha Corporation 5 VOCALOID プラグインのライフサイクル AppStartup YVFStartup() Playback合成 Real+me合成 YVFShutdown() AppShutdown ©2016 VOCALOID Group, Yamaha Corporation 6 VOCALOID プラグインの起動,合成モード設定 // VOCALOID エンジンの起動" public void Startup() {" if (!initialized) {" " // Workshop..." YVF.YVFResult result = YVF.YVFStartup("personal", " Application.streamingAssetsPath + "/VOCALOID/DB_ini");" print(result);" if (result != YVF.YVFResult.Success) {" return;" }" // ...Workshop" " initialized = true;" " // Realtime 合成モードに設定する (バッファサイズ: 512 Samples)" // Workshop..." YVF.YVFRealtimeSetStaticSetting(YVF.YVFRealtimeMode.Mode512);" // ...Workshop" " VAudio.Create();" } }" Scripts/VocAudioManager.cs ©2016 VOCALOID Group, Yamaha Corporation 7 VOCALOID プラグインの終了 // VOCALOID エンジンの停止" public void Shutdown() {" if (initialized) {" VAudio.Delete();" " // Workshop..." YVF.YVFShutdown();" // ...Workshop" " }" initialized = false;" } • Scripts/VocAudioManager.cs アプリケーション終了前に,必ず VOCALOID プラグインの終了処理を行ってください ©2016 VOCALOID Group, Yamaha Corporation 8 Realtime 合成 流れ 1. リアルタイム合成処理の開始 (イベントの待ち受け開始) 2. 歌詞設定 (事前に設定した歌詞でループする) 3. イベントの追加 4. イベントの確定 5. Unity のオーディオ出力データに歌声合成データを設定,出音 6. リアルタイム合成処理の終了 イベント ノートオン/オフや表情パラメータ設定の変更などの情報 ©2016 VOCALOID Group, Yamaha Corporation 9 Realtime 合成 Unityアプリケーション上位層 VOCALOIDプラグイン inac+ve オーディオ出力データ VOCALOID エンジン 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 10 Realtime 合成 -リアルタイム合成処理の開始- Unityアプリケーション上位層 オーディオ出力データ VOCALOIDプラグイン ac+ve [リアルタイム合成処理の開始] VOCALOID エンジン 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 11 Realtime 合成 -歌詞設定- Unityアプリケーション上位層 オーディオ出力データ [歌詞の設定] VOCALOIDプラグイン ac+ve VOCALOID エンジン よろしくね 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 12 Realtime 合成 -イベントの追加,確定- Unityアプリケーション上位層 VOCALOIDプラグイン ac+ve オーディオ出力データ [イベントの追加,確定] e.g.ノートオン VOCALOID エンジン よろしくね 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 13 Realtime 合成 -歌声合成データの取得- Unityアプリケーション上位層 オーディオ出力データ 歌声合成データ short[] よー [歌声合成データの取得] VOCALOIDプラグイン ac+ve VOCALOID エンジン よろしくね 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 14 Realtime 合成 -歌声合成データの設定,出音- Unityアプリケーション上位層 VOCALOIDプラグイン ac+ve オーディオ出力データ VOCALOID エンジン よろしくね Unityのオーディオ出力用データに 歌声合成データを設定,出音 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 15 Realtime 合成 -リアルタイム合成処理の終了- Unityアプリケーション上位層 オーディオ出力データ VOCALOIDプラグイン inac+ve [リアルタイム合成処理の終了] VOCALOID エンジン 歌声ライブラリ ©2016 VOCALOID Group, Yamaha Corporation 16 Realtime 合成 OnAudioFilterRead を利用した実装 • OnAudioFilterRead – 短いインターバルで呼ばれる,オーディオフィルタリングを行うメソッド – 優れたレイテンシ • オーディオフィルタリングを実行するのではなく,直接歌声合成データを 書き込む ©2016 VOCALOID Group, Yamaha Corporation 17 Realtime 合成 -リアルタイム合成処理の開始・終了- public void Create() {" // リアルタイム合成処理の起動 (イベント待ち受けの開始)" // Workshop..." YVF.YVFResult result = YVF.YVFRealtimeStart();" if (result != YVF.YVFResult.Success) {" return;" }" // ...Workshop" " renderData = new short[AudioSettings.GetConfiguration().dspBufferSize * 2];" " // OnAudioFilterRead() で値を設定できるように AudioClip を生成,AudioSource を Play" AudioClip clip = AudioClip.Create("VOCALOID", YVF.YVFSamplingRate, 1, YVF.YVFSamplingRate, true);" AudioSource source = gameObject.GetComponent<AudioSource>();" source.loop = true;" source.clip = clip;" source.Play();" } " public void Delete() {" // リアルタイム合成処理の終了 (イベント待ち受けの停止)" YVF.YVFRealtimeStop();" }" ©2016 VOCALOID Group, Yamaha Corporation Scripts/VocAudio.cs 18 Realtime 合成 -歌詞設定- // 歌詞の設定" public void SetLyrics(string lyrics) {" " // Workshop..." " YVF.YVFRealtimeSetLyrics(lyrics, YVF.YVFLang.Japanese);" " // ...Workshop" " }" Scripts/VocAudio.cs ©2016 VOCALOID Group, Yamaha Corporation 19 Realtime 合成 -歌詞設定- Unityアプリケーション上位層 オーディオ出力データ [歌詞の設定] VOCALOIDプラグイン ac+ve VOCALOID エンジン よろしくね 歌声ライブラリ 今ココ ©2016 VOCALOID Group, Yamaha Corporation 20 Realtime 合成 -イベントの追加,確定- // ノートオン (発音開始) イベントを VOCALOID エンジンに通知する" private void NoteOn(int noteNumber) {" if (YVF.YVFRealtimeGetSynthState() == YVF.YVFRealtimeSynthState.Running) {" // 現在発音しているノートのノートオフ (発音停止),新しいノートオン (発音開始)を追加して確定 (Commit)" " // Workshop..." " YVF.YVFRealtimeAddNoteOff();" YVF.YVFRealtimeAddNoteOn(noteNumber);" YVF.YVFRealtimeCommitMidi();" " // ...Workshop" " }" if (runningCoroutine != null) {" StopCoroutine(runningCoroutine);" }" runningCoroutine = StartCoroutine(dynamicsCoroutine());" } Scripts/BallController.cs ©2016 VOCALOID Group, Yamaha Corporation 21 Realtime 合成 -イベントの追加,確定- Unityアプリケーション上位層 VOCALOIDプラグイン ac+ve オーディオ出力データ [イベントの追加,確定] e.g.ノートオン VOCALOID エンジン よろしくね 歌声ライブラリ 今ココ ©2016 VOCALOID Group, Yamaha Corporation 22 Realtime 合成 -歌声合成データの取得,設定,出音- void OnAudioFilterRead(float[] data, int channels) {" if (YVF.YVFRealtimeGetSynthState() != YVF.YVFRealtimeSynthState.Running) {" return;" } " // 合成済み歌声合成データサイズの取得" int numBufferdSamples = (int)YVF.YVFRealtimeGetAudioNumData();" if (numBufferdSamples <= 0) {" return;" }" " " // 合成済み歌声合成データを short[] renderData に書き込む" // Workshop..." " YVF.YVFRealtimePopAudio(renderData, numBufferdSamples);" // ...Workshop" " // 歌声合成データをAudioClipに書き込む" for (int i = 0; i < numBufferdSamples; ++i) {" float value = renderData[i] / 32768.0f; // uint16_t (-32768 ~ 32767) → float (-1.0 ~ 1.0)" int index = i * channels;" for (int j = index; j < index + channels; ++j) {" data[j] = value;" }" }" } Scripts/VocAudio.cs ©2016 VOCALOID Group, Yamaha Corporation 23 Realtime 合成 -歌声合成データの取得- Unityアプリケーション上位層 オーディオ出力データ 歌声合成データ short[] よー [歌声合成データの取得] VOCALOIDプラグイン ac+ve VOCALOID エンジン よろしくね 歌声ライブラリ 今ココ から 次ページ→ ©2016 VOCALOID Group, Yamaha Corporation 24 Realtime 合成 -歌声合成データの設定,出音- Unityアプリケーション上位層 VOCALOIDプラグイン ac+ve オーディオ出力データ VOCALOID エンジン よろしくね Unityのオーディオ出力用データに 歌声合成データを設定,出音 歌声ライブラリ →前ページ ココ まで ©2016 VOCALOID Group, Yamaha Corporation 25 ヘディングの位置が低すぎると音を外す void OnTriggerEnter(Collider collision) {" if (collision.tag == "UnityChanHead") {" // ボールが上向きの速度をもっている場合には衝突判定を無視する" if (GetComponent<Rigidbody>().velocity.y > 0) {" return;" }" " // ドレミファソラシド の高さで順番に歌う" int noteNumber = middleC + majorScale[noteIndex++];" if (noteIndex >= majorScale.Length) {" noteIndex = 0;" } // 続く.. Scripts/BallController.cs ©2016 VOCALOID Group, Yamaha Corporation 26 ヘディングの位置が低すぎると音を外す // ..続き OnTriggerEnter " // ヘディングしたときのボールの高さが一定値以上のときに成功とする" if (transform.position.y > threshold) {" mistaken = 0;" bound();" } else {" ++mistaken;" " // 失敗したら音を外す" // Workshop..." " int rnd = Random.Range(1, 4);" rnd = (Random.Range(0, 2) == 0) ? rnd : -rnd; " noteNumber += rnd;" " // ...Workshop" " // 続く.. Scripts/BallController.cs ©2016 VOCALOID Group, Yamaha Corporation 27 ヘディングの位置が低すぎると音を外す " // ..続き OnTriggerEnter " if (mistaken <= excuse) {" bound();" } else {" // 失敗が連続した場合は,ボールにx軸方向の力をかけ床に落とし終了とする" GetComponent<Rigidbody>().AddForce(5, 0, 0, ForceMode.VelocityChange);" }" }" NoteOn(noteNumber); } else if (collision.tag == "Field") {" // 床に落ちたら終了" NoteOff();" VDirector.Deactivate();" }" } Scripts/BallController.cs ©2016 VOCALOID Group, Yamaha Corporation 28 ©2016 VOCALOID Group, Yamaha Corporation
© Copyright 2024 ExpyDoc