Tech Racho エンジニアの「?」を「!」に。
  • 開発

python-oscを使ってみる:後編

本日も

暑いです。昨晩少々飲み過ぎたせいで集中力とお金がなくなってしまいました。アルバイトの片山です。用務員としてアルバイトで採用されたはずがいつの間にかダラダラと記事書くだけのお荷物になっていることに気づきましたので、今度久しぶりに雑用をしたいなぁと思っています。


さて、前回、PythonでOSC(Open Sound Control)を扱ってみようということでしょうもない感じのコードを書きましたので、それらをもう少し応用していきたいと思います。

今回も前回に引き続き、Puredataを使います。Pythonは3です。

PythonとPuredataをOSCで連携する

Pythonをクライアント側(送信側)、Puredataをサーバー側(受信側)としてOSCで連携していきます。

前回も掲載しましたが、一応復習(と文字数稼ぎ)を兼ねてやっていきたいと思います。

python-oscでOSCを飛ばす

pyosc.py


import argparse from pythonosc import osc_message_builder from pythonosc import udp_client port_num = 8002 # セットアップ parser = argparse.ArgumentParser() parser.add_argument("--ip", default="127.0.0.1", help="The ip of th OSC Server") parser.add_argument("--port", type=int, default=port_num, help="The port the OSC server is listening on") args = parser.parse_args() client = udp_client.UDPClient(args.ip, args.port) print("ip:127.0.0.1, port:" + str(port_num) + ", address:/filter") def main(): print("type int:") input_str = input() osc_msg, osc_list = make_osc(input_str) print(osc_list) client.send(osc_msg) def make_osc(input_str): msg = osc_message_builder.OscMessageBuilder(address= "/filter") input_list = list(input_str) output_list = [] for i in range(len(input_list)): output_list.append(int(input_list[i])) msg.add_arg(output_list[i]) msg = msg.build() return msg, output_list if __name__ == "__main__": while True: main()

Pd(Puredata)のパッチは

puredata

ターミナルから


$ python3 pyosc.py ip:127.0.0.1, port:8002, address:/filter type int: 12345 [1, 2, 3, 4, 5] type int:

するとPdのコンソールにこんな感じにOSCメッセージが表示されます。

puredata

ちなみに、上のpyosc.pyですが、(私が無精したせいで)数字以外を入力するとエラーでプログラムが終了してしまうので、数字だけ入力するように気をつけて下さい。

というか大した手間じゃなさそうなのでPythonの勉強も兼ねて強制終了しないコードに書き換えてみました。

基本的に私は「とりあえず動けばいいでしょ」という雑な性格で例外処理のような丁寧な作業はやったことはないのですが、Pythonではとても簡単に出来そうな感じだったのでちょっと書き換えてみました。


import argparse import sys from pythonosc import osc_message_builder from pythonosc import udp_client port_num = 8002 # setup parser = argparse.ArgumentParser() parser.add_argument("--ip", default="127.0.0.1", help="The ip of th OSC Server") parser.add_argument("--port", type=int, default=port_num, help="The port the OSC server is listening on") args = parser.parse_args() client = udp_client.UDPClient(args.ip, args.port) print("ip:127.0.0.1, port:" + str(port_num) + ", address:/filter") def main(): sys.stdout.write("type int:") input_str = input() osc_msg, osc_list = make_osc(input_str) print(osc_list) client.send(osc_msg) def make_osc(input_str): msg = osc_message_builder.OscMessageBuilder(address= "/filter") input_list = list(input_str) output_list = [] try: for i in range(len(input_list)): output_list.append(int(input_list[i])) msg.add_arg(output_list[i]) except ValueError: print("<ValueError!!>") msg = msg.build() return msg, output_list if __name__ == "__main__": while True: main()

tryとexceptを使ってあげると簡単に例外処理が出来ます。(書き方はこれでいいのかな……?)
int()の部分で引っかかるっぽいので一応周辺をゴッソリtryの中にぶち込んでみた感じです。

ひとまずこれで間違えて「buhi~!」とか入力してもValueErrorで強制終了することはなくなりました。

せっかく修正するということで、type int:とprintしていたところも、改行が邪魔だなぁと思っていたのもありprint()ではなく改行無しのsys.stdout.write()を使うように少し改良しました。


$ python3 pyosc.py ip:127.0.0.1, port:8002, address:/filter type int:12345 [1, 2, 3, 4, 5] type int:hogehoge <ValueError!!> [] type int:

こんな感じになります。

応用編(?)

復習という体裁の文字数稼ぎ(ほぼ前回のコピペ)が終わりましたので、ちょっとした応用をやってみたいと思います。

Pythonの方のコードは最早弄っても大して面白いことにならなさそうなので、Puredataの勉強を兼ねてPdのパッチをいじっていきたいと思います。(勉強というほどでもない)

ひとまず出来上がったパッチはこちらになります。OSCで送られてきた数値とRootの音をかけ合わせて倍音を合成しようというものです。超絶単純な加算合成です。

puredata


※注意(必ず読んで下さい)

  • 赤枠で囲ってあるVUメーターと垂直スライダーはPd-extendedの[メニューバー>配置]から設置できます
  • 必ず垂直スライダーは[右クリック>プロパティ]から「出力範囲 上:」を最大で1にしてください。さもないととんでもないことになることがあります。
  • ちなみに真四角のボックスは「オブジェクトボックス」、右上が欠けてるグレーのボックスは「ナンバーボックス」といいますのでパッチの参考にしてください
  • 音が出ない場合はoutput~のdspというところにチェックが入っていること、GainとRootが設定されていることを確認してください。
  • Gain等の調整はVUメーターを見ながら慎重に行って下さい。最初はかなりGainを絞った状態から始めたほうがいいです。

上のpyosc.pyを起動して適当な数字を入力すればこのパッチから音が出ます。

結論から申しますと、とてもつまらない音しか出ませんでした。
薄々予想はしていましたが、想像以上に退屈な音しか出なかったので流石にちょっとショックでした。

ですが、ひとまずOSCでPythonとPdを連携して音をだすところに結びつけることができました。

終わり

ちなみに、なぜosc~オブジェクトを13コ用意しているのかと言うと、JANコードを読み取った値から演奏できたら面白いかなと思ったからです。

JANコードというのはお菓子の袋とかについてるバーコードのことで、基本的には13桁の番号を表しています。

ジャン!(私が適当に生成したやつです)

puredata

糞寒いギャグが出てくるくらいには調子が悪くなってきたので、今回はこの辺にしておきます。

関連記事


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。