2 //#include "xbyak\xbyak.h"
3 #include "WaveTableSynth.h"
5 using namespace std::placeholders;
9 std::vector<Synthesizer::WaveTable> Synthesizer::WaveTable::WaveTables;
11 void makeWaveFormat(WAVEFORMATEXTENSIBLE& format,
12 int sample_rate = 44100,int channels = 2,int bits_per_sample = 32,int valid_bits_per_sample = 32,
13 uint32_t type = WAVE_FORMAT_EXTENSIBLE,
14 const GUID& sub_type = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)
16 ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));
17 format.Format.wFormatTag = type;
18 format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
19 format.SubFormat = sub_type;
20 format.Format.nSamplesPerSec = sample_rate;
21 format.Format.nChannels = channels;
22 format.Format.wBitsPerSample = bits_per_sample;
23 format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;
24 format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;
25 format.Samples.wValidBitsPerSample = valid_bits_per_sample;
26 format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
29 void makeWaveFormat(WAVEFORMATEX& format,int sample_rate = 44100,int channels = 2,int bits = 16,uint32_t type = WAVE_FORMAT_PCM)
31 ZeroMemory(&format,sizeof(WAVEFORMATEX));
32 format.wFormatTag = type;
33 format.nSamplesPerSec = sample_rate;
34 format.nChannels = channels;
35 format.wBitsPerSample = bits;
36 format.nBlockAlign = (format.wBitsPerSample / 8) * format.nChannels;
37 format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
40 void Synthesizer::WaveTableOscillator::WaveTable(Synthesizer::WaveTable *p)
43 if(waveTable_->stereo)
45 processor_ = std::bind(&sf::Synthesizer::WaveTableOscillator::ProcessStereo,this,_1,_2,_3);
47 processor_ = std::bind(&sf::Synthesizer::WaveTableOscillator::ProcessMono,this,_1,_2,_3);
52 struct Synthesizer::impl {
55 explicit impl(WAVEFORMATEXTENSIBLE& format,int channel) : format_(format) ,isEnable_(false)
58 // Voice
\82Ì
\83Z
\83b
\83g
\83A
\83b
\83v
59 //Voice v((float)format.Format.nSamplesPerSec);
60 //v.SetProgram(0,programs_[0]);
61 //Voice v1((float)format.Format.nSamplesPerSec);
62 //v1.SetProgram(0,programs_[0]);
65 //Voice v2 = std::move(v);
66 //Voice v3(std::move(v1));
68 for(int i = 0; i < channel;++i)
70 voices_.push_back(Voice((float)format.Format.nSamplesPerSec));
79 void Process(float *buffer)
81 for(int j = 0;j < voices_.size();++j)
83 voices_[j].Process(buffer);
84 //*buffer += buffer[0];
85 //*(buffer+ 1) += buffer[1];
88 //void ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
90 // //
\8d¡
\82Ì
\82Æ
\82±
\82ë
\8fo
\97Í
\82Í
\83X
\83e
\83\8c\83I
\91O
\92ñ
91 // float *ptr = arr.get();
93 // for(int i = 0;i < bufferSize;++i)
95 // for(int j = 0;j < voices_.size();++j)
97 // voices_[j].Process(buffer);
99 // *(ptr + 1) += buffer[1];
104 // //static float sampleIncrement = (440.0f /* Hz */ * (M_PI * 2.0f)) / (float)format_.Format.nSamplesPerSec;
105 // //static float theta = 0.0f;
107 // //for (size_t i = 0 ; i < bufferSize ; ++i)
109 // // float sinValue = sinf( theta );
110 // // int offset = i * format_.Format.nChannels;
111 // // for(size_t j = 0 ;j < format_.Format.nChannels; j++)
113 // // arr[offset + j] = sinValue;
115 // // theta += sampleIncrement;
120 enum struct EnvelopeStatus
122 None,Attack,Decay,Sustain,Release,End
125 struct EnvelopeController
127 EnvelopeController() : envelope_(nullptr),stepTime_(1.0f / 44100.0f)
130 EnvelopeController(const EnvelopeController& src) :
131 envelope_(src.envelope_),
132 status_(src.status_),
134 counter_(src.counter_),
135 stepTime_(src.stepTime_),
140 EnvelopeController(EnvelopeController&& src) :
141 envelope_(std::move( src.envelope_)),
142 status_(std::move(src.status_)),
143 delta_(std::move(src.delta_)),
144 counter_(std::move(src.counter_)),
145 stepTime_(std::move(src.stepTime_)),
146 time_(std::move(src.time_)),
147 value_(std::move(src.value_))
150 EnvelopeController& operator= (const EnvelopeController& src)
154 envelope_ = src.envelope_;
155 status_ = src.status_;
157 counter_ = src.counter_;
158 stepTime_ = src.stepTime_;
165 EnvelopeController& operator= (EnvelopeController&& src)
169 envelope_ = std::move(src.envelope_);
170 status_ = std::move(src.status_);
171 delta_ = std::move(src.delta_);
172 counter_ = std::move(src.counter_);
173 stepTime_ = std::move(src.stepTime_);
174 time_ = std::move(src.time_);
175 value_ = std::move(src.value_);
182 status_ = EnvelopeStatus::None;
185 void Init(Envelope * env,float sampleRate)
188 stepTime_ = 1.0f / sampleRate;
194 if(envelope_->attackTime == 0.0f)
199 status_ = EnvelopeStatus::Attack;
200 delta_ = stepTime_ / envelope_->attackTime;
207 if(envelope_->sustainLevel == 1.0f)
211 delta_ = (1.0f - envelope_->sustainLevel) * stepTime_ / (envelope_->decayTime);
212 status_ = EnvelopeStatus::Decay;
218 if(envelope_->sustainLevel == 0.0f)
220 status_ = EnvelopeStatus::End;
223 status_ = EnvelopeStatus::Sustain;
228 if(envelope_->releaseNoteOff){
229 delta_ = value_ * stepTime_ / (envelope_->releaseTime );
230 status_ = EnvelopeStatus::Release;
241 if(envelope_->gain == 0.0f)
245 counter_ += stepTime_;
248 case EnvelopeStatus::Attack:
256 case EnvelopeStatus::Decay:
258 if(value_ <= envelope_->sustainLevel)
260 value_ = envelope_->sustainLevel;
264 case EnvelopeStatus::Sustain:
266 value_ = envelope_->sustainLevel;
269 case EnvelopeStatus::Release:
275 status_ = EnvelopeStatus::End;
280 return value_ * envelope_->gain;
283 EnvelopeStatus GetStatus()
288 bool IsEnable() const {return envelope_ != nullptr && envelope_->enable;}
292 EnvelopeStatus status_;
302 LFOController() : lfo_(nullptr),value_(0.0f),stepTime_(0.0f)
306 LFOController(const LFOController& src) :
309 envelopeController_(src.envelopeController_),
310 sampleRate_(src.sampleRate_),
312 stepTime_(src.stepTime_),
313 pitchDelta_(src.pitchDelta_),
314 stepDelta_(src.stepDelta_)
319 LFOController(LFOController&& src) :
320 lfo_(std::move(src.lfo_)),
321 osc_(std::move(src.osc_)),
322 envelopeController_(std::move(src.envelopeController_)),
323 sampleRate_(std::move(src.sampleRate_)),
324 value_(std::move(src.value_)),
325 stepTime_(std::move(src.stepTime_)),
326 pitchDelta_(std::move(src.pitchDelta_)),
327 stepDelta_(std::move(src.stepDelta_))
332 LFOController& operator= (const LFOController& src)
338 envelopeController_ = src.envelopeController_;
339 sampleRate_ = src.sampleRate_;
341 stepTime_ = src.stepTime_;
342 pitchDelta_ = src.pitchDelta_;
343 stepDelta_ = src.stepDelta_;
348 LFOController& operator= (LFOController&& src)
352 lfo_ = std::move(src.lfo_);
353 osc_ = std::move(src.osc_);
354 envelopeController_ = std::move(src.envelopeController_);
355 sampleRate_ = std::move(src.sampleRate_);
356 value_ = std::move(src.value_);
357 stepTime_ = std::move(src.stepTime_);
358 pitchDelta_ = std::move(src.pitchDelta_);
359 stepDelta_ = std::move(src.stepDelta_);
364 void LFOController::LFO(sf::Synthesizer::LFO *lfo)
369 sf::Synthesizer::LFO& LFOController::LFO()
374 void Init(float sampleRate)
376 // assert(lfo_ != nullptr);
377 osc_.WaveTable(lfo_->waveForm);
378 sampleRate_ = sampleRate;
379 stepDelta_ = 1.0f / sampleRate_;
380 pitchDelta_ = lfo_->freq * ((float)osc_.WaveTable().waveData.size()) / ( sampleRate_ );
381 envelopeController_.Init(&lfo_->envelope,sampleRate);
386 envelopeController_.Attack();
391 envelopeController_.Release();
396 assert(lfo_ != nullptr);
402 osc_.Process(buffer,pitchDelta_,1.0f);
403 float value = buffer[0];
404 value = value * envelopeController_.Process() * lfo_->gain;
411 osc_.Process(buffer,pitchDelta_,0.0f);
412 envelopeController_.Process();
415 float SampleRate() const {return sampleRate_;}
416 void SampleRate(float v)
421 // Synthesizer::impl::Envelope& Envelope() {return envelope_;}
425 sf::Synthesizer::LFO * lfo_;
426 WaveTableOscillator osc_;
427 // Synthesizer::impl::Envelope envelope_;
428 EnvelopeController envelopeController_;
436 struct FilterController
455 sampleRate_(44100.0f),
473 FilterController(const FilterController& src) :
474 cutoff_(src.cutoff_),
475 sampleRate_(src.sampleRate_),
476 filter_(src.filter_),
493 FilterController(FilterController&& src) :
494 cutoff_(std::move(src.cutoff_)),
495 sampleRate_(std::move(src.sampleRate_)),
496 filter_(std::move(src.filter_)),
497 y1_(std::move(src.y1_)),
498 y2_(std::move(src.y2_)),
499 y3_(std::move(src.y3_)),
500 y4_(std::move(src.y4_)),
501 oldx_(std::move(src.oldx_)),
502 oldy1_(std::move(src.oldy1_)),
503 oldy2_(std::move(src.oldy2_)),
504 oldy3_(std::move(src.oldy3_)),
505 x_(std::move(src.x_)),
506 r_(std::move(src.r_)),
507 p_(std::move(src.p_)),
508 k_(std::move(src.k_))
513 FilterController& operator= (const FilterController& src)
517 cutoff_ = src.cutoff_;
518 sampleRate_ = src.sampleRate_;
519 filter_ = src.filter_;
536 FilterController& operator= (FilterController&& src)
540 cutoff_ = std::move(src.cutoff_);
541 sampleRate_ = std::move(src.sampleRate_);
542 filter_ = std::move(src.filter_);
543 y1_ = std::move(src.y1_);
544 y2_ = std::move(src.y2_);
545 y3_ = std::move(src.y3_);
546 y4_ = std::move(src.y4_);
547 oldx_ = std::move(src.oldx_);
548 oldy1_ = std::move(src.oldy1_);
549 oldy2_ = std::move(src.oldy2_);
550 oldy3_ = std::move(src.oldy3_);
551 x_ = std::move(src.x_);
552 r_ = std::move(src.r_);
553 p_ = std::move(src.p_);
554 k_ = std::move(src.k_);
559 ~FilterController(){}
561 void Init(Synthesizer::Filter* filter,float sampleRate)
564 cutoff_ = filter->cutoff;
565 sampleRate_ = sampleRate;
566 assert(filter_ != nullptr);
568 y1_ = y2_ = y3_ = y4_ = oldx_ = oldy1_ = oldy2_ = oldy3_ = 0.0f;
574 float f = (cutoff_ + cutoff_) / sampleRate_;
575 p_ = f * (1.8f - 0.8f * f);
578 float t = (1.0f - p_) * 1.386249f;
579 float t2 = 12.0f + t*t;
580 r_ = filter_->resonance * (t2 + 6.0f * t) / (t2 - 6.0f * t);
583 float Process(float input)
585 x_ = input - r_ * y4_;
587 y1_ = x_ * p_ + oldx_ * p_ - k_ * y1_;
588 y2_ = y1_ * p_ + oldy1_ * p_ - k_ * y2_;
589 y3_ = y2_ * p_ + oldy2_ * p_ - k_ * y3_;
590 y4_ = y3_ * p_ + oldy3_ * p_ - k_ * y4_;
592 y4_ -= (y4_ * y4_ * y4_) / 6.0f;
594 oldx_ = x_; oldy1_ = y1_; oldy2_ = y2_; oldy3_ = y3_;
598 Synthesizer::Filter* FilterController::Filter()
603 void FilterController::Filter(Synthesizer::Filter* filter)
605 Init(filter,sampleRate_);
610 y1_ = y2_ = y3_ = y4_ = oldx_ = oldy1_ = oldy2_ = oldy3_ = 0.0f;
614 void CutOff(float v ) {cutoff_ = v;Calc();}
615 float CutOff() const {return cutoff_;}
620 Synthesizer::Filter *filter_;
622 float y1_,y2_,y3_,y4_;
624 float oldy1_,oldy2_,oldy3_;
637 explicit Voice(float sampleRate)
648 sampleRate_(sampleRate),
654 Voice(const Voice& src)
656 timber_(src.timber_),
657 programNo_(src.programNo_),
658 noteOn_(src.noteOn_),
659 isFree_(src.isFree_),
660 pitchOffset_(src.pitchOffset_),
661 volumeOffset_(src.volumeOffset_),
662 stepTime_(src.stepTime_),
663 currentTime_(src.currentTime_),
664 curentIndex_(src.curentIndex_),
666 sampleRate_(src.sampleRate_),
667 pitchDelta_(src.pitchDelta_),
668 pitchCounter_(src.pitchCounter_),
669 waveSize_(src.waveSize_),
670 ampEnv_(src.ampEnv_),
671 ampLFO_(src.ampLFO_),
672 filterEnv_(src.filterEnv_),
673 filterLFO_(src.filterLFO_),
674 filterL_(src.filterL_),
675 filterR_(src.filterR_),
676 pitchEnv_(src.pitchEnv_),
677 pitchLFO_(src.pitchLFO_),
678 panEnv_(src.panEnv_),
681 // osc_ = std::move(osc_->Clone());
686 timber_(std::move(src.timber_)),
687 programNo_(std::move(src.programNo_)),
688 noteOn_(std::move(src.noteOn_)),
689 isFree_(std::move(src.isFree_)),
690 pitchOffset_(std::move(src.pitchOffset_)),
691 volumeOffset_(std::move(src.volumeOffset_)),
692 stepTime_(std::move(src.stepTime_)),
693 currentTime_(std::move(src.currentTime_)),
694 curentIndex_(std::move(src.curentIndex_)),
695 pan_(std::move(src.pan_)),
696 sampleRate_(std::move(src.sampleRate_)),
697 pitchDelta_(std::move(src.pitchDelta_)),
698 pitchCounter_(std::move(src.pitchCounter_)),
699 waveSize_(std::move(src.waveSize_)),
700 // osc_(std::move(src.osc_)),
701 ampEnv_(std::move(src.ampEnv_)),
702 ampLFO_(std::move(src.ampLFO_)),
703 filterEnv_(std::move(src.filterEnv_)),
704 filterLFO_(std::move(src.filterLFO_)),
705 filterL_(std::move(src.filterL_)),
706 filterR_(std::move(src.filterR_)),
707 pitchEnv_(std::move(src.pitchEnv_)),
708 pitchLFO_(std::move(src.pitchLFO_)),
709 panEnv_(std::move(src.panEnv_)),
710 panLFO_(std::move(src.panLFO_))
712 // osc_.reset(src.osc_.release());
713 // *this = std::move(src);
716 Voice& operator= (const Voice& src)
720 timber_ = src.timber_;
721 programNo_ = src.programNo_;
722 noteOn_ = src.noteOn_;
723 isFree_ = src.isFree_;
724 pitchOffset_ = src.pitchOffset_;
725 volumeOffset_ = src.volumeOffset_;
726 stepTime_ = src.stepTime_;
727 currentTime_ = src.currentTime_;
728 curentIndex_ = src.curentIndex_;
730 sampleRate_ = src.sampleRate_;
731 pitchDelta_ = src.pitchDelta_;
732 pitchCounter_ = src.pitchCounter_;
733 waveSize_ = src.waveSize_;
734 // osc_ = src.osc_->Clone();
735 ampEnv_ = src.ampEnv_;
736 ampLFO_ = src.ampLFO_;
737 filterEnv_ = src.filterEnv_;
738 filterLFO_ = src.filterLFO_;
739 filterL_ = src.filterL_;
740 filterR_ = src.filterR_;
741 pitchEnv_ = src.pitchEnv_;
742 pitchLFO_ = src.pitchLFO_;
743 panEnv_ = src.panEnv_;
744 panLFO_ = src.panLFO_;
749 Voice& operator= (Voice&& src)
753 timber_ = std::move(src.timber_);
754 programNo_ = std::move(src.programNo_);
755 noteOn_ = std::move(src.noteOn_);
756 isFree_ = std::move(src.isFree_);
757 pitchOffset_ = std::move(src.pitchOffset_);
758 volumeOffset_ = std::move(src.volumeOffset_);
759 stepTime_ = std::move(src.stepTime_);
760 currentTime_ = std::move(src.currentTime_);
761 curentIndex_ = std::move(src.curentIndex_);
762 pan_ = std::move(src.pan_);
763 sampleRate_ = std::move(src.sampleRate_);
764 pitchDelta_ = std::move(src.pitchDelta_);
765 pitchCounter_ = std::move(src.pitchCounter_);
766 waveSize_ = std::move(src.waveSize_);
767 // osc_.reset(src.osc_.release());
768 ampEnv_ = std::move(src.ampEnv_);
769 ampLFO_ = std::move(src.ampLFO_);
770 filterEnv_ = std::move(src.filterEnv_);
771 filterLFO_ = std::move(src.filterLFO_);
772 filterL_ = std::move(src.filterL_);
773 filterR_ = std::move(src.filterR_);
774 pitchEnv_ = std::move(src.pitchEnv_);
775 pitchLFO_ = std::move(src.pitchLFO_);
776 panEnv_ = std::move(src.panEnv_);
777 panLFO_ = std::move(src.panLFO_);
782 void SetSampleRate(float sampleRate)
784 sampleRate_ = sampleRate;
787 void SetProgram(int programNo,Program& program)
789 timber_ = program.timber;
790 programNo_ = programNo;
792 // osc_->Init(timber_);
797 ampEnv_.Init(&(timber_.amplitude.envelope),sampleRate_);
798 filterEnv_.Init(&(timber_.filter.envelope),sampleRate_);
799 pitchEnv_.Init(&(timber_.pitch.envelope),sampleRate_);
800 panEnv_.Init(&(timber_.pan.envelope),sampleRate_);
801 filterL_.Init(&(timber_.filter),sampleRate_);
802 filterR_.Init(&(timber_.filter),sampleRate_);
804 ampLFO_.LFO(&timber_.amplitude.lfo);
805 pitchLFO_.LFO(&timber_.pitch.lfo);
806 panLFO_.LFO(&timber_.pan.lfo);
807 filterLFO_.LFO(&timber_.filter.lfo);
809 ampLFO_.Init(sampleRate_);
810 pitchLFO_.Init(sampleRate_);
811 panLFO_.Init(sampleRate_);
812 filterLFO_.Init(sampleRate_);
815 void Process(float* buffer) // 1
\83T
\83\93\83v
\83\8b\95ª
\82Ì
\8f\88\97\9d\82ð
\8ds
\82¤
819 //if(pitchCounter_ >= (waveSize_ - 1.0f))
821 // pitchCounter_ -= (waveSize_ - 1.0f);
828 timber_.oscillator->Process(
832 + pitchLFO_.Process()
833 + pitchEnv_.Process()
834 + timber_.pitch.pitch );
836 //
\83t
\83B
\83\8b\83^
\81[
\8f\88\97\9d
838 float cutoff = timber_.filter.cutoff + filterEnv_.Process() + filterLFO_.Process();
839 filterL_.CutOff(cutoff);
840 filterR_.CutOff(cutoff);
842 waveData[0] = filterL_.Process(waveData[0]);
843 waveData[1] = filterR_.Process(waveData[1]);
846 float volume = ampEnv_.Process() + ampLFO_.Process();
855 //
\83N
\83\8a\83b
\83s
\83\93\83O
857 //if(waveData > 1.0f) waveData = 1.0f;
858 //if(waveData < 1.0f) waveData = -1.0f;
860 float pan = (pan_ + panLFO_.Process());
861 if(pan > 1.0f) pan = 1.0f;
862 if(pan < -1.0f) pan = -1.0f;
870 rvolume = volume * volumeOffset_;
871 lvolume = rvolume * (1.0f - pan);
873 lvolume = volume * volumeOffset_;
874 rvolume = lvolume * (1.0f + pan);
877 waveData[0] = waveData[0] * lvolume;
878 waveData[1] = waveData[1] * rvolume;
880 buffer[0] += waveData[0];
881 buffer[1] += waveData[1];
883 if(!noteOn_ && ampEnv_.GetStatus() == EnvelopeStatus::End)
890 bool isFree() {return isFree_;}
892 void NoteOn(float pitch,float volume)
897 pitchOffset_ = pitch;
898 volumeOffset_ = volume;
899 stepTime_ = 1.0f / sampleRate_;
900 pitchDelta_ = timber_.oscillator->CalcPitchDelta(sampleRate_);
901 // waveSize_ = (float)osc_->waveData.size();
904 pan_ = timber_.pan.pan;
905 pitchCounter_ = 0.0f;
927 filterEnv_.Release();
932 filterLFO_.Release();
939 int CurrentProgramNo() const {return programNo_;}
956 // std::unique_ptr<Oscillator> osc_;
957 EnvelopeController ampEnv_;
958 LFOController ampLFO_;
959 EnvelopeController filterEnv_;
960 LFOController filterLFO_;
961 FilterController filterL_;
962 FilterController filterR_;
963 EnvelopeController pitchEnv_;
964 LFOController pitchLFO_;
965 EnvelopeController panEnv_;
966 LFOController panLFO_;
969 typedef std::vector<Voice> VoicesType;
970 typedef std::vector<Timber> TimbersType;
971 typedef std::vector<Program> ProgramsType;
973 void NoteOn(int index,float pitch,float velocity)
975 voices_[index].NoteOn(pitch,velocity);
978 void NoteOff(int index)
980 voices_[index].NoteOff();
983 void AddProgram(Program&& program)
985 programs_.push_back(program);
988 Program& GetProgram(int index)
990 return programs_.at(index);
993 void UpdateProgram(int index,Program&& program)
995 programs_[index] = std::move(program);
998 size_t ProgramsSize()
1000 return programs_.size();
1003 void AssignProgramToVoice(int programNo,int voiceChannelNo)
1005 assert(programNo < programs_.size() && voiceChannelNo < voices_.size());
1006 voices_.at(voiceChannelNo).SetProgram(programNo,programs_.at(programNo));
1009 size_t Voices() const {return voices_.size();};
1011 bool isEnable() const {return isEnable_;}
1012 void isEnable(bool v) {isEnable_ = v;}
1016 WaveTable::WaveTables.clear();
1022 WAVEFORMATEXTENSIBLE format_;
1023 ProgramsType programs_;//
\83v
\83\8a\83Z
\83b
\83g
1024 VoicesType voices_; // Max 64 Voices
1025 // WaveTablesType waveTables_;
1028 Synthesizer::Synthesizer() : impl_(new Synthesizer::impl()){};
1030 Synthesizer::Synthesizer(WAVEFORMATEXTENSIBLE& format,int channel ) : impl_(new Synthesizer::impl(format,channel))
1034 Synthesizer::~Synthesizer()
1039 //void Synthesizer::ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
1041 // impl_->ProcessBuffer(arr,bufferSize);
1044 void Synthesizer::Process(float* buffer)
1046 impl_->Process(buffer);
1050 void Synthesizer::Restart()
1055 void Synthesizer::NoteOn(int index,float pitch,float velocity)
1057 impl_->NoteOn(index,pitch,velocity);
1059 void Synthesizer::NoteOff(int index)
1061 impl_->NoteOff(index);
1064 size_t Synthesizer::Voices() const
1066 return impl_->Voices();
1069 void Synthesizer::AddProgram(Program&& program)
1071 impl_->AddProgram(std::move(program));
1074 Synthesizer::Program& Synthesizer::GetProgram(int index)
1076 return impl_->GetProgram(index);
1079 void Synthesizer::UpdateProgram(int index,Program&& program)
1081 impl_->UpdateProgram(index,std::move(program));
1083 size_t Synthesizer::ProgramsSize()
1085 return impl_->ProgramsSize();
1088 void Synthesizer::AssignProgramToVoice(int programNo,int voiceChannelNo)
1090 impl_->AssignProgramToVoice(programNo,voiceChannelNo);
1093 Synthesizer::WaveTablesType& Synthesizer::WaveTables()
1095 return WaveTable::WaveTables;
1098 bool Synthesizer::isEnable() const
1100 return impl_->isEnable();
1103 void Synthesizer::isEnable(bool v)
1108 void Synthesizer::Clear()