honeylab's blog

各種ハードウェアの改造、主にファミコンミニなどをやってます(ました)

技術書典16の託児サービスを使ったら売り上げが倍増した件について

今回ブログの方で告知するの忘れてましたが、技術書典16(オフライン会場)に参加してきました。

過去記事を読んでいる方は知っていると思いますが、うちには呼び込み君とその所有者である息子と、その妹がいます。

honeylab.hatenablog.jp

で、前回は特にその呼び込み君の本を作ったことと、うちの家庭の事情で子供たちを家に置いて私がオフライン会場に出てくることは難しいため、前回の技術書典15ではオンライン参加、その前の14ではオフライン会場のブース裏に子供を2人抱え込んで参加しました。

 

その前、多分6かな?では外部の一時預かりを利用しました。

https://aieiyohogakuen.com/ (いまはないようですが、当時池袋園がありました)

で、7の時になんと技術書典の運営としてサークル参加者向け託児サービスが始まり、これだ!と申し込んだのですが、息子がまさかの発熱で託児することができず、どうにかうちで見ててもらって私単騎で参加しました。

(コロナ禍以前のため、家族の発熱に対してはまだ制限がなかった時代の話です)

その後、コロナ禍を受けて託児サービスが難しくなり、提供が休止されていました。

 

そのため、技術書典14では子供をブース裏に抱え込んで参加することにしました

技術書典、普通の即売会からは考えられないほどブースが広く(1サークルで180cm机1卓)、ブース裏もまぁまぁ、こどもがうっかり転がっても大丈夫なぐらいな広さはあるんです。なぜか。

あとは子供たちがブース裏で極力退屈せず、最悪ずっとYoutubeでも見せておけばいいやと思ってやってみましたがこれがなかなか大失敗でした。
そんなに悪さをすることはありませんでしたが、まず到着時点で子供見ながらの移動・搬入のおかげでまずサークル入場遅刻。そのため開始前チェックに間に合わず販売開始が遅れ、それに伴いろくにPOPも飾ることもできずテーブルの上は本が並んでいるだけ。

どうにか値段表はつけましたが、表紙だけでは大した訴求もできず、前を通る人の目には映ってんだか映ってないんだかのままみんな素通りしていきます。そして暇だとぐずり出す子供達。ああもうw

昼飯も食わせないといけないし、遊びにもいきたいし、で結局15時前には撤収せざるを得ませんでした。

売り上げも過去の過去に子供を外部の一時預かりに委託して参加したときに比べて凄惨な結果になり、参加したという記録が残っただけな感じになりました。

 

という過去があった上で、コロナ禍を耐え切った技術書典、16で堂々の託児サービスの復活!(だったよね??経緯間違ってたらごめん)やっとキタ!ということで託児を申し込み、新刊を抱えて乗り込むことにしました。

 

託児サービスについて

nijiiropokke.info

同人イベントのための託児」と記載されているように、同人イベントの日程に合わせて一時保育を提供してくれている「にじいろポッケ」さんが運営しています。

そのため「〇〇合わせ」と表記されてるのおもろい。

comic.webnewtype.com

 

で、普通のイベントとかだと額面を書いていいのか悪いのかあれなんですが、ちゃんと案内されてるので書いておきますが、当然有料です。

https://nijiiropokke.info/?p=6075

このイベント合わせの日は8時間で8000円、とのことです。まぁ安いです。

しかもこの日は水族館遠足らしいです。すごい。

 

で、恐ろしいことに、「技術書店あわせ」の場合、(事前申し込みが必要です)
技術書典サークル参加者に対して無料で提供されます。恐ろしいです。
必要な持ち物として着替え、おやつ、お弁当、さえ持っていけば無料です。

託児場所も、サンシャインのビルの中なので、売り場からビルの中を5分も歩けば到着します。

活動の様子も随時Upしてくれるので安心です

そんなわけで全く子供の心配もせず設営に専念でき、

無事開催時間満了で参加することができました。
売り上げとしても無事十分な冊数を頒布でき、ちゃんと「参加した」感を得ることができました。

終了後お迎えで、子供達からも特に不平不満もなく、十分に遊んでいただいたことがよくわかりました。

 

詳細なレポートもいただけて大変感謝です。

(↓名前出てますが隠してないので問題ないです)

下の子、保育園ではお昼寝しますが自宅で休日に寝ることはほとんどないんですが、ポックリと昼寝したらしいです。びっくり。

