Browse Source

works now (kinda)

master
nebogeo 22 years ago
parent
commit
e64314de90
5 changed files with 1113 additions and 111 deletions
  1. +1
    -1
      SpiralSound/Plugins/SequencerPlugin/Makefile.in
  2. +561
    -59
      SpiralSound/Plugins/SequencerPlugin/SequencerPlugin.C
  3. +147
    -26
      SpiralSound/Plugins/SequencerPlugin/SequencerPlugin.h
  4. +363
    -22
      SpiralSound/Plugins/SequencerPlugin/SequencerPluginGUI.C
  5. +41
    -3
      SpiralSound/Plugins/SequencerPlugin/SequencerPluginGUI.h

+ 1
- 1
SpiralSound/Plugins/SequencerPlugin/Makefile.in View File

@@ -184,7 +184,7 @@ SequencerPlugin.o: SequencerPlugin.C \

SequencerPluginGUI.o: SequencerPluginGUI.C \
SequencerPluginGUI.h \
SequencerPluginss.h \
SequencerPlugin.h \
../SpiralPlugin.h \
../../Sample.h \
../../SpiralInfo.h \


+ 561
- 59
SpiralSound/Plugins/SequencerPlugin/SequencerPlugin.C View File

@@ -25,6 +25,398 @@
// for note on's
static const float TRIGGER_LEV=0.1;

//////////////////////////////////////////////////////////////////////////
// base sequencing stuff

Note::Note(float t=0, float l=0.1f, int n=0, float v=1.0f)
{
Time = t;
Length = l;
MidiNote = n;
Vol = v;
}

Note::~Note()
{
}
istream &operator>>(istream &s, Note &o)
{
int version=1;
string dummy;
s>>version>>dummy>>o.Time>>o.Length>>o.MidiNote>>o.Vol;
return s;
}

ostream &operator<<(ostream &s, Note &o)
{
int version=1;
s<<version<<" note "<<o.Time<<" "<<o.Length<<" "<<o.MidiNote<<" "<<o.Vol<<" ";
return s;
}

/////////////////////////////////////////////////////////////////////////

Pattern::Pattern()
{
}

Pattern::~Pattern()
{
}

void Pattern::Copy(const Pattern *o)
{
// can't do this as we don't want to preserve the id numbers
//m_NoteMap=o->m_NoteMap;
int c=0;
for (map<int,Note>::const_iterator i = o->m_NoteMap.begin();
i!=o->m_NoteMap.end(); i++)
{
m_NoteMap[c++]=i->second;
}
}

void Pattern::AddNote(int ID, float t, float l, int n, float v)
{
map<int,Note>::iterator i = m_NoteMap.find(ID);
if (i != m_NoteMap.end())
{
cerr<<"duplicate note "<<ID<<" not added"<<endl;
return;
}
Note newnote(t,l,n,v);
m_NoteMap[ID]=newnote;
}

void Pattern::RemoveNote(int ID)
{
map<int,Note>::iterator i = m_NoteMap.find(ID);
if (i == m_NoteMap.end())
{
cerr<<"couldn't find note "<<ID<<" not removed"<<endl;
return;
}
m_NoteMap.erase(i);
}

Note *Pattern::GetNote(int ID)
{
map<int,Note>::iterator i = m_NoteMap.find(ID);
if (i == m_NoteMap.end())
{
cerr<<"couldn't find note "<<ID<<endl;
return NULL;
}
return &i->second;
}

istream &operator>>(istream &s, Pattern &o)
{
int version=1,Num;
string dummy;
int id=0;
s>>version>>dummy>>Num;
for (int n=0; n<Num; n++)
{
Note t;
s>>t;
o.m_NoteMap[id++]=t;
}
return s;
}

ostream &operator<<(ostream &s, Pattern &o)
{
int version=1;
s<<version<<" pattern "<<o.m_NoteMap.size()<<" ";
for (map<int,Note>::iterator i = o.m_NoteMap.begin();
i!=o.m_NoteMap.end(); i++)
{
s<<i->second;
}
s<<endl;
return s;
}

//////////////////////////////////////////////////////////////////////////

Sequence::Sequence(float st=0, int pat=0)
{
m_StartTime=st;
m_Pattern=pat;
}

Sequence::~Sequence()
{
}

istream &operator>>(istream &s, Sequence &o)
{
int version=1;
string dummy;
s>>version>>dummy>>o.m_StartTime>>o.m_Pattern>>o.m_Colour>>o.m_YPos>>o.m_Length>>o.m_Channel;
char Buf[4096];
int size;
s>>size;
s.ignore(1);
s.get(Buf,size+1);
o.m_Name=Buf;
return s;
}

ostream &operator<<(ostream &s, Sequence &o)
{
int version=1;
s<<version<<" sequence"<<" "<<o.m_StartTime<<" "<<o.m_Pattern<<" "<<o.m_Colour<<" "<<o.m_YPos<<" "<<o.m_Length<<" "<<o.m_Channel<<" ";
s<<o.m_Name.size()<<" "<<o.m_Name<<endl;
return s;
}

//////////////////////////////////////////////////////////////////////////

Track::Track()
{
m_NextPatternID=0;
}

Track::~Track()
{
}

void Track::AddSequence(int ID)
{
map<int,Sequence>::iterator i = m_SequenceMap.find(ID);
if (i != m_SequenceMap.end())
{
cerr<<"duplicate sequence "<<ID<<" not added"<<endl;
return;
}
Sequence newsequence;
AddPattern(m_NextPatternID);
newsequence.SetPatternID(m_NextPatternID);
newsequence.SetColour(0);
newsequence.SetName("noname");
newsequence.SetLength(10.0f);
newsequence.SetYPos(1);
newsequence.SetChannel(0);
m_NextPatternID++;
m_SequenceMap[ID]=newsequence;
}

// duplicate the sequence, but reference the same pattern
void Track::CloneSequence(int ID, int nID)
{
AddSequence(nID);
Sequence *s=GetSequence(nID);
s->SetColour(GetSequence(ID)->GetColour());
s->SetName(GetSequence(ID)->GetName());
s->SetLength(GetSequence(ID)->GetLength());
s->SetYPos(GetSequence(ID)->GetYPos());
s->SetPatternID(GetSequence(ID)->GetPatternID());
s->SetStartTime(GetSequence(ID)->GetStartTime());
s->SetChannel(GetSequence(ID)->GetChannel());
}

