第一世代　スマホからサウンドコントロール

「aibo ers-11x/210で遊ぶ Advent Calendar 2023」の12日目です。

:::note
業務外の個人的な検討活動です。
:::

ERS-11xには正弦波音声の組み合わせでaiboを制御するサウンドコマンダーという機材が付属していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/56a37f91-4ef5-420f-cb5c-dda28f672aeb.png)

例えばCEDの順番の音をaiboに聞かせるとゲームモードに移行するといった操作でした。

つまり音を発生させることができればサウンドコマンダーは必要ないとも考えられます。
今回はスマホでサウンドコマンダーをエミュレーションしてみます。

androidアプリをUnityで作ることも考えましたが、検討当時はライセンス方針の変更で騒動が起きていたため、Unityでの作成は見送りました。

#### htmlで音声発生スクリプトを作成
ChatGPT先生と問答しながら、下記のスクリプトを作成しました。

```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音を再生するボタン</title>
</head>
<body>

<!-- ボタンを作成 -->
<button id="btnCDE" onclick="playSound('CDE.mp3')">自律モード</button>
 <button id="btnCED" onclick="playSound('CED.mp3')">ゲームモード</button>
 <button id="btnECD" onclick="playSound('ECD.mp3')">パフォーマンスモード</button>
<br>
<br>
ゲームモード <br>
<button id="btnDFC" onclick="playSound('DFC.mp3')">左　Ｐ</button>
 <button id="btnCDF" onclick="playSound('CDF.mp3')">前　進</button>
 <button id="btnDCF" onclick="playSound('DCF.mp3')">右　Ｐ</button>
<br><br>
<button id="btnFDC" onclick="playSound('FDC.mp3')">左回転</button>
 <button id="btnCFD" onclick="playSound('CFD.mp3')">後　退</button>
 <button id="btnFCD" onclick="playSound('FCD.mp3')">右回転</button>
<br><br>
<button id="btnFCDs" onclick="playSound('FCDs.mp3')">咥える</button>
 <button id="btnFDsC" onclick="playSound('FDsC.mp3')">放　す</button>
<br><br>
<button id="btnDsCF" onclick="playSound('DsFC.mp3')">ボール</button>
 <button id="btnCDsF" onclick="playSound('CDsF.mp3')">勝ちポ</button>
 <button id="btnCFDs" onclick="playSound('CFDs.mp3')">負けポ</button>
 <button id="btnDsCF" onclick="playSound('DsCF.mp3')">停　止</button>
<br>
<br>
パフォーマンスモード <br>
<button id="btnCDsG" onclick="playSound('CDsG.mp3')">立っち</button>
 <button id="btnGCDs" onclick="playSound('CGDs.mp3')">お座り</button>
 <button id="btnGDsC" onclick="playSound('GDsC.mp3')">伏　せ</button><br><br>
スタイル<br>
<button id="btnCEF" onclick="playSound('CEF.mp3')">右手振</button>
 <button id="btnCFE" onclick="playSound('CFE.mp3')">バイ２</button>
 <button id="btnFCE" onclick="playSound('FCE.mp3')">どうも</button>
 <button id="btnFEC" onclick="playSound('FEC.mp3')">な　し</button><br><br>
パフォーマンス<br>
<button id="btnCFG" onclick="playSound('CFG.mp3')">右手振</button>
 <button id="btnCGF" onclick="playSound('CGF.mp3')">吠える</button>
 <button id="btnGCF" onclick="playSound('GCF.mp3')">耳掻く</button>
 <button id="btnGFC" onclick="playSound('GFC.mp3')">の　び</button>
 <button id="btnFCG" onclick="playSound('FCG.mp3')">左足振</button><br><br>
<br>
<br>
<button id="btnDCE" onclick="playSound('DCE.mp3')">スリープ</button>

<script>
    // 現在再生中のAudioオブジェクトを保持する変数
    let currentAudio = null;

    // すべてのボタンの状態を設定する関数
    function setAllButtonsState(state) {
        let buttons = document.querySelectorAll('button');
        buttons.forEach(button => {
            button.disabled = !state;
        });
    }

    function playSound(filename) {
        // 現在再生中の音があれば停止
        if (currentAudio) {
            currentAudio.pause();
            currentAudio.currentTime = 0;
        }

        // すべてのボタンを無効にする
        setAllButtonsState(false);

        // 新しいAudioオブジェクトを作成して再生
        currentAudio = new Audio(filename);
        currentAudio.play();

        // 音声が終わったらボタンを再び有効にする
        currentAudio.onended = function() {
            setAllButtonsState(true);
            currentAudio = null;
        };
    }
</script>

</body>
</html>
```

Androidスマホ上で実行すると、下記のようなページが開きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/e0ad87ca-4190-67d8-e6fd-bb0fe455e6b0.png)


#### 命令用の音声を作成
今回はAudacityを使い、正弦波音声を組み合わせて命令用の音声ファイルを作成しました。

下記はCFDの場合です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/7f15a6d3-b2f3-0fae-0ab0-bb78e82b9f84.png)

地道に作成した音声ファイルたちを所定のフォルダに置きました。

#### 動作確認
動画を撮り忘れましたが、ページのボタンを押して発生した音をaiboに聞かせて動作することを確認できました。