LoginSignup
10
9

More than 5 years have passed since last update.

oF、Max/MSP、QCから外部コマンドを実行する方法

Last updated at Posted at 2016-12-08

TL;DR

クリエイティブコーディング Advent Calendar 2016へ3本目の投稿です。

MacOSがBSD系UNIXであることを最大限活かすと、クリエィティブコーディングが少し楽になりますよ。
「oFでディレクトリ作るときはofDirectory::createDirectory(const string &dirPath, bool bRelativeToData=true, bool recursive=false)…?」なんてやらなくて良いんです。
そう、いつもと同じようにmkdirで良いんです。

たとえば…

  • 日別にログファイルを整理したい → mv, date
  • 書き出したファイルを圧縮したい → zip, tar
  • 処理が終わったら通知を出したい → terminal-notifier, osascript
  • 喋らせたい → say
  • Web APIを叩いた結果が欲しい → curl, wget, jq
  • 適当なアプリで開きたい → open

正直、osascriptでAppleScriptが叩ければ、すなわちMacOSのほとんどが制御できることになるので、
クリップボードを共有するなり、カーソルを動かすなり、音量を最大にするなり、他のアプリを前面に持ってくるなり、なんでもござれ。
こういったコマンドを駆使できるからクリエィティブコーディングは極力MacOSでやりたいと思っています。

参考までに、openFrameworksとMax/MSP、QuartzComposerからシェルを叩く方法をご紹介します。

w/ openFrameworks

ofSystem()を使う

もっとも簡単なのはofSystemを使う方法。

ofSystem("say -v Kyoko こんにちは");

ちゃんとPIPEする

ofSystem()では途中出力を受け取れないし、処理が終わるまでスレッドがブロックされるので、
BrettさんがGistに上げていた実装が参考になります。

SysCommand.h
//
//  SysCommand.h
//
//  Created by Brett Renfer on 2/22/12.
//

#pragma once
#include "ofThread.h"

class SysCommand : private ofThread
{
public:
    ofEvent<string> commandComplete;

    void callCommand( string command ){
        cmd = command;
        stopThread();
        startThread();
    }

    // CALL THIS DIRECTLY FOR BLOCKING COMMAND
    // thanks to: http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c
    std::string exec(char* cmd) {
        FILE* pipe = popen(cmd, "r");
        if (!pipe) return "ERROR";
        char buffer[128];
        std::string result = "";
        while(!feof(pipe)) {
            if(fgets(buffer, 128, pipe) != NULL)
                result += buffer;
        }
        pclose(pipe);
        return result;
    }

private:
    void threadedFunction(){
        ofLog( OF_LOG_VERBOSE, "call "+cmd );
        string result = exec( (char *) cmd.c_str() );
        ofLog( OF_LOG_VERBOSE, "RESULT "+result );
        stopThread();
        ofNotifyEvent( commandComplete, result, this );
    }
    string cmd;
};

w/ Max/MSP

Bill氏の"shell"オブジェクトを使う

Screen Shot 2016-12-08 at 22.12.40.png

公式のフォーラムからダウンロードできます。
中身を見るとCからpthreadしてますね。

赤松先生の"aka.shell"を使う

Screen Shot 2016-12-08 at 22.14.28.png

赤松先生のWebよりダウンロードできます。
こちらはpopenでの実装ですが、よりメジャーなので参考になる記事がたくさん見つかります。
Qiitaに詳しい記事もありました。 → UnixコマンドをインタフェースとしたMax-外部アプリ間の連携方法

w/ Quartz Composer

CommandLineTool

デペロッパーライブラリから謹製のサンプルコードが手に入ります。
古いので、Xcodeで読み込んでから微修正が必要です。
日本語で書かれた参考記事がありました。 → UNIX Command – execute in Quartz Composer

ShellCommandパッチを使う

shell-command-patch.png
Kosada inc.が公開しているShellCommandパッチを使う方法もあります。
Kinemaからダウンロードできます。

まとめ

どのツール/フレームワークも外部コマンドを実行できる仕組みが複数あります。
それぐらい強力な連携なのですが、いずれも「とんでもない引数を渡してた!」「コマンドを絶対パスにしないと動かない!」といったリスク&あるあるがあったりしますので、心してお使いくださいませ。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9