GPDSP ライブラリ概要
GPDSP とは
GPDSP ライブラリは, 音響演算やセンサデータの信号処理などのデジタル信号処理を手軽に行うための C++ 言語で記述されたライブラリです. 増幅や遅延や加算などを表す任意のノードをソースコード上で接続することにより, デジタル信号処理のアルゴリズムを迅速に構築して実行することができます.
開発者はデジタル信号処理の計算順序やアルゴリズムの詳細を記述する必要はなく, GPDSP ライブラリがデータフローを適切に最適化します. 最適化はデジタル信号処理の実行中にも動的に行われるため, ノードの構成をダイナミックに変更しても最速となる計算順序を自動的に探索します.
また, gpdsp 形式の外部ファイルから XML で記述された任意のノード構成を読み込み, 1つのノードとして利用することができます. この機能を利用することにより, あらかじめ用意されたノードの動作以外にも, 任意の特性を持つノードを作成して実行することができるようになります.
推奨環境と開発環境
GPDSP ライブラリは POSIX 準拠の C++ 言語で記述され, ソースコードとして提供されます. RTTI (Run-Time Type Information) を有効にした C++ 言語を利用できる環境であれば, ワンチップマイコンなどの少資源な環境でも動作させることができます.
一方で, 複雑な多数のノード構成の演算にはマシンパワーが必要であるため, リアルタイムにデジタル信号処理を行う場合は十分なマシンパワーを持った環境が推奨されます.
推奨環境
- C++ 11 (RTTI 有効)
- ヒープ割り当て利用可能
開発環境
- macOS High Sierra (10.13.3)
- Xcode 9.2 (9C40b)
- Apple LLVM version 9.0.0 (clang-900.0.39.2)
- MacBook Pro (Retina, 13-inch, Late 2013)
- 2.8 GHz Intel Core i7
- 16 GB 1600 MHz DDR3
- Intel Iris 1536 MB
ダウンロードとインストール
GPDSP ライブラリの最新版は, 以下のサイトからダウンロードすることができます.
http:/
クローン, もしくは .zip ファイルでダウンロードしたファイルを任意の場所に解凍して配置します. 実際の開発で利用するライブラリは lib/GPDSP ディレクトリに含まれており, ソースコードレベルでリンクして利用します.
ディレクトリの構成
- docs – doxygen により生成されたドキュメント
- lib – GPDSP ライブラリ本体
- mcss-doxygen – m.css フレームワーク用のドキュメントテンプレート
- openFrameworks – openFrameworks を利用したサンプルコード
- release – コンパイル済みのサンプルコード
利用方法
ダウンロードしたディレクトリに含まれる lib/GPDSP ディレクトリ以下のすべてのヘッダファイルとソースファイルを GPDSP ライブラリを利用したいプロジェクトに追加し, ソースコードから次のように読み込みます.
ヘッダファイルの読み込み
#include "GPDSP.hpp"
GPDSP ライブラリでは, 基本的には GPDSPNodeRenderer クラスを利用して, 各種ノードを生成したりノードを接続してデータフローを設計します.
各種ノードに固有の属性を設定するときは, GPDSPNodeRenderer クラスのインスタンスから各種ノードのインスタンスを取得して, ノードに固有の関数を呼び出します.
次に 100 バイトのデータに対して増幅率 2.0 のデジタル信号処理を行うプログラム例を示します.
GPDSP ライブラリを利用したプログラム例
#include "GPDSP.hpp" using namespace ir; GPDSPNodeRenderer dsp; float* in; float const* out; int i; // サンプリングレートを 44100Hz に設定 dsp.setRate(44100); // 100 バイトの入力バッファを確保して, バッファ入力ノードを作成 dsp.newNodeBufferInput("data_in", NULL, 100, 1); // 100 バイトの出力バッファを確保して, バッファ出力ノードを作成 dsp.newNodeBufferOutput("data_out", NULL, 100, 1); // 増幅率 2.0 の増幅ノードを作成 dsp.newNodeAmplify("amp", 2.0f); // 増幅ノードの入力とバッファ入力ノードの出力を接続 dsp.setLinkPositiveI("amp", 0, "data_in", 0); // バッファ出力ノードの入力と増幅ノードの出力を接続 dsp.setLinkPositiveI("data_out", 0, "amp", 0); // バッファ入力ノードが確保した 100 バイトのバッファを取得 in = dsp.getNodeBufferInput("data_in")->getBufferWritable(NULL, NULL); // バッファに処理前のデータを書き込み for (i = 0; i < 100; ++i) { in[i] = i / 100.0f; } // 100 バイト分のデジタル信号処理を実行 dsp.render(100); // バッファ出力ノードが確保した 100 バイトのバッファを取得 out = dsp.getNodeBufferOutput("data_out")->getBufferReadonly(NULL, NULL); // 処理後のデータをバッファから読み出し for (i = 0; i < 100; ++i) { std::cout << out[i] << std::endl; }
ノードの種類
GPDSP ライブラリには, 以下の表に示すような具象ノードがあらかじめ用意されています.
開発者は GPDSPGenerativeNode クラスを利用するか, 抽象ノードを継承した新しいノードを実装することにより, 独自の機能を持ったカスタムノードを追加することもできます.
クラス名 | 解説 |
---|---|
GPDSPBufferInputNode | バッファ入力ノード |
GPDSPBufferOutputNode | バッファ出力ノード |
GPDSPConstantNode | 定数ノード |
GPDSPSignNode | 符号ノード |
GPDSPGateNode | 制限ノード |
GPDSPPeakNode | 極値ノード |
GPDSPAmplifyNode | 増幅ノード |
GPDSPDelayNode | 単位遅延ノード |
GPDSPBufferNode | 任意遅延ノード |
GPDSPSumNode | 総和ノード |
GPDSPMultiplyNode | 総積ノード |
GPDSPSquareRootNode | 平方根ノード |
GPDSPSinWaveNode | サイン波ノード |
GPDSPTriangleWaveNode | 三角波ノード |
GPDSPSawtoothWaveNode | 鋸波ノード |
GPDSPSquareWaveNode | 矩形波ノード |
GPDSPGenerativeNode | 生成的ノード |
ライブラリの特徴
GPDSP ライブラリを利用することで, デジタル信号処理の計算順序やアルゴリズムの詳細を開発者が記述する必要がなくなります. これは GPDSPNodeRenderer::
一方で GPDSP ライブラリは, 一度接続されたノード構成をデジタル信号処理の途中で動的に再接続することを可能にします. GPDSPNodeRenderer::
また, ディレイ・フリー・ループなどの離散的に演算ができないノード構成や, 入力を待ち続け演算を完了できない条件なども自動的に判別し, 安全にエラーを返却します.
これらの動作は, GPDSPGenerativeNode クラスによりノード構成が再帰的な入れ子構造を持つ場合にも有効であり, ダイナミックに特性の変わる非常に柔軟なデジタル信号処理の実現を可能にします.
その他の詳細
上記では記述されていない詳細な情報については, こちらを参照してください.