飛電ゼロワンドライバー専用 音声拡張パックをつくる

およそ二ヶ月半ぶりの工作です。今回は見た目も機能もシンプル、でもそのわりには結構遊べる『飛電ゼロワンドライバー専用 音声拡張パック』のご紹介です。

開発経緯

皆様ご存知の通り、ゼロワンドライバーには、(2020/3/20時点で)まだ使用されていない拡張部分があります。

ビルドドライバーの拡張部分は中間フォームのハザードトリガーで使用されましたが、ゼロワンではメタルクラスタホッパーでも使用されなかったので、おそらく最終フォームの変身玩具用に使用されるのだと思います。

ともあれ、こういう拡張部分を見ると、男の子としては(?)もうそれだけでワクワクしてしまいます。NINTENDO64のコントローラの拡張部分とか大好きでした。そんなわけで、この部分を活かして何かできないかな、ということはずっと考えていました。

どうせならいろんな拡張アイテムを量産しやすいようにアダプタ的なもの作れないかなとか色々考えたのですが、最終的に音声を強化するものをつくるだけでも結構遊べそうなイメージができましたので、『音声拡張パック』として、これ単体でとりあえず仕上げてみることにしました。この名前はもちろん、先に述べたNINTENDO64の周辺機器であるコントローラーパックや振動パック、メモリー拡張パックなどに由来しています。

作品概要

ゼロワンドライバーの拡張部分に差し込むだけで、ゼロワンドライバーの音声を強化することができます。

ドライバーに挿したまま、好きな時に押せるボタンが1つと、

ゼロワンドライバーのプログライズキーを押し込んだときに押されるボタンが1つ。

さらに、ゼロワンドライバーへの挿入認識 兼 電力供給用のソケット。これらの組み合わせにより、最大5つのポイントで音声を鳴らせるようにしています。

No. タイミング
1 拡張パック挿入時 “Ready to utilize.”
2 ボタン押下時 “Authorize.”
3 プログライズキー押込時(1回目) “飛び上がライズ! Rising Hopper!”
4 プログライズキー押込時(2回目前半) “Rising!”
5 プログライズキー押込時(2回目後半) 必殺技音

どこでどういう音声を再生させるかで、いろんな遊び方ができるようになっています。

遊び方

実際にどんな風に遊べるかは、冒頭のYouTubeの動画をご覧頂くのが良いと思いますので、そちらをご参照くださいませ。ここでは、どういうふうに音声を設定しているかを少し詳細に説明します。

SG・GP版のDX化ツールとして

一番素直な遊び方で、SG・GP版のプログライズキーに、DX版とほぼ同等の音声を追加して遊ぶことができるようになります。例えば『ドラミング響鬼プログライズキー』だと、以下のように音声を設定します。

No. タイミング
1 拡張パック挿入時 “Ready to utilize.”
2 ボタン押下時 “Authorize.”
3 プログライズキー押込時(1回目) なし(無音)
4 プログライズキー押込時(2回目前半) “Druming!”
5 プログライズキー押込時(2回目後半) 必殺技音

No.1は別になんでもOKですが、せっかくなのでそれっぽく、”Ready to utilize.”にしています。アタッシュウェポンシリーズの音声ですね。

No.2に”Authorize.”を割り当てることにより、プログライズキーをゼロワンドライバーに接触させたタイミングでボタンを押せば”Authorize.”を鳴らすことができます。ここは人がタイミングを合わせる形で済ませています。

No.3は通常は変身音に相当しますが、SG・GP版でもさすがにこの音声は入っているので、無音を鳴らすように設定しています。

No.4の”Druming!”については、響鬼さんについてはたまたま変身音の中の”Druming”の部分をうまく単独で切り出せたので音声を用意することができましたが、例えばオーズとかだと”TATOBA Singing!”を用意するのはかなり困難な気がします。

No.5の必殺技音は、劇中の響鬼さんの音撃の音声を適当に編集して作ってみました。

 

上記が基本的な音声の設定方法ですが、極端な話、

No. タイミング
1 拡張パック挿入時 “Jump!”
2 ボタン押下時 “Authorize.”
3 プログライズキー押込時(1回目) “飛び上がライズ! Rising Hopper!”
4 プログライズキー押込時(2回目前半) “Rising!”
5 プログライズキー押込時(2回目後半) 必殺技音

のように、主要な音声を全て音声拡張パック側に設定してしまえば、プログライズキー側はほぼほぼ中身を空っぽにすることができます(←Authorize用の磁石だけは必要)。したがって、ラベルと音声は自作する必要はありますが、完全オリジナルのプログライズキーも比較的作りやすくなります。

CSM化ツールとして

個人的にはこれが音声拡張パックの一番効果的な使い方じゃないかなと思います。以下のように音声を設定します。