// duplicate the sequence, and copy the pattern to it's own version
void Track::CopySequence(int ID, int nID)
{
AddSequence(nID);
Sequence *s=GetSequence(nID);
s->SetColour(GetSequence(ID)->GetColour());
s->SetName(GetSequence(ID)->GetName());
s->SetLength(GetSequence(ID)->GetLength());
s->SetYPos(GetSequence(ID)->GetYPos());
s->SetStartTime(GetSequence(ID)->GetStartTime());
s->SetChannel(GetSequence(ID)->GetChannel());
AddPattern(m_NextPatternID);
GetPattern(m_NextPatternID)->Copy(GetPattern(GetSequence(ID)->GetPatternID()));
GetSequence(nID)->SetPatternID(m_NextPatternID);
m_NextPatternID++;
}

// copy the sequences pattern, so it's got it's own version
void Track::InstanceSequence(int ID)
{
AddPattern(m_NextPatternID);
GetPattern(m_NextPatternID)->Copy(GetPattern(GetSequence(ID)->GetPatternID()));
GetSequence(ID)->SetPatternID(m_NextPatternID);
m_NextPatternID++;
}

void Track::RemoveSequence(int ID)
{
map<int,Sequence>::iterator i = m_SequenceMap.find(ID);
if (i == m_SequenceMap.end())
{
cerr<<"couldn't find sequence "<<ID<<" not removed"<<endl;
return;
}
// todo - refcount the patterns
m_SequenceMap.erase(i);
}

Sequence *Track::GetSequence(int ID)
{
map<int, Sequence>::iterator i = m_SequenceMap.find(ID);
if (i == m_SequenceMap.end())
{
cerr<<"couldn't find sequence "<<ID<<endl;
return NULL;
}
return &i->second;
}

void Track::AddNote(int ID, int Sequence, float t, float l, int n, float v)
{
GetPattern(GetSequence(Sequence)->GetPatternID())->AddNote(ID,t,l,n,v);
}

void Track::RemoveNote(int ID, int Sequence)
{
GetPattern(GetSequence(Sequence)->GetPatternID())->RemoveNote(ID);
}

void Track::ChangeNote(int ID, int Sequence, float t, float l, int n, float v)
{
Note *note = GetPattern(GetSequence(Sequence)->GetPatternID())->GetNote(ID);
note->Time = t;
note->Length = l;
note->MidiNote = n;
note->Vol = v;
}
void Track::ReadTrack(float t, int channel, vector<Note> &NoteVec)
{
// for every sequence
for (map<int, Sequence>::iterator i = m_SequenceMap.begin();
i!=m_SequenceMap.end(); i++)
{
if (i->second.GetChannel()==channel)
{
Pattern *p=GetPattern(i->second.GetPatternID());
float SeqTime=i->second.GetStartTime();
// for every note in the pattern
for (map<int, Note>::iterator n = p->m_NoteMap.begin();
n!=p->m_NoteMap.end(); n++)
{
if (n->second.Time+SeqTime<t && n->second.Time+n->second.Length+SeqTime>t)
{
NoteVec.push_back(n->second);
}
}
}
}
}

//// private //////

void Track::AddPattern(int ID)
{
map<int,Pattern>::iterator i = m_PatternMap.find(ID);
if (i != m_PatternMap.end())
{
cerr<<"duplicate pattern "<<ID<<" not added"<<endl;
return;
}
Pattern newpattern;
m_PatternMap[ID]=newpattern;
}

void Track::RemovePattern(int ID)
{
map<int,Pattern>::iterator i = m_PatternMap.find(ID);
if (i == m_PatternMap.end())
{
cerr<<"couldn't find pattern "<<ID<<" not removed"<<endl;
return;
}
m_PatternMap.erase(i);
}

Pattern *Track::GetPattern(int ID)
{
map<int,Pattern>::iterator i = m_PatternMap.find(ID);
if (i == m_PatternMap.end())
{
cerr<<"couldn't find pattern "<<ID<<endl;
return NULL;
}
return &i->second;
}

istream &operator>>(istream &s, Track &o)
{
int version=1,Num,id=0;
string dummy;
s>>version>>dummy;
s>>Num;
for (int n=0; n<Num; n++)
{
Pattern t;
s>>t;
o.m_PatternMap[id++]=t;
}
s>>Num;
id=0;
for (int n=0; n<Num; n++)
{
Sequence t;
s>>t;
o.m_SequenceMap[id++]=t;
cerr<<"Loaded sequence "<<t.GetName()<<endl;
}
s>>o.m_NextPatternID;
o.m_NextPatternID=o.m_PatternMap.size();
return s;
}