そんなわけで、うちの体制としてはちょうどいいところに一時保育が可能であるか、この施策が行われている技術書典ぐらいしか参加できず、特に技術書典に関しては託児利用者が優遇され過ぎているのではないかという気がしないでもないですが、ちゃんと体制として運営されている、ということでありがたく利用させていただけました。ありがとうございました。

 

で、新刊ですが、そんなに売れるもんでもなく、万人に刺さるわけではないので物理本は取り置きを残すのみになっています。

techbookfest.org

その他の本に関しては、引き続き開催されているオンラインマーケットにて電子版をDLしていただくことも出来ますんので、うっかり刺さった方は是非読んでいただけたら嬉しいです。

 

techbookfest.org

DAM XG1000の演奏中にTMIDI鍵盤表示風の画面を表示する

いよいよ煮詰まってきました。

元々私がこのカラオケマシンをいじっているのは、カラオケ中に
画面内にただの「見えるガイドメロディ」ではなく、
なんらかの方法で歌唱すべき階名を表示することなのです。

↓正式名称「見えるガイドメロディ」

採点開発者突撃インタビュー!Vol.2 精密採点II編【後編】|カラオケDAM公式

できれば五線譜、もしくは階名付きのピアノロールを出したい。

そのためには、現在再生している、本来は採点に使用されているデータを横取りし、
さらに画面表示を横取りしなければなりません。

研究に研究を重ね、ようやく全てのデータの取得が完了し、
画面表示の基礎部分ができたので、これから画面表示機能を精緻化させていく予定です。

そのファーストステップとして、DTMをやっていた人なら誰も知っている
「TMIDI Player」に内蔵されている、鍵盤表示画面を実装してみました。

TMIDI Playerには鍵盤表示画面内に、
各チャンネルの和音を解析してコード表示する機能もあるんですよね。
これと同じようにコードを表示してやれば、伴奏補助機能がつくんですよ。
これをどうしても実装したくてな。

↓TMIDIPlayerの鍵盤表示画面。A06のところに「Cm」って出てる

 

実際に実装した鍵盤画面(WIP)

 

 

ここまでできたんだからあと少しだわ。
なんか音符長が想定より長いトラックがあったりして表示が変だけど、
とりあえずメロディがちゃんと動いてるのは見えると思う

 

っていうけど大変なのよこれ。

その辺の大変な技や、リバースエンジニアリングの手法などは、

5月に開催予定の技術書典16(2024/05/26)の新刊としてまとめて発表したいと思いますので興味のある方はぜひお買い求めください(自分の首を絞めた)

 

DAMの機械でDOOMが動いた

別にこれをやろうと思ってたわけではないんだけど、そういえばやってなかったな、というのと

DAMの機械でDOOM、DAAMじゃん、とかくだらないことを思いついたのでやってみることにしました。

 

ここまでのリバエンの成果で、一応画面に何かしら出せることはわかっていました。
しかし、動作している時に割り込んだりしているのでいまいち思い通りにはかけていませんでした。

 

そこで、DAMの機械の中の描画関数について調べていきました。

どうやら、CScreenというクラスがあり、そいつが描画関数を持っているらしい、ということはわかったのですが、いまいち挙動がよくわかりません。
あちらこちらにprintfやメモリダンプを埋め込み、調べていた結果、ある程度のまとめを得ました。

 

システムは以下の描画レイヤを持ち、バッファサイズとカラーフォーマットは以下の通り

0 LAYER_OSD 1280x720 INXDEXED SP8 

1 LAYER_LYRIC 1280x2880 RGB32

2 LAYER_SCORE 704x1920 RGB32

3 LAYER_VIDEO 1280x720 RGB32

4 LAYER_TFT_LYRIC 512x2048 TFT_RGB16

5 LAYER_TFT_BACK 512x2048 TFT_RGB16

6 LAYER_SUB_VIDEO 704x480 RGB32

・CScreenインスタンスを作成後、CreateメソッドでLayer IDとposition,sizeを指定すると、その大きさを持つサブウィンドウとして実体化される

・CScreenインスタンスは以下の描画メソッドを持ち、それぞれが作成したサブウィンドウ左上を0とする座標で描画可能。実際には親レイヤを参照し、ウィンドウ内に描画している。

PutCharの中身