No. タイミング
1 拡張パック挿入時 REALxEYES(短縮版)
2 ボタン押下時 或人セリフ(「お前を止められるのはただ一人、俺だ!」)
3 プログライズキー押込時(1回目) なし(無音)
4 プログライズキー押込時(2回目前半) 必殺技テロップ音
5 プログライズキー押込時(2回目後半) 戦闘用BGM(短縮版)

このように設定することで、REALxEYESを鳴らしながら変身や必殺攻撃を行ったり、或人社長の決めセリフ後に劇中演出のような形で必殺攻撃を行うことが可能になります。自分で遊んでみたら想像以上に楽しかったです。オススメ(?)。

なお、動画を見た鋭い人なら、「REALxEYESを鳴らしてるときにプログライズキー押し込んでたけど、必殺技テロップ音と戦闘用BGM鳴ってないじゃん」ということに気が付いたかもしれません。これについては、後でソフトウェア解説のところでも改めて説明しますが、搭載しているMP3プレイヤーでは同時に二つの音声ファイルを鳴らすということはできないため、「音声の再生条件を満たした時にすでに音声が再生中であれば、新たに音声の再生はせず、現在再生中の音声を優先して鳴らし続ける」というルールでプログラムを書いているからです。

ZAIA製ハッキングツールとして

ラベルの部分は、後述しますが後から簡単に交換できるようにしているので、飛電製ではなくZAIA製ツールとして使うこともできます。この場合は、例えば以下のように音声を設定すれば、

No. タイミング
1 拡張パック挿入時 ハッキング音
2 ボタン押下時 “Jackrize.”
3 プログライズキー押込時(1回目) (無音) + “presented by ZAIA.”
4 プログライズキー押込時(2回目前半) なし(無音)
5 プログライズキー押込時(2回目後半) (無音) + “ZAIA Enterprise.”

1000%の嫌がらせをすることができます。変身すればZAIA。必殺技を出してもZAIA。

これはちょっと応用的な使い方をして、通常はNo.3, 4, 5はゼロワンドライバーとの連動部分のボタンが押されてから何秒後に音声を再生するというのが決まっているのですが、今回は通常の変身音や必殺技音の後に音声を再生する必要があるため、音声ファイルの方に無音部分を予め含んでおくことで、実際に音声を鳴らすタイミングを後ろの方にずらすようにしています。

サードパーティ製強化アイテムとして

『ゼロワン』では『企業』というものがかなりフィーチャリングされているので、せっかくなので過去に仮面ライダーシリーズで活躍した企業とコラボレーションしてみることにしました。変身後にセットして使用するような強化アイテムのイメージです。

【スマートブレインパック】

No. タイミング
1 拡張パック挿入時 “Ready.”
2 ボタン押下時 “Exceed charge.”
3 プログライズキー押込時(1回目) “Start up. … … 3, 2, 1, time out.”
4 プログライズキー押込時(2回目前半) “Start up. … … 3, 2, 1, time out.”
5 プログライズキー押込時(2回目後半) なし(無音)

スマートブレイン社製のパックを追加することで、ファイズアクセルに搭載した超加速能力を付与するイメージで作ってみました。

神の恵み 幻夢コーポレーションパック】

No. タイミング
1 拡張パック挿入時 “ハイバームテキ!”
2 ボタン押下時 “ガッチャーン!ムテキ!レベルアップ!”
3 プログライズキー押込時(1回目) 無敵音
4 プログライズキー押込時(2回目前半) 無敵音
5 プログライズキー押込時(2回目後半) なし(無音)

幻夢コーポレーション製のパックを追加することで、無敵の力を付与するイメージで作ってみました。一応、ハイパームテキの力を無制限に使えるのはエグゼイドのみということで、時間制限付きにしています。

 

ちなみに、この他社コラボの遊び方のアイデアを思いついたのは動画撮影日当日の朝で、製作前〜制作中はこの遊び方は自分でも全く想定していませんでした。鴻上ファウンデーション製、ユグドラシル製も当然存在していてもおかしくないな、とは思いましたが、ちょっと準備期間の関係で、今回は上記の2社のパックのみに絞ってのご紹介としました。

 

以上が遊び方の詳細説明になります。以降は中身の方の詳細説明になります。

 

ハードウェア解説

まず、ケースは3Dプリンタで作成しました。前回のプログライズライターでプラ板工作を覚えましたが、微調整のトライ&エラーが多く必要になる場合は、やっぱり3Dプリンタがラクです。

特に今回は、ドライバー連動スイッチの押し込み部分の関係で、ケースの大きさは結構細かく調整しました。ここがいい加減だと、プログライズキーを押し込んだときに音が鳴ったり鳴らなかったりして台無しになってしまうので。