ostream &operator<<(ostream &s, Track &o)
{
int version=1;
s<<version<<" "<<"track"<<" ";
s<<o.m_PatternMap.size()<<endl;
for (map<int,Pattern>::iterator i = o.m_PatternMap.begin();
i!=o.m_PatternMap.end(); i++)
{
s<<i->second;
}
s<<o.m_SequenceMap.size()<<endl;
for (map<int,Sequence>::iterator i = o.m_SequenceMap.begin();
i!=o.m_SequenceMap.end(); i++)
{
s<<i->second;
}
s<<o.m_NextPatternID<<" "<<endl;
return s;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

extern "C" {
SpiralPlugin* CreateInstance()
{
@@ -45,29 +437,83 @@ int GetID()
///////////////////////////////////////////////////////

SequencerPlugin::SequencerPlugin() :
m_TransferPattern(-1),
m_Time(0.0f),
m_Length(10.0f),
m_Length(4),
m_BarLength(1.0f),
m_BeatsPerBar(4),
m_NextBeatTime(0.0f),
m_BeatLevel(-1.0f),
m_BeatCount(0),
m_BarCount(0),
m_SpeedMod(1.0f),
m_CurrentNoteCV(0),
m_CurrentTriggerCV(0),
m_InNoteDown(false),
m_InNoteID(0),
m_CurrentPattern(0),
m_Triggered(false)
{
m_Version=2;
m_Version=1;
m_PluginInfo.Name="Sequencer";
m_PluginInfo.Width=540;
m_PluginInfo.Height=290;
m_PluginInfo.NumInputs=4;
m_PluginInfo.NumOutputs=2;
m_PluginInfo.NumOutputs=17;
m_PluginInfo.PortTips.push_back("Play Trigger");
m_PluginInfo.PortTips.push_back("Speed CV");
m_PluginInfo.PortTips.push_back("Input Pitch CV");
m_PluginInfo.PortTips.push_back("Input Trigger CV");
m_PluginInfo.PortTips.push_back("Output Pitch");
m_PluginInfo.PortTips.push_back("Output Trigger");
m_PluginInfo.PortTips.push_back("Channel 0 Pitch");
m_PluginInfo.PortTips.push_back("Channel 0 Trigger");
m_PluginInfo.PortTips.push_back("Channel 1 Pitch");
m_PluginInfo.PortTips.push_back("Channel 1 Trigger");
m_PluginInfo.PortTips.push_back("Channel 2 Pitch");
m_PluginInfo.PortTips.push_back("Channel 2 Trigger");
m_PluginInfo.PortTips.push_back("Channel 3 Pitch");
m_PluginInfo.PortTips.push_back("Channel 3 Trigger");
m_PluginInfo.PortTips.push_back("Channel 4 Pitch");
m_PluginInfo.PortTips.push_back("Channel 4 Trigger");
m_PluginInfo.PortTips.push_back("Channel 5 Pitch");
m_PluginInfo.PortTips.push_back("Channel 5 Trigger");
m_PluginInfo.PortTips.push_back("Channel 6 Pitch");
m_PluginInfo.PortTips.push_back("Channel 6 Trigger");
m_PluginInfo.PortTips.push_back("Channel 7 Pitch");
m_PluginInfo.PortTips.push_back("Channel 7 Trigger");
/*m_PluginInfo.PortTips.push_back("Channel 8 Pitch");
m_PluginInfo.PortTips.push_back("Channel 8 Trigger");
m_PluginInfo.PortTips.push_back("Channel 9 Pitch");
m_PluginInfo.PortTips.push_back("Channel 9 Trigger");
m_PluginInfo.PortTips.push_back("Channel 10 Pitch");
m_PluginInfo.PortTips.push_back("Channel 10 Trigger");
m_PluginInfo.PortTips.push_back("Channel 11 Pitch");
m_PluginInfo.PortTips.push_back("Channel 11 Trigger");
m_PluginInfo.PortTips.push_back("Channel 12 Pitch");
m_PluginInfo.PortTips.push_back("Channel 12 Trigger");
m_PluginInfo.PortTips.push_back("Channel 13 Pitch");
m_PluginInfo.PortTips.push_back("Channel 13 Trigger");
m_PluginInfo.PortTips.push_back("Channel 14 Pitch");
m_PluginInfo.PortTips.push_back("Channel 14 Trigger");
m_PluginInfo.PortTips.push_back("Channel 15 Pitch");
m_PluginInfo.PortTips.push_back("Channel 15 Trigger");*/
m_PluginInfo.PortTips.push_back("Beat");
m_AudioCH->Register("ID",&m_GUIArgs.Num);
m_AudioCH->Register("ID2",&m_GUIArgs.Num2);
m_AudioCH->Register("Channel",&m_GUIArgs.Channel);
m_AudioCH->Register("Sequence",&m_GUIArgs.Sequence);
m_AudioCH->Register("Time",&m_GUIArgs.t);
m_AudioCH->Register("Length",&m_GUIArgs.l);
m_AudioCH->Register("Vol",&m_GUIArgs.v);
m_AudioCH->Register("Note",&m_GUIArgs.n);
m_AudioCH->Register("CurrentTime",&m_Time,ChannelHandler::OUTPUT);
m_AudioCH->Register("TotalLength",&m_Length);
m_AudioCH->Register("BeatsPerBar",&m_BeatsPerBar);
m_AudioCH->Register("BarLength",&m_BarLength);
m_AudioCH->RegisterData("Name",ChannelHandler::INPUT,m_GUIArgs.Name,sizeof(m_GUIArgs.Name));
// use OUTPUT_REQUEST for these, as we don't have to copy them constantly (and the gui can request them)
m_AudioCH->Register("TransCount",&m_TransferCount,ChannelHandler::OUTPUT_REQUEST);
m_AudioCH->RegisterData("TransNote",ChannelHandler::OUTPUT_REQUEST,&m_Transfer,sizeof(m_Transfer));
}

SequencerPlugin::~SequencerPlugin()
@@ -171,35 +617,55 @@ void SequencerPlugin::Execute()
}
}
// Get the notes from the map
/*vector<EventInfo> NoteVec=m_Eventmap[m_CurrentPattern]->GetEvents(m_Time);
// play all the notes found
for (vector<EventInfo>::iterator i=NoteVec.begin();
i!=NoteVec.end(); i++)
for (int channel=0; channel<NUM_CHANNELS; channel++)
{
if (i->m_Type==EventInfo::START)
{
m_CurrentNoteCV=NoteTable[i->m_Group];
m_CurrentTriggerCV=1;
}
if (i->m_Type==EventInfo::END)
{
m_CurrentTriggerCV=0;
if (m_NoteCut) m_CurrentNoteCV=0;
// Get the notes from the map
vector<Note> NoteVec;
m_Track.ReadTrack(m_Time,channel,NoteVec);
m_CurrentTriggerCV[channel]=0;
//m_CurrentNoteCV=0;
// play all the notes found
for (vector<Note>::iterator i=NoteVec.begin();
i!=NoteVec.end(); i++)
{
//cerr<<"time = "<<m_Time<<endl;
//cerr<<"found note "<<i->Time<<" "<<i->Length<<endl;
m_CurrentNoteCV[channel]=NoteTable[i->MidiNote];
m_CurrentTriggerCV[channel]=1;
}
SetOutputPitch(channel*2,n,m_CurrentNoteCV[channel]);
SetOutput(channel*2+1,n,m_CurrentTriggerCV[channel]);
}
*/
SetOutputPitch(0,n,m_CurrentNoteCV);
SetOutput(1,n,m_CurrentTriggerCV);
m_Time+=Speed*m_SpeedMod;
if (m_Time>m_Length)
// deal with the beat calculation
if (m_Time>m_NextBeatTime)
{
float BeatTime=m_BarLength/m_BeatsPerBar;
m_NextBeatTime=m_Time+BeatTime;
if (m_BeatLevel!=1.0f) m_BeatLevel=1.0f;
else m_BeatLevel=-1.0f;
m_BeatCount++;
}
SetOutput(NUM_CHANNELS*2,n,m_BeatLevel);
if (m_BeatCount>=m_BeatsPerBar)
{
m_BeatCount=0;
m_BarCount++;
}
if (m_BarCount>=m_Length)
{
m_Time=0;
m_BeatCount=-1;
m_BarCount=0;
m_NextBeatTime=0;
}
if (m_Time<0)
@@ -211,6 +677,68 @@ void SequencerPlugin::Execute()

void SequencerPlugin::ExecuteCommands()
{
if (m_AudioCH->IsCommandWaiting())
{
switch (m_AudioCH->GetCommand())
{
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;
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;
case REM_NOTE : m_Track.RemoveNote(m_GUIArgs.Num,m_GUIArgs.Sequence); break;
case NEW_SEQ :
{
m_Track.AddSequence(m_GUIArgs.Num);
m_Track.GetSequence(m_GUIArgs.Num)->SetColour(m_GUIArgs.Num2);
m_Track.GetSequence(m_GUIArgs.Num)->SetName(m_GUIArgs.Name);
m_Track.GetSequence(m_GUIArgs.Num)->SetLength(m_GUIArgs.l);
m_Track.GetSequence(m_GUIArgs.Num)->SetYPos(m_GUIArgs.n);
m_Track.GetSequence(m_GUIArgs.Num)->SetChannel(m_GUIArgs.Channel);
} break;
case COPY_SEQ : m_Track.CopySequence(m_GUIArgs.Num,m_GUIArgs.Num2); break;
case INST_SEQ : m_Track.InstanceSequence(m_GUIArgs.Num); break;
case CLONE_SEQ : m_Track.CloneSequence(m_GUIArgs.Num,m_GUIArgs.Num2); break;
case REM_SEQ : m_Track.RemoveSequence(m_GUIArgs.Num); break;
case CHG_SEQ :
{
m_Track.GetSequence(m_GUIArgs.Num)->SetColour(m_GUIArgs.Num2);
m_Track.GetSequence(m_GUIArgs.Num)->SetName(m_GUIArgs.Name);
m_Track.GetSequence(m_GUIArgs.Num)->SetLength(m_GUIArgs.l);
m_Track.GetSequence(m_GUIArgs.Num)->SetYPos(m_GUIArgs.n);
m_Track.GetSequence(m_GUIArgs.Num)->SetChannel(m_GUIArgs.Channel);
m_Track.GetSequence(m_GUIArgs.Num)->SetStartTime(m_GUIArgs.t);
} break;
case GET_PATTERN :
{
// start of transfer
if (m_TransferPattern==-1)
{
m_TransferPattern=m_Track.GetSequence(m_GUIArgs.Num)->GetPatternID();
m_TransferNote=m_Track.GetPattern(m_TransferPattern)->m_NoteMap.begin();
m_TransferCount=m_Track.GetPattern(m_TransferPattern)->GetNoteCount();
cerr<<"going to transfer "<<m_TransferCount<<" notes"<<endl;
}
else
{
// last note gone
if (m_TransferNote==m_Track.GetPattern(m_TransferPattern)->m_NoteMap.end())
{
m_TransferPattern=-1;
}
else
{
// copy this note over
m_Transfer.Time = m_TransferNote->second.Time;
m_Transfer.Length = m_TransferNote->second.Length;
m_Transfer.MidiNote = m_TransferNote->second.MidiNote;
m_Transfer.Vol = m_TransferNote->second.Vol;
m_TransferNote++;
}
}
} break;
default: break;
}
}
}

void SequencerPlugin::StreamOut(ostream &s)
@@ -219,23 +747,10 @@ void SequencerPlugin::StreamOut(ostream &s)
switch (m_Version)
{
case 2:
{
s<<m_Time<<" ";
s<<m_Length<<" ";
s<<m_SpeedMod<<" ";
s<<m_Loop<<" ";
s<<m_NoteCut<<" ";
s<<m_CurrentPattern<<" ";
}
// fallthrough
case 1:
{
for(int n=0; n<NUM_PATTERNS; n++)
{
//s<<*m_Eventmap[n]<<" ";
}
s<<m_Time<<" "<<m_Length<<" "<<m_BarLength<<" "<<m_BeatsPerBar<<" ";
s<<m_Track;
} break;
}
}
@@ -247,23 +762,10 @@ void SequencerPlugin::StreamIn(istream &s)
switch (version)
{
case 2:
{
s>>m_Time;
s>>m_Length;
s>>m_SpeedMod;
s>>m_Loop;
s>>m_NoteCut;
s>>m_CurrentPattern;
}
// fallthrough
case 1:
{
for(int n=0; n<NUM_PATTERNS; n++)
{
//s>>*m_Eventmap[n];
}
s>>m_Time>>m_Length>>m_BarLength>>m_BeatsPerBar;
s>>m_Track;
} break;
}
}

