OSDN Git Service

フィルターを実装しはじめた。
authorsfpgmr <sfpg@users.sourceforge.jp>
Mon, 28 May 2012 21:22:35 +0000 (06:22 +0900)
committersfpgmr <sfpg@users.sourceforge.jp>
Mon, 28 May 2012 21:22:35 +0000 (06:22 +0900)
ShootingGame/Sequencer.cpp
ShootingGame/Sequencer.h
ShootingGame/ShootingGame.vcxproj
ShootingGame/SoundDriver.cpp
ShootingGame/SoundDriver.h
ShootingGame/TestSong.cpp [new file with mode: 0644]
ShootingGame/TestSong.h [new file with mode: 0644]
ShootingGame/WaveTableSynth.cpp
ShootingGame/WaveTableSynth.h

index 91bc435..d10ca89 100644 (file)
 #include "pch.h"
 #include "Sequencer.h"
 
+namespace sf {
 
-Sequencer::Sequencer(void)
+  struct Sequencer::impl 
+  {
+    impl(Synthesizer& synth,WAVEFORMATEXTENSIBLE& format) 
+      : synth_(synth), format_(format) ,tempo_(120.0f),timebase_(480.0f),meter_(4.0f),meterDiv_(4.0f),
+      currentTime_(0)
+    {
+      Update();
+      for(int i = 0,end = synth_.Voices();i < end;++i)
+      {
+        gateBuffer_.push_back(0);
+        currentIndexs_.push_back(0);
+        SequenceTracks_.push_back(SequenceDatasType());
+      }
+    }
+
+    void Update()
+    {
+     // stepDeltaTime_ = (int64_t)((((double)meter_ * (double)tempo_ * (double)format_.Format.nSamplesPerSec) / ((double)meterDiv_ * 60.0 * (double)timebase_ )) * (double)(0x100000000));
+     stepDeltaTime_ = (int64_t)((  ((double)tempo_ * (double)timebase_ ) / (60.0  * (double)format_.Format.nSamplesPerSec)) * (double)(0x100000000));
+    }
+
+
+
+    void Process()
+    {
+      currentTime_ += stepDeltaTime_;
+      int currentTime = currentTime_ >> 32;
+      for(int i  = 0,end = SequenceTracks_.size();i < end;++i)
+      {
+        SequenceDatasType& track(SequenceTracks_[i]);
+        if(!track.empty() && track.size() > currentIndexs_[i]) {
+          if(currentTime >= track[currentIndexs_[i]].step) 
+          {
+            do
+            { 
+              SequenceData& d(SequenceTracks_[i][currentIndexs_[i]]);
+              synth_.NoteOn(i,d.pitch,d.velocity);
+              gateBuffer_[i] = (int64_t)d.gateTime << 32;
+              currentIndexs_[i] = currentIndexs_[i] + 1;
+              if(currentIndexs_[i] >= track.size())
+              {
+                break;
+              }
+            } while(currentTime >= SequenceTracks_[i][currentIndexs_[i]].step);
+          }
+        }
+        // \83Q\81[\83g\83^\83C\83\80\82Ì\8f\88\97\9d
+        if(gateBuffer_[i] > 0)
+        {
+          gateBuffer_[i] -= stepDeltaTime_;
+          if(gateBuffer_[i] <= 0)
+          {
+            gateBuffer_[i] = 0;
+            synth_.NoteOff(i);
+          }
+        }
+      }
+    }
+
+    float TimeBase() const {return timebase_;}
+    void TimeBase(float v) {timebase_ = v;Update();}
+
+    float Tempo() const {return tempo_;}
+    void Tempo(float v) {tempo_ = v;Update();}
+
+    std::vector<SequenceDatasType>& SequenceTracks() {return SequenceTracks_;}
+
+  private:
+
+    WAVEFORMATEXTENSIBLE& format_;
+    float tempo_;
+    float timebase_;
+    int meter_;
+    int meterDiv_;
+    int64_t stepDeltaTime_;
+    int64_t currentTime_;
+    std::vector<int> currentIndexs_;
+    std::vector<int64_t> gateBuffer_;
+    SequenceTracksType SequenceTracks_;
+    Synthesizer& synth_;
+  };
+  
+Sequencer::Sequencer(Synthesizer& synth,WAVEFORMATEXTENSIBLE& format) : impl_(new impl(synth,format))
 {
-}
 
+}
 
-Sequencer::~Sequencer(void)
+Sequencer::~Sequencer()
 {
+
+}
+
+float Sequencer::TimeBase() const {return impl_->TimeBase();}
+void Sequencer::TimeBase(float v) {impl_->TimeBase(v);}
+
+float Sequencer::Tempo() const {return impl_->Tempo();}
+void Sequencer::Tempo(float v) {impl_->Tempo(v);}
+
+void Sequencer::Process() {impl_->Process();}
+
+  SequenceTracksType& Sequencer::SequenceTracks() {return impl_->SequenceTracks();}
+
 }
index 80b1799..b5d33c5 100644 (file)
@@ -1,8 +1,73 @@
 #pragma once
-class Sequencer
-{
-public:
-  Sequencer(void);
-  ~Sequencer(void);
-};
+#include "WaveTableSynth.h"
 
+namespace sf {
+  enum struct SequenceCommand {
+    Note
+  };
+
+  struct SequenceData 
+  {
+    SequenceData () : step(0.0f),pitch(0.0f),velocity(0.0f),gateTime(0.0f){};
+    SequenceData(SequenceCommand c,int s,float p,float v,int g )
+      : cmd(c),step(s),pitch(p),velocity(v),gateTime(g) {};
+    SequenceData(SequenceData& src)
+      : cmd(src.cmd),step(src.step),pitch(src.pitch),velocity(src.velocity),gateTime(src.gateTime) {}
+
+    SequenceData(SequenceData&& src)
+      : cmd(std::move(src.cmd)),step(std::move(src.step)),pitch(std::move(src.pitch)),velocity(std::move(src.velocity)),gateTime(std::move(src.gateTime)) {}
+
+    SequenceData& operator=(SequenceData& src)
+    {
+      if(this != &src)
+      {
+        cmd = src.cmd;
+        step = src.step;
+        pitch = src.pitch;
+        velocity = src.velocity;
+        gateTime = src.gateTime;
+      }
+      return *this;
+    }
+
+    SequenceData& operator=(SequenceData&& src)
+    {
+      if(this != &src)
+      {
+        cmd = std::move(src.cmd);
+        step = std::move(src.step);
+        pitch = std::move(src.pitch);
+        velocity = std::move(src.velocity);
+        gateTime = std::move(src.gateTime);
+      }
+      return *this;
+    }
+
+    SequenceCommand cmd;
+    int step;
+    float pitch;
+    float velocity;
+    int gateTime;
+  };
+
+  typedef std::vector<SequenceData> SequenceDatasType;
+  typedef std::vector<SequenceDatasType> SequenceTracksType;
+
+  struct Sequencer
+  {
+  public:
+    Sequencer(Synthesizer& synth,WAVEFORMATEXTENSIBLE& format);
+    void Process();
+    ~Sequencer();
+
+    float TimeBase() const;
+    void TimeBase(float v); 
+
+    float Tempo() const;
+    void Tempo(float v);
+    SequenceTracksType& SequenceTracks();
+  private:
+    struct impl;
+    std::unique_ptr<impl> impl_;
+  };
+}
index 618f7b7..1ae9cec 100644 (file)
     <ClInclude Include="sf_com.h" />
     <ClInclude Include="sf_memory.h" />
     <ClInclude Include="SoundDriver.h" />
+    <ClInclude Include="TestSong.h" />
     <ClInclude Include="WaveTableSynth.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Sequencer.cpp" />
     <ClCompile Include="sf_com.cpp" />
     <ClCompile Include="SoundDriver.cpp" />
+    <ClCompile Include="TestSong.cpp" />
     <ClCompile Include="WaveTableSynth.cpp">
       <AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AssemblyAndSourceCode</AssemblerOutput>
     </ClCompile>
index 4d0ad86..6eaa91a 100644 (file)
@@ -1,7 +1,6 @@
 #include "pch.h"
 #include "sf_memory.h"
 #include "SoundDriver.h"
-
 using namespace std;
 using namespace Windows::Foundation;
 using namespace Windows::Foundation::Collections;