・CSpriteというオブジェクトがあって、スプライト描画機能を持っている。
AddしてPutしておくと、スプライトとして保持される

これらを元に、とりあえずLAYER_LYRICレイヤを実体化し、

このバックバッファにDOOMのfb用のバックバッファを転送することで、

↑LyricLayerにバッファ作成し

DOOMのバッファからコピーする

このようにDOOMの画面を表示することができました。

 


しかし、ピクセル単位での転送なので結構重いね...
LAYER_VIDEOはどうやらデコーダからのDMAで受け取るっぽいのでその辺で何かできないかな?

 

さてしかし、ここまでやったおかげで描画周りを明確に把握することができましたので、
カラオケ再生中に追加情報を表示するのも割とできたりするような気もしてきましたぞ。

 

DAM カラオケコマンダ XG1000に自前BGV再生機能を追加

honeylab.hatenablog.jp

 

カラオケ、本人映像や専用アニメ映像が入っていると嬉しいですよね。
でも、皆さんがカラオケで歌うようなあまりメジャーではないアーティストや曲のBGVに
そういう専用映像が入ってくることは、公式ではほとんどないじゃないですか

せっかくなので、自分専用の映像を背景にカラオケしたいですよね。

多分、外部入力から入れる、っていう手ができる気もしますが、それだと同期が大変です。
ここは、本体を改造して自分用の映像を再生できたらいいなぁ、と30年ぐらい前から思っていました。

引き続きじわじわと逆コンパイルする日々の中、実現できそうな気がしたのでサクッと実装してみました。

大抵のカラオケ機では、曲のジャンルやアーティスト、事前設定されたパラメータなどから本体内に保存されている映像DBを参照し、専用映像があればそれを、なければ無難な映像を探し出して再生してくれます。

DAMでもそのようになっていて、ログを見るとその流れが確認できます。Image

まずはDBを見て、専用動画があるかを確認、なければさらに検索して動画を選択しているようです。

動画を検索する関数でファイル名リストを取得したあと、それぞれの動画が本当に存在しているかを「CMDVIndex::CheckPresentBGV」という関数でチェックし、OKならプレイリストに追加している、ということがわかりました。
ならば、この関数にファイル名が渡された時点でそのファイル名を自分専用の動画ファイル名に書き換えて仕舞えばそのファイルを再生してくれそうな気がします。

早速やっていきます。

CheckPresentBGVはファイル名を受け取りますが、実際にそのファイル名の格納されたフォルダを複数のフォルダ(304,305)から検索するようになっています。

見つかった場合、そのフォルダを引数で渡されたフォルダポインタ(LPWORD lpFolderNumber)に格納し、trueを返してくれるようになっていました。


なんと好都合。指定したフォルダから探す、として値渡しだった場合、関数一つ戻ってそっちで書き換える必要があるんですが、これならこの中で自分専用のフォルダを返してやればいいんじゃないでしょうか。
専用フォルダ番号は「666」とし、ファイル名に指定されたファイルを準備してやります。
動画ファイルは、あらかじめ曲番号に準じた形式で保存しておきます。
このファイルをコピーすると遅くなってしまいますので、シンボリックリンクで処理します。
対応しているファイル形式はいくつかありますが、とりあえずWMVがうまくいったためこれでやっていきます。

ついでに、同じ曲でも複数のBGV、バージョン違いが存在する場合、ランダムに選択されるようにしてみました。これなら最大10個のバージョンを準備できます。素敵!

で、この関数をどうやって書き換えるか、という話なんですが、よく私の使う

「LD_PRELOAD」でライブラリを読み込ませる、という方法を使います。

qiita.com

ATOMCamなどのハックもこの手法でやっています。

実際に記述した関数はこんな感じになります。

gist.github.com

大変ヘンテコな関数名「_ZN9CMDVIndex15CheckPresentBGVEPtmP15tagVSTREAM_TYPE」になっていますが、これは

「bool __thiscall CMDVIndex::CheckPresentBGV(CMDVIndex *this,LPWORD lpFolderNumber,DWORD dwFileNumber,VSTREAM_TYPE *type)」

C言語名前空間に配置した時に行われる「名前マングリング」という処理の結果です。

C++のクラス関数を上書きする際には、この名前で関数を書く必要があります。
また、引数にクラスオブジェクトのポインタが渡される場合、型情報は自分で定義するか、
ポインタを自分でインクリメントして型を設定し、アクセスする必要があります。
今回は本来の関数へ橋渡しするのと、数値を書き換えるだけなのでそこまでめんどくさいことをする必要はありません。

 

