Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
バイナリ読むのにElixirしてみた
Search
Tomohiko Himura
October 01, 2024
110
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
バイナリ読むのにElixirしてみた
Tomohiko Himura
October 01, 2024
More Decks by Tomohiko Himura
See All by Tomohiko Himura
Marpでmermaidは簡単だときいたけど
eiel
1
2.4k
アジャイルはさておきMake People Awesomeしたい
eiel
0
220
レビューは最優先にするようにしている
eiel
0
350
再考 Fourkeys メトリクス
eiel
2
720
Test mockをSnapshot testする
eiel
0
170
devenvに入門した
eiel
1
170
関数プログラミングの考え方
eiel
1
380
逆コンウェイ作戦はフィードバックループを作るために 逆向きの流れをつくること (5分版)
eiel
0
500
組織のパフォーマンスを高めるために 第1話 学習と文化
eiel
0
280
Featured
See All Featured
The Spectacular Lies of Maps
axbom
PRO
1
820
New Earth Scene 8
popppiees
3
2.3k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
How to make the Groovebox
asonas
2
2.2k
Done Done
chrislema
186
16k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
So, you think you're a good person
axbom
PRO
2
2.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Ruling the World: When Life Gets Gamed
codingconduct
0
260
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
480
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
Transcript
バイナリ読むのにElixirしてみた 2024-10-01
自己紹介 ひむら ともひこ 最近してること • 音声合成入門
バイナリ解読にElixir
経緯 • PythonとRustで書き込んだ音声ファイルのそれぞれ挙動が違う • スピーカーから片方しか音がでてない • なにが違うのか ◦ 書き込み処理を見比べる ◦
書き込まれたファイルを見比べる
ファイルの中身をみてみるか
None
眠いときだっので 目と脳がきつい
ツールを使おう
$ nix-shell -p sox $ soxi output.wav Input File :
'output.wav' Channels : 1 Sample Rate : 24000 Precision : 25-bit Duration : 00:00:00.00 = 1 samples ~ 0.003125 CDDA sectors File Size : 956k Bit Rate : 32bit Sample Encoding: 32-bit Floating Point PCM
特に問題が見当たらない
自分で書いてみるかー
そういえば Erlangはバイナリのパターンマッチができる
Elixirでやってみるか
その前に基本 << 1 :: 32 >> # => << 0,
0, 0, 1 >> << 1 :: 16 >> # => << 0, 1 >> << 1 :: 8 >> # => << 1 >> << 1 :: 4 >> # => << 1::size(4) >> << 1 :: 2 >> # => << 1::size(2) >> <<1::size(2)>> # => << 1::size(2) >> << 256 :: 32 >> # => << 0, 0, 1, 0 >>
例 真ん中の2byteだけ取り出したい << _::8, a::16, _::8 >> = << 256::32
>> # => <<0, 0, 1, 0>> a # => 1 << _::8, a::16, _ >> = << 512::32 >> # => <<0, 0, 2, 0>> a # => 2
例 文字列に対しても << a::bitstring-8, b::bitstring-16, _ >> = "goro" a
# => “g” b # => “or”
例 文字列2 << a::bitstring-8, 111::8, b::bitstring-16 >> = "goro" a
#=> g b # => ro # 以下のような書き方もできる << a::bitstring-8, ?o, b::bitstring-16 >> = "goro" << a::bitstring-8, “o”, b::bitstring-16 >> = "goro"
例 case def x(v) do case v do << a::bitstring-8,
“o”, b :: bitstring-16 >> -> [a,b] << a ::bitstring-8, “a”, b :: bitstring-8 >> -> [a,b] end end x “goro” # => [“g”, “ro”] x “gao” # => [“g”, “o”]
WAVの構造を確認しながら 書いてみた
filename = Enum.at System.argv, 0 {:ok, data} = File.read filename
<< id :: bitstring-32, chunk_size :: integer-little-32, riff_type :: bitstring-32, rest >> = data IO.puts """ groupID: #{id} churk size: #{chunk_size} byte (filesize #{chunk_size+8}) riff type: #{riff_type} """
case rest do << “fmt “, # 先頭が “fmt “
で始まっていて… format_chunk_size :: integer-little-32, format_tag :: integer-little-16, channel :: unsigned-integer-little-16, sample_per_sec :: integer-little-32, avg_byte_per_sec :: integer-little-32, block_align :: integer-little-16, bits_per_sample :: integer-little-16, _ >> -> IO.puts """ chunkID: fmt format chunk size: #{format_chunk_size} byte format tag: #{format_tag} #{B.tag format_tag} channel: #{B.channel channel} #{channel} sample per sec: #{sample_per_sec} Hz byte per sec: #{avg_byte_per_sec} block align: #{block_align} bits per sample(bitrate): #{bits_per_sample} """ << “fact”, … >> -> # “fact” だったら... end
groupID: RIFF churk size: 956210 byte (filesize 956218) riff type:
WAVE chunkID: fmt format chunk size: 18 byte format tag: 3 IEEE float channel: mono 1 sample per sec: 24000 Hz byte per sec: 96000 block align: 4 bits per sample(bitrate): 32
まとめ
まとめというか振り返り - ErlangVMは通信を得意とするのでビット列を扱いやすいはず - 使いやすそうだった - ビット列をパターンマッチできる - 便利さがわかるところまで触れなかった -
でも、試す良い機会になった - 今回の用途では構造体をつらつら書くのと大差ない感じになってしまった - 別にElixirでなくても簡単にかけただろう - とはいえ、新しい道具を試すのは大切
で問題は解決したのか? • 昨夜書いてみただけなので、まだ解決はしていない
参考文献とか - https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3 E%3E/1-types - 指定できるtypeの確認に -