+ 147
- 26
SpiralSound/Plugins/SequencerPlugin/SequencerPlugin.h View File

@@ -24,36 +24,127 @@
#ifndef SequencerPLUGIN
#define SequencerPLUGIN

const int NUM_PATTERNS = 16;
const int NUM_PATTERNS = 8;
const int NUM_CHANNELS = 8;

//////////////////////////////////////////////////////////////////////////
// base sequencing stuff

class Note
{
public:
Note(float t, float l, int n, float v);
virtual ~Note();
float Time;
float Length;
int MidiNote;
float Vol;

friend istream &operator>>(istream &s, Note &o);
friend ostream &operator<<(ostream &s, Note &o);
};

istream &operator>>(istream &s, Note &o);
ostream &operator<<(ostream &s, Note &o);

class Pattern
{
public:
Pattern();
virtual ~Pattern();
void Copy(const Pattern *o);
void AddNote(int ID, float t, float l, int n, float v);
void RemoveNote(int ID);
Note *GetNote(int ID);
int GetNoteCount() { return m_NoteMap.size(); }
map<int,Note> m_NoteMap;
friend istream &operator>>(istream &s, Pattern &o);
friend ostream &operator<<(ostream &s, Pattern &o);
};

istream &operator>>(istream &s, Pattern &o);
ostream &operator<<(ostream &s, Pattern &o);
class Sequence
{
public:
Sequence(float st=0, int pat=0);
virtual ~Sequence();

void SetStartTime(float t) { m_StartTime=t; }
float GetStartTime() { return m_StartTime; }
void SetPatternID(int p) { m_Pattern=p; }
int GetPatternID() { return m_Pattern; }
void SetName(string s) { m_Name=s; }
string GetName() { return m_Name; }
void SetColour(int s) { m_Colour=s; }
int GetColour() { return m_Colour; }
void SetYPos(int s) { m_YPos=s; }
int GetYPos() { return m_YPos; }
void SetLength(float t) { m_Length=t; }
float GetLength() { return m_Length; }
void SetChannel(int s) { m_Channel=s; }
int GetChannel() { return m_Channel; }

private:
float m_StartTime;
int m_Pattern;
string m_Name;
int m_Colour;
int m_YPos;
float m_Length;
int m_Channel;

friend istream &operator>>(istream &s, Sequence &o);
friend ostream &operator<<(ostream &s, Sequence &o);
};
istream &operator>>(istream &s, Sequence &o);
ostream &operator<<(ostream &s, Sequence &o);

class Track
{
public:
class Sequence
{
public:
class Pattern
{
public:
class Note
{
public:
float time;
int note;
float vol;
};
map<int,Note> m_NoteMap;
};
Track();
virtual ~Track();

void AddSequence(int ID);
void CloneSequence(int ID, int nID);
void CopySequence(int ID, int nID);
void InstanceSequence(int ID);
void RemoveSequence(int ID);
Sequence *GetSequence(int ID);
float m_StartTime;
int m_Pattern;
};
void AddNote(int ID, int Sequence, float t, float l, int n, float v);
void RemoveNote(int ID, int Sequence);
void ChangeNote(int ID, int Sequence, float t, float l, int n, float v);
void ReadTrack(float t, int channel, vector<Note> &NoteVec);
Pattern *GetPattern(int ID);
map<int,Sequence> *GetSequenceMap() { return &m_SequenceMap; }
private:
void AddPattern(int ID);
void RemovePattern(int ID);
map<int,Pattern> m_PatternMap;
map<int,Sequence> m_SequenceMap;
int m_NextPatternID;
map<int,Sequence::Pattern> m_PatternMap;
list<Sequence> m_SequenceList;
friend istream &operator>>(istream &s, Track &o);
friend ostream &operator<<(ostream &s, Track &o);
};

