@@ -184,7 +184,7 @@ SequencerPlugin.o: SequencerPlugin.C \ | |||||
SequencerPluginGUI.o: SequencerPluginGUI.C \ | SequencerPluginGUI.o: SequencerPluginGUI.C \ | ||||
SequencerPluginGUI.h \ | SequencerPluginGUI.h \ | ||||
SequencerPluginss.h \ | |||||
SequencerPlugin.h \ | |||||
../SpiralPlugin.h \ | ../SpiralPlugin.h \ | ||||
../../Sample.h \ | ../../Sample.h \ | ||||
../../SpiralInfo.h \ | ../../SpiralInfo.h \ | ||||
@@ -25,6 +25,398 @@ | |||||
// for note on's | // for note on's | ||||
static const float TRIGGER_LEV=0.1; | 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" { | extern "C" { | ||||
SpiralPlugin* CreateInstance() | SpiralPlugin* CreateInstance() | ||||
{ | { | ||||
@@ -45,29 +437,83 @@ int GetID() | |||||
/////////////////////////////////////////////////////// | /////////////////////////////////////////////////////// | ||||
SequencerPlugin::SequencerPlugin() : | SequencerPlugin::SequencerPlugin() : | ||||
m_TransferPattern(-1), | |||||
m_Time(0.0f), | 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_SpeedMod(1.0f), | ||||
m_CurrentNoteCV(0), | |||||
m_CurrentTriggerCV(0), | |||||
m_InNoteDown(false), | m_InNoteDown(false), | ||||
m_InNoteID(0), | m_InNoteID(0), | ||||
m_CurrentPattern(0), | m_CurrentPattern(0), | ||||
m_Triggered(false) | m_Triggered(false) | ||||
{ | { | ||||
m_Version=2; | |||||
m_Version=1; | |||||
m_PluginInfo.Name="Sequencer"; | m_PluginInfo.Name="Sequencer"; | ||||
m_PluginInfo.Width=540; | m_PluginInfo.Width=540; | ||||
m_PluginInfo.Height=290; | m_PluginInfo.Height=290; | ||||
m_PluginInfo.NumInputs=4; | m_PluginInfo.NumInputs=4; | ||||
m_PluginInfo.NumOutputs=2; | |||||
m_PluginInfo.NumOutputs=17; | |||||
m_PluginInfo.PortTips.push_back("Play Trigger"); | m_PluginInfo.PortTips.push_back("Play Trigger"); | ||||
m_PluginInfo.PortTips.push_back("Speed CV"); | m_PluginInfo.PortTips.push_back("Speed CV"); | ||||
m_PluginInfo.PortTips.push_back("Input Pitch CV"); | m_PluginInfo.PortTips.push_back("Input Pitch CV"); | ||||
m_PluginInfo.PortTips.push_back("Input Trigger 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() | 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; | 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_Time=0; | ||||
m_BeatCount=-1; | |||||
m_BarCount=0; | |||||
m_NextBeatTime=0; | |||||
} | } | ||||
if (m_Time<0) | if (m_Time<0) | ||||
@@ -211,6 +677,68 @@ void SequencerPlugin::Execute() | |||||
void SequencerPlugin::ExecuteCommands() | 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) | void SequencerPlugin::StreamOut(ostream &s) | ||||
@@ -219,23 +747,10 @@ void SequencerPlugin::StreamOut(ostream &s) | |||||
switch (m_Version) | 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: | 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; | } break; | ||||
} | } | ||||
} | } | ||||
@@ -247,23 +762,10 @@ void SequencerPlugin::StreamIn(istream &s) | |||||
switch (version) | 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: | 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; | } break; | ||||
} | } | ||||
} | } |
@@ -24,36 +24,127 @@ | |||||
#ifndef SequencerPLUGIN | #ifndef SequencerPLUGIN | ||||
#define 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 | class Track | ||||
{ | { | ||||
public: | 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 | class SequencerPlugin : public SpiralPlugin | ||||
{ | { | ||||
public: | public: | ||||
@@ -70,26 +161,56 @@ public: | |||||
bool GetNoteCut() { return m_NoteCut; } | bool GetNoteCut() { return m_NoteCut; } | ||||
void ClearAll() { /*m_Eventmap[m_CurrentPattern]->RemoveAllEvents();*/ } | void ClearAll() { /*m_Eventmap[m_CurrentPattern]->RemoveAllEvents();*/ } | ||||
int GetCurrentPattern() { return m_CurrentPattern; } | 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: | private: | ||||
GUIArgs m_GUIArgs; | |||||
Track m_Track; | 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 SetEventMap(int n, Fl_EventMap* s) { /*m_Eventmap[n]=s;*/ } | ||||
void SetUpdate(bool s) { /*m_Eventmap[m_CurrentPattern]->SetUpdate(s);*/ } | void SetUpdate(bool s) { /*m_Eventmap[m_CurrentPattern]->SetUpdate(s);*/ } | ||||
void SetZoom(float s) { /*m_Eventmap[m_CurrentPattern]->SetZoomLevel(s);*/ } | void SetZoom(float s) { /*m_Eventmap[m_CurrentPattern]->SetZoomLevel(s);*/ } | ||||
void SetNoteCut(bool s) { m_NoteCut=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 SetSpeed(float s) { m_SpeedMod=s; } | ||||
void SetPattern(int s); | void SetPattern(int s); | ||||
float m_Time; | 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_Loop; | ||||
bool m_NoteCut; | bool m_NoteCut; | ||||
float m_SpeedMod; | float m_SpeedMod; | ||||
float m_CurrentNoteCV; | |||||
float m_CurrentTriggerCV; | |||||
float m_CurrentNoteCV[NUM_CHANNELS]; | |||||
float m_CurrentTriggerCV[NUM_CHANNELS]; | |||||
bool m_InNoteDown; | bool m_InNoteDown; | ||||
int m_InNoteID; | int m_InNoteID; | ||||
float m_InNoteTime; | float m_InNoteTime; | ||||
@@ -21,6 +21,7 @@ | |||||
#include <FL/fl_draw.h> | #include <FL/fl_draw.h> | ||||
#include <FL/fl_draw.H> | #include <FL/fl_draw.H> | ||||
#include <FL/fl_file_chooser.h> | #include <FL/fl_file_chooser.h> | ||||
#include <FL/Fl_Color_Chooser.H> | |||||
static const int GUI_COLOUR = 179; | static const int GUI_COLOUR = 179; | ||||
static const int GUIBG_COLOUR = 144; | 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, ""); | m_Scroll = new Fl_Scroll(0, 0, w, h, ""); | ||||
resizable(m_Scroll); | resizable(m_Scroll); | ||||
add(m_Scroll); | add(m_Scroll); | ||||
m_NextNoteID=0; | |||||
m_Melody = new Fl_EventMap(0, 0, 1000, 1000, ""); | m_Melody = new Fl_EventMap(0, 0, 1000, 1000, ""); | ||||
m_Melody->SetType(Fl_EventMap::MELODY_MAP); | m_Melody->SetType(Fl_EventMap::MELODY_MAP); | ||||
m_Scroll->add(m_Melody); | m_Scroll->add(m_Melody); | ||||
m_Scroll->position(0,350); | |||||
m_Melody->CreateWindow(); | m_Melody->CreateWindow(); | ||||
m_Melody->SetUpdateLineClip(0, 18, w, h-38); | |||||
m_Melody->show(); | 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(); | end(); | ||||
} | } | ||||
@@ -52,25 +62,56 @@ SpiralPluginGUI(w,h,o,ch) | |||||
{ | { | ||||
m_Scroll = new Fl_Scroll(50, 20, w-57, h-26, ""); | m_Scroll = new Fl_Scroll(50, 20, w-57, h-26, ""); | ||||
add(m_Scroll); | 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->user_data((void*)this); | ||||
m_ArrangementMap->SetType(Fl_EventMap::ARRANGE_MAP); | m_ArrangementMap->SetType(Fl_EventMap::ARRANGE_MAP); | ||||
m_Scroll->add(m_ArrangementMap); | m_Scroll->add(m_ArrangementMap); | ||||
m_Scroll->position(-50,350); | |||||
m_ArrangementMap->CreateWindow(); | m_ArrangementMap->CreateWindow(); | ||||
m_ArrangementMap->SetUpdateLineClip(0, 18, w, h-38); | |||||
m_ArrangementMap->SetZoomLevel(3.0f); | |||||
m_ArrangementMap->show(); | 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); | m_Length->callback((Fl_Callback*)cb_Length); | ||||
add(m_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 = new Fl_Knob(5, 115, 40, 40, "Speed"); | ||||
m_Speed->color(GUI_COLOUR); | m_Speed->color(GUI_COLOUR); | ||||
m_Speed->type(Fl_Knob::DOTLIN); | m_Speed->type(Fl_Knob::DOTLIN); | ||||
@@ -85,9 +126,9 @@ SpiralPluginGUI(w,h,o,ch) | |||||
m_Zoom->color(GUI_COLOUR); | m_Zoom->color(GUI_COLOUR); | ||||
m_Zoom->type(Fl_Knob::DOTLIN); | m_Zoom->type(Fl_Knob::DOTLIN); | ||||
m_Zoom->labelsize(10); | m_Zoom->labelsize(10); | ||||
m_Zoom->maximum(2); | |||||
m_Zoom->maximum(6); | |||||
m_Zoom->step(0.01); | m_Zoom->step(0.01); | ||||
m_Zoom->value(1.0); | |||||
m_Zoom->value(3.0); | |||||
m_Zoom->callback((Fl_Callback*)cb_Zoom); | m_Zoom->callback((Fl_Callback*)cb_Zoom); | ||||
add(m_Zoom); | add(m_Zoom); | ||||
@@ -114,10 +155,94 @@ SpiralPluginGUI(w,h,o,ch) | |||||
end(); | 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*)¬e); | |||||
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) | 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) | inline void SequencerPluginGUI::cb_NoteCut_i(Fl_Button* o, void* v) | ||||
{ | { | ||||
//m_Plugin->SetNoteCut(o->value()); | //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) | 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) | void SequencerPluginGUI::cb_Zoom(Fl_Knob* o, void* v) | ||||
{ ((SequencerPluginGUI*)(o->parent()))->cb_Zoom_i(o,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) | void SequencerPluginGUI::cb_Pattern(Fl_Counter* o, void* v) | ||||
{ ((SequencerPluginGUI*)(o->parent()))->cb_Pattern_i(o,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);} | { ((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) | inline void SequencerPluginGUI::cb_Speed_i(Fl_Knob* o, void* v) | ||||
{ | { | ||||
//m_Plugin->SetSpeed(o->value()-2.0f); | //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) | void SequencerPluginGUI::cb_Clear(Fl_Button* o, void* v) | ||||
{ ((SequencerPluginGUI*)(o->parent()))->cb_Clear_i(o,v);} | { ((SequencerPluginGUI*)(o->parent()))->cb_Clear_i(o,v);} | ||||
/// sequence callbacks ///////////////////////////////////////////////////////// | |||||
inline void SequencerPluginGUI::cb_NewPattern_i(Fl_Button* o, void* v) | 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"); | 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_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(); | redraw(); | ||||
} | } | ||||
void SequencerPluginGUI::cb_NewPattern(Fl_Button* o, void* v) | void SequencerPluginGUI::cb_NewPattern(Fl_Button* o, void* v) | ||||
{ ((SequencerPluginGUI*)(o->parent()))->cb_NewPattern_i(o,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) | inline void SequencerPluginGUI::cb_ArrangeRM_i(Fl_Button* o, void* v) | ||||
{ | { | ||||
int ID=((Fl_SEvent*)o)->GetID(); | 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) | void SequencerPluginGUI::cb_ArrangeRM(Fl_Button* o, void* v) | ||||
{ ((SequencerPluginGUI*)(o->parent()->user_data()))->cb_ArrangeRM_i(o,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);} | |||||
@@ -23,6 +23,7 @@ | |||||
#include <FL/Fl_Slider.H> | #include <FL/Fl_Slider.H> | ||||
#include <FL/Fl_Counter.H> | #include <FL/Fl_Counter.H> | ||||
#include <FL/Fl_Output.H> | #include <FL/Fl_Output.H> | ||||
#include <FL/Fl_Input.H> | |||||
#include "SequencerPlugin.h" | #include "SequencerPlugin.h" | ||||
#include "../SpiralPluginGUI.h" | #include "../SpiralPluginGUI.h" | ||||
@@ -39,6 +40,7 @@ public: | |||||
SequencerPluginGUI(int w, int h, SequencerPlugin *o, ChannelHandler *ch,const HostInfo *Info); | SequencerPluginGUI(int w, int h, SequencerPlugin *o, ChannelHandler *ch,const HostInfo *Info); | ||||
virtual void UpdateValues(SpiralPlugin *o); | virtual void UpdateValues(SpiralPlugin *o); | ||||
virtual void Update(); | |||||
private: | private: | ||||
@@ -46,23 +48,34 @@ private: | |||||
Fl_Button* m_NewPattern; | Fl_Button* m_NewPattern; | ||||
Fl_Button* m_NoteCut; | Fl_Button* m_NoteCut; | ||||
Fl_Knob* m_Zoom; | Fl_Knob* m_Zoom; | ||||
Fl_Knob* m_Length; | |||||
Fl_Knob* m_Speed; | Fl_Knob* m_Speed; | ||||
Fl_Button* m_Clear; | 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 | class PatternWin : public Fl_Double_Window | ||||
{ | { | ||||
public: | public: | ||||
PatternWin(int w,int h,const char* n); | PatternWin(int w,int h,const char* n); | ||||
Fl_EventMap *GetEventMap() { return m_Melody; } | |||||
private: | private: | ||||
Fl_Scroll* m_Scroll; | Fl_Scroll* m_Scroll; | ||||
Fl_EventMap* m_Melody; | Fl_EventMap* m_Melody; | ||||
int m_NextNoteID; | |||||
}; | }; | ||||
map<int,PatternWin*> m_PatternWinMap; | map<int,PatternWin*> m_PatternWinMap; | ||||
Fl_EventMap* m_ArrangementMap; | Fl_EventMap* m_ArrangementMap; | ||||
// get the notes from the audio thread | |||||
void LoadPatternData(int ID); | |||||
void ChangeSequenceHelper(Fl_SEvent *event); | |||||
//// Callbacks //// | //// Callbacks //// | ||||
inline void cb_Zoom_i(Fl_Knob* o, void* v); | inline void cb_Zoom_i(Fl_Knob* o, void* v); | ||||
static void cb_Zoom(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); | static void cb_NoteCut(Fl_Button* o, void* v); | ||||
inline void cb_Pattern_i(Fl_Counter* o, void* v); | inline void cb_Pattern_i(Fl_Counter* o, void* v); | ||||
static void cb_Pattern(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); | inline void cb_Speed_i(Fl_Knob* o, void* v); | ||||
static void cb_Speed(Fl_Knob* o, void* v); | static void cb_Speed(Fl_Knob* o, void* v); | ||||
inline void cb_Clear_i(Fl_Button* 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); | inline void cb_NewPattern_i(Fl_Button* o, void* v); | ||||
static void cb_NewPattern(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); | inline void cb_ArrangeRM_i(Fl_Button* o, void* v); | ||||
static void cb_ArrangeRM(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 | #endif |