【JUCEプラグイン開発】C++で処理時間の計測をしてみる

パンダさん

processBlockでどのくらい時間がかかるのか知りたいな

コパンダ

C++の処理時間計測クラスを使ってみたらわかるかも

ディレイのプラグイン内では、音声処理部分で条件を利用してしまっているので、処理時間が気になっていました。そのため、C++で処理時間を計測するようなプログラムを検証してみました。ディレイプラグインのprocessBlockがどのくらい時間かかっているかを計測してみました。

今までのディレイプラグインの制作過程の記事については、こちらをご参照ください。

C++の処理時間計測について、幾つかの方法があるようです。こちらの記事を参考にさせて頂きました。

今回は、C++11以降で利用できる、Chronoクラスを選択してみました。いろいろと調べた結果、次のような特徴がありました。

①クロスプラットフォーム

②記載が直感的でわかりやすい

③およそミリ秒単位で時間取得可能

目次

こんな人の約に立つかも

・C++のChronoクラスで処理時間を計測したい人

・JUCEプログラミングで処理時間を計測したい人

・JUCE開発のデバッグ手法を模索している人

処理時間計測の実装

処理の概要

C++のChronoクラスで時間を計測するには、次のシンプルな3ステップで計測ができます。

①最初にchronoをincludeします。

#include <chrono>

②chronoクラスを使った処理で計測対象処理を挟み込みます。

        std::chrono::system_clock::time_point start, end;
        start = std::chrono::system_clock::now();

        //ここに時間を計測したい処理を挟みます。

        end = std::chrono::system_clock::now();

③次のようにして、計測時間をミリ秒で出力します。最後はJUCEのDBGでコンソールに出力します。

//ミリ秒で処理時間を取得します。
        double time = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0);
        DBG("time:" << time);

プラグイン内の処理時間計測

先ほどの計測プログラムを、プラグインの音声処理の時間計測に埋め込んでみました。

プリプロセッサの追加を行いました。


#pragma once

#include <JuceHeader.h>

#include <chrono>//追加しました

#define MAXDELAYNUM 10.0f

processBlockの処理時間を計測したかったので、次のようにChronoクラスのプログラムで処理を挟み込みました。

void TheDelayAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    //[1]chronoクラスの準備です。
    std::chrono::system_clock::time_point start, end;
    start = std::chrono::system_clock::now();//[1-1]スタート時間を記録します。

    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    //...略...
 
    auto block = juce::dsp::AudioBlock<float>(buffer).getSubBlock((size_t)0, (size_t)buffer.getNumSamples());
    auto context = juce::dsp::ProcessContextReplacing<float>(block);
    processorChain.process(context);

    //[2]処理終了時間を記録します。
    end = std::chrono::system_clock::now();

    //[3]計測時間をミリ秒で出力します。
    double time = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0);
    DBG("time:" << time << "ms");
}

③のようにして、最後にDBGでコンソール出力を行いました。

結構処理時間にもばらつきがありますので、今の状態では、処理が速すぎて追うのも大変なので、100階の処理を平均化して出力しようと思いました。

publicなメンバとして、テスト用のカウンターと累積用の変数を作成しました。

    int test_cnt = 1;
    double test_time = 0.0;

processBlock関数の最後で、次のように平均化処理を行いました。

//...略...
    double time = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0);

    //以下の処理で100回の平均を作成して出力するように変更しました。
    test_time += time;  

    if (test_cnt >= 100) {
        DBG("time:" << test_time/100);
        test_cnt = 1;
        test_time = 0.0;
    }
    else {
        test_cnt++;
    }
}

大体、0.06msec~0.2msecくらいの処理時間ということが分かりました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次