istream &operator>>(istream &s, Track &o);
ostream &operator<<(ostream &s, Track &o);

///////////////////////////////////////////////////////////////////////////

class SequencerPlugin : public SpiralPlugin
{
public:
@@ -70,26 +161,56 @@ public:
bool GetNoteCut() { return m_NoteCut; }
void ClearAll() { /*m_Eventmap[m_CurrentPattern]->RemoveAllEvents();*/ }
int GetCurrentPattern() { return m_CurrentPattern; }
Track *GetTrack() { return &m_Track; }
enum GUICommands {NONE,NEW_NOTE,REM_NOTE,CHG_NOTE,NEW_SEQ,CHG_SEQ,COPY_SEQ,
INST_SEQ,CLONE_SEQ,REM_SEQ,GET_PATTERN};
struct GUIArgs
{
int Num,Num2;
int Sequence;
float t,l,v;
int n;
char Name[256];
int Channel;
};
private:

GUIArgs m_GUIArgs;

Track m_Track;

int m_TransferPattern;
//int m_TransferNote;
map<int,Note>::iterator m_TransferNote;
int m_TransferCount;
Note m_Transfer;
void SetEventMap(int n, Fl_EventMap* s) { /*m_Eventmap[n]=s;*/ }
void SetUpdate(bool s) { /*m_Eventmap[m_CurrentPattern]->SetUpdate(s);*/ }
void SetZoom(float s) { /*m_Eventmap[m_CurrentPattern]->SetZoomLevel(s);*/ }
void SetNoteCut(bool s) { m_NoteCut=s; }
void SetEndTime(float s) { /*m_Eventmap[m_CurrentPattern]->SetEndTime(s);*/ m_Length=s; }
//void SetEndTime(float s) { /*m_Eventmap[m_CurrentPattern]->SetEndTime(s);*/ m_Length=s; }
void SetSpeed(float s) { m_SpeedMod=s; }
void SetPattern(int s);
float m_Time;
float m_Length;
int m_Length; // in bars
float m_BarLength;
int m_BeatsPerBar;
float m_NextBeatTime;
float m_BeatLevel;
int m_BeatCount;
int m_BarCount;
bool m_Loop;
bool m_NoteCut;
float m_SpeedMod;
float m_CurrentNoteCV;
float m_CurrentTriggerCV;

float m_CurrentNoteCV[NUM_CHANNELS];
float m_CurrentTriggerCV[NUM_CHANNELS];

bool m_InNoteDown;
int m_InNoteID;
float m_InNoteTime;


+ 363
- 22
SpiralSound/Plugins/SequencerPlugin/SequencerPluginGUI.C View File

@@ -21,6 +21,7 @@
#include <FL/fl_draw.h>
#include <FL/fl_draw.H>
#include <FL/fl_file_chooser.h>
#include <FL/Fl_Color_Chooser.H>

static const int GUI_COLOUR = 179;
static const int GUIBG_COLOUR = 144;
@@ -34,14 +35,23 @@ Fl_Double_Window(w,h,n)
m_Scroll = new Fl_Scroll(0, 0, w, h, "");
resizable(m_Scroll);
add(m_Scroll);
m_NextNoteID=0;
m_Melody = new Fl_EventMap(0, 0, 1000, 1000, "");
m_Melody->SetType(Fl_EventMap::MELODY_MAP);
m_Scroll->add(m_Melody);
m_Scroll->position(0,350);
m_Melody->CreateWindow();
m_Melody->SetUpdateLineClip(0, 18, w, h-38);
m_Melody->show();
// callbacks for note events
Fl_EventMap::EventCallbacks cb;
cb.cb_NewEvent=(Fl_Callback*)cb_NewNote;
cb.cb_MoveEvent=(Fl_Callback*)cb_MoveNote;
cb.cb_DelEvent=(Fl_Callback*)cb_RemoveNote;
m_Melody->SetCallbacks(cb);
end();
}

@@ -52,25 +62,56 @@ SpiralPluginGUI(w,h,o,ch)
{
m_Scroll = new Fl_Scroll(50, 20, w-57, h-26, "");
add(m_Scroll);
m_ArrangementMap = new Fl_EventMap(0, 0, 1000, 1000, "");
m_ArrangementMap = new Fl_EventMap(0, 0, 1000, 132*10, "");
// num midi notes * gridsize y ^
m_ArrangementMap->user_data((void*)this);
m_ArrangementMap->SetType(Fl_EventMap::ARRANGE_MAP);
m_Scroll->add(m_ArrangementMap);
m_Scroll->position(-50,350);
m_ArrangementMap->CreateWindow();
m_ArrangementMap->SetUpdateLineClip(0, 18, w, h-38);
m_ArrangementMap->SetZoomLevel(3.0f);
m_ArrangementMap->show();
m_Length = new Fl_Knob(5, 60, 40, 40, "Length");
m_Length->color(GUI_COLOUR);
m_Length->type(Fl_Knob::DOTLIN);
m_Length->labelsize(10);
m_Length->maximum(30);
m_Length->step(0.01);
m_Length->value(1.0);
// callbacks for sequence events
Fl_EventMap::EventCallbacks cb;
cb.cb_EventDoubleClicked=(Fl_Callback*)cb_ArrangeRM;
cb.cb_MoveEvent=(Fl_Callback*)cb_MoveSequence;
cb.cb_RenameEvent=(Fl_Callback*)cb_Rename;
cb.cb_Recolour=(Fl_Callback*)cb_Recolour;
cb.cb_CopyEvent=(Fl_Callback*)cb_Copy;
cb.cb_DelEvent=(Fl_Callback*)cb_RemoveSequence;
cb.cb_EditEvent=(Fl_Callback*)cb_Edit;
m_ArrangementMap->SetCallbacks(cb);
m_Length = new Fl_Input(12, 15, 24, 12, "LengthBars");
m_Length->color(GUI_COLOUR);
m_Length->labelsize(8);
m_Length->align(FL_ALIGN_BOTTOM|FL_ALIGN_CENTER);
m_Length->textsize(8);
m_Length->value("4");
m_Length->callback((Fl_Callback*)cb_Length);
add(m_Length);
m_BeatsPerBar = new Fl_Input(12, 38, 24, 12, "BeatsPerBar");
m_BeatsPerBar->color(GUI_COLOUR);
m_BeatsPerBar->labelsize(8);
m_BeatsPerBar->align(FL_ALIGN_BOTTOM|FL_ALIGN_CENTER);
m_BeatsPerBar->textsize(8);
m_BeatsPerBar->value("4");
m_BeatsPerBar->callback((Fl_Callback*)cb_BeatsPerBar);
add(m_BeatsPerBar);
m_BarLength = new Fl_Knob(5, 60, 40, 40, "BarLength");
m_BarLength->color(GUI_COLOUR);
m_BarLength->type(Fl_Knob::DOTLIN);
m_BarLength->labelsize(10);
m_BarLength->maximum(10);
m_BarLength->step(0.01);
m_BarLength->value(1.0);
m_BarLength->callback((Fl_Callback*)cb_BarLength);
add(m_BarLength);
m_Speed = new Fl_Knob(5, 115, 40, 40, "Speed");
m_Speed->color(GUI_COLOUR);
m_Speed->type(Fl_Knob::DOTLIN);
@@ -85,9 +126,9 @@ SpiralPluginGUI(w,h,o,ch)
m_Zoom->color(GUI_COLOUR);
m_Zoom->type(Fl_Knob::DOTLIN);
m_Zoom->labelsize(10);
m_Zoom->maximum(2);
m_Zoom->maximum(6);
m_Zoom->step(0.01);
m_Zoom->value(1.0);
m_Zoom->value(3.0);
m_Zoom->callback((Fl_Callback*)cb_Zoom);
add(m_Zoom);
@@ -114,10 +155,94 @@ SpiralPluginGUI(w,h,o,ch)
end();
}