で、できたーーーーー

これでマジで好きな動画ファイルでカラオケができるぞ素敵すぎる!

 

 

 

DAMカラオケコマンダXG1000の便利隠し機能を発見した

honeylab.hatenablog.jp

前のブログからの続きでもあります。

センター室モードで採点機能が使えず消沈しつつ、新たな手法を探していると、
おそらくデバッグか開発・設定用と思われる新たな入力方法を見つけました

何と、起動時にコンソールにしてたシリアル入力、標準入力をパネルボタンと同じように扱ってくれることを発見しました。

 

 

これは便利!!!!!

これならマジでマイデンモクが自作できます!

 

スタートボタンだけハンドルされないんですが、
演奏モードを連続にしていればどうやらスタートボタンを押す機会はないようです。

DAMカラオケコマンダの遠隔制御モードを掌握した

前のブログで、うっかり買い集めたDAMのカラオケ機(専門用語で「コマンダー」というらしい)を買っていじっている話をしましたが

 

honeylab.hatenablog.jp

色々いじっていたところ「センター室モード」という特殊モードを発見しました。

Image

これは、外部の機器から曲番号をセットしたりして再生できる特別なモードです。

何のために実装されているのか。

カラオケマニアの人なら知っているかもしれませんが、一部の店舗では
各部屋にこのコマンダーを設置しているわけではなく、数室で共有するシステム、
カラオケの鉄人や、カラオケ館「Σシステム」などで使われているあのシステムです。

ja.wikipedia.org

中身を見てみると、「HotelSystem」というクラス名がついていました。

Image
ホテルとは。

よくあるラブなホテルなんかにある「カラオケ」と書いてる設備の一部は
各部屋にコマンダーが設置されているわけではなく、ホテル設備として準備されているテレビ一体型の配信システムにカラオケ予約キューがあり、そこにキューが入るとシステム内に番号を発信し、部屋のテレビでカラオケができる、というシステムを採用しています。

(最近は普通に部屋にコマンダがあることも多いみたいですが)


なんでそんなめんどくさいことをするのか。

こいつがバカ高いからです。

本体定価は200万〜300万円、加えて配信料や利用料など、
常に利用されることが前提のカラオケルームとは違い、これを常設したらとんでもないコストになってしまいますね。そうならないために、このシステムがあるわけです。

が、メーカーはこの使い方はOKなんですな。もしかしたら、これを利用するために別途契約がいるのかもしれませんが。

そう、利用する、と書いてありますが、使い方は説明書に書いてありません。

というわけで、解析していきます。

まず、コマンダが起動したら「8295ー00」をセットします。
すると「センター室モード」に入り、以後、本体は全く操作できません。

接続するのはカラオケ機背面のシリアルポート。
コマンド(通信プロトコル)は全く不明です。契約なりNDAしたら貰えるんじゃないですかね。

 

コンパイル

Image

そのほか大変省略!(約1週間の睡眠不足と数十ページのプリンタ印刷)

 

解析できました!

シリアルポートから好きな曲番号でカラオケの曲を再生することができました

 

が…

これ、遠隔で使用することが前提なこともあって採点機能が使えないんです…
(あとちょっとで解析完了というところで気づきました)

ええええええー、これ使ってマイセットリストを予約キューにブチ込む便利なアプリを作ろうと思っていたのにーーーーーーーーぴえんぴえん

完全にオプション込みで放り込むにはデンモク系のインターフェイスを使わないかんのか…
買って解析するか???高いな…逆コンパイルだけでいけないかなぁ

 

あーーーん

まぁ、このモード、ちょっと頑張ればシステムごっこできるので
その辺は時間のある時にやってみたいと思います。

 

せっかくなので、実験に使ったクソC言語コード置いときますね。

 

gist.github.com

 

あーーーん。デンモク、そもそもまともにペアリングから使ったことないから通信のイメージが湧かないんだよな。

DAM XG1000に入っているLinuxで遊ぶ方法

前回、うっかりJOYSOUNDのマシンを買って色々遊べたので、

honeylab.hatenablog.jp


続いてDAMの XG1000を買ったのですが、いじり過ぎてしまい壊してしまいました。

