exerciseに音量追加とあったので、やってみました。
こないだやったデシベルで音量を追加したいね
JUCEプログラミングチュートリアル 、Synthの「 Build a sine wave synthesiser」の項目を進めています。
エクササイズで音量を追加とありましたので、ちょっとやってみます。この間までチュートリアルで進めていたデシベル表記でのスライダーを実装してみたいと考えたので、復習しながらやってみることにしました。
こんな人の役に立つかも
・JUCEプログラミングを勉強している人
・JUCEの「Build a sine wave synthesiser」チュートリアルを進めている人
・JUCEでスライダーのデシベル表示をしたい人
MainComponent.h
DecibelSliderクラス
次のDecibelSliderクラスを追加しました。
#pragma once
#include <JuceHeader.h>
class DecibelSlider : public juce::Slider
{
public:
DecibelSlider() {}
double getValueFromText(const juce::String& text) override
{
auto minusInfinitydB = -100.0;
auto decibelText = text.upToFirstOccurrenceOf("dB", false, false).trim();
return decibelText.equalsIgnoreCase("-INF") ? minusInfinitydB
: decibelText.getDoubleValue();
}
juce::String getTextFromValue(double value) override
{
return juce::Decibels::toString(value);
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DecibelSlider)
};
このDecibelSliderクラスは、以前のチュートリアルで実装したものをコピぺしました。一つだけ変更点として、このクラス定義の中に関数の実装も含めてしまった点を変更しました。というのも、わざわざcppに分離するよりも、このようにひとまとめにしてしまえば、今後、ヘッダーファイルにコピペして利用できるので、便利かと思ったからです。
MainComponentクラス
MainComponentクラスには、privateなメンバとして、先ほど定義したDecibelSliderクラスのオブジェクト「volumeSlider」と、floatのゲイン値の変数「volume」を定義しました。
//...略...
private:
juce::Slider frequencySlider;
double currentSampleRate = 0.0, currentAngle = 0.0, angleDelta = 0.0;
//ここに音量関連のメンバ変数を追加しました。
float volume = 0.0f;
DecibelSlider volumeSlider;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
MainComponent.cpp
コンストラクタ
まずはコンストラクタです。DecibelSliderクラスのvolumeSliderを初期化します。
MainComponent::MainComponent()
{
//...略...
//DecibelSliderを初期化します。
addAndMakeVisible(volumeSlider);
volumeSlider.setRange(-100.0, -12.0);
volumeSlider.onValueChange = [this]
{
volume = juce::Decibels::decibelsToGain((float)volumeSlider.getValue());
};
volumeSlider.setValue(juce::Decibels::gainToDecibels(volume));
setSize(600, 100);
setAudioChannels(0, 2);
}
初期化の時に与える数値はデシベルです。また、ハンドラの定義もここでしておきます。スライダーの値が変化した時には、volume変数に数値を書き換えるようにしています。もちろん、volumeに与える数値はゲイン値なので、Decibelクラスで変換をしています。
getNextAudioBlock関数
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
//...略...
for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
{
auto currentSample = (float)std::sin(currentAngle);
currentAngle += angleDelta;
leftBuffer[sample] = currentSample * level * volume;//ここと
rightBuffer[sample] = currentSample * level * volume;//ここにvolumeを掛けます。
}
}
音声処理のところで、最後にvolume変数を掛け合わせることで、音量を反映しています。LとR2チャンネルとも変更しています。
resized関数
最後に、GUIへの配置を行います。volumeSliderは、frequencySlidernのすぐ下に配置されるように、原点Yの値を30として少し下に下げただけです。
void MainComponent::resized()
{
frequencySlider.setBounds(10, 10, getWidth() - 20, 20);
volumeSlider.setBounds(10, 30, getWidth() - 20, 20);//ここを追加しました。
}
最終的に、次のようなGUIのアプリとなりました。
デシベルのスライダーはこれから使いまわせそうです。