void SequencerPluginGUI::LoadPatternData(int ID)
{
Note note(0,1.0f,0,0);

m_PatternWinMap[ID]->GetEventMap()->RemoveAllEvents();
m_GUICH->Wait();
m_GUICH->Set("ID",ID);
m_GUICH->SetCommand(SequencerPlugin::GET_PATTERN);
m_GUICH->Wait();
m_GUICH->RequestChannelAndWait("TransCount");
int c = m_GUICH->GetInt("TransCount");
cerr<<"TransCount="<<c<<endl;
for (int n=0; n<c; n++)
{
m_GUICH->SetCommand(SequencerPlugin::GET_PATTERN);
m_GUICH->RequestChannelAndWait("TransNote");
m_GUICH->GetData("TransNote",(void*)&note);
cerr<<"Adding note "<<n<<" "<<note.Time<<" "<<note.MidiNote<<" "<<note.Length<<endl;
m_PatternWinMap[ID]->GetEventMap()->AddEventTime(note.Time,note.MidiNote,note.Length,Fl_SEvent::MELODY,false);
}
}

void SequencerPluginGUI::UpdateValues(SpiralPlugin *o)
{
SequencerPlugin *Plugin = (SequencerPlugin *)o;
Track *t = Plugin->GetTrack();
map<int,Sequence> *seqmap=t->GetSequenceMap();
map<int,Note>::iterator pi;
// for each sequence
for (map<int,Sequence>::iterator i=seqmap->begin();
i!=seqmap->end(); i++)
{
int eid = m_ArrangementMap->AddEventTime(i->second.GetStartTime(),i->second.GetYPos(),i->second.GetLength(),Fl_SEvent::NO_TYPE,false);
m_ArrangementMap->GetEvent(eid)->SetName(i->second.GetName());
m_ArrangementMap->GetEvent(eid)->SetColour(i->second.GetColour());
m_ArrangementMap->GetEvent(eid)->SetChannel(i->second.GetChannel());
m_ArrangementMap->GetEvent(eid)->SetLengthTime(i->second.GetLength());
m_PatternWinMap[eid] = new PatternWin(400,200,m_ArrangementMap->GetEvent(eid)->GetName().c_str());
Fl_EventMap *map = m_PatternWinMap[eid]->GetEventMap();
map->user_data((void*)this);
map->SetID(eid);
// load the pattern data
Pattern *p = t->GetPattern(i->second.GetPatternID());
for (pi=p->m_NoteMap.begin();
pi!=p->m_NoteMap.end(); pi++)
{
map->AddEventTime(pi->second.Time,pi->second.MidiNote,pi->second.Length,Fl_SEvent::MELODY,false);
}
}
redraw();
}
void SequencerPluginGUI::Update()
{
float Time=m_GUICH->GetFloat("CurrentTime");
m_ArrangementMap->SetTime(Time);
for (map<int,PatternWin*>::iterator i=m_PatternWinMap.begin();
i!=m_PatternWinMap.end(); i++)
{
i->second->GetEventMap()->SetTime(Time);
}
}

void SequencerPluginGUI::ChangeSequenceHelper(Fl_SEvent *event)
{
m_GUICH->Set("ID",event->GetID());
m_GUICH->Set("ID2",event->GetColour());
char t[256];
sprintf(t,"%s",event->GetName().c_str());
m_GUICH->SetData("Name",(void*)t);
m_GUICH->Set("Length",event->GetLengthTime());
m_GUICH->Set("Note",event->GetGroup());
m_GUICH->Set("Channel",event->GetChannel());
m_GUICH->Set("Time",event->GetStartTime());
m_GUICH->SetCommand(SequencerPlugin::CHG_SEQ);
}

