//******************************************************************************
//
// Simple MIDI Library / SMWavetableSynthCtrl
//
// Wavetableシンセサイザ制御クラス
//
// Copyright (C) 2018-2019 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import <AudioUnit/AudioUnit.h>
#import <AudioToolbox/AudioToolbox.h>
#import "SMCommon.h"


//******************************************************************************
// パラメータ定義
//******************************************************************************
//デバイス情報
#define SM_WAVETABLE_SYNTH_DISPLAY_NAME         @"Internal Wavetable Synthesizer"
#define SM_WAVETABLE_SYNTH_DEVID_NAME           @"MIDITrail/Internal Wavetable Synthesizer"
#define SM_WAVETABLE_SYNTH_MANUFACTURER_NAME    @""

//パーカッションチャンネル番号（0始まり）
#define SM_WAVETABLE_SYNTH_PERCUSSION_CH		(9)

//マルチチャンネルミキサーサンプルレート
#define SM_WAVETABLE_SYNTH_MIXER_SAMPLE_RATE	(44100.0)


//******************************************************************************
// Wavetableシンセサイザ制御クラス
//******************************************************************************
class SMWavetableSynthCtrl
{
public:
	
	//コンストラクタ／デストラクタ
	SMWavetableSynthCtrl();
	virtual ~SMWavetableSynthCtrl();
	
	//初期化
	int Initialize();
	
	//デバイス表示名称取得
	NSString* GetDevDisplayName();
	
	//デバイス識別名取得
	NSString* GetDevIdName();
	
	//メーカー名取得
	NSString* GetManufacturerName();
	
	//Wavetableファイルパス設定
	int SetWavetableFilePath(NSString* pWavetableFilePath);
	
	//デバイスオープン
	int Open();
	
	//デバイスクローズ
	int Close();
	
	//終了
	//void Terminate();
	
	//MIDI出力メッセージ送信
	int SendShortMsg(unsigned char* pMsg, unsigned int size);
	int SendLongMsg(unsigned char* pMsg, unsigned int size);
	int NoteOffAll();
	
private:
	
	//Wavetableファイルパス
	NSString* m_pWavetableFilePath;
	
	//グラフ
	AUGraph m_AUGraph;
	
	//ノード
	AUNode m_NodeSampler[SM_MAX_CH_NUM] = {0};
	AUNode m_NodeMixer;
	AUNode m_NodeOutput;
	
	//ユニット
	AudioUnit m_UnitSampler[SM_MAX_CH_NUM] = {0};
	AudioUnit m_UnitMixer;
	AudioUnit m_UnitOutput;
	
	//コントロール番号サポート情報
	unsigned char m_ControlNoSupport[128];
	
	//バンクセレクト
	unsigned char m_BankSelectMSB[SM_MAX_CH_NUM];
	unsigned char m_BankSelectLSB[SM_MAX_CH_NUM];
	
	//ステータス
	bool m_isOpened;
	bool m_isWavetableLoaded[SM_MAX_CH_NUM];
	
private:
	
	void _ReleaseAUGraph();
	int _CreateAUGraph();
	int _CreateNodes();
	int _ConnectNodes();
	int _GetAudioUnits();
	int _InitSamplerUnits();
	int _InitMixerUnit();
	int _InitOutputUnit();
	int _LoadInstrument(unsigned char ch, AudioUnit audioUnit, UInt8 bankMSB, UInt8 bankLSB, UInt8 presetId);
	
	//コントロール番号サポート情報初期化
	void _InitControlNoSupport();
	
};


