Good afternoon, ladies and gentlemen.
I am new to DAISY SEED.
I have looked at some of your sample projects.
One of the things that bothered me a little was the use of global variables.
I don’t like to use global variables as much as possible.
So, I thought of creating a class called CoreSystem to control the whole program and implement all the necessary functions in it.
Is this an appropriate approach?
First, main.cpp should be as follows
#include "daisy_seed.h"
#include "daisysp.h"
#include "core_system.hpp"
int main(void){
core = std::make_unique<CoreSystem>();
core->run();
return 0;
}
Then, core_system.cpp should look like this
#include "daisy_seed.h"
#include "daisysp.h"
#include <memory>
#include "pedal_board.hpp"
using namespace daisysp;
using namespace daisy;
// CoreSystem クラスの前方宣言
class CoreSystem;
// CoreSystem クラスのインスタンスを保持するユニークポインタ
std::unique_ptr<CoreSystem> core;
// オーディオコールバック関数の前方宣言
void audioCallback(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size);
// CoreSystem クラスの定義
class CoreSystem
{
public:
CoreSystem() : feedback_(0.5f), delay_time_(0.5f * 48000.0f) // ディレイタイム0.5秒
{
}
void init(){
hw_.Configure();
hw_.Init();
hw_.SetAudioBlockSize(4); // コールバックごとのサンプル数
hw_.StartAudio(audioCallback);
// ディレイエフェクトの初期化
delay_.Init();
delay_.SetDelay(delay_time_);
}
void run(){
init();
while(1) {
// メインループのコード
}
}
// インスタンスメンバー関数
void processAudio(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size)
{
for (size_t i = 0; i < size; i++)
{
applyDelayEffect(in, out, i);
}
}
private:
daisy::DaisySeed hw_;
DelayLine<float, 48000> delay_; // 1秒のディレイバッファ
float feedback_; // フィードバック量
float delay_time_; // ディレイタイム(サンプル数)
// ディレイエフェクトを適用するメンバー関数
void applyDelayEffect(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t index)
{
float dry_signal = in[0][index];
float wet_signal = delay_.Read();
delay_.Write(dry_signal + (wet_signal * feedback_));
out[0][index] = dry_signal + wet_signal;
out[1][index] = out[0][index];
}
};
// オーディオコールバック関数の定義
void audioCallback(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size)
{
if (core)
{
core->processAudio(in, out, size);
}
}
The pointer to the CoreSystem is made a global variable, and in main(), we just initialize the CoreSystem.
StartAudio() is a static function because the argument to hw_.StartAudio() must be a static function,
StartAudio() must be a static function, so only the audio callback is a global function.
In this function, CoreSystem, a global variable, is referenced, and necessary processing is implemented in CoreSystem.
Aggregating this entire system into a CoreSystem Class has the advantage that while CoreSystem can be accessed from all programs, only one global variable is needed.
Is there any problem with this idea?
Also, I would like to be able to declare the audio callback in the class, but do you have any other ideas? (I thought about making it a static function of the class, but decided against it because I felt it would be too complicated.)