inline void SequencerPluginGUI::cb_NoteCut_i(Fl_Button* o, void* v)
{
//m_Plugin->SetNoteCut(o->value());
@@ -127,7 +252,7 @@ void SequencerPluginGUI::cb_NoteCut(Fl_Button* o, void* v)

inline void SequencerPluginGUI::cb_Zoom_i(Fl_Knob* o, void* v)
{
//m_Plugin->SetZoom(o->value());
if (o->value()!=0) m_ArrangementMap->SetZoomLevel(o->value());
}
void SequencerPluginGUI::cb_Zoom(Fl_Knob* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_Zoom_i(o,v);}
@@ -144,13 +269,60 @@ inline void SequencerPluginGUI::cb_Pattern_i(Fl_Counter* o, void* v)
void SequencerPluginGUI::cb_Pattern(Fl_Counter* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_Pattern_i(o,v);}

inline void SequencerPluginGUI::cb_Length_i(Fl_Knob* o, void* v)
inline void SequencerPluginGUI::cb_Length_i(Fl_Input* o, void* v)
{
//m_Plugin->SetEndTime(o->value());
int val=(int)strtod(o->value(),NULL);
if (val<1) o->value("error!");
else
{
m_GUICH->Set("TotalLength",val);
}
}
void SequencerPluginGUI::cb_Length(Fl_Knob* o, void* v)
void SequencerPluginGUI::cb_Length(Fl_Input* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_Length_i(o,v);}

inline void SequencerPluginGUI::cb_BeatsPerBar_i(Fl_Input* o, void* v)
{
int val=(int)strtod(o->value(),NULL);
if (val<1) o->value("error!");
else
{
m_GUICH->Set("BeatsPerBar",val);
m_ArrangementMap->SetBeatsBar(val);
m_ArrangementMap->redraw();
for (map<int,PatternWin*>::iterator i=m_PatternWinMap.begin();
i!=m_PatternWinMap.end(); i++)
{
i->second->GetEventMap()->SetBeatsBar(val);
i->second->GetEventMap()->redraw();
}
}
}
void SequencerPluginGUI::cb_BeatsPerBar(Fl_Input* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_BeatsPerBar_i(o,v);}

inline void SequencerPluginGUI::cb_BarLength_i(Fl_Knob* o, void* v)
{
if (o->value()!=0)
{
m_GUICH->Set("BarLength",(float)o->value());
m_ArrangementMap->SetBarLength(o->value());
m_ArrangementMap->redraw();
for (map<int,PatternWin*>::iterator i=m_PatternWinMap.begin();
i!=m_PatternWinMap.end(); i++)
{
i->second->GetEventMap()->SetBarLength(o->value());
i->second->GetEventMap()->redraw();
}
redraw();
}
}
void SequencerPluginGUI::cb_BarLength(Fl_Knob* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_BarLength_i(o,v);}

inline void SequencerPluginGUI::cb_Speed_i(Fl_Knob* o, void* v)
{
//m_Plugin->SetSpeed(o->value()-2.0f);
@@ -165,20 +337,110 @@ inline void SequencerPluginGUI::cb_Clear_i(Fl_Button* o, void* v)
void SequencerPluginGUI::cb_Clear(Fl_Button* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_Clear_i(o,v);}

/// sequence callbacks /////////////////////////////////////////////////////////

inline void SequencerPluginGUI::cb_NewPattern_i(Fl_Button* o, void* v)
{
int eid = m_ArrangementMap->AddEvent(300,100,100,Fl_SEvent::NO_TYPE);
int eid = m_ArrangementMap->AddEventTime(1,50,2,Fl_SEvent::NO_TYPE);
m_ArrangementMap->GetEvent(eid)->SetName("My Pattern");
const char *name = fl_input("Name the new pattern:", "My Pattern");
if (name) m_ArrangementMap->GetEvent(eid)->SetName(name);
m_PatternWinMap[eid] = new PatternWin(400,200,m_ArrangementMap->GetEvent(eid)->GetName().c_str());
m_ArrangementMap->SetEventCallback((Fl_Callback*)cb_ArrangeRM);
Fl_EventMap *map = m_PatternWinMap[eid]->GetEventMap();
Fl_SEvent *event = m_ArrangementMap->GetEvent(eid);
// setup the stuff needed by the callbacks
map->user_data((void*)this);
map->SetID(eid);
m_GUICH->Set("ID",eid);
m_GUICH->Set("ID2",event->GetColour());
char t[256];
sprintf(t,"%s",event->GetName().c_str());
m_GUICH->SetData("Name",(void*)t);
m_GUICH->Set("Length",event->GetLengthTime());
m_GUICH->Set("Channel",event->GetChannel());
m_GUICH->Set("Note",event->GetGroup());
m_GUICH->SetCommand(SequencerPlugin::NEW_SEQ);
redraw();
}
void SequencerPluginGUI::cb_NewPattern(Fl_Button* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()))->cb_NewPattern_i(o,v);}

inline void SequencerPluginGUI::cb_Rename_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);

const char *name = fl_input("Rename the sequence:",
m_ArrangementMap->GetEvent(event->GetID())->GetName().c_str());
if (name) m_ArrangementMap->GetEvent(event->GetID())->SetName(name);
ChangeSequenceHelper(event);
redraw();
}

void SequencerPluginGUI::cb_Rename(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_Rename_i(o,v);}

inline void SequencerPluginGUI::cb_Recolour_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);

unsigned char r=255,g=255,b=255;
if (fl_color_chooser("colour",r,g,b))
{
fl_color(r,g,b);
Fl_Color col=fl_color();
m_ArrangementMap->GetEvent(event->GetID())->SetColour(col);
ChangeSequenceHelper(event);
redraw();
}
}
void SequencerPluginGUI::cb_Recolour(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_Recolour_i(o,v);}

inline void SequencerPluginGUI::cb_RemoveSequence_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);
Fl_EventMap *map = ((Fl_EventMap*)event->parent());
event->KillMe();
map->redraw();
m_GUICH->Set("ID",event->GetID());
m_GUICH->SetCommand(SequencerPlugin::REM_SEQ);
}
void SequencerPluginGUI::cb_RemoveSequence(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_RemoveSequence_i(o,v);}

inline void SequencerPluginGUI::cb_Copy_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);
int NewID = m_ArrangementMap->CopyEvent(event->x()+event->w(),event->y(),event->w(),event->GetID(), event->GetLengthTime());
m_PatternWinMap[NewID] = new PatternWin(400,200,m_ArrangementMap->GetEvent(NewID)->GetName().c_str());
m_PatternWinMap[NewID]->GetEventMap()->user_data((void*)this);
m_PatternWinMap[NewID]->GetEventMap()->SetID(NewID);
m_GUICH->Set("ID",event->GetID());
m_GUICH->Set("ID2",NewID);
m_GUICH->SetCommand(SequencerPlugin::COPY_SEQ);
LoadPatternData(NewID);
}
void SequencerPluginGUI::cb_Copy(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_Copy_i(o,v);}

inline void SequencerPluginGUI::cb_MoveSequence_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)o);
m_PatternWinMap[event->GetID()]->GetEventMap()->SetTimeOffset(event->GetStartTime());
ChangeSequenceHelper(event);
}
void SequencerPluginGUI::cb_MoveSequence(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->user_data()))->cb_MoveSequence_i(o,v);}

inline void SequencerPluginGUI::cb_ArrangeRM_i(Fl_Button* o, void* v)
{
int ID=((Fl_SEvent*)o)->GetID();
@@ -188,4 +450,83 @@ inline void SequencerPluginGUI::cb_ArrangeRM_i(Fl_Button* o, void* v)
}
void SequencerPluginGUI::cb_ArrangeRM(Fl_Button* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->user_data()))->cb_ArrangeRM_i(o,v);}
#include <unistd.h>
inline void SequencerPluginGUI::cb_Edit_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);
Fl_Double_Window *EditWin = new Fl_Double_Window(100,100,"Properties");
Fl_Button *exit = new Fl_Button(10,80,80,10,"Exit");
exit->labelsize(8);
Fl_Counter *channel = new Fl_Counter(5,10,90,20,"Channel");
channel->labelsize(8);
channel->textsize(8);
channel->type(FL_SIMPLE_COUNTER);
channel->step(1);
channel->value(event->GetChannel());
EditWin->show();
while (!exit->value() || !EditWin->shown())
{
Fl::check();
usleep(10000);
}
event->SetChannel((int)channel->value());
ChangeSequenceHelper(event);
redraw();
EditWin->hide();
}
void SequencerPluginGUI::cb_Edit(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_Edit_i(o,v);}

