Archives : Max Tips集

top > archives > max_tips > 2016/10/02

ドラッグ&ドロップでファイルを読み込んじゃえ!

概要

「いちいちダイアログを表示させてファイルを読み込むのはめんどくさい!」
ということで、ある部分にファイルをドラッグ&ドロップしたらファイルを読み込んでくれるような処理を実装してみました。

今回はbuffer~(オーディオファイル)を対象にした処理ですが、応用すればオーディオファイル以外の処理でも使えます。

【注意】用語、各オブジェクトの詳細な説明は致しませんので、その辺についてはMaxのリファレンスをご参照くださいますようお願い致します。

パッチ説明

main_pic

※クリックすると拡大図が見れます。

「枠の中にオーディオファイルをドラッグ&ドロップすればファイルを読み込まれる。」
...と、難しいことは一切抜きにして至ってシンプルに表現してみました。

あ、このパッチはあくまでもファイルを読み込むだけのパッチです。

1.まずは入り口を...。

まずは入り口(ファイルを取り入れるところ)から。

dropfile

ここの部分はdropfileオブジェクトを敷きます。
あ、dropfileオブジェクト内にある「drag and drop afile here...」はコメントオブジェクトで追加しているものです。
決してdropfileオブジェクトのみで表示されるものではないのでご注意ください。

さて、このオブジェクトにファイルをツッコんだらアウトレット(※オブジェクトの出口)からファイルのパス名を吐いてくれるだけのシンプルなオブジェクトです。
dropfileオブジェクトから出力されたパス(メッセージ)は下のメッセージボックスに格納されます。
まあ、こんな感じですね...。

ここで注意しなければいけないのは
「パス名を表記させるにはメッセージボックス第2インレットにつなぐこと」
です。インレットとはオブジェクトの入り口部分にあたります。

第1インレットにつながずに処理を実行させるとメッセージボックスにパス名が格納されず、ただメッセージボックスがbangされる(中身の無いメッセージが次の処理に送られる)だけなので意味がありません。
もちろん、格納したメッセージを次の処理に送るためには第1インレットにbangをしてやる必要があります。

なお、メッセージボックスのインレットの関係については下記の図のとおりになります。

ん?ちょっと待てや、第1インレットの前になんか変なもんが挟まれとるやないか?

はいはい、分かっておりますよ。
まあ、これに関しては後々説明するんでもう少しお待ちくださいな。

2.どうやってファイル読み込ませるか?

まず、読み込ませたいファイルのパスをメッセージボックスに格納しました。

では、こいつをbuffer~オブジェクトに読み込ませるにはどうすればいいか?

いろいろとやり方はあるんですが、今回は「オーディオファイル全体を読み込みたい」のでreplaceメッセージを使う事にします。
今回のパッチで言うと、この部分にあたります。

お察しのいい方はここまでの説明でなんとなく分かると思いますが、基本的なところから説明していきますね。

「そもそもbuffer~オブジェクトってなんやねん?」と言う方は昔ブログで説明した記事があるのでそちらをご覧くださいませ。→buffer~オブジェクトについて

まず、buffer~オブジェクトにオーディオファイルを読み込むにはreplaceメッセージを送ります、と。
パッチで表すと今感じですね。

この"replace"と書かれたメッセージボックスを押すことでお馴染みのファイルダイアログが表示されます。
ここで選択したオーディオファイル(例えば、上に合わせてtest_160914.wavを選んだとしましょう。)がbuffer~で生成したsample_bufというバッファーに読み込まれます。
実際の処理としては、
「メッセージ:"replace C:~中略~/test_160914.wav"をbuffer~に送る」
という処理が行われています。
...とまあ、これで、オーディオファイルの読み込みはできました。

では、今一度、今回のケースに戻ってみましょう。

パス名が書かれたメッセージボックスの下にprependオブジェクトなるものがあります。

prependオブジェクトは「隣の文字列(オーギュメントで指定した文字列)を送られたメッセージの頭に追記する」という役割があります。
似たようなオブジェクトに「送られてきたメッセージの後ろにオーギュメントで指定した文字列を追記」するappendオブジェクトというものもあります。

今回の場合、パス名が書かれたメッセージボックスに対してbangすることでパス名(メッセージ)がprependオブジェクトに送られ、パス名の頭にreplaceを追記され、
「メッセージ:"replace C:~中略~/test_160914.wav"」
が作られ、buffer~オブジェクトにこのメッセージが送られます。

結果として、replaceボタンを押してダイアログが表示され読み込むのと同じ処理になるという訳です。