この企業ロゴラベルを貼っている部分だけ、シルバーに塗装したプラ板を両面テープで貼り付けています。ラベルはスマホの液晶保護フィルムに貼り付けたものをプラ板に貼り付けるようにしているので、飛電製、ZAIA製をラベルの貼り替えで簡単に切り替えられるようにしています。プログライズライター用のプログライズキーでオーズタイプとビルドタイプを切り替えるのに使ったやり方と同じですね。3Dプリンタの印刷面だと液晶保護フィルムが全然貼り付いてくれなかったので、間に一枚プラ板を挟むようにしました。

なお、この企業ロゴのラベルはZXライドウォッチ、プログライズライターに引き続き、いつもご協力頂いている方に作成頂きました。感謝。

 

続いて、今回使用した主な電子部品の紹介です。

MP3ボイスモジュールは前作プログライズライターから使い始めたものですが、こういう小規模工作にはうってつけです。DFPlayer+マイクロSDカードを買うより安く済みます。コネクタ部分が結構大きくて邪魔になることもありますが、ニッパーで簡単に切り落としてしまえるので問題ありません。

あとは手元にあったタクトスイッチとスピーカーを使ったので、正式な型番はわかりません、すみません。

回路図はこんな感じで、いたってシンプルです。ポイントは、MP3プレイヤーのBusyピンを使用しているところです。これにより、「音声を再生しているとき/していないとき」で内部処理を簡単に分けることができるようになります。これについては、後のソフトウェア解説のところでまた改めて説明します。

また、上図を見て頂くとわかるように、今回は毎度おなじみのリチウムイオンポリマー充電池は使用していません。

電源は、ゼロワンドライバー側から供給してもらうようにしています。この形にすることで、誰のゼロワンドライバーでも使用できるような汎用性はなくなってしまうものの、サイズはコンパクトになり、また充電や電源ON/OFFが不要になって扱いやすくなるため、今回はこの形で実現することにしました。もちろん、汎用性重視で、サイズを多少大きくして、リチウムイオンボリマー充電池や単四電池3本とかを搭載するのもアリだと思います。そこは、何を重視するか次第です。

今回は音声ファイルは頻繁に書き換えることになるため、ここから簡単にPCと接続できるようにしておきました。

部品を全部詰め込んだところ。結構ギリギリの密な感じになりました。

ソフトウェア解説

高々150行程度のコードになりますので、いつもなら記事の最後にコードは載せていますが、今回はここに載せてしまいます。

////////// 基本定義 ////////////////////////////////////////////////////////////

#define MP3_RX_PIN        2
#define MP3_TX_PIN        3
#define MP3_BUSY_PIN      4
#define BTN_PUSH_PIN      5
#define BTN_DRIVER_PIN    6

#define ON  LOW
#define OFF HIGH

uint8_t prev_btn_push_state   = OFF;
uint8_t btn_push_state        = OFF;
uint8_t prev_btn_driver_state = OFF;
uint8_t btn_driver_state      = OFF;

uint8_t driver_counter = 0;
boolean isBusy = false;

////////// 音声処理 ////////////////////////////////////////////////////////////////

#include <SoftwareSerial.h>

#define SOUND_VOLUME_DEFAULT 25 // 0〜30

#define SOUND_1  1
#define SOUND_2  2
#define SOUND_3  3
#define SOUND_4  4
#define SOUND_5  5

#define STAGE_DRIVER_SOUND_INIT 0
#define STAGE_DRIVER_SOUND_1ST  1
#define STAGE_DRIVER_SOUND_2ND  2
#define STAGE_DRIVER_SOUND_3RD  3

#define WAIT_SOUND_3_MS 3000
#define WAIT_SOUND_4_MS  800
#define WAIT_SOUND_5_MS 5580

SoftwareSerial ss_mp3_player(MP3_RX_PIN, MP3_TX_PIN);

uint8_t stage_driver_sound = STAGE_DRIVER_SOUND_INIT;
unsigned long sound_wait_start_time = 0;

void mp3_play(uint8_t track){
  // この定義だと再生曲数は255に限定されるので注意。
  // Upper-Byte, Lower-Byteをちゃんと処理してやれば65535曲まで対応可能だが、
  // 容量的にそこまで使うことはほぼないと思われる。

  // なぜか、指定したトラックに対して以下のようにファイルが再生される
  // 指定:1 -> 再生:01.mp3
  // 指定:2 -> 再生:不可
  // 指定:3 -> 再生:02.mp3
  // 指定:4 -> 再生:不可
  // 指定:5 -> 再生:03.mp3
  // 指定:6 -> 再生:不可
  // 指定:7 -> 再生:04.mp3
  // 指定:8 -> 再生:不可
  // ...
  // 原因は不明だが、とりあえず上記仕様に合わせるようにしておく

  uint8_t temp_track = track*2 - 1;
  uint8_t play[6] = {0xAA,0x07,0x02,0x00,temp_track,temp_track+0xB3};
  ss_mp3_player.write(play,6);
}

