You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

778 lines
19KB

  1. /* SpiralSound
  2. * Copyleft (C) 2001 David Griffiths <dave@pawfal.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "SequencerPlugin.h"
  19. #include "SequencerPluginGUI.h"
  20. #include <FL/Fl_Button.h>
  21. #include "SpiralIcon.xpm"
  22. #include "../../NoteTable.h"
  23. using namespace std;
  24. // for note on's
  25. static const float TRIGGER_LEV=0.1;
  26. //////////////////////////////////////////////////////////////////////////
  27. // base sequencing stuff
  28. Note::Note(float t=0, float l=0.1f, int n=0, float v=1.0f)
  29. {
  30. Time = t;
  31. Length = l;
  32. MidiNote = n;
  33. Vol = v;
  34. }
  35. Note::~Note()
  36. {
  37. }
  38. istream &operator>>(istream &s, Note &o)
  39. {
  40. int version=1;
  41. string dummy;
  42. s>>version>>dummy>>o.Time>>o.Length>>o.MidiNote>>o.Vol;
  43. return s;
  44. }
  45. ostream &operator<<(ostream &s, Note &o)
  46. {
  47. int version=1;
  48. s<<version<<" note "<<o.Time<<" "<<o.Length<<" "<<o.MidiNote<<" "<<o.Vol<<" ";
  49. return s;
  50. }
  51. /////////////////////////////////////////////////////////////////////////
  52. Pattern::Pattern()
  53. {
  54. }
  55. Pattern::~Pattern()
  56. {
  57. }
  58. void Pattern::Copy(const Pattern *o)
  59. {
  60. // can't do this as we don't want to preserve the id numbers
  61. //m_NoteMap=o->m_NoteMap;
  62. int c=0;
  63. for (map<int,Note>::const_iterator i = o->m_NoteMap.begin();
  64. i!=o->m_NoteMap.end(); i++)
  65. {
  66. m_NoteMap[c++]=i->second;
  67. }
  68. }
  69. void Pattern::AddNote(int ID, float t, float l, int n, float v)
  70. {
  71. map<int,Note>::iterator i = m_NoteMap.find(ID);
  72. if (i != m_NoteMap.end())
  73. {
  74. cerr<<"duplicate note "<<ID<<" not added"<<endl;
  75. return;
  76. }
  77. Note newnote(t,l,n,v);
  78. m_NoteMap[ID]=newnote;
  79. }
  80. void Pattern::RemoveNote(int ID)
  81. {
  82. map<int,Note>::iterator i = m_NoteMap.find(ID);
  83. if (i == m_NoteMap.end())
  84. {
  85. cerr<<"couldn't find note "<<ID<<" not removed"<<endl;
  86. return;
  87. }
  88. m_NoteMap.erase(i);
  89. }
  90. Note *Pattern::GetNote(int ID)
  91. {
  92. map<int,Note>::iterator i = m_NoteMap.find(ID);
  93. if (i == m_NoteMap.end())
  94. {
  95. cerr<<"couldn't find note "<<ID<<endl;
  96. return NULL;
  97. }
  98. return &i->second;
  99. }
  100. istream &operator>>(istream &s, Pattern &o)
  101. {
  102. int version=1,Num;
  103. string dummy;
  104. int id=0;
  105. s>>version>>dummy>>Num;
  106. for (int n=0; n<Num; n++)
  107. {
  108. Note t;
  109. s>>t;
  110. o.m_NoteMap[id++]=t;
  111. }
  112. return s;
  113. }
  114. ostream &operator<<(ostream &s, Pattern &o)
  115. {
  116. int version=1;
  117. s<<version<<" pattern "<<o.m_NoteMap.size()<<" ";
  118. for (map<int,Note>::iterator i = o.m_NoteMap.begin();
  119. i!=o.m_NoteMap.end(); i++)
  120. {
  121. s<<i->second;
  122. }
  123. s<<endl;
  124. return s;
  125. }
  126. //////////////////////////////////////////////////////////////////////////
  127. Sequence::Sequence(float st, int pat)
  128. {
  129. m_StartTime=st;
  130. m_Pattern=pat;
  131. }
  132. Sequence::~Sequence()
  133. {
  134. }
  135. istream &operator>>(istream &s, Sequence &o)
  136. {
  137. int version=1;
  138. string dummy;
  139. s>>version>>dummy>>o.m_StartTime>>o.m_Pattern>>o.m_Colour>>o.m_YPos>>o.m_Length>>o.m_Channel;
  140. char Buf[4096];
  141. int size;
  142. s>>size;
  143. s.ignore(1);
  144. s.get(Buf,size+1);
  145. o.m_Name=Buf;
  146. return s;
  147. }
  148. ostream &operator<<(ostream &s, Sequence &o)
  149. {
  150. int version=1;
  151. s<<version<<" sequence"<<" "<<o.m_StartTime<<" "<<o.m_Pattern<<" "<<o.m_Colour<<" "<<o.m_YPos<<" "<<o.m_Length<<" "<<o.m_Channel<<" ";
  152. s<<o.m_Name.size()<<" "<<o.m_Name<<endl;
  153. return s;
  154. }
  155. //////////////////////////////////////////////////////////////////////////
  156. Track::Track()
  157. {
  158. m_NextPatternID=0;
  159. }
  160. Track::~Track()
  161. {
  162. }
  163. void Track::AddSequence(int ID)
  164. {
  165. map<int,Sequence>::iterator i = m_SequenceMap.find(ID);
  166. if (i != m_SequenceMap.end())
  167. {
  168. cerr<<"duplicate sequence "<<ID<<" not added"<<endl;
  169. return;
  170. }
  171. Sequence newsequence;
  172. AddPattern(m_NextPatternID);
  173. newsequence.SetPatternID(m_NextPatternID);
  174. newsequence.SetColour(0);
  175. newsequence.SetName("noname");
  176. newsequence.SetLength(10.0f);
  177. newsequence.SetYPos(1);
  178. newsequence.SetChannel(0);
  179. m_NextPatternID++;
  180. m_SequenceMap[ID]=newsequence;
  181. }
  182. // duplicate the sequence, but reference the same pattern
  183. void Track::CloneSequence(int ID, int nID)
  184. {
  185. AddSequence(nID);
  186. Sequence *s=GetSequence(nID);
  187. s->SetColour(GetSequence(ID)->GetColour());
  188. s->SetName(GetSequence(ID)->GetName());
  189. s->SetLength(GetSequence(ID)->GetLength());
  190. s->SetYPos(GetSequence(ID)->GetYPos());
  191. s->SetPatternID(GetSequence(ID)->GetPatternID());
  192. s->SetStartTime(GetSequence(ID)->GetStartTime());
  193. s->SetChannel(GetSequence(ID)->GetChannel());
  194. }
  195. // duplicate the sequence, and copy the pattern to it's own version
  196. void Track::CopySequence(int ID, int nID)
  197. {
  198. AddSequence(nID);
  199. Sequence *s=GetSequence(nID);
  200. s->SetColour(GetSequence(ID)->GetColour());
  201. s->SetName(GetSequence(ID)->GetName());
  202. s->SetLength(GetSequence(ID)->GetLength());
  203. s->SetYPos(GetSequence(ID)->GetYPos());
  204. s->SetStartTime(GetSequence(ID)->GetStartTime());
  205. s->SetChannel(GetSequence(ID)->GetChannel());
  206. AddPattern(m_NextPatternID);
  207. GetPattern(m_NextPatternID)->Copy(GetPattern(GetSequence(ID)->GetPatternID()));
  208. GetSequence(nID)->SetPatternID(m_NextPatternID);
  209. m_NextPatternID++;
  210. }
  211. // copy the sequences pattern, so it's got it's own version
  212. void Track::InstanceSequence(int ID)
  213. {
  214. AddPattern(m_NextPatternID);
  215. GetPattern(m_NextPatternID)->Copy(GetPattern(GetSequence(ID)->GetPatternID()));
  216. GetSequence(ID)->SetPatternID(m_NextPatternID);
  217. m_NextPatternID++;
  218. }
  219. void Track::RemoveSequence(int ID)
  220. {
  221. map<int,Sequence>::iterator i = m_SequenceMap.find(ID);
  222. if (i == m_SequenceMap.end())
  223. {
  224. cerr<<"couldn't find sequence "<<ID<<" not removed"<<endl;
  225. return;
  226. }
  227. // todo - refcount the patterns
  228. m_SequenceMap.erase(i);
  229. }
  230. Sequence *Track::GetSequence(int ID)
  231. {
  232. map<int, Sequence>::iterator i = m_SequenceMap.find(ID);
  233. if (i == m_SequenceMap.end())
  234. {
  235. cerr<<"couldn't find sequence "<<ID<<endl;
  236. return NULL;
  237. }
  238. return &i->second;
  239. }
  240. void Track::AddNote(int ID, int Sequence, float t, float l, int n, float v)
  241. {
  242. GetPattern(GetSequence(Sequence)->GetPatternID())->AddNote(ID,t,l,n,v);
  243. }
  244. void Track::RemoveNote(int ID, int Sequence)
  245. {
  246. GetPattern(GetSequence(Sequence)->GetPatternID())->RemoveNote(ID);
  247. }
  248. void Track::ChangeNote(int ID, int Sequence, float t, float l, int n, float v)
  249. {
  250. Note *note = GetPattern(GetSequence(Sequence)->GetPatternID())->GetNote(ID);
  251. note->Time = t;
  252. note->Length = l;
  253. note->MidiNote = n;
  254. note->Vol = v;
  255. }
  256. void Track::ReadTrack(float t, int channel, vector<Note> &NoteVec)
  257. {
  258. // for every sequence
  259. for (map<int, Sequence>::iterator i = m_SequenceMap.begin();
  260. i!=m_SequenceMap.end(); i++)
  261. {
  262. if (i->second.GetChannel()==channel)
  263. {
  264. Pattern *p=GetPattern(i->second.GetPatternID());
  265. float SeqTime=i->second.GetStartTime();
  266. // for every note in the pattern
  267. for (map<int, Note>::iterator n = p->m_NoteMap.begin();
  268. n!=p->m_NoteMap.end(); n++)
  269. {
  270. if (n->second.Time+SeqTime<t && n->second.Time+n->second.Length+SeqTime>t)
  271. {
  272. NoteVec.push_back(n->second);
  273. }
  274. }
  275. }
  276. }
  277. }
  278. //// private //////
  279. void Track::AddPattern(int ID)
  280. {
  281. map<int,Pattern>::iterator i = m_PatternMap.find(ID);
  282. if (i != m_PatternMap.end())
  283. {
  284. cerr<<"duplicate pattern "<<ID<<" not added"<<endl;
  285. return;
  286. }
  287. Pattern newpattern;
  288. m_PatternMap[ID]=newpattern;
  289. }
  290. void Track::RemovePattern(int ID)
  291. {
  292. map<int,Pattern>::iterator i = m_PatternMap.find(ID);
  293. if (i == m_PatternMap.end())
  294. {
  295. cerr<<"couldn't find pattern "<<ID<<" not removed"<<endl;
  296. return;
  297. }
  298. m_PatternMap.erase(i);
  299. }
  300. Pattern *Track::GetPattern(int ID)
  301. {
  302. map<int,Pattern>::iterator i = m_PatternMap.find(ID);
  303. if (i == m_PatternMap.end())
  304. {
  305. cerr<<"couldn't find pattern "<<ID<<endl;
  306. return NULL;
  307. }
  308. return &i->second;
  309. }
  310. istream &operator>>(istream &s, Track &o)
  311. {
  312. int version=1,Num,id=0;
  313. string dummy;
  314. s>>version>>dummy;
  315. s>>Num;
  316. for (int n=0; n<Num; n++)
  317. {
  318. Pattern t;
  319. s>>t;
  320. o.m_PatternMap[id++]=t;
  321. }
  322. s>>Num;
  323. id=0;
  324. for (int n=0; n<Num; n++)
  325. {
  326. Sequence t;
  327. s>>t;
  328. o.m_SequenceMap[id++]=t;
  329. cerr<<"Loaded sequence "<<t.GetName()<<endl;
  330. }
  331. s>>o.m_NextPatternID;
  332. o.m_NextPatternID=o.m_PatternMap.size();
  333. return s;
  334. }
  335. ostream &operator<<(ostream &s, Track &o)
  336. {
  337. int version=1;
  338. s<<version<<" "<<"track"<<" ";
  339. s<<o.m_PatternMap.size()<<endl;
  340. for (map<int,Pattern>::iterator i = o.m_PatternMap.begin();
  341. i!=o.m_PatternMap.end(); i++)
  342. {
  343. s<<i->second;
  344. }
  345. s<<o.m_SequenceMap.size()<<endl;
  346. for (map<int,Sequence>::iterator i = o.m_SequenceMap.begin();
  347. i!=o.m_SequenceMap.end(); i++)
  348. {
  349. s<<i->second;
  350. }
  351. s<<o.m_NextPatternID<<" "<<endl;
  352. return s;
  353. }
  354. ////////////////////////////////////////////////////////////////////////////////////
  355. ////////////////////////////////////////////////////////////////////////////////////
  356. extern "C" {
  357. SpiralPlugin* SpiralPlugin_CreateInstance()
  358. {
  359. return new SequencerPlugin;
  360. }
  361. char** SpiralPlugin_GetIcon()
  362. {
  363. return SpiralIcon_xpm;
  364. }
  365. int SpiralPlugin_GetID()
  366. {
  367. return 0x0011;
  368. }
  369. string SpiralPlugin_GetGroupName()
  370. {
  371. return "Sequencing";
  372. }
  373. }
  374. ///////////////////////////////////////////////////////
  375. SequencerPlugin::SequencerPlugin() :
  376. m_TransferPattern(-1),
  377. m_Time(0.0f),
  378. m_Length(4),
  379. m_BarLength(1.0f),
  380. m_BeatsPerBar(4),
  381. m_NextBeatTime(0.0f),
  382. m_BeatLevel(-1.0f),
  383. m_BeatCount(0),
  384. m_BarCount(0),
  385. m_SpeedMod(1.0f),
  386. m_InNoteDown(false),
  387. m_InNoteID(0),
  388. m_CurrentPattern(0),
  389. m_Triggered(false)
  390. {
  391. m_Version=1;
  392. m_PluginInfo.Name="Sequencer";
  393. m_PluginInfo.Width=540;
  394. m_PluginInfo.Height=290;
  395. m_PluginInfo.NumInputs=4;
  396. m_PluginInfo.NumOutputs=17;
  397. m_PluginInfo.PortTips.push_back("Play Trigger");
  398. m_PluginInfo.PortTips.push_back("Speed CV");
  399. m_PluginInfo.PortTips.push_back("Input Pitch CV");
  400. m_PluginInfo.PortTips.push_back("Input Trigger CV");
  401. m_PluginInfo.PortTips.push_back("Channel 0 Pitch");
  402. m_PluginInfo.PortTips.push_back("Channel 0 Trigger");
  403. m_PluginInfo.PortTips.push_back("Channel 1 Pitch");
  404. m_PluginInfo.PortTips.push_back("Channel 1 Trigger");
  405. m_PluginInfo.PortTips.push_back("Channel 2 Pitch");
  406. m_PluginInfo.PortTips.push_back("Channel 2 Trigger");
  407. m_PluginInfo.PortTips.push_back("Channel 3 Pitch");
  408. m_PluginInfo.PortTips.push_back("Channel 3 Trigger");
  409. m_PluginInfo.PortTips.push_back("Channel 4 Pitch");
  410. m_PluginInfo.PortTips.push_back("Channel 4 Trigger");
  411. m_PluginInfo.PortTips.push_back("Channel 5 Pitch");
  412. m_PluginInfo.PortTips.push_back("Channel 5 Trigger");
  413. m_PluginInfo.PortTips.push_back("Channel 6 Pitch");
  414. m_PluginInfo.PortTips.push_back("Channel 6 Trigger");
  415. m_PluginInfo.PortTips.push_back("Channel 7 Pitch");
  416. m_PluginInfo.PortTips.push_back("Channel 7 Trigger");
  417. /*m_PluginInfo.PortTips.push_back("Channel 8 Pitch");
  418. m_PluginInfo.PortTips.push_back("Channel 8 Trigger");
  419. m_PluginInfo.PortTips.push_back("Channel 9 Pitch");
  420. m_PluginInfo.PortTips.push_back("Channel 9 Trigger");
  421. m_PluginInfo.PortTips.push_back("Channel 10 Pitch");
  422. m_PluginInfo.PortTips.push_back("Channel 10 Trigger");
  423. m_PluginInfo.PortTips.push_back("Channel 11 Pitch");
  424. m_PluginInfo.PortTips.push_back("Channel 11 Trigger");
  425. m_PluginInfo.PortTips.push_back("Channel 12 Pitch");
  426. m_PluginInfo.PortTips.push_back("Channel 12 Trigger");
  427. m_PluginInfo.PortTips.push_back("Channel 13 Pitch");
  428. m_PluginInfo.PortTips.push_back("Channel 13 Trigger");
  429. m_PluginInfo.PortTips.push_back("Channel 14 Pitch");
  430. m_PluginInfo.PortTips.push_back("Channel 14 Trigger");
  431. m_PluginInfo.PortTips.push_back("Channel 15 Pitch");
  432. m_PluginInfo.PortTips.push_back("Channel 15 Trigger");*/
  433. m_PluginInfo.PortTips.push_back("Beat");
  434. m_AudioCH->Register("ID",&m_GUIArgs.Num);
  435. m_AudioCH->Register("ID2",&m_GUIArgs.Num2);
  436. m_AudioCH->Register("Channel",&m_GUIArgs.Channel);
  437. m_AudioCH->Register("Sequence",&m_GUIArgs.Sequence);
  438. m_AudioCH->Register("Time",&m_GUIArgs.t);
  439. m_AudioCH->Register("Length",&m_GUIArgs.l);
  440. m_AudioCH->Register("Vol",&m_GUIArgs.v);
  441. m_AudioCH->Register("Note",&m_GUIArgs.n);
  442. m_AudioCH->Register("CurrentTime",&m_Time,ChannelHandler::OUTPUT);
  443. m_AudioCH->Register("TotalLength",&m_Length);
  444. m_AudioCH->Register("BeatsPerBar",&m_BeatsPerBar);
  445. m_AudioCH->Register("BarLength",&m_BarLength);
  446. m_AudioCH->RegisterData("Name",ChannelHandler::INPUT,m_GUIArgs.Name,sizeof(m_GUIArgs.Name));
  447. // use OUTPUT_REQUEST for these, as we don't have to copy them constantly (and the gui can request them)
  448. m_AudioCH->Register("TransCount",&m_TransferCount,ChannelHandler::OUTPUT_REQUEST);
  449. m_AudioCH->RegisterData("TransNote",ChannelHandler::OUTPUT_REQUEST,&m_Transfer,sizeof(m_Transfer));
  450. }
  451. SequencerPlugin::~SequencerPlugin()
  452. {
  453. }
  454. PluginInfo &SequencerPlugin::Initialise(const HostInfo *Host)
  455. {
  456. return SpiralPlugin::Initialise(Host);
  457. }
  458. SpiralGUIType *SequencerPlugin::CreateGUI()
  459. {
  460. return new SequencerPluginGUI(m_PluginInfo.Width,
  461. m_PluginInfo.Height,
  462. this,m_AudioCH,m_HostInfo);
  463. }
  464. void SequencerPlugin::SetPattern(int s)
  465. {
  466. //m_Eventmap[m_CurrentPattern]->hide();
  467. m_CurrentPattern=s;
  468. //m_Eventmap[m_CurrentPattern]->show();
  469. }
  470. void SequencerPlugin::Execute()
  471. {
  472. float Speed;
  473. for (int n=0; n<m_HostInfo->BUFSIZE; n++)
  474. {
  475. if (GetInputPitch(0,n)>0)
  476. {
  477. if (!m_Triggered)
  478. {
  479. float Freq=GetInputPitch(0,n);
  480. // Notes 0 to 16 trigger patterns 0 to 16
  481. // No other notes catered for
  482. for (int i=0; i<NUM_PATTERNS; i++)
  483. {
  484. if (feq(Freq,NoteTable[i],0.01f))
  485. {
  486. SetPattern(i);
  487. break;
  488. }
  489. }
  490. m_Time=0;
  491. m_Triggered=true;
  492. }
  493. }
  494. else
  495. {
  496. m_Triggered=false;
  497. }
  498. if (InputExists(1))
  499. Speed =(1.1025f/m_HostInfo->SAMPLERATE) * (GetInput(1,n)+1.0f);
  500. else
  501. Speed =1.1025f/m_HostInfo->SAMPLERATE;
  502. if (!m_InNoteDown)
  503. {
  504. // Check trigger
  505. if (GetInput(3,n)>TRIGGER_LEV)
  506. {
  507. m_InNoteDown=true;
  508. float Freq=GetInputPitch(2,n);
  509. int NoteNum=0;
  510. for (int i=0; i<131; i++)
  511. {
  512. if (feq(Freq,NoteTable[i],0.01f))
  513. {
  514. NoteNum=i;
  515. break;
  516. }
  517. }
  518. /*cerr<<"note recieved ="<<NoteNum<<" f="<<Freq
  519. <<" t-1="<<NoteTable[NoteNum-1]
  520. <<" t="<<NoteTable[NoteNum]
  521. <<" t+1="<<NoteTable[NoteNum+1]<<endl;
  522. */
  523. //m_InNoteID=m_Eventmap[m_CurrentPattern]->AddEventTime(m_Time, NoteNum, 0.5, Fl_SEvent::MELODY, false);
  524. m_InNoteTime=m_Time;
  525. }
  526. }
  527. else
  528. {
  529. // Check trigger
  530. if (GetInput(3,n)<TRIGGER_LEV)
  531. {
  532. //m_Eventmap[m_CurrentPattern]->SetEventLength(m_InNoteID, m_Time-m_InNoteTime);
  533. m_InNoteDown=false;
  534. }
  535. }
  536. for (int channel=0; channel<NUM_CHANNELS; channel++)
  537. {
  538. // Get the notes from the map
  539. vector<Note> NoteVec;
  540. m_Track.ReadTrack(m_Time,channel,NoteVec);
  541. m_CurrentTriggerCV[channel]=0;
  542. //m_CurrentNoteCV=0;
  543. // play all the notes found
  544. for (vector<Note>::iterator i=NoteVec.begin();
  545. i!=NoteVec.end(); i++)
  546. {
  547. //cerr<<"time = "<<m_Time<<endl;
  548. //cerr<<"found note "<<i->Time<<" "<<i->Length<<endl;
  549. m_CurrentNoteCV[channel]=NoteTable[i->MidiNote];
  550. m_CurrentTriggerCV[channel]=1;
  551. }
  552. SetOutputPitch(channel*2,n,m_CurrentNoteCV[channel]);
  553. SetOutput(channel*2+1,n,m_CurrentTriggerCV[channel]);
  554. }
  555. m_Time+=Speed*m_SpeedMod;
  556. // deal with the beat calculation
  557. if (m_Time>m_NextBeatTime)
  558. {
  559. float BeatTime=m_BarLength/m_BeatsPerBar;
  560. m_NextBeatTime=m_Time+BeatTime;
  561. if (m_BeatLevel!=1.0f) m_BeatLevel=1.0f;
  562. else m_BeatLevel=-1.0f;
  563. m_BeatCount++;
  564. }
  565. SetOutput(NUM_CHANNELS*2,n,m_BeatLevel);
  566. if (m_BeatCount>=m_BeatsPerBar)
  567. {
  568. m_BeatCount=0;
  569. m_BarCount++;
  570. }
  571. if (m_BarCount>=m_Length)
  572. {
  573. m_Time=0;
  574. m_BeatCount=-1;
  575. m_BarCount=0;
  576. m_NextBeatTime=0;
  577. }
  578. if (m_Time<0)
  579. {
  580. m_Time=m_Length;
  581. }
  582. }
  583. }
  584. void SequencerPlugin::ExecuteCommands()
  585. {
  586. if (m_AudioCH->IsCommandWaiting())
  587. {
  588. switch (m_AudioCH->GetCommand())
  589. {
  590. case NEW_NOTE : m_Track.AddNote(m_GUIArgs.Num,m_GUIArgs.Sequence,m_GUIArgs.t,m_GUIArgs.l,m_GUIArgs.n,m_GUIArgs.v); break;
  591. case CHG_NOTE : m_Track.ChangeNote(m_GUIArgs.Num,m_GUIArgs.Sequence,m_GUIArgs.t,m_GUIArgs.l,m_GUIArgs.n,m_GUIArgs.v); break;
  592. case REM_NOTE : m_Track.RemoveNote(m_GUIArgs.Num,m_GUIArgs.Sequence); break;
  593. case NEW_SEQ :
  594. {
  595. m_Track.AddSequence(m_GUIArgs.Num);
  596. m_Track.GetSequence(m_GUIArgs.Num)->SetColour(m_GUIArgs.Num2);
  597. m_Track.GetSequence(m_GUIArgs.Num)->SetName(m_GUIArgs.Name);
  598. m_Track.GetSequence(m_GUIArgs.Num)->SetLength(m_GUIArgs.l);
  599. m_Track.GetSequence(m_GUIArgs.Num)->SetYPos(m_GUIArgs.n);
  600. m_Track.GetSequence(m_GUIArgs.Num)->SetChannel(m_GUIArgs.Channel);
  601. } break;
  602. case COPY_SEQ : m_Track.CopySequence(m_GUIArgs.Num,m_GUIArgs.Num2); break;
  603. case INST_SEQ : m_Track.InstanceSequence(m_GUIArgs.Num); break;
  604. case CLONE_SEQ : m_Track.CloneSequence(m_GUIArgs.Num,m_GUIArgs.Num2); break;
  605. case REM_SEQ : m_Track.RemoveSequence(m_GUIArgs.Num); break;
  606. case CHG_SEQ :
  607. {
  608. m_Track.GetSequence(m_GUIArgs.Num)->SetColour(m_GUIArgs.Num2);
  609. m_Track.GetSequence(m_GUIArgs.Num)->SetName(m_GUIArgs.Name);
  610. m_Track.GetSequence(m_GUIArgs.Num)->SetLength(m_GUIArgs.l);
  611. m_Track.GetSequence(m_GUIArgs.Num)->SetYPos(m_GUIArgs.n);
  612. m_Track.GetSequence(m_GUIArgs.Num)->SetChannel(m_GUIArgs.Channel);
  613. m_Track.GetSequence(m_GUIArgs.Num)->SetStartTime(m_GUIArgs.t);
  614. } break;
  615. case GET_PATTERN :
  616. {
  617. // start of transfer
  618. if (m_TransferPattern==-1)
  619. {
  620. m_TransferPattern=m_Track.GetSequence(m_GUIArgs.Num)->GetPatternID();
  621. m_TransferNote=m_Track.GetPattern(m_TransferPattern)->m_NoteMap.begin();
  622. m_TransferCount=m_Track.GetPattern(m_TransferPattern)->GetNoteCount();
  623. cerr<<"going to transfer "<<m_TransferCount<<" notes"<<endl;
  624. }
  625. else
  626. {
  627. // last note gone
  628. if (m_TransferNote==m_Track.GetPattern(m_TransferPattern)->m_NoteMap.end())
  629. {
  630. m_TransferPattern=-1;
  631. }
  632. else
  633. {
  634. // copy this note over
  635. m_Transfer.Time = m_TransferNote->second.Time;
  636. m_Transfer.Length = m_TransferNote->second.Length;
  637. m_Transfer.MidiNote = m_TransferNote->second.MidiNote;
  638. m_Transfer.Vol = m_TransferNote->second.Vol;
  639. m_TransferNote++;
  640. }
  641. }
  642. } break;
  643. default: break;
  644. }
  645. }
  646. }
  647. void SequencerPlugin::StreamOut(ostream &s)
  648. {
  649. s<<m_Version<<" ";
  650. switch (m_Version)
  651. {
  652. case 1:
  653. {
  654. s<<m_Time<<" "<<m_Length<<" "<<m_BarLength<<" "<<m_BeatsPerBar<<" ";
  655. s<<m_Track;
  656. } break;
  657. }
  658. }
  659. void SequencerPlugin::StreamIn(istream &s)
  660. {
  661. int version;
  662. s>>version;
  663. switch (version)
  664. {
  665. case 1:
  666. {
  667. s>>m_Time>>m_Length>>m_BarLength>>m_BeatsPerBar;
  668. s>>m_Track;
  669. } break;
  670. }
  671. }