3.もしかしたら上手い事メッセージが生成されず、メッセージが送られないかもしれない。

オーディオファイルを読み込む原理としては上で説明した通りになります。
では、もう一度、最初の部分に戻ってみましょう。

少し初めの状態から一部の処理を抜いた状態にしておりますが、これでも同じように処理(オーディオファイルを読み込む)が行われます。
ただ、これだと場合によってはパス名がメッセージボックスに表記される前にメッセージボックスがbangされる可能性があります。

Maxの仕様上、「同時に実行されようとするオブジェクトが複数ある場合、右側のオブジェクトから順に実行される。※左右の位置が同じ場合は下側から実行される」というルールがあります。
まあ、今回のパッチ程度のコーディングだと何の問題も無く処理は行われますが、大規模なパッチを制作する場合、いくつものオブジェクトを並列につなげるなんて当たり前のようにやりますので、オブジェクトの配置の仕方によっては上手い事処理が予定通りの順番に実行されないなんてこともあります。
正直、僕はそれで何回Maxに泣かされたことか...(笑)。

人生に保険というものが必要であるようにプログラムだって不具合を想定した保険的なコードというものは重要なものなんです。
ましてや、僕みたいな(元)落ちこぼれエンジニアにはこういう保険は何重にも入っておくに越したことがありません。
さて、今回のパッチの場合だと、この部分が保険的な役割を果たしてくれます。

やっと初めのところに戻ってこれましたね。
そうです、こいつらが安定した動作をやってくれるように仕込んでくれているのです。
実際に何をやっているかと言うと、「dropfileオブジェからメッセージに対してdelayオブジェクトで指定した20msec送らせてメッセージを出力する」ということをやってくれています。
delayオブジェクトの上にある〇はボタンオブジェクトなんですが、これも保険的な役割で万が一dropfileが出力したメッセージをメッセージボックスの第1インレットに入力した時にbang的な働きをしてくれないと困るので、ボタンオブジェを介して確実にbangメッセージを出すようにしています。

つまりのところ、
1.dropfileにオーディオファイルをドロップする
2.dropfileからパス名(メッセージ)が出力される
3.ボタン・オブジェクトを通り、bangが出力される
4.delayオブジェクトで20msec待機させられる
5.その間にメッセージボックスの第2インレットからパス名がメッセージボックスに格納される
6.bangメッセージがメッセージボックスに送られ、パス名がメッセージとして出力される
という処理の流れになっています。

うーん、なんかいろいろとツッコみたいことが...。
察しのいい方は究極にナイスなツッコミを思いついたかと思いますが、今は黙っておいてください。
(後でちゃんと自虐的に書いていますから...(涙)。)

4.せっかくなんだから格納されてる波形も表示させましょうや。

せっかくなんで読込んだオーディオファイルの波形を表示させてみましょう。
波形表示はwaveformオブジェクトを使い、下記のようにつなげます。

オーディオファイルを読み込ませると同時にbuffer~オブジェクト(第2アウトレット)からbangが出力されるので"set バッファー名(今回の場合だと"set sample_buf")"メッセージをwaveformオブジェクトに送ると波形が表示されます。

まあ、buffer~オブジェクトをダブルクリックすることでも波形を見ることはできますが、いちいちダブクリせなアカンなんて、やっぱりめんどくさいじゃないですか?
それにこうした方が「ああ、ちゃんと処理できてるなあ...。」って嬉しくもなりますし(笑)。

とりあえず、これで完成!おっつです!

5.実は...。

ここまで長ったらしく説明してきましたけど、上記の内容って実はこれで実現できます。

「dropfileからパス名が吐かれるんだったら直接prependオブジェクトで繋げたらええやないか。」

うん、まさにその通り。
ぶっちゃけ、僕自身、説明を書いている途中で気づきました。
大バカ野郎でした。すみません...(苦笑)。

仕組みと理屈さえわかれば上記で長ったらしく説明したことをたったこれだけのことでまとめることができます。

...うん、何も言わないで。長ったらしく書いてきたことに対する労力がマジで無下になるから(笑)。

と、まあ、今回の説明はこんな感じになります。

上記の内容を踏まえて他の用途でも応用して頂けたらな、と思いますのでぜひ試してみてください。
もちろん、これが絶対というわけではないので試行錯誤してみて、いい方法を模索してもらえればとおもいます。

それでは。

ダウンロード

パッチファイル
※Maxは必要です。
ダウンロード

- Page Top -

Archives

Archives内リンク

Archivesトップへ戻る

関連ページ

Max Patch置き場

Maxパッチの利用規約