/// note callbacks ///////////////////////////////////////////////////////////////

inline void SequencerPluginGUI::cb_NewNote_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)o);
Fl_EventMap *map = ((Fl_EventMap*)o->parent());
m_GUICH->Set("ID",event->GetID());
m_GUICH->Set("Sequence",map->GetID());
m_GUICH->Set("Time",event->GetStartTime());
m_GUICH->Set("Length",event->GetLengthTime());
m_GUICH->Set("Note",event->GetGroup());
m_GUICH->Set("Vol",1.0f);
m_GUICH->SetCommand(SequencerPlugin::NEW_NOTE);
}
void SequencerPluginGUI::cb_NewNote(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->user_data()))->cb_NewNote_i(o,v);}

inline void SequencerPluginGUI::cb_MoveNote_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)o);
Fl_EventMap *map = ((Fl_EventMap*)o->parent());
m_GUICH->Set("ID",event->GetID());
m_GUICH->Set("Sequence",map->GetID());
m_GUICH->Set("Time",event->GetStartTime());
m_GUICH->Set("Length",event->GetLengthTime());
m_GUICH->Set("Note",event->GetGroup());
m_GUICH->Set("Vol",1.0f);

m_GUICH->SetCommand(SequencerPlugin::CHG_NOTE);
}
void SequencerPluginGUI::cb_MoveNote(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->user_data()))->cb_MoveNote_i(o,v);}

inline void SequencerPluginGUI::cb_RemoveNote_i(Fl_Widget* o, void* v)
{
Fl_SEvent *event = ((Fl_SEvent*)v);
Fl_EventMap *map = ((Fl_EventMap*)event->parent());
event->KillMe();
map->redraw();
m_GUICH->Set("ID",event->GetID());
m_GUICH->Set("Sequence",map->GetID());
m_GUICH->SetCommand(SequencerPlugin::REM_NOTE);
}
void SequencerPluginGUI::cb_RemoveNote(Fl_Widget* o, void* v)
{ ((SequencerPluginGUI*)(o->parent()->parent()->user_data()))->cb_RemoveNote_i(o,v);}


+ 41
- 3
SpiralSound/Plugins/SequencerPlugin/SequencerPluginGUI.h View File

@@ -23,6 +23,7 @@
#include <FL/Fl_Slider.H>
#include <FL/Fl_Counter.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Input.H>

#include "SequencerPlugin.h"
#include "../SpiralPluginGUI.h"
@@ -39,6 +40,7 @@ public:
SequencerPluginGUI(int w, int h, SequencerPlugin *o, ChannelHandler *ch,const HostInfo *Info);
virtual void UpdateValues(SpiralPlugin *o);
virtual void Update();

private:
@@ -46,23 +48,34 @@ private:
Fl_Button* m_NewPattern;
Fl_Button* m_NoteCut;
Fl_Knob* m_Zoom;
Fl_Knob* m_Length;
Fl_Knob* m_Speed;
Fl_Button* m_Clear;
Fl_Input* m_Length;
Fl_Input* m_BeatsPerBar;
Fl_Knob* m_BarLength;
int m_NextPatternID;
class PatternWin : public Fl_Double_Window
{
public:
PatternWin(int w,int h,const char* n);
Fl_EventMap *GetEventMap() { return m_Melody; }
private:
Fl_Scroll* m_Scroll;
Fl_EventMap* m_Melody;
int m_NextNoteID;
};
map<int,PatternWin*> m_PatternWinMap;
Fl_EventMap* m_ArrangementMap;
// get the notes from the audio thread
void LoadPatternData(int ID);
void ChangeSequenceHelper(Fl_SEvent *event);

//// Callbacks ////
inline void cb_Zoom_i(Fl_Knob* o, void* v);
static void cb_Zoom(Fl_Knob* o, void* v);
@@ -70,8 +83,12 @@ private:
static void cb_NoteCut(Fl_Button* o, void* v);
inline void cb_Pattern_i(Fl_Counter* o, void* v);
static void cb_Pattern(Fl_Counter* o, void* v);
inline void cb_Length_i(Fl_Knob* o, void* v);
static void cb_Length(Fl_Knob* o, void* v);
inline void cb_Length_i(Fl_Input* o, void* v);
static void cb_Length(Fl_Input* o, void* v);
inline void cb_BeatsPerBar_i(Fl_Input* o, void* v);
static void cb_BeatsPerBar(Fl_Input* o, void* v);
inline void cb_BarLength_i(Fl_Knob* o, void* v);
static void cb_BarLength(Fl_Knob* o, void* v);
inline void cb_Speed_i(Fl_Knob* o, void* v);
static void cb_Speed(Fl_Knob* o, void* v);
inline void cb_Clear_i(Fl_Button* o, void* v);
@@ -79,8 +96,29 @@ private:
inline void cb_NewPattern_i(Fl_Button* o, void* v);
static void cb_NewPattern(Fl_Button* o, void* v);
// sequence event callbacks
inline void cb_ArrangeRM_i(Fl_Button* o, void* v);
static void cb_ArrangeRM(Fl_Button* o, void* v);
inline void cb_MoveSequence_i(Fl_Widget* o, void* v);
static void cb_MoveSequence(Fl_Widget* o, void* v);
inline void cb_Rename_i(Fl_Widget* o, void* v);
static void cb_Rename(Fl_Widget* o, void* v);
inline void cb_Recolour_i(Fl_Widget* o, void* v);
static void cb_Recolour(Fl_Widget* o, void* v);
inline void cb_Copy_i(Fl_Widget* o, void* v);
static void cb_Copy(Fl_Widget* o, void* v);
inline void cb_RemoveSequence_i(Fl_Widget* o, void* v);
static void cb_RemoveSequence(Fl_Widget* o, void* v);
inline void cb_Edit_i(Fl_Widget* o, void* v);
static void cb_Edit(Fl_Widget* o, void* v);
// note event callbacks
inline void cb_NewNote_i(Fl_Widget* o, void* v);
static void cb_NewNote(Fl_Widget* o, void* v);
inline void cb_MoveNote_i(Fl_Widget* o, void* v);
static void cb_MoveNote(Fl_Widget* o, void* v);
inline void cb_RemoveNote_i(Fl_Widget* o, void* v);
static void cb_RemoveNote(Fl_Widget* o, void* v);
};

#endif

Loading…
Cancel
Save