【JUCEプラグイン開発】ディレイエフェクト、テンポ同期部分、アンドゥ部分のGUIの調整、Macでの不具合修正

パンダさん

スライダー以外のGUI部分を作成しました。

コパンダ

配置の調整くらいかな~

JUCEでのディレイプラグイン製、スライダー以外のGUI部分を整えていきました。

赤枠の部分の作成の備忘録になります。

また、Macでビルドしたら、タイマーを使うと正常に機能していない部分をMac版のみプログラムを変更して対応しましたので、その修正点をまとめます。

目次

こんな人の役に立つかも

・JUCEプラグイン開発をしている人

・本ブログのディレイプラグイン作成をしている人

・JUCEでグラフィカルなGUIを作成したい人

プログラムの変更

コンストラクタ

TheDelayAudioProcessorEditor::TheDelayAudioProcessorEditor (TheDelayAudioProcessor& p, juce::AudioProcessorValueTreeState& vts, juce::UndoManager& um)//20211104
//...略...
    , undoButton("<-"), redoButton("->")//[1]アンドゥ、リドゥボタンの表記を変更しました。

//...略...

    //[2]トグルボタンの色をグレーにします。
    getLookAndFeel().setColour(juce::ToggleButton::tickColourId, juce::Colours::grey);
    getLookAndFeel().setColour(juce::ToggleButton::tickDisabledColourId, juce::Colours::grey);

    setSize (400, 300);
}

[1]で、アンドゥ、リドゥボタンに記載する文字をコンストラクタで変更しました。->という記号がちょうど良い大きさで、わかりやすい記号になったと思います。

[2]では、テンポシンク機能のトグルボタンの枠の色を変更します。デフォルトでは、白なので、背景により見にくくなってしまいます。そのため、setColour関数で、「tickColourId」と「tickDisabledColourId」を「grey」とすることで、トグルボタンの枠と、チェックマークがグレーになりました。

Paint関数

右下のロゴの画像を追加しました。

void TheDelayAudioProcessorEditor::paint (juce::Graphics& g)
{
//...略...

    //ロゴの画像を描画します。
    juce::Image logo = juce::ImageCache::getFromMemory(BinaryData::logo_png, BinaryData::logo_pngSize);
    g.drawImageAt(logo, 250, 220);
}

resized関数

最終的なresized関数でのGUIコンポーネントの配置は次のようになりました。力業で微調整を行っています。

void TheDelayAudioProcessorEditor::resized()
{
    //スライダー4個
    delayTimeLSlider.setBounds(40, 65, 64, 64);
    delayTimeRSlider.setBounds(122, 65, 64, 64);
    wetLevelSlider.setBounds(208, 70, 64, 64);
    feedbackSlider.setBounds(287, 70, 64, 64);

    //コンボボックス
    DelayNumerator.setBounds(40, 220, 100, 30);

    //テキストボタン
    undoButton.setBounds(260, 190, 30, 30);
    redoButton.setBounds(300, 190, 30, 30);

    //トグルボタン
    tempoSyncButton.setBounds(115, 185, 30, 30);
}

Macでのプログラム変更

Macでビルドして、LogicProXでプラグインを動作させると、テンポシンクの機能が正常に動作しておらず、タイマーを使わず音声処理内でパラメータ更新を行うと、うまく動作しました。

音声処理内で条件などを利用する部分について、少し後ろめたい感じもありましたが、正常に動作しましたので、Mac版については、この方式で行きたいと思います。

コンストラクタのタイマーを起動させないようにしました。

//AudioProcessorクラスのコンストラクタです。
{
//...略...

    //タイマーを停止します。
    //startTimerHz(30);

}

processBlock関数内でタイマーで行っていたパラメータ更新処理を行うように変更しました。

void TheDelayAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

//ここからパラメータ更新処理、以下を追加しました。
    float val2 = 0;
    float val3 = 0;

    if (tempopSyncState == true) {
        playHead = this->getPlayHead();
        playHead->getCurrentPosition(currentPositionInfo);

        current_bpm = currentPositionInfo.bpm;

        float selected_delayNum = *delayNumerator;
        float delayNum = 0.0f;
        if (selected_delayNum == 1.0f) {
            delayNum = 1.0f;
        }
        else if (selected_delayNum == 2.0f) {
            delayNum = 2.0f;
        }
        else if (selected_delayNum == 3.0f) {
            delayNum = 4.0f;
        }
        else if (selected_delayNum == 4.0f) {
            delayNum = 8.0f;
        }
        val2 = ((float)60.0 / current_bpm) * (4.0f / delayNum);

        if (val2 >= 2.0f) {
            val2 = 1.99f;
        }

        val3 = val2;
    }
    else {
        val2 = *delayTime_L;
        val3 = *delayTime_R;

        if (val2 >= 2.0f) {
            val2 = 1.99f;
        }
        if (val3 >= 2.0f) {
            val3 = 1.99f;
        }
    }

    processorChain.get<DelayIndex>().setDelayTime(0, val2);
    processorChain.get<DelayIndex>().setDelayTime(1, val3);
//ここまでを追加しました。

    float val4 = *wetLevel;
    float val5 = *feedback;
    processorChain.get<DelayIndex>().setWetLevel(val4);
    processorChain.get<DelayIndex>().setFeedback(val5);
 
    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);
}
よかったらシェアしてね!
目次
閉じる