@@ -45,7 +44,6 @@ namespace {
 namespace sf {
 
 
-
   SoundDriver::SoundDriver() : bufferIndex_(0),eventHolder_(nullptr),synth_(nullptr)
   {
     //::AvMMAvSetMmThreadCharacteristics
@@ -135,14 +133,18 @@ namespace sf {
     ThrowIfErr(audioClient_->GetService(__uuidof(IAudioRenderClient),&audioRenderClient_));
     eventHolder_.reset(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE));
     audioClient_->SetEventHandle(eventHolder_.get());
-    synth_.reset(new WaveTableSynth(format_));
+    synth_.reset(new Synthesizer(format_));
+    sequencer_.reset(new Sequencer(*synth_.get(),format_));
+    sequencer_->Tempo(220.0f);
 
-    synth_->ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
+    TestSong song(sequencer_->SequenceTracks());
+
+    ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
     BYTE* rawBuffer;
     ThrowIfErr(audioRenderClient_->GetBuffer(bufferSize_,&rawBuffer));
     audioRenderClient_->ReleaseBuffer(bufferSize_,0);
     bufferIndex_ = (bufferIndex_ + 1) & 0x1;
-    synth_->ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
+    ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
 
     ThrowIfErr(audioClient_->Start());
   }
@@ -154,6 +156,27 @@ namespace sf {
     audioClient_->Reset();
   }
 
+  void SoundDriver::ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
+  {
+      // \8d¡\82Ì\82Æ\82±\82ë\8fo\97Í\82Í\83X\83e\83\8c\83I\91O\92ñ
+        //for(int j = 0;j < voices_.size();++j)
+        //{
+        //  voices_[j].Process(buffer);
+        //  *ptr +=  buffer[0]; 
+        //  *(ptr + 1) += buffer[1]; 
+        //}
+      float *ptr = arr.get();
+
+      ZeroMemory(ptr,bufferByteCount_);
+
+      for(int i = 0;i < bufferSize;++i)
+      {
+        sequencer_->Process();
+        synth_->Process(ptr);
+        ptr += 2;
+      }
+  }
+
   void SoundDriver::Render()
   {
     ::WaitForSingleObjectEx(eventHolder_.get(),INFINITE,FALSE);
@@ -166,8 +189,7 @@ namespace sf {
       ::memcpy(rawBuffer,buffer_[bufferIndex_].get(),bufferByteCount_);
       audioRenderClient_->ReleaseBuffer(bufferSize_,0);
       bufferIndex_ = (bufferIndex_ + 1) & 0x1;
-      ZeroMemory(buffer_[bufferIndex_].get(),bufferByteCount_);
-      synth_->ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
+      ProcessBuffer(buffer_[bufferIndex_],bufferSize_);
     }
   }
 }
index f69f92e..2de3f27 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 #include "WaveTableSynth.h"
+#include "Sequencer.h"
+#include "TestSong.h"
 
 typedef Microsoft::WRL::ComPtr<IAudioClient2> IAudioClient2Ptr;
 //typedef Microsoft::WRL::ComPtr<IAudioClock2> IAudioClock2Ptr;
@@ -18,7 +20,7 @@ namespace sf {
     ~SoundDriver();
 
     void Render();
-
+    void ProcessBuffer(boost::shared_array<float> arr,int bufferSize);
   private:
     IAudioClient2Ptr audioClient_;
     uint32_t bufferSize_;
@@ -27,7 +29,8 @@ namespace sf {
     IAudioRenderClientPtr audioRenderClient_;
     WAVEFORMATEXTENSIBLE format_;
     sf::handle_holder eventHolder_;
-    std::unique_ptr<sf::WaveTableSynth> synth_;
+    std::unique_ptr<sf::Synthesizer> synth_;
+    std::unique_ptr<sf::Sequencer> sequencer_;
     boost::shared_array<float> buffer_[2];
     int bufferIndex_;
     int bufferByteCount_;
diff --git a/ShootingGame/TestSong.cpp b/ShootingGame/TestSong.cpp
new file mode 100644 (file)
index 0000000..f466d2f
--- /dev/null
@@ -0,0 +1,453 @@
+#include "pch.h"
+#include <array>
+#include "WaveTableSynth.h"
+#include "Sequencer.h"
+#include "TestSong.h"
+
+namespace sf {
+
+
+
+  TestSong::TestSong(SequenceTracksType& tracks) : tracks_(tracks)
+  {
+    for(float i = -5.0f;i < 5.0f;++i)
+    {
+      noteTable_.push_back(powf(2.0f,-9.0f/12.0f + i  ));//C
+      noteTable_.push_back(powf(2.0f,-8.0f/12.0f + i ));//C#
+      noteTable_.push_back(powf(2.0f,-7.0f/12.0f + i ));//D
+      noteTable_.push_back(powf(2.0f,-6.0f/12.0f + i ));//D#
+      noteTable_.push_back(powf(2.0f,-5.0f/12.0f + i ));//E
+      noteTable_.push_back(powf(2.0f,-4.0f/12.0f + i ));//F
+      noteTable_.push_back(powf(2.0f,-3.0f/12.0f + i ));//F#
+      noteTable_.push_back(powf(2.0f,-2.0f/12.0f + i ));//G
+      noteTable_.push_back(powf(2.0f,-1.0f/12.0f + i ));//G#4
+      noteTable_.push_back(powf(2.0f,0.0f + i ));//A4
+      noteTable_.push_back(powf(2.0f,1.0f/12.0f + i ));//A#4
+      noteTable_.push_back(powf(2.0f,2.0f/12.0f + i ));//B4  
+    }
+
+    for(int i = 0;i < tracks.size();++i)
+    {
+      stepCounters_.push_back(0);
+    }
+
+    //CreateTestTone();
+    CreateMappyData();
+ //   CreateCosmicSurfin();
+
+
+ }
+
+  void TestSong::CreateMappyData()
+  {
+    AddNote(0,480,Note::E,5,1.0f,120);
+    AddNote(0,480,Note::B,5,1.0f,120);
+    AddNote(0,480,Note::AS,5,1.0f,120);
+    AddNote(0,360,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::C,6,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+    AddNote(0,120,Note::B,5,1.0f,30);
+
+    AddNote(0,480,Note::A,5,1.0f,90);
+    AddNote(0,480,Note::B,5,1.0f,90);
+    AddNote(0,360,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::G,5,1.0f,90);
+    AddNote(0,360,Note::E,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+
+    AddNote(0,480,Note::D,5,1.0f,90);
+    AddNote(0,480,Note::A,5,1.0f,90);
+    AddNote(0,480,Note::GS,5,1.0f,90);
+    AddNote(0,360,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+    AddNote(0,120,Note::A,5,1.0f,90);
+
+    AddNote(0,480,Note::G,5,1.0f,90);
+    AddNote(0,480,Note::A,5,1.0f,90);
+    AddNote(0,360,Note::G,5,1.0f,90);
+    AddNote(0,480,Note::E,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+
+    AddNote(0,360,Note::B,3,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+    AddNote(0,360,Note::G,5,1.0f,90);
+    AddNote(0,120,Note::B,3,1.0f,90);
+    AddNote(0,360,Note::D,5,1.0f,90);
+    AddNote(0,120,Note::G,5,1.0f,90);
+    AddNote(0,360,Note::B,3,1.0f,90);
+    AddNote(0,120,Note::D,5,1.0f,90);
+
+    AddNote(0,360,Note::C,5,1.0f,90);
+    AddNote(0,120,Note::E,5,1.0f,90);
+    AddNote(0,360,Note::G,5,1.0f,90);
+    AddNote(0,120,Note::CS,5,1.0f,90);
+    AddNote(0,360,Note::E,5,1.0f,90);
+    AddNote(0,120,Note::G,5,1.0f,90);
+    AddNote(0,360,Note::CS,5,1.0f,90);
+    AddNote(0,120,Note::E,5,1.0f,90);
+
+    AddRest(0,480);
+    AddNote(0,360,Note::B,5,1.0f,90);
+    AddNote(0,120,Note::AS,5,1.0f,90);
+    AddNote(0,480,Note::A,5,1.0f,90);
+    AddNote(0,360,Note::D,5,1.0f,90);
+    AddNote(0,600,Note::G,5,1.0f,90);
+
+    AddNote(0,480,Note::G,5,1.0f,90);
+    AddNote(0,480,Note::FS,5,1.0f,90);
+    AddNote(0,480,Note::E,5,1.0f,90);
+
+    //
+
+    AddNote(2/*channel*/,480/*step*/,Note::E /*\89¹\8aK*/,5/*octave*/,1.0f/*velocity*/,10 /*gatetime*/,0.002f/*ofset*/);
+    AddNote(2,480,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::AS,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::C,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,6,1.0f,10,0.002f);
+
+    AddNote(2,480,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::E,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+
+    AddNote(2,480,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::GS,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::A,5,1.0f,10,0.002f);
+
+    AddNote(2,480,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::E,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+
+    AddNote(2,360,Note::B,3,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::B,3,1.0f,10,0.002f);
+    AddNote(2,360,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::B,3,1.0f,10,0.002f);
+    AddNote(2,120,Note::D,5,1.0f,10,0.002f);
+
+    AddNote(2,360,Note::C,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::E,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::CS,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::E,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::CS,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::E,5,1.0f,10,0.002f);
+
+    AddRest(2,480);
+    AddNote(2,360,Note::B,5,1.0f,10,0.002f);
+    AddNote(2,120,Note::AS,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::A,5,1.0f,10,0.002f);
+    AddNote(2,360,Note::D,5,1.0f,10,0.002f);
+    AddNote(2,600,Note::G,5,1.0f,10,0.002f);
+
+    AddNote(2,480,Note::G,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::FS,5,1.0f,10,0.002f);
+    AddNote(2,480,Note::E,5,1.0f,10,0.002f);
+
+    //
+
+    AddNote(1,480,Note::E,2,1.0f,90);
+    AddRest(1,480);
+    AddNote(1,480,Note::B,1,1.0f,90);
+    AddRest(1,360);
+    AddNote(1,120,Note::E,2,1.0f,90);
+
+    AddRest(1,360);
+    AddNote(1,120,Note::E,2,1.0f,90);
+    AddNote(1,480,Note::B,1,1.0f,90);
+    AddNote(1,360,Note::E,2,1.0f,90);
+    AddNote(1,120,Note::FS,2,1.0f,90);
+    AddNote(1,480,Note::GS,2,1.0f,90);
+
+    AddNote(1,480,Note::A,2,1.0f,90);
+    AddRest(1,480);
+    AddNote(1,480,Note::E,2,1.0f,90);
+    AddRest(1,360);
+    AddNote(1,120,Note::A,2,1.0f,90);
+
+    AddRest(1,360);
+    AddNote(1,120,Note::A,2,1.0f,90);
+    AddNote(1,480,Note::G,2,1.0f,90);
+    AddNote(1,480,Note::FS,2,1.0f,90);
+    AddNote(1,480,Note::E,2,1.0f,90);
+
+    AddNote(1,480,Note::D,2,1.0f,90);
+    AddRest(1,480);
+    AddNote(1,480,Note::A,1,1.0f,90);
+    AddRest(1,360);
+    AddNote(1,120,Note::D,2,1.0f,90);
+
+    AddRest(1,360);
+    AddNote(1,120,Note::D,2,1.0f,90);
+    AddNote(1,480,Note::A,1,1.0f,90);
+    AddNote(1,360,Note::D,2,1.0f,90);
+    AddNote(1,120,Note::E,2,1.0f,90);
+    AddNote(1,480,Note::FS,2,1.0f,90);
+  }
+
+  void TestSong::CreateTestTone()
+  {
+    for(int j = 0;j < 5;++j){
+      for(int i = 2;i < 9;++i)
+      {
+        AddNote(0,960,Note::C,i,1.0f,600);
+        AddNote(0,960,Note::D,i,1.0f,600);
+        AddNote(0,960,Note::E,i,1.0f,600);
+        AddNote(0,960,Note::F,i,1.0f,600);
+        AddNote(0,960,Note::G,i,1.0f,600);
+        AddNote(0,960,Note::A,i,1.0f,600);
+        AddNote(0,960,Note::B,i,1.0f,600);
+      }
+    }
+  }
+
+  void TestSong::CreateCosmicSurfin()
+  {
+
+    for(int i = 0;i < 8;++i){
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+    
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+    AddNote(0,240,Note::A,2,1.0f,190);
+    AddNote(0,240,Note::A,3,1.0f,190);
+    AddNote(0,240,Note::G,2,1.0f,190);
+    AddNote(0,240,Note::G,3,1.0f,190);
+
+    AddNote(0,240,Note::D,3,1.0f,190);
+    AddNote(0,240,Note::D,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::D,3,1.0f,190);
+    AddNote(0,240,Note::D,4,1.0f,190);
+    AddNote(0,240,Note::D,3,1.0f,190);
+    AddNote(0,240,Note::D,4,1.0f,190);
+
+    AddNote(0,240,Note::F,3,1.0f,190);
+    AddNote(0,240,Note::F,4,1.0f,190);
+    AddNote(0,240,Note::DS,3,1.0f,190);
+    AddNote(0,240,Note::DS,4,1.0f,190);
+    AddNote(0,240,Note::F,3,1.0f,190);
+    AddNote(0,240,Note::F,4,1.0f,190);
+    AddNote(0,240,Note::F,3,1.0f,190);
+    AddNote(0,240,Note::F,4,1.0f,190);
+
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::C,3,1.0f,190);
+    AddNote(0,240,Note::C,4,1.0f,190);
+    AddNote(0,240,Note::B,2,1.0f,190);
+    AddNote(0,240,Note::B,3,1.0f,190);
+
+    }
+
+  }
+
+
+  void TestSong::AddNote(int channel,int step,float pitch,float velocity,int gatetime)
+  {
+    tracks_[channel].push_back(SequenceData(SequenceCommand::Note,stepCounters_[channel],pitch,velocity,gatetime));
+    stepCounters_[channel] += step;
+  }
+
+  void TestSong::AddNote(int channel,int step,Note note,int octave,float velocity,int gatetime,float detune )
+  {
+    tracks_[channel].push_back(SequenceData(SequenceCommand::Note,stepCounters_[channel],GetPitch(note,octave) + detune,velocity,gatetime));
+    stepCounters_[channel] += step;
+  }
+
+  void TestSong::AddRest(int channel,int step)
+  {
+    stepCounters_[channel] += step;
+  }
+
+  float  TestSong::GetPitch(Note note,int octave)
+  {
+    return noteTable_[(int)note +  octave * 12];
+  }
+
+  TestSong::~TestSong(void)
+  {
+  }
+}
diff --git a/ShootingGame/TestSong.h b/ShootingGame/TestSong.h
new file mode 100644 (file)
index 0000000..4562515
--- /dev/null
@@ -0,0 +1,26 @@
+#pragma once
+namespace sf {
+  enum struct Note 
+  {
+    C,CS,D,DS,E,F,FS,G,GS,A,AS,B
+  };
+
+  class TestSong
+  {
+  public:
+    TestSong(SequenceTracksType& tracks);
+    void AddNote(int channel,int step,float pitch,float velocity,int gatetime);
+    void AddNote(int channel,int step,Note note,int octave,float velocity,int gatetime,float detune = 0.0f);
+    void AddRest(int channel,int step);
+    void CreateMappyData();
+    void CreateTestTone();
+    void CreateCosmicSurfin();
+    float GetPitch(Note note ,int octave);
+    ~TestSong();
+  private:
+    std::vector<int> stepCounters_;
+    std::vector<float> noteTable_;
+    SequenceTracksType& tracks_;
+  };
+}
+
index 7d34316..1c56279 100644 (file)
@@ -6,6 +6,8 @@ using namespace std::placeholders;
 
 namespace sf {
 
+  std::vector<Synthesizer::WaveTable> Synthesizer::WaveTable::WaveTables;
+
   void makeWaveFormat(WAVEFORMATEXTENSIBLE& format,
     int sample_rate = 44100,int channels = 2,int bits_per_sample = 32,int valid_bits_per_sample = 32,
     uint32_t type = WAVE_FORMAT_EXTENSIBLE,
@@ -35,296 +37,222 @@ namespace sf {
     format.nAvgBytesPerSec = format.nSamplesPerSec  * format.nBlockAlign;
   };
 
-  struct WaveTableSynth::impl {
+  void Synthesizer::WaveTableOscillator::WaveTable(Synthesizer::WaveTable *p) 
+  {
+    waveTable_ = p;
+    if(waveTable_->stereo)
+    {
+      processor_ = std::bind(&sf::Synthesizer::WaveTableOscillator::ProcessStereo,this,_1,_2,_3);
+    } else {
+      processor_ = std::bind(&sf::Synthesizer::WaveTableOscillator::ProcessMono,this,_1,_2,_3);
+    }
+
+  }
+
+  struct Synthesizer::impl {
 
     impl(){};
-    explicit impl(WAVEFORMATEXTENSIBLE& format) : format_(format) 
+    explicit impl(WAVEFORMATEXTENSIBLE& format,int channel) : format_(format) 
     {
 
       // \8b\98\94g\83e\81[\83u\83\8b\82ð\8dì\82é
       {
         WaveTable sawtbl;
-        sawtbl.SampleRate(440.0f);
-        sawtbl.BasePitch(1.0f);
-        sawtbl.Stereo(false);
+        sawtbl.sampleRate = 440.0f;
+        sawtbl.basePitch = 0.0f;
+        sawtbl.stereo = false;
 
         float v = -1.0f,d = 2.0f / 32.0f;
         for(int  i = 0;i < 32;++i)
         {
           //        if(i < 15) v = -1.0f; else v = 1.0f; 
-          sawtbl.WaveData().push_back(v) ;
+          sawtbl.waveData.push_back(v) ;
           v += d;
         }
-        waveTable_.push_back(sawtbl);
+        WaveTable::WaveTables.push_back(std::move(sawtbl));
       }
 
       // \8bé\8c`\94g\83e\81[\83u\83\8b\82ð\8dì\82é
       {
         WaveTable squaretbl;
-        squaretbl.SampleRate(440.0f);
-        squaretbl.BasePitch(1.0f);
-        squaretbl.Stereo(false);
+        squaretbl.sampleRate = 440.0f;
+        squaretbl.basePitch = 0.0f;
+        squaretbl.stereo = false;
 
         float v = 0.0f;
         for(int  i = 0;i < 32;++i)
         {
           if(i < 15) v = -1.0f; else v = 1.0f; 
-          squaretbl.WaveData().push_back(v) ;
+          squaretbl.waveData.push_back(v) ;
         }
-        waveTable_.push_back(squaretbl);
+        WaveTable::WaveTables.push_back(std::move(squaretbl));
       }
 
       // \8eO\8ap\94g\83e\81[\83u\83\8b
       {
         WaveTable tritbl;
-        tritbl.SampleRate(440.0f);
-        tritbl.BasePitch(1.0f);
-        tritbl.Stereo(false);
+        tritbl.sampleRate = 440.0f;
+        tritbl.basePitch = 0.0f;
+        tritbl.stereo = false;
 
         float v = -1.0f,d = 2.0f / 16.0f;
         for(int  i = 0;i < 32;++i)
         {
           if(i < 15) d = -d; 
-          tritbl.WaveData().push_back(v) ;
+          tritbl.waveData.push_back(v) ;
           v += d;
         }
-        waveTable_.push_back(tritbl);
+        WaveTable::WaveTables.push_back(std::move(tritbl));
       }
 
       // sin\83e\81[\83u\83\8b
       {
         WaveTable sintbl;
-        sintbl.SampleRate(440.0f);
-        sintbl.BasePitch(1.0f);
-        sintbl.Stereo(false);
+        sintbl.sampleRate = 440.0f;
+        sintbl.basePitch = 0.0f;
+        sintbl.stereo = false;
 
         float v = 0.0f,d = 2.0f * M_PI / 128.0f;
         for(int  i = 0;i < 128;++i)
         {
-          sintbl.WaveData().push_back(sinf(v));
+          sintbl.waveData.push_back(sinf(v));
           v += d;
         }
-        waveTable_.push_back(sintbl);
+        WaveTable::WaveTables.push_back(std::move(sintbl));
       }
 
-
-
-
-
-      //      ::OutputDebugStringW((boost::wformat(L"waveTable size: %d") % waveTable_[0].WaveData().size()).str().c_str());
-
-      // timber\82Ì\83Z\83b\83g\83A\83b\83v
-      Timber timber;
-      timber.waveTableNo = 3;
-      timber.amplitude.gain = 1.0f;
-      timber.amplitude.envelope.attackTime = 0.0f;
-      timber.amplitude.envelope.decayTime = 0.5f;
-      timber.amplitude.envelope.sustainLevel = 0.25f;
-      timber.amplitude.envelope.releaseTime = 3.0f;
-      timber.amplitude.envelope.gain = 1.0f;
-
-      timbers_.push_back(timber);
-
-      // Voice\82Ì\83Z\83b\83g\83A\83b\83v
-      for(int i = 0; i < 1;++i){
-        voices_.push_back(Voice(waveTable_,format.Format.nSamplesPerSec));
-        voices_[i].SetTimber(&timbers_[0]);
-        voices_[i].NoteOn(1.0f,1.0f);
-      }
-
-    };
-
-    ~impl(){};
-
-    void Restart(){};
-    void ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
-    {
-      // \8d¡\82Ì\82Æ\82±\82ë\8fo\97Í\82Í\83X\83e\83\8c\83I\91O\92ñ
-      float *ptr = arr.get();
-      float buffer[2];
-      for(int i = 0;i < bufferSize;++i)
+      // LFO\97p Sin\83e\81[\83u\83\8b
       {
-        for(int j = 0;j < voices_.size();++j)
+        WaveTable sintbl;
+        sintbl.sampleRate = 440.0f;
+        sintbl.basePitch = 0.0f;
+        sintbl.stereo = false;
+
+        float v = 0.0f,d = 2.0f * M_PI / 128.0f;
+        for(int  i = 0;i < 128;++i)
         {
-          voices_[j].Process(buffer);
-          *ptr +=  buffer[0]; 
-          *(ptr + 1) += buffer[1]; 
+          sintbl.waveData.push_back(sinf(v) / 2.0f + 0.5f);
+          v += d;
         }
-        ptr += 2;
+         WaveTable::WaveTables.push_back(std::move(sintbl));
       }
 
-      // \83T\83C\83\93\94g\82Ì\90\90¬
 
-      //static float sampleIncrement = (440.0f /* Hz */ * (M_PI * 2.0f)) / (float)format_.Format.nSamplesPerSec;
-      //static float theta = 0.0f;
 
-      //for (size_t i = 0 ; i < bufferSize ; ++i)
-      //{
-      //  float sinValue = sinf( theta );
-      //  int offset = i * format_.Format.nChannels;
-      //  for(size_t j = 0 ;j < format_.Format.nChannels; j++)
-      //  {
-      //    arr[offset + j] = sinValue;
-      //  }
-      //  theta += sampleIncrement;
-      //}
-    }
 
-    struct Envelope 
-    {
-      Envelope() : 
-        attackTime(0.0f),
-        decayTime(0.5f),
-        sustainLevel(0.5f),
-        releaseTime(3.0f),gain(1.0f)
-      {}
-      float attackTime;
-      float decayTime;
-      float sustainLevel;
-      float releaseTime;
-      float gain;
-    };
-
-    struct Oscillator 
-    {
-      virtual void Process(float * data,float delta) = 0;
-      virtual bool Stereo() const = 0;
-    };
-    struct WaveTable : public Oscillator
-    {
-      typedef std::vector<float> WaveDataType;
-      typedef std::function<void (float * ,float)> ProcessorType;
+      //      ::OutputDebugStringW((boost::wformat(L"waveTable size: %d") % osc_[0].WaveData().size()).str().c_str());
 
-      WaveTable() : waveCounter_(0.0f),stereo_(false)
-      {
-        Stereo(false);
-      };
-
-      WaveTable(const WaveTable& src) :
-        sampleRate_(src.sampleRate_),//
-        basePitch_(src.basePitch_),
-        waveCounter_(src.waveCounter_),
-        waveData_(src.waveData_)
-      {
-        Stereo(src.stereo_);
+      // timber\82Ì\83Z\83b\83g\83A\83b\83v
+      for(int i = 0; i < channel;++i){
+
+        Timber timber;
+        timber.oscillator.reset(new WaveTableOscillator(&WaveTable::WaveTables.at(0)));
+        timber.amplitude.gain = 1.0f;
+        timber.amplitude.envelope.releaseNoteOff = true;
+        timber.amplitude.envelope.attackTime = 0.01f;
+        timber.amplitude.envelope.decayTime = 0.02f;
+        timber.amplitude.envelope.sustainLevel = 0.5f;
+        timber.amplitude.envelope.releaseTime = 0.2f;
+        timber.amplitude.envelope.gain = 1.0f;
+        timber.amplitude.lfo.waveForm = &(WaveTable::WaveTables[4]);
+        timber.amplitude.lfo.freq = 5.0f;
+        timber.amplitude.lfo.gain = 0.0f;
+
+        timber.pitch.lfo.freq = 10.0f;
+        timber.pitch.lfo.gain = 0.000f;
+        timber.pitch.lfo.waveForm = &(WaveTable::WaveTables[4]);
+        timber.pitch.lfo.startNoteOn = true;
+        timber.pitch.envelope.attackTime = 0.0f;
+        timber.pitch.envelope.decayTime = 0.02f;
+        timber.pitch.envelope.sustainLevel = 0.5f;
+        timber.pitch.envelope.gain =0.0f;
+        timber.pitch.pitch = 0.0f;
+
+        timber.pan.lfo.freq = 2.0f;
+        timber.pan.lfo.gain = 1.0f;
+        timber.pan.lfo.waveForm = &(WaveTable::WaveTables[3]);
+        timber.pan.lfo.startNoteOn = true;
+        timber.pan.envelope.enable = false;
+        timber.pan.lfo.envelope.enable = false;
+        timber.pan.pan = 0.0f;
+
+        timber.filter.lfo.freq = 10.0f;
+        timber.filter.lfo.gain = 1.0f;
+        timber.filter.lfo.waveForm = &(WaveTable::WaveTables[4]);
+        timber.filter.lfo.startNoteOn = true;
+        timber.filter.cutoff = 8000.0f;
+        timber.filter.resonance = 0.5f;
+
+        programs_.push_back(Program(std::move((boost::wformat(L"Program No.%d") % i).str()),std::move(timber)));   
+//        timbers_.push_back(std::move(timber));
       }
 
-      void Process(float * data,float delta)
+      // Voice\82Ì\83Z\83b\83g\83A\83b\83v
+      //Voice v((float)format.Format.nSamplesPerSec);
+      //v.SetProgram(0,programs_[0]);
+      //Voice v1((float)format.Format.nSamplesPerSec);
+      //v1.SetProgram(0,programs_[0]);
+      //Voice v4 = v;
+      //Voice v5 = v;
+      //Voice v2 = std::move(v);
+      //Voice v3(std::move(v1));
+
+      for(int i = 0; i < channel;++i)
       {
-        processor_(data,delta);
+        voices_.push_back(Voice((float)format.Format.nSamplesPerSec));
       }
 
-      bool Stereo() const {return stereo_;}
-      void Stereo(bool v) {
-        stereo_ = v;
-        if(v)
-        {
-          processor_ = [&](float * data,float delta) -> void
-          {
-            waveCounter_ += delta;
-
-            if(waveData_.size() <= (int)(waveCounter_ * 2.0f))
-            {
-              waveCounter_ -= (float)waveData_.size() / 2.0f;
-            }
-
-            int index = (float) waveCounter_;
-            float *src = &waveData_[index * 2];
-            *data = *src;
-            ++data;++src;
-            *data = *src;
-
-          };
-        } else {
-          processor_ = [&](float * data,float delta) -> void
-          {
-            waveCounter_ += delta;
-            if(waveData_.size() <= (int)(waveCounter_))
-            {
-              waveCounter_ -= (float)waveData_.size();
-            }
-            int index = (int) waveCounter_;
-            float d = waveData_[index];
-            *data++ = d;
-            *data = d;
-
-
-          };
-        }
-      }
-      WaveDataType& WaveData() {return waveData_;}
-      void WaveData(const WaveDataType& src)
+      for(int i = 0; i < channel;++i)
       {
-        waveData_ = src;
+        voices_[i].SetProgram(0,programs_[0]);
       }
 
-      void SampleRate(float s) {sampleRate_ = s;}
-      float SampleRate() const {return sampleRate_;}
-      void BasePitch(float v) {basePitch_ = v;}
-      float BasePitch() { return basePitch_ ;}
-    private:
-      bool stereo_;
-      float sampleRate_;//
-      float basePitch_;
-      float waveCounter_;
-      ProcessorType processor_;
-      WaveDataType waveData_;
-    };
-
-    struct LFO
-    {
-      LFO(){}
-      WaveTable* waveForm;
-      bool startNoteOn;
-      float freq;
-      float gain;
-    };
-
-    struct Filter
-    {
-      int type;
-      float level;
-      float resonance;
-      Envelope envelope;
-      LFO  lfo;
     };
 
-    struct Amplitude
-    {
-      Amplitude() : gain(1.0f) {}
-      float gain;
-      Envelope envelope;
-      LFO lfo;
-    };
-
-    struct Pitch {
-      Pitch() : pitch(1.0f){}
-      float pitch;
-      Envelope envelope;
-      LFO lfo;
-    };
+    ~impl(){};
 
-    struct Pan {
-      Pan() : pan(0.5f) {};
-      float pan;
-      Envelope envelope;
-      LFO lfo;
-    };
+    void Restart(){};
 
-    struct Timber 
+    void Process(float *buffer)
     {
-      Timber() : waveTableNo(0){};
-      int waveTableNo;
-      Amplitude amplitude;
-      Filter filter;
-      Pitch pitch;
-      Pan pan;
-    };
+      for(int j = 0;j < voices_.size();++j)
+      {
+        voices_[j].Process(buffer);
+        //*buffer +=  buffer[0]; 
+        //*(buffer+ 1) += buffer[1]; 
+      }
+    }
+    //void ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
+    //{
+    //  // \8d¡\82Ì\82Æ\82±\82ë\8fo\97Í\82Í\83X\83e\83\8c\83I\91O\92ñ
+    //  float *ptr = arr.get();
+    //  float buffer[2];
+    //  for(int i = 0;i < bufferSize;++i)
+    //  {
+    //    for(int j = 0;j < voices_.size();++j)
+    //    {
+    //      voices_[j].Process(buffer);
+    //      *ptr +=  buffer[0]; 
+    //      *(ptr + 1) += buffer[1]; 
+    //    }
+    //    ptr += 2;
+    //  }
+
+    //  //static float sampleIncrement = (440.0f /* Hz */ * (M_PI * 2.0f)) / (float)format_.Format.nSamplesPerSec;
+    //  //static float theta = 0.0f;
+
+    //  //for (size_t i = 0 ; i < bufferSize ; ++i)
+    //  //{
+    //  //  float sinValue = sinf( theta );
+    //  //  int offset = i * format_.Format.nChannels;
+    //  //  for(size_t j = 0 ;j < format_.Format.nChannels; j++)
+    //  //  {
+    //  //    arr[offset + j] = sinValue;
+    //  //  }
+    //  //  theta += sampleIncrement;
+    //  //}
+    //}
 
-    struct Program {
-      std::wstring name;
-      Timber Timber;
-    };
 
     enum struct EnvelopeStatus
     {
@@ -336,6 +264,55 @@ namespace sf {
       EnvelopeController() : envelope_(nullptr),stepTime_(1.0f / 44100.0f)
       {
       }
+      EnvelopeController(const EnvelopeController& src) :
+        envelope_(src.envelope_),
+        status_(src.status_),
+        delta_(src.delta_),
+        counter_(src.counter_),
+        stepTime_(src.stepTime_),
+        time_(src.time_),
+        value_(src.value_)
+      {}
+
+      EnvelopeController(EnvelopeController&& src) :
+        envelope_(std::move( src.envelope_)),
+        status_(std::move(src.status_)),
+        delta_(std::move(src.delta_)),
+        counter_(std::move(src.counter_)),
+        stepTime_(std::move(src.stepTime_)),
+        time_(std::move(src.time_)),
+        value_(std::move(src.value_))
+      {}
+
+      EnvelopeController& operator= (const EnvelopeController& src)
+      {
+        if(this != &src)
+        {
+          envelope_ = src.envelope_;
+          status_ = src.status_;
+          delta_ = src.delta_;
+          counter_ = src.counter_;
+          stepTime_ = src.stepTime_;
+          time_ = src.time_;
+          value_ = src.value_;
+        }
+        return *this;
+      }
+
+      EnvelopeController& operator= (EnvelopeController&& src)
+      {
+        if(this != &src)
+        {
+          envelope_ = std::move(src.envelope_);
+          status_ = std::move(src.status_);
+          delta_ = std::move(src.delta_);
+          counter_ = std::move(src.counter_);
+          stepTime_ = std::move(src.stepTime_);
+          time_ = std::move(src.time_);
+          value_ = std::move(src.value_);
+        }
+        return *this;
+      }
 
       void Reset()
       {
@@ -347,8 +324,10 @@ namespace sf {
         envelope_ = env;
         stepTime_ = 1.0f / sampleRate;
       }
+
       void Attack()
       {
+        counter_ = 0.0f;
         if(envelope_->attackTime == 0.0f)
         {
           value_ = 1.0f;
@@ -383,12 +362,24 @@ namespace sf {
 
       void Release()
       {
-        delta_ = (value_) * stepTime_ / (envelope_->decayTime); 
-        status_ = EnvelopeStatus::Release;
+        if(envelope_->releaseNoteOff){
+          delta_ = value_ * stepTime_ / (envelope_->releaseTime ); 
+          status_ = EnvelopeStatus::Release;
+        }
       }
 
       float Process()
       {
+        if(!IsEnable())
+        {
+          return 1.0f;
+        }
+
+        if(envelope_->gain == 0.0f)
+        {
+          return 0.0f;
+        }
+        counter_ += stepTime_;
         switch (status_)
         {
         case EnvelopeStatus::Attack:
@@ -418,8 +409,8 @@ namespace sf {
             if(value_ <= 0.0f)
             {
               value_ = 0.0f;
+              status_ = EnvelopeStatus::End;
             }
-            status_ = EnvelopeStatus::End;
           }
           break;
         }
@@ -430,10 +421,14 @@ namespace sf {
       {
         return status_;
       }
+
+      bool IsEnable() const {return envelope_ != nullptr && envelope_->enable;}
+
     private:
       Envelope* envelope_;
       EnvelopeStatus status_;
       float delta_;
+      float counter_;
       float stepTime_;
       float time_;
       float value_;
@@ -441,42 +436,347 @@ namespace sf {
 
     struct LFOController
     {
-      LFOController() : lfo_(nullptr),value_(0.0f),stepTime_(0.0f) {};
-      void SetLFO(LFO *lfo)
+      LFOController() : lfo_(nullptr),value_(0.0f),stepTime_(0.0f)
+      {
+      };
+
+      LFOController(const LFOController& src) :
+        lfo_(src.lfo_),
+        osc_(src.osc_),
+        envelopeController_(src.envelopeController_),
+        sampleRate_(src.sampleRate_),
+        value_(src.value_),
+        stepTime_(src.stepTime_),
+        pitchDelta_(src.pitchDelta_),
+        stepDelta_(src.stepDelta_)
+      {
+
+      }
+
+      LFOController(LFOController&& src) :
+        lfo_(std::move(src.lfo_)),
+        osc_(std::move(src.osc_)),
+        envelopeController_(std::move(src.envelopeController_)),
+        sampleRate_(std::move(src.sampleRate_)),
+        value_(std::move(src.value_)),
+        stepTime_(std::move(src.stepTime_)),
+        pitchDelta_(std::move(src.pitchDelta_)),
+        stepDelta_(std::move(src.stepDelta_))
+      {
+
+      }
+
+      LFOController& operator= (const LFOController& src)
+      {
+        if(this != & src)
+        {
+          lfo_ = src.lfo_;
+          osc_ = src.osc_;
+          envelopeController_ = src.envelopeController_;
+          sampleRate_ = src.sampleRate_;
+          value_ = src.value_;
+          stepTime_ = src.stepTime_;
+          pitchDelta_ = src.pitchDelta_;
+          stepDelta_ = src.stepDelta_;
+        }
+        return *this;
+      }
+
+      LFOController& operator= (LFOController&& src)
+      {
+        if(this != & src)
+        {
+          lfo_ = std::move(src.lfo_);
+          osc_ = std::move(src.osc_);
+          envelopeController_ = std::move(src.envelopeController_);
+          sampleRate_ = std::move(src.sampleRate_);
+          value_ = std::move(src.value_);
+          stepTime_ = std::move(src.stepTime_);
+          pitchDelta_ = std::move(src.pitchDelta_);
+          stepDelta_ = std::move(src.stepDelta_);
+        }
+        return *this;
+      }
+
+      void LFOController::LFO(sf::Synthesizer::LFO *lfo)
       {
         lfo_ = lfo;
       }
-      void Init()
+
+      sf::Synthesizer::LFO& LFOController::LFO()
       {
-        assert(lfo_ != nullptr);
+        return *lfo_;
+      }
+
+      void Init(float sampleRate)
+      {
+        // assert(lfo_ != nullptr);
+        osc_.WaveTable(lfo_->waveForm);
+        sampleRate_ = sampleRate;
+        stepDelta_ = 1.0f / sampleRate_;
+        pitchDelta_ = lfo_->freq  * ((float)osc_.WaveTable().waveData.size()) /  ( sampleRate_ );
+        envelopeController_.Init(&lfo_->envelope,sampleRate);
       };
+
+      void Attack()
+      {
+        envelopeController_.Attack();
+      }
+
+      void Release()
+      {
+        envelopeController_.Release();
+      }
+
       void Reset()
       {
         assert(lfo_ != nullptr);
       }
-      void Process()
+
+      float Process()
       {
-        assert(lfo_ != nullptr);
+        float buffer[2];
+        osc_.Process(buffer,pitchDelta_,1.0f);
+        float value = buffer[0];
+        value = value * envelopeController_.Process() * lfo_->gain;
+        return value;
       };
+
+      void PreProcess()
+      {
+        float buffer[2];
+        osc_.Process(buffer,pitchDelta_,0.0f);
+        envelopeController_.Process();
+      }
+
+      float SampleRate() const {return sampleRate_;}
+      void SampleRate(float v) 
+      {
+        sampleRate_ = v;
+      }
+
+//      Synthesizer::impl::Envelope& Envelope() {return envelope_;}
+
+
     private:
-      LFO * lfo_;
+      sf::Synthesizer::LFO * lfo_;
+      WaveTableOscillator osc_;
+//      Synthesizer::impl::Envelope envelope_;
       EnvelopeController envelopeController_;
+      float sampleRate_;
       float value_;
       float stepTime_;
+      float pitchDelta_;
+      float stepDelta_;
+    };
+
+    struct FilterController
+    {
+      //sampleRate_,
+      //  filter_,
+      //  y1_,
+      //  y2_,
+      //  y3_,
+      //  y4_,
+      //  oldx_,
+      //  oldy1_,
+      //  oldy2_,
+      //  oldy3_,
+      //  x_,
+      //  r_,
+      //  p_,
+      //  k_
+
+      FilterController() :
+        cutoff_(0.0f),
+      sampleRate_(44100.0f),
+      filter_(nullptr),
+      y1_(0.0f),
+      y2_(0.0f),
+      y3_(0.0f),
+      y4_(0.0f),
+      oldx_(0.0f),
+      oldy1_(0.0f),
+      oldy2_(0.0f),
+      oldy3_(0.0f),
+      x_(0.0f),
+      r_(0.0f),
+      p_(0.0f),
+      k_(0.0f)
+      {
+//        Init();
+      }
+
+      FilterController(const FilterController& src) :
+        cutoff_(src.cutoff_),
+      sampleRate_(src.sampleRate_),
+        filter_(src.filter_),
+        y1_(src.y1_),
+        y2_(src.y2_),
+        y3_(src.y3_),
+        y4_(src.y4_),
+        oldx_(src.oldx_),
+        oldy1_(src.oldy1_),
+        oldy2_(src.oldy2_),
+        oldy3_(src.oldy3_),
+        x_(src.x_),
+        r_(src.r_),
+        p_(src.p_),
+        k_(src.k_)
+      {
+
+      }
+
+      FilterController(FilterController&& src) :
+        cutoff_(std::move(src.cutoff_)),
+      sampleRate_(std::move(src.sampleRate_)),
+        filter_(std::move(src.filter_)),
+        y1_(std::move(src.y1_)),
+        y2_(std::move(src.y2_)),
+        y3_(std::move(src.y3_)),
+        y4_(std::move(src.y4_)),
+        oldx_(std::move(src.oldx_)),
+        oldy1_(std::move(src.oldy1_)),
+        oldy2_(std::move(src.oldy2_)),
+        oldy3_(std::move(src.oldy3_)),
+        x_(std::move(src.x_)),
+        r_(std::move(src.r_)),
+        p_(std::move(src.p_)),
+        k_(std::move(src.k_))
+      {
+
+      }
+
+     FilterController& operator= (const FilterController& src)
+      {
+        if(this != &src)
+        {
+          cutoff_ = src.cutoff_;
+          sampleRate_ = src.sampleRate_;
+          filter_ = src.filter_;
+          y1_ = src.y1_;
+          y2_ = src.y2_;
+          y3_ = src.y3_;
+          y4_ = src.y4_;
+          oldx_ = src.oldx_;
+          oldy1_ = src.oldy1_;
+          oldy2_ = src.oldy2_;
+          oldy3_ = src.oldy3_;
+          x_ = src.x_;
+          r_ = src.r_;
+          p_ = src.p_;
+          k_ = src.k_;
+        }
+        return *this;
+      }
+
+      FilterController& operator= (FilterController&& src)
+      {
+        if(this != &src)
+        {
+          cutoff_ = std::move(src.cutoff_);
+          sampleRate_ = std::move(src.sampleRate_);
+          filter_ = std::move(src.filter_);
+          y1_ = std::move(src.y1_);
+          y2_ = std::move(src.y2_);
+          y3_ = std::move(src.y3_);
+          y4_ = std::move(src.y4_);
+          oldx_ = std::move(src.oldx_);
+          oldy1_ = std::move(src.oldy1_);
+          oldy2_ = std::move(src.oldy2_);
+          oldy3_ = std::move(src.oldy3_);
+          x_ = std::move(src.x_);
+          r_ = std::move(src.r_);
+          p_ = std::move(src.p_);
+          k_ = std::move(src.k_);
+        }
+        return *this;
+      }
+
+      ~FilterController(){}
+
+      void Init(Synthesizer::Filter* filter,float sampleRate)
+      {
+        filter_ = filter;
+        cutoff_ = filter->cutoff;
+        sampleRate_ = sampleRate;
+        assert(filter_ != nullptr);
+
+        y1_ = y2_ = y3_ = y4_ = oldx_ = oldy1_ = oldy2_ = oldy3_ = 0.0f;
+        Calc();
+      }
+
+      void Calc()
+      {
+        float f = (cutoff_ + cutoff_) / sampleRate_;
+        p_ = f * (1.8f - 0.8f * f);
+        k_ = p_+ p_ - 1.0f;
+
+        float t = (1.0f - p_) * 1.386249f;
+        float t2 = 12.0f + t*t;
+        r_ = filter_->resonance * (t2 + 6.0f * t) / (t2 - 6.0f * t);
+      }
+
+      float Process(float input)
+      {
+        x_ = input - r_ * y4_;
+
+        y1_ = x_ * p_ +  oldx_ * p_ -  k_ * y1_;
+        y2_ = y1_ * p_ + oldy1_ * p_ - k_ * y2_;
+        y3_ = y2_ * p_ + oldy2_ * p_ - k_ * y3_;
+        y4_ = y3_ * p_ + oldy3_ * p_ - k_ * y4_;
+
+        y4_ -= (y4_ * y4_ * y4_) / 6.0f;
+
+        oldx_ = x_; oldy1_ = y1_; oldy2_ = y2_; oldy3_ = y3_;
+        return y4_;
+      }
+
+      Synthesizer::Filter* FilterController::Filter()
+      {
+        return filter_;
+      }
+
+      void FilterController::Filter(Synthesizer::Filter* filter)
+      {
+        Init(filter,sampleRate_);
+      }
+
+      void Start()
+      {
+        y1_ = y2_ = y3_ = y4_ = oldx_ = oldy1_ = oldy2_ = oldy3_ = 0.0f;
+        Calc();
+      }
+
+      void CutOff(float v ) {cutoff_ = v;Calc();}
+      float CutOff() const {return cutoff_;}
+
+    private:
+      float cutoff_;
+      float sampleRate_;
+      Synthesizer::Filter *filter_;
+      float fs_;
+      float y1_,y2_,y3_,y4_;
+      float oldx_;
+      float oldy1_,oldy2_,oldy3_;
+      float x_;
+      float r_;
+      float p_;
+      float k_;
+
     };
+      
 
-    typedef std::vector<WaveTable> WaveTablesType;
 
     struct Voice 
     {
 
-      Voice(WaveTablesType& waveTables,float sampleRate)  
+      explicit Voice(float sampleRate)  
         : 
-        timber_(nullptr),
-        waveTables_(waveTables),
+        programNo_(0),
         noteOn_(false),
         isFree_(true),
-        pitchOffset_(1.0f),
+        pitchOffset_(0.0f),
         volumeOffset_(1.0f),
         stepTime_(0.0f),
         currentTime_(0.0f),
@@ -485,14 +785,13 @@ namespace sf {
         sampleRate_(sampleRate),
         pitchDelta_(0.0f),
         pitchCounter_(0.0f),
-        waveSize_(0),
-        waveTable_(nullptr)
+        waveSize_(0)
       {};
 
       Voice(const Voice& src) 
         : 
         timber_(src.timber_),
-        waveTables_(src.waveTables_),
+        programNo_(src.programNo_),
         noteOn_(src.noteOn_),
         isFree_(src.isFree_),
         pitchOffset_(src.pitchOffset_),
@@ -505,17 +804,116 @@ namespace sf {
         pitchDelta_(src.pitchDelta_),
         pitchCounter_(src.pitchCounter_),
         waveSize_(src.waveSize_),
-        waveTable_(src.waveTable_),
-        ampEnv(src.ampEnv),
-        ampLFO(src.ampLFO),
-        filterEnv(src.filterEnv),
-        filterLFO(src.filterLFO),
-        pitchEnv(src.pitchEnv),
-        pitchLFO(src.pitchLFO),
-        panEnv(src.panEnv),
-        panLFO(src.panLFO)
+        ampEnv_(src.ampEnv_),
+        ampLFO_(src.ampLFO_),
+        filterEnv_(src.filterEnv_),
+        filterLFO_(src.filterLFO_),
+        filterL_(src.filterL_),
+        filterR_(src.filterR_),
+        pitchEnv_(src.pitchEnv_),
+        pitchLFO_(src.pitchLFO_),
+        panEnv_(src.panEnv_),
+        panLFO_(src.panLFO_)
       {
+//        osc_ = std::move(osc_->Clone());
+      }
+
+      Voice(Voice&& src) 
+        : 
+        timber_(std::move(src.timber_)),
+        programNo_(std::move(src.programNo_)),
+        noteOn_(std::move(src.noteOn_)),
+        isFree_(std::move(src.isFree_)),
+        pitchOffset_(std::move(src.pitchOffset_)),
+        volumeOffset_(std::move(src.volumeOffset_)),
+        stepTime_(std::move(src.stepTime_)),
+        currentTime_(std::move(src.currentTime_)),
+        curentIndex_(std::move(src.curentIndex_)),
+        pan_(std::move(src.pan_)),
+        sampleRate_(std::move(src.sampleRate_)),
+        pitchDelta_(std::move(src.pitchDelta_)),
+        pitchCounter_(std::move(src.pitchCounter_)),
+        waveSize_(std::move(src.waveSize_)),
+//        osc_(std::move(src.osc_)),
+        ampEnv_(std::move(src.ampEnv_)),
+        ampLFO_(std::move(src.ampLFO_)),
+        filterEnv_(std::move(src.filterEnv_)),
+        filterLFO_(std::move(src.filterLFO_)),
+        filterL_(std::move(src.filterL_)),
+        filterR_(std::move(src.filterR_)),
+        pitchEnv_(std::move(src.pitchEnv_)),
+        pitchLFO_(std::move(src.pitchLFO_)),
+        panEnv_(std::move(src.panEnv_)),
+        panLFO_(std::move(src.panLFO_))
+      {
+ //       osc_.reset(src.osc_.release());
+ //       *this = std::move(src);
+      }
+
+      Voice& operator= (const Voice& src)
+      {
+        if(this != &src)
+        {
+          timber_ = src.timber_;
+          programNo_ = src.programNo_;
+          noteOn_ = src.noteOn_;
+          isFree_ = src.isFree_;
+          pitchOffset_ = src.pitchOffset_;
+          volumeOffset_ = src.volumeOffset_;
+          stepTime_ = src.stepTime_;
+          currentTime_ = src.currentTime_;
+          curentIndex_ = src.curentIndex_;
+          pan_ = src.pan_;
+          sampleRate_ = src.sampleRate_;
+          pitchDelta_ = src.pitchDelta_;
+          pitchCounter_ = src.pitchCounter_;
+          waveSize_ = src.waveSize_;
+  //        osc_ = src.osc_->Clone();
+          ampEnv_ = src.ampEnv_;
+          ampLFO_ = src.ampLFO_;
+          filterEnv_ = src.filterEnv_;
+          filterLFO_ = src.filterLFO_;
+          filterL_ = src.filterL_;
+          filterR_ = src.filterR_;
+          pitchEnv_ = src.pitchEnv_;
+          pitchLFO_ = src.pitchLFO_;
+          panEnv_ = src.panEnv_;
+          panLFO_ = src.panLFO_;          
+        }
+        return *this;
+      }
 
+      Voice& operator= (Voice&& src)
+      {
+        if(this != &src)
+        {
+          timber_ = std::move(src.timber_);
+          programNo_ = std::move(src.programNo_);
+          noteOn_ = std::move(src.noteOn_);
+          isFree_ = std::move(src.isFree_);
+          pitchOffset_ = std::move(src.pitchOffset_);
+          volumeOffset_ = std::move(src.volumeOffset_);
+          stepTime_ = std::move(src.stepTime_);
+          currentTime_ = std::move(src.currentTime_);
+          curentIndex_ = std::move(src.curentIndex_);
+          pan_ = std::move(src.pan_);
+          sampleRate_ = std::move(src.sampleRate_);
+          pitchDelta_ = std::move(src.pitchDelta_);
+          pitchCounter_ = std::move(src.pitchCounter_);
+          waveSize_ = std::move(src.waveSize_);
+  //        osc_.reset(src.osc_.release());
+          ampEnv_ = std::move(src.ampEnv_);
+          ampLFO_ = std::move(src.ampLFO_);
+          filterEnv_ = std::move(src.filterEnv_);
+          filterLFO_ = std::move(src.filterLFO_);
+          filterL_ = std::move(src.filterL_);
+          filterR_ = std::move(src.filterR_);
+          pitchEnv_ = std::move(src.pitchEnv_);
+          pitchLFO_ = std::move(src.pitchLFO_);
+          panEnv_ = std::move(src.panEnv_);
+          panLFO_ = std::move(src.panLFO_);        
+        }
+        return *this;
       }
 
       void SetSampleRate(float sampleRate)
@@ -523,53 +921,102 @@ namespace sf {
         sampleRate_ = sampleRate;
       }
 
-      void SetTimber(Timber* timber)
+      void SetProgram(int programNo,Program& program)
       {
-        timber_ = timber;
-        waveTable_ = &(waveTables_[timber_->waveTableNo]);
-        ampEnv.Init(&(timber_->amplitude.envelope),sampleRate_);
-        filterEnv.Init(&(timber_->filter.envelope),sampleRate_);
-        pitchEnv.Init(&(timber_->pitch.envelope),sampleRate_);
-        panEnv.Init(&(timber_->pitch.envelope),sampleRate_);
+        timber_ = program.timber;
+        programNo_ = programNo;
+        Init();
+//        osc_->Init(timber_);
+      }
+
+      void Init()
+      {
+        ampEnv_.Init(&(timber_.amplitude.envelope),sampleRate_);
+        filterEnv_.Init(&(timber_.filter.envelope),sampleRate_);
+        pitchEnv_.Init(&(timber_.pitch.envelope),sampleRate_);
+        panEnv_.Init(&(timber_.pan.envelope),sampleRate_);
+        filterL_.Init(&(timber_.filter),sampleRate_);
+        filterR_.Init(&(timber_.filter),sampleRate_);
+
+        ampLFO_.LFO(&timber_.amplitude.lfo);
+        pitchLFO_.LFO(&timber_.pitch.lfo);
+        panLFO_.LFO(&timber_.pan.lfo);
+        filterLFO_.LFO(&timber_.filter.lfo);
+
+        ampLFO_.Init(sampleRate_);
+        pitchLFO_.Init(sampleRate_);
+        panLFO_.Init(sampleRate_);
+        filterLFO_.Init(sampleRate_);
       }
 
       void Process(float* buffer) // 1\83T\83\93\83v\83\8b\95ª\82Ì\8f\88\97\9d\82ð\8ds\82¤
       {
-        //        assert(!isFree_);
+        if(!isFree_){
 
-        //currentTime_ += stepTime_;
+          //if(pitchCounter_ >= (waveSize_ - 1.0f))
+          //{
+          //  pitchCounter_ -= (waveSize_ - 1.0f);
+          //}
 
-        //pitchCounter_ += pitchDelta_ * pitchOffset_ * waveTable_->BasePitch() * pitchEnv.Process() * timber_->pitch.pitch;
+          float waveData[2];
 
-        //if(pitchCounter_ >= (waveSize_ - 1.0f))
-        //{
-        //  pitchCounter_ -= (waveSize_ - 1.0f);
-        //}
+          timber_.oscillator->Process(
+            waveData,
+            pitchDelta_, 
+              pitchOffset_
+                + pitchLFO_.Process() 
+                + pitchEnv_.Process() 
+                + timber_.pitch.pitch );
 
-        float waveData[2];
+          float cutoff = timber_.filter.cutoff;// + filterEnv_.Process(),
+          filterL_.CutOff(cutoff);
+          filterR_.CutOff(cutoff);
 
-        waveTable_->Process(waveData,pitchDelta_  * pitchOffset_ * waveTable_->BasePitch() * pitchEnv.Process() * timber_->pitch.pitch );
+          waveData[0] = filterL_.Process(waveData[0]);
+          waveData[1] = filterR_.Process(waveData[1]);
 
-        float volume = ampEnv.Process();
-        if(volume > 1.0f) 
-        {
-          volume = 1.0f;
-        }
 
-        waveData[0] = waveData[0] * volume * volumeOffset_;
-        waveData[1] = waveData[1] * volume * volumeOffset_;
+          float volume = ampEnv_.Process() + ampLFO_.Process();
+          if(volume > 1.0f) 
+          {
+            volume = 1.0f;
+          }
 
-        // \83N\83\8a\83b\83s\83\93\83O
 
-        //if(waveData > 1.0f) waveData = 1.0f;
-        //if(waveData < 1.0f) waveData = -1.0f;
 
-        buffer[0] = waveData[0]; //* pan_;
-        buffer[1] = waveData[1]; //* (1.0f - pan_);
 
-        if(!noteOn_ && ampEnv.GetStatus() == EnvelopeStatus::End)
-        {
-          isFree_ = true;
+          // \83N\83\8a\83b\83s\83\93\83O
+
+          //if(waveData > 1.0f) waveData = 1.0f;
+          //if(waveData < 1.0f) waveData = -1.0f;
+
+          float pan =  (pan_ + panLFO_.Process());
+          if(pan > 1.0f) pan = 1.0f;
+          if(pan < -1.0f) pan = -1.0f;
+          
+          float rvolume;
+          float lvolume;
+
+          
+          if(pan > 0.0f)
+          {
+            rvolume = volume * volumeOffset_;
+            lvolume = rvolume * (1.0f - pan);
+          } else {
+            lvolume = volume * volumeOffset_;
+            rvolume = lvolume * (1.0f + pan);
+          }
+
+          waveData[0] = waveData[0] * lvolume;
+          waveData[1] = waveData[1] * rvolume;
+
+          buffer[0] += waveData[0]; //* pan_;
+          buffer[1] += waveData[1]; //* (1.0f - pan_);
+
+          if(!noteOn_ && ampEnv_.GetStatus() == EnvelopeStatus::End)
+          {
+            isFree_ = true;
+          }
         }
       }
 
@@ -578,20 +1025,29 @@ namespace sf {
       void NoteOn(float pitch,float volume) 
       { 
         if(!noteOn_){
+          isFree_ = false;
           noteOn_ = true;
           pitchOffset_ = pitch;
           volumeOffset_ = volume;
           stepTime_ = 1.0f / sampleRate_;
-          pitchDelta_ = waveTable_->SampleRate()  * ((float)waveTable_->WaveData().size()) /  sampleRate_ ;
-          //          waveSize_ = (float)waveTable_->waveData.size();
+          pitchDelta_ = timber_.oscillator->CalcPitchDelta(sampleRate_);
+          //          waveSize_ = (float)osc_->waveData.size();
           currentTime_ = 0.0f;
           curentIndex_ = 0;
-          pan_ = timber_->pan.pan;
+          pan_ = timber_.pan.pan;
           pitchCounter_ = 0.0f;
-          ampEnv.Attack();
-          filterEnv.Attack();
-          pitchEnv.Attack();
-          panEnv.Attack();
+          ampEnv_.Attack();
+          filterEnv_.Attack();
+          pitchEnv_.Attack();
+          panEnv_.Attack();
+
+          ampLFO_.Attack();
+          filterLFO_.Attack();
+          pitchLFO_.Attack();
+          panLFO_.Attack();
+
+          filterL_.Start();
+          filterR_.Start();
         }
       }
 
@@ -600,16 +1056,24 @@ namespace sf {
         if(noteOn_)
         {
           noteOn_ = false;
-          ampEnv.Release();
-          filterEnv.Release();
-          pitchEnv.Release();
-          panEnv.Release();
+          ampEnv_.Release();
+          filterEnv_.Release();
+          pitchEnv_.Release();
+          panEnv_.Release();
+
+          ampLFO_.Release();
+          filterLFO_.Release();
+          pitchLFO_.Release();
+          panLFO_.Release();
+
         }
       }
 
+      int CurrentProgramNo() const {return programNo_;}
+
     private:
-      Timber* timber_;
-      WaveTablesType& waveTables_;
+      Timber timber_;
+      int programNo_;
       bool noteOn_;
       bool isFree_;
       float pitchOffset_;
@@ -622,47 +1086,131 @@ namespace sf {
       float pitchDelta_;
       float pitchCounter_;
       float waveSize_;
-      WaveTable *waveTable_;
-      EnvelopeController ampEnv;
-      LFOController ampLFO;
-      EnvelopeController filterEnv;
-      LFOController filterLFO;
-      EnvelopeController pitchEnv;
-      LFOController pitchLFO;
-      EnvelopeController panEnv;
-      LFOController panLFO;
+     // std::unique_ptr<Oscillator> osc_;
+      EnvelopeController ampEnv_;
+      LFOController ampLFO_;
+      EnvelopeController filterEnv_;
+      LFOController filterLFO_;
+      FilterController filterL_;
+      FilterController filterR_;
+      EnvelopeController pitchEnv_;
+      LFOController pitchLFO_;
+      EnvelopeController panEnv_;
+      LFOController panLFO_;
     };
 
     typedef std::vector<Voice> VoicesType; 
     typedef std::vector<Timber> TimbersType; 
     typedef std::vector<Program> ProgramsType; 
 
+    void NoteOn(int index,float pitch,float velocity)
+    {
+      voices_[index].NoteOn(pitch,velocity);
+    };
+
+    void NoteOff(int index)
+    {
+      voices_[index].NoteOff();
+    };
+
+    void AddProgram(Program&& program)
+    {
+      programs_.push_back(program);
+    }
+
+    Program& GetProgram(int index)
+    {
+      return programs_.at(index);
+    }
+
+    void UpdateProgram(int index,Program&& program)
+    {
+      programs_[index] = std::move(program);
+    }
+    
+    size_t ProgramsSize()
+    {
+      return programs_.size();
+    }
+
+    void AssignProgramToVoice(int programNo,int voiceChannelNo)
+    {
+      assert(programNo < programs_.size() && voiceChannelNo < voices_.size());
+      voices_.at(voiceChannelNo).SetProgram(programNo,programs_.at(programNo));
+    }
+
+    size_t Voices() const {return voices_.size();};
+
   private:
     WAVEFORMATEXTENSIBLE format_;
     ProgramsType programs_;// \83v\83\8a\83Z\83b\83g
-    TimbersType timbers_;
     VoicesType voices_; // Max 64 Voices
-    WaveTablesType waveTable_;
+//    WaveTablesType waveTables_;
   };
 
-  WaveTableSynth::WaveTableSynth() : impl_(new WaveTableSynth::impl()){};
+  Synthesizer::Synthesizer() : impl_(new Synthesizer::impl()){};
 
-  WaveTableSynth::WaveTableSynth(WAVEFORMATEXTENSIBLE& format ) : impl_(new WaveTableSynth::impl(format))
+  Synthesizer::Synthesizer(WAVEFORMATEXTENSIBLE& format,int channel ) : impl_(new Synthesizer::impl(format,channel))
   {
   }
 
-  WaveTableSynth::~WaveTableSynth()
+  Synthesizer::~Synthesizer()
   {
 
   }
 
-  void WaveTableSynth::ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
+  //void Synthesizer::ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
+  //{
+  //  impl_->ProcessBuffer(arr,bufferSize);
+  //}
+
+  void Synthesizer::Process(float* buffer)
   {
-    impl_->ProcessBuffer(arr,bufferSize);
+    impl_->Process(buffer);
   }
 
-  void WaveTableSynth::Restart()
+
+  void Synthesizer::Restart()
   {
     impl_->Restart();
   }
+
+  void Synthesizer::NoteOn(int index,float pitch,float velocity)
+  {
+    impl_->NoteOn(index,pitch,velocity);
+  };
+  void Synthesizer::NoteOff(int index)
+  {
+    impl_->NoteOff(index);
+  };
+
+  size_t Synthesizer::Voices() const 
+  {
+    return impl_->Voices();
+  }
+
+  void Synthesizer::AddProgram(Program&& program)
+  {
+    impl_->AddProgram(std::move(program));
+  }
+
+  Synthesizer::Program& Synthesizer::GetProgram(int index)
+  {
+    return impl_->GetProgram(index);
+  };
+
+  void Synthesizer::UpdateProgram(int index,Program&& program)
+  {
+    impl_->UpdateProgram(index,std::move(program));
+  }
+  size_t Synthesizer::ProgramsSize()
+  {
+    return impl_->ProgramsSize();
+  }
+
+  void Synthesizer::AssignProgramToVoice(int programNo,int voiceChannelNo)
+  {
+    impl_->AssignProgramToVoice(programNo,voiceChannelNo);
+  }
+
 }
index efa790a..a7a1fc2 100644 (file)
 #pragma once
 
 namespace sf {
-  struct WaveTableSynth
+  struct Synthesizer
   {
-    WaveTableSynth();
-    explicit WaveTableSynth(WAVEFORMATEXTENSIBLE& format);
-    ~WaveTableSynth();
+    // \83G\83\93\83x\83\8d\81[\83v\83p\83\89\83\81\81[\83^
+    struct Envelope 
+    {
+      Envelope() : 
+        enable(true),
+        releaseNoteOff(true),
+        attackTime(0.0f),
+        decayTime(0.5f),
+        sustainLevel(0.5f),
+        releaseTime(3.0f),
+        gain(1.0f)
+      {}
+
+      Envelope(const Envelope& src) :
+        enable(src.enable),
+        releaseNoteOff(src.releaseNoteOff),
+        attackTime(src.attackTime),
+        decayTime(src.decayTime),
+        sustainLevel(src.sustainLevel),
+        releaseTime(src.releaseTime),
+        gain(src.gain)
+      {}
+
+      Envelope(Envelope&& src) :
+        enable(std::move(src.enable)),
+        releaseNoteOff(std::move(src.releaseNoteOff)),
+        attackTime(std::move(src.attackTime)),
+        decayTime(std::move(src.decayTime)),
+        sustainLevel(std::move(src.sustainLevel)),
+        releaseTime(std::move(src.releaseTime)),
+        gain(std::move(src.gain))
+      {}
+
+      Envelope& operator=(const Envelope& src)
+      {
+        if(this != &src)
+        {
+          enable = src.enable;
+          releaseNoteOff = src.releaseNoteOff;
+          attackTime = src.attackTime;
+          decayTime = src.decayTime;
+          sustainLevel = src.sustainLevel;
+          releaseTime = src.releaseTime;
+          gain = src.gain;
+        }
+        return *this;
+      }
+
+      Envelope& operator=(Envelope&& src)
+      {
+        if(this != &src)
+        {
+          enable = std::move(src.enable);
+          releaseNoteOff = std::move(src.releaseNoteOff);
+          attackTime = std::move(src.attackTime);
+          decayTime = std::move(src.decayTime);
+          sustainLevel = std::move(src.sustainLevel);
+          releaseTime = std::move(src.releaseTime);
+          gain = std::move(src.gain);
+        }
+        return *this;
+      }
+
+      bool enable;
+      bool releaseNoteOff;
+      float attackTime;
+      float decayTime;
+      float sustainLevel;
+      float releaseTime;
+      float gain;
+    };
+
+    struct Timber;
+    enum struct OscillatorCategory
+    {
+      WaveTable,SquwareWave,SinWave
+    };
+    // \83I\83V\83\8c\81[\83^\83C\83\93\83^\81[\83t\83F\81[\83X
+    struct Oscillator 
+    {
+      typedef  std::unique_ptr<Oscillator> PtrType; 
+      virtual ~Oscillator(){}
+      virtual void Process(float * data,float delta,float offset) = 0;
+      virtual float SampleRate() const = 0;
+      virtual float CalcPitchDelta(float sampleRate) = 0;
+//      virtual void Init(Timber& timber) = 0;
+      virtual OscillatorCategory Category() = 0;
+      virtual PtrType Clone() = 0;
+    };
+
+    // \83E\83F\81[\83u\83f\81[\83^
+    typedef std::vector<float> WaveData;
+
+    // \83E\83F\81[\83u\83e\81[\83u\83\8b
+    struct WaveTable 
+    {
+      WaveTable() :
+        stereo(false),
+        sampleRate(44100.0f),//
+        basePitch(0.0f)
+      {};
+
+      WaveTable(const WaveTable& src) :
+        stereo(src.stereo),
+        sampleRate(src.sampleRate),//
+        basePitch(src.basePitch)
+      {waveData = src.waveData;};
+
+      WaveTable(WaveTable&& src) :
+        stereo(std::move(src.stereo)),
+        sampleRate(std::move(src.sampleRate)),//
+        basePitch(std::move(src.basePitch))
+      {waveData = std::move(src.waveData);};
+
+      WaveTable& operator=(const WaveTable& src)
+      {
+        if(this != &src)
+        {
+          stereo = src.stereo;
+          sampleRate = src.sampleRate;//
+          basePitch = src.basePitch;
+          waveData = src.waveData;
+        }
+        return *this;
+      }
+
+      WaveTable& operator=(WaveTable&& src)
+      {
+        if(this != &src)
+        {
+          stereo = std::move(src.stereo);
+          sampleRate = std::move(src.sampleRate);//
+          basePitch = std::move(src.basePitch);
+          waveData = std::move(src.waveData);
+        }
+        return *this;
+      }
+
+      bool stereo;
+      float sampleRate;//
+      float basePitch;
+      WaveData waveData;
+      static std::vector<WaveTable> WaveTables;
+    };
+
+    // LFO
+    struct LFO
+    {
+      LFO() : 
+        waveForm(nullptr),
+        startNoteOn(true),
+        freq(20.0f),
+        gain(1.0f)
+      {}
+      LFO(const LFO &src)
+        :
+        waveForm(src.waveForm),
+        envelope(src.envelope),
+        startNoteOn(src.startNoteOn),
+        freq(src.freq),
+        gain(src.gain) 
+      {}
+
+      LFO(LFO &&src) :
+        waveForm(std::move(src.waveForm)),
+        envelope(std::move(src.envelope)),
+        startNoteOn(std::move(src.startNoteOn)),
+        freq(std::move(src.freq)),
+        gain(std::move(src.gain)) 
+      {}
+
+      LFO& operator=(const LFO &src)
+      {
+        if(this !=  &src)
+        {
+          waveForm = src.waveForm;
+          envelope = src.envelope;
+          startNoteOn = src.startNoteOn;
+          freq = src.freq;
+          gain = src.gain; 
+
+        }
+        return *this;
+      }
+      LFO& operator=(LFO &&src)
+      {
+        if(this !=  &src)
+        {
+          waveForm = std::move(src.waveForm);
+          envelope = std::move(src.envelope);
+          startNoteOn = std::move(src.startNoteOn);
+          freq = std::move(src.freq);
+          gain = std::move(src.gain); 
+
+        }
+        return *this;
+      }
+
+      bool startNoteOn;
+      WaveTable* waveForm;
+      Envelope envelope;
+      float freq;
+      float gain;
+    };
+
+    // \83t\83B\83\8b\83^\81[\83J\83e\83S\83\8a\81[
+    enum struct FilterCategory
+    {
+      LPF,HPF,BPF
+    };
+
+    // \83t\83B\83\8b\83^\81[
+    struct Filter
+    {
+      Filter() : category(FilterCategory::LPF),level(0.0f),resonance(0.0f),cutoff(0.0f){};
+      Filter(const Filter& src) :
+        category(src.category),
+        level(src.level),
+        cutoff(src.cutoff),
+        resonance(src.resonance),
+        envelope(src.envelope),
+        lfo(src.lfo)
+      {
+      }
+
+      Filter( Filter&& src) :
+        category(std::move(src.category)),
+        level(std::move(src.level)),
+        cutoff(std::move(src.cutoff)),
+        resonance(std::move(src.resonance)),
+        envelope(std::move(src.envelope)),
+        lfo(std::move(src.lfo))
+      {
+      }
+
+      Filter& operator= (const Filter& src)
+      {
+        if(this != &src)
+        {
+          category = src.category;
+          level = src.level;
+          cutoff = src.cutoff;
+          resonance = src.resonance;
+          envelope = src.envelope;
+          lfo = src.lfo;
+        }
+        return *this;
+      }
+
+      Filter& operator= (Filter&& src)
+      {
+        if(this != &src)
+        {
+          category = std::move(src.category);
+          level = std::move(src.level);
+          cutoff = std::move(src.cutoff);
+          resonance = std::move(src.resonance);
+          envelope = std::move(src.envelope);
+          lfo = std::move(src.lfo);
+        }
+        return *this;
+      }
+
+      FilterCategory category;
+      float level;
+      float cutoff;
+      float resonance;
+      Envelope envelope;
+      LFO  lfo;
+    };
+
+    // \89¹\97Ê\83p\83\89\83\81\81[\83^
+    struct Amplitude
+    {
+      Amplitude() : gain(1.0f) {}
+      Amplitude(const Amplitude& src) :
+        gain(src.gain),
+        envelope(src.envelope),
+        lfo(src.lfo)
+      {}
+
+      Amplitude(Amplitude&& src) :
+        gain(std::move(src.gain)),
+        envelope(std::move(src.envelope)),
+        lfo(std::move(src.lfo))
+      {}
+      Amplitude& operator= (const Amplitude& src)
+      {
+        if(this != &src)
+        {
+          gain = src.gain;
+          envelope = src.envelope;
+          lfo = src.lfo;
+        }
+        return *this;
+      }
+
+      Amplitude& operator= (Amplitude&& src)
+      {
+        if(this != &src)
+        {
+          gain = std::move(src.gain);
+          envelope = std::move(src.envelope);
+          lfo = std::move(src.lfo);
+        }
+        return *this;
+      }
+
+      float gain;
+      Envelope envelope;
+      LFO lfo;
+    };
+
+    // \8eü\94g\90\94\83p\83\89\83\81\81[\83^
+    struct Pitch {
+      Pitch() : pitch(1.0f){}
+      Pitch(const Pitch& src) :
+        pitch(src.pitch),
+        envelope(src.envelope),
+        lfo(src.lfo)
+      {}
+
+      Pitch(Pitch&& src) :
+        pitch(std::move(src.pitch)),
+        envelope(std::move(src.envelope)),
+        lfo(std::move(src.lfo))
+      {}
+      Pitch& operator= (const Pitch& src)
+      {
+        if(this != &src)
+        {
+          pitch = src.pitch;
+          envelope = src.envelope;
+          lfo = src.lfo;
+        }
+        return *this;
+      }
+
+      Pitch& operator= (Pitch&& src)
+      {
+        if(this != &src)
+        {
+          pitch = std::move(src.pitch);
+          envelope = std::move(src.envelope);
+          lfo = std::move(src.lfo);
+        }
+        return *this;
+      }
+
+      float pitch;
+      Envelope envelope;
+      LFO lfo;
+    };
+
+    // \92è\88Ê\83p\83\89\83\81\81[\83^
+    struct Pan {
+      Pan() : pan(0.5f) {};
+      Pan(const Pan& src) :
+        pan(src.pan),
+        envelope(src.envelope),
+        lfo(src.lfo)
+      {}
+
+      Pan(Pan&& src) :
+        pan(std::move(src.pan)),
+        envelope(std::move(src.envelope)),
+        lfo(std::move(src.lfo))
+      {}
+
+      Pan& operator= (const Pan& src)
+      {
+        if(this != &src)
+        {
+          pan = src.pan;
+          envelope = src.envelope;
+          lfo = src.lfo;
+
+        }
+        return *this;
+      }
+
+      Pan& operator= (Pan&& src)
+      {
+        if(this != &src)
+        {
+          pan = std::move(src.pan);
+          envelope = std::move(src.envelope);
+          lfo = std::move(src.lfo);
+        }
+        return *this;
+      }
+
+      float pan;
+      Envelope envelope;
+      LFO lfo;
+    };
+
+    typedef std::vector<WaveTable> WaveTablesType;
+
+    struct WaveTableOscillator : public Oscillator
+    {
+      typedef std::function<void (float * ,float,float)> ProcessorType;
+
+      WaveTableOscillator() : waveTable_(nullptr),waveCounter_(0.0f)
+      {
+
+      };
+
+      explicit WaveTableOscillator(WaveTable* waveTable) : waveTable_(nullptr),waveCounter_(0.0f)
+      {
+        WaveTable(waveTable);
+      }
+
+      WaveTableOscillator(const WaveTableOscillator& src) : waveTable_(nullptr),
+        waveCounter_(src.waveCounter_)
+      {
+        if(src.waveTable_ != nullptr)
+        {
+          WaveTable(src.waveTable_);
+        }
+
+      }
+
+      WaveTableOscillator(WaveTableOscillator&& src) : 
+        waveTable_(std::move(nullptr)),
+        waveCounter_(std::move(src.waveCounter_))
+      {
+        if(src.waveTable_ != nullptr)
+        {
+          WaveTable(src.waveTable_);
+        }
+
+      }
+
+      WaveTableOscillator& operator= (const WaveTableOscillator& src)
+      {
+        if(this != &src)
+        {
+          this->waveCounter_ = src.waveCounter_;
+          WaveTable(src.waveTable_);
+        }
+        return *this;
+      }
+
+      WaveTableOscillator& operator= (WaveTableOscillator&& src)
+      {
+        if(this != &src)
+        {
+          this->waveCounter_ = std::move(src.waveCounter_);
+          WaveTable(src.waveTable_);
+        }
+        return *this;
+      }
+
+      void Process(float * data,float delta,float offset)
+      {
+
+        //if(waveTable_->stereo)
+        //{
+        //  ProcessStereo(data,delta);
+        //} else {
+        //  ProcessMono(data,delta);
+        //}
+        processor_(data,delta,offset);
+      }
+
+      void ProcessStereo(float * data,float delta,float offset)
+      {
+        waveCounter_ += delta * (offset + waveTable_->basePitch);
+
+        if(waveTable_->waveData.size() <= (int)(waveCounter_ * 2.0f))
+        {
+          waveCounter_ -= (float)waveTable_->waveData.size() / 2.0f;
+        }
+
+        int index = (float) waveCounter_;
+        float *src = &waveTable_->waveData[index * 2];
+        *data = *src;
+        ++data;++src;
+        *data = *src;
+
+      }
+
+      void ProcessMono(float * data,float delta,float offset)
+      {
+        waveCounter_ += delta * (offset + waveTable_->basePitch);
+
+        if(waveTable_->waveData.size() <= (int)(waveCounter_))
+        {
+          waveCounter_ -= (float)waveTable_->waveData.size();
+        }
+        int index = (int) waveCounter_;
+        float d = waveTable_->waveData[index];
+        *data++ = d;
+        *data = d;
+
+      }
+
+      float SampleRate() const {return waveTable_->sampleRate;}
+      float CalcPitchDelta(float sampleRate)
+      {
+        return SampleRate() * ((float)WaveTable().waveData.size() / sampleRate);         
+      }
+
+      //void Init()
+      //{
+      //    //WaveTable(&(WaveTable::WaveTables[timber.waveTableNo]));
+      //}
+
+      OscillatorCategory Category() {return OscillatorCategory::WaveTable;};
+
+      PtrType Clone() {return PtrType(new WaveTableOscillator(*this));}
+
+      Synthesizer::WaveTable& WaveTableOscillator::WaveTable() {return *waveTable_;}
+      void Synthesizer::WaveTableOscillator::WaveTable(Synthesizer::WaveTable *p);
+
+    private:
+      Synthesizer::WaveTable *waveTable_;
+      float waveCounter_;
+      ProcessorType processor_;
+    };
+
+    // \89¹\90F\83p\83\89\83\81\81[\83^
+    struct Timber 
+    {
+      Timber() {};
+      Timber(const Timber& src) :
+        amplitude(src.amplitude),
+        filter(src.filter),
+        pitch(src.pitch),
+        pan(src.pan)
+      {
+        if(src.oscillator.get() != nullptr){
+          oscillator = src.oscillator->Clone();
+        }
+      }
+
+      Timber(Timber&& src) :
+//        waveTableNo(std::move(src.waveTableNo)),
+        amplitude(std::move(src.amplitude)),
+        filter(std::move(src.filter)),
+        pitch(std::move(src.pitch)),
+        pan(std::move(src.pan))
+      {
+        if(src.oscillator.get() != nullptr){
+          oscillator.reset(src.oscillator.release());
+        }
+      }
+
+      Timber& operator= (const Timber& src)
+      {
+        if(this != &src)
+        {
+   //       waveTableNo = src.waveTableNo;
+        if(src.oscillator.get() != nullptr){
+          oscillator  = src.oscillator->Clone();
+        }
+          amplitude = src.amplitude;
+          filter = src.filter;
+          pitch = src.pitch;
+          pan = src.pan;
+
+        }
+        return *this;
+      }
+
+      Timber& operator= (Timber&& src)
+      {
+        if(this != &src)
+        {
+ //         waveTableNo = std::move(src.waveTableNo);
+        if(src.oscillator.get() != nullptr){
+          oscillator.reset(src.oscillator.release());
+        }
+          amplitude = std::move(src.amplitude);
+          filter = std::move(src.filter);
+          pitch = std::move(src.pitch);
+          pan = std::move(src.pan);
+        }
+        return *this;
+      }
+
+      Oscillator::PtrType oscillator;
+//      int waveTableNo;
+      Amplitude amplitude;
+      Filter filter;
+      Pitch pitch;
+      Pan pan;
+    };
+
+    // \89¹\90F\83v\83\8d\83O\83\89\83\80\83p\83\89\83\81\81[\83^
+    struct Program {
+      Program(){}
+      Program(const std::wstring& name,const Timber& timber) :
+        name(name),timber(timber)
+      {}
+
+      Program(const Program& src) 
+        :
+        name(src.name),timber(src.timber)
+      {
+
+      }
+
+      Program(const Program&& src) :
+        name(std::move(src.name)),timber(std::move(src.timber))
+      {
+
+      }
+
+      Program& operator= (const Program& src)
+      {
+        if(this != &src)
+        {
+          name = src.name;
+          timber = src.timber;
+        }
+        return *this;
+      }
+
+      Program& operator= (const Program&& src)
+      {
+        if(this != &src)
+        {
+          name = std::move(src.name);
+          timber = std::move(src.timber);
+        }
+        return *this;
+      }
+
+      std::wstring name;
+      Timber timber;
+    };
+    typedef std::vector<Program> ProgramsType;
+    // \83R\83\93\83X\83g\83\89\83N\83^
+    Synthesizer();
+    // \83R\83\93\83X\83g\83\89\83N\83^
+    explicit Synthesizer(WAVEFORMATEXTENSIBLE& format,int channel = 4);
+    // \83f\83X\83g\83\89\83N\83^
+    ~Synthesizer();
+    // \83\8a\83X\83^\81[\83g
     void Restart();
-    void ProcessBuffer(boost::shared_array<float> arr,int bufferSize);
+    // \94g\8c`\90\90¬\8f\88\97\9d
+    void Process(float* buffer);
+    // \83m\81[\83g\83I\83\93\8f\88\97\9d
+    void NoteOn(int index,float pitch,float velocity);
+    // \83m\81[\83g\83I\83t\8f\88\97\9d
+    void NoteOff(int index);
+
+    // \89¹\90F\83v\83\8d\83O\83\89\83\80
+    void AddProgram(Program&& program);
+    Program& GetProgram(int index);
+    void UpdateProgram(int index,Program&& Program);
+    size_t ProgramsSize();
+    void AssignProgramToVoice(int programNo,int voiceChannelNo);
+
+    size_t Voices() const;
+
   private:
     struct impl;
     std::unique_ptr<impl> impl_;