void mp3_stop(){
  unsigned char stop[4] = {0xAA,0x04,0x00,0xAE};
  ss_mp3_player.write(stop,4);
}

void mp3_set_volume(uint8_t vol){
  uint8_t volume[5] = {0xAA,0x13,0x01,vol,vol+0xBE};
  ss_mp3_player.write(volume,5);
}

////////// メイン処理 ////////////////////////////////////////////////////////////

void setup(){
  pinMode(BTN_PUSH_PIN,  INPUT_PULLUP);
  pinMode(BTN_DRIVER_PIN,INPUT_PULLUP);
  pinMode(MP3_BUSY_PIN, INPUT);

  // MP3プレイヤーセットアップ
  ss_mp3_player.begin(9600);
  mp3_set_volume(SOUND_VOLUME_DEFAULT);

  // 起動エフェクト
  mp3_play(SOUND_1);
}

void loop(){

  unsigned long now_ms = millis();
  // BusyピンがHIGHなら再生中、LOWなら再生中でない
  isBusy = digitalRead(MP3_BUSY_PIN) == HIGH ? true: false; 

  //////////////////// ボタン処理 ////////////////////

  btn_push_state = digitalRead(BTN_PUSH_PIN);
  if(prev_btn_push_state == OFF && btn_push_state == ON){
    if(isBusy){
      mp3_stop();
    }else{
      mp3_play(SOUND_2);
    }
  }
  prev_btn_push_state = btn_push_state;

  btn_driver_state = digitalRead(BTN_DRIVER_PIN);
  if(prev_btn_driver_state == OFF && btn_driver_state == ON){
    driver_counter++;
    if(driver_counter == 1){
      stage_driver_sound = STAGE_DRIVER_SOUND_1ST;
      sound_wait_start_time = now_ms;
    }else if(driver_counter >= 2){
      stage_driver_sound = STAGE_DRIVER_SOUND_2ND;
      sound_wait_start_time = now_ms;
    }
  }
  prev_btn_driver_state = btn_driver_state;

  //////////////////// 時間経過処理 ////////////////////

  if(stage_driver_sound == STAGE_DRIVER_SOUND_1ST && now_ms - sound_wait_start_time >= WAIT_SOUND_3_MS){
    if(!isBusy){ // 曲が再生中でなければ再生する
      mp3_play(SOUND_3);
    }
    stage_driver_sound = STAGE_DRIVER_SOUND_INIT;
  }

  if(stage_driver_sound == STAGE_DRIVER_SOUND_2ND && now_ms - sound_wait_start_time >= WAIT_SOUND_4_MS){
    if(!isBusy){ // 曲が再生中でなければ再生する
      mp3_play(SOUND_4);
    }
    stage_driver_sound = STAGE_DRIVER_SOUND_3RD;
  }

  if(stage_driver_sound == STAGE_DRIVER_SOUND_3RD && now_ms - sound_wait_start_time >= WAIT_SOUND_5_MS){
    if(!isBusy){ // 曲が再生中でなければ再生する
      mp3_play(SOUND_5);
    }
    stage_driver_sound = STAGE_DRIVER_SOUND_INIT;
  }

  delay(20);
}

工夫点としては、先のCSM化ツールの遊び方やハードウェア解説のところでも少し説明しましたが、「音声が再生されている間にドライバー連動スイッチが押された場合は、現在再生されている音声を中断せずにそのまま再生し続ける」という仕様にしているところです。この仕様により、『REALxEYEZ』を流しながら必殺技を出すパターンと、テロップ+戦闘BGMを流しながら必殺技を出すパターンを同時に楽しむことができるようになりました。

音声が再生されているかどうかのチェックは、MP3ボイスモジュールに対してコマンドを送信することでも確認できるかもしれませんが、マイコン側のGPIOに空きがあるのであれば、今回のようにBusyピンを監視してしまうのがラクです。

まとめ

以上、『飛電ゼロワンドライバー専用 音声拡張パック』のご紹介でした。自分用にはゼロワンドライバー側も少し改造する形で作ってしまいましたが、筐体を少し大きくして電池搭載型にすれば誰のゼロワンドライバーでも使えるので、そのときは人それぞれでいろんな遊び方ができると思います。

さて、次の作品ですが、ちょっとゼロワン&オリジナルの工作は一回お休みにして、珍しいですが一つ頼まれごとにチャレンジしてみたいと思います。基本的に人に頼まれてのものづくりはやらないのですが、今回は例外的にトライしてみます。できるかどうかは正直未定なので、うまくいかなそうならしれっとゼロワン関係の工作に戻ることにします。