満を持して、もう一台XG1000を買ったので丁寧にいじっています。

DAM XG1000はLinuxが使用され、その上でカラオケシステムが動作しています。
せっかくLinuxが入っているのですが、自動でそのような動きをしているため、自由に使うことができません。

HDDを引っこ抜いて書き換えてあれやこれやする、というところで壊したので、
今回はできるだけ分解せず、ソフトウェアだけであれこれする方法が確立できたので
こっそり紹介します。

 

背面、コントロール端子のこの2ピンがそれぞれRS-232C(ttyS0)のRXとTXです。
TTLCMOSの5V/3V - 0V ではなく、RS-232Cレベルですので気をつけましょう

ブートローダの起動中、のメッセージを見ながら、徐にスペースキーを押すと
YAMON> のプロンプトで停止します。

Image
ここで

YAMON> pflash probe
YAMON> xrpc 0xac080090
YAMON> load zbf 0xb3000000
を実行すると、Linuxカーネルが読み込まれます。
ここで、
YAMON> go . "console=ttyS0 rdinit=/bin/sh"

する


と、直接busyboxのshが立ち上がります。

何が起きたかというと、内蔵Flashに記録されているLinuxカーネルにはrootfsとしてinitrdというミニファイルシステムが添付されています。

(initrdの中身)

 

何も指定しなければinitrdの中のinitが起動して、/etc/init.d/ からカラオケシステムが起動しますが、それをやめさせるためにrdinit=/bin/sh つまり、busyboxのシェルだけを起動させています。

initされてないのでマウントとかがされていませんが、ログイン不要でなんでもできるプロンプトになります。マウントが動いてないので /procとかも使えません。最低限。

 

で、ここで 

# exec init

すると、通常のカラオケシステムの起動ルーチンに戻ります。
それ以外の作業をしたければ、別途準備した rootfsにchrootする
rm /etc/init.d/S50NK1000
してから exec init すると、普通にマウントとかができてますが、/etc/shadowが使われたgettyが起動してしまうので、その前に/etc/passwdのroot行を上書きしてパスワードを無効化しましょう。

(R/Wマウントですが、これはRAMDISKなので次回起動時には影響しません。永続化されない。)

 /proc/versionとcpuinfoはこんな感じでした

 

参考までに、どっかから落としてきたこのCPU用のtoolchainでビルドした自前rootfs、自前ビルドbusyboxchrootした画面を置いておきます。
普通のLinuxですので、普通に作ったプログラムが動きます。

残念ながらお腹のLCDはそのままfbになったりはしていないようです。
頑張ってあれやこれやしたら何か出るかもしれませんが、今のところ難しそうです。

 

Image

 

もし何かしたければ、上記の S50NK1000の中で、 HDD-A、HDD-B、PATA HDD(搭載されていない)の順で /Data/MODUL/module.sh というスクリプトがあれば起動してくるようになっていますので、そこに引っ掛けるようにしてやれば永続化した自分専用の起動スクリプトを割り込ませることができます。フラッシュメモリをダンプするとか。

カラオケシステムが立ち上がると、telnetサービスも動きますが、そのままではパスワードがかかっていてログインできません。上記の流れの中で、/etc/passwdを上書きして、パスワードを無効化するといいです。(同様に、永続化はされません)

 

HDD-A、HDD-Bのp1はext3で、それぞれ/NK1000,/NK2000というマウントポイントにマウントされ、カラオケシステムから参照され、アップグレードなどのために二重化されています。そのため、スペック表記にある”RAID1”というのは実は正しくないと思われます。

カーネル上はRAIDもサポートされてますが、使ってないように見えます)

HDD p2にはOSMFという独自のファイルシステムがあるようですが、なんかよくわかりません。

 

p3はext3ファイルシステムですが、一部のバイトを書き換えてあり、XG1000以外のマシンに持っていっても認識されないようになっていました。


XG1000のLinux上ではおそらくカーネルにパッチがあってext3として認識されるようになっています。他で読みたいなら該当部分を書き換えてもいいです。
もし書き換えたものを戻しても、同じようにext3として認識されます。
注意点ですが、ext3は認識するのに、ext2がサポートされてないので、自前で作ったrootfsなどを読み込むときは注意が必要です。そのせいなのか、mount に -t ext3をつけないとダメなことがありました。

このようにすると、XG1000を普通のMIPS Linux環境として使用することができます。

 

できます!!