1
//=========================================================
5
// (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)
7
// This program is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU General Public License
9
// as published by the Free Software Foundation; version 2 of
10
// the License, or (at your option) any later version.
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with this program; if not, write to the Free Software
19
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
//=========================================================
27
#include "functions.h"
34
#define CHORD_TIMEOUT 75
38
StepRec::StepRec(bool* note_held_down_array)
40
note_held_down=note_held_down_array;
42
chord_timer=new QTimer(this);
43
chord_timer->setSingleShot(true);
44
chord_timer->setInterval(CHORD_TIMEOUT);
46
connect(chord_timer, SIGNAL(timeout()), SLOT(timeout()));
49
void StepRec::timeout()
51
if (chord_timer_set_to_tick != MusEGlobal::song->cpos())
53
Pos p(chord_timer_set_to_tick, true);
54
MusEGlobal::song->setPos(0, p, true, false, true);
58
void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift)
60
unsigned tick = MusEGlobal::song->cpos();
64
if (pitch!=MusEGlobal::rcSteprecNote)
68
// extend len of last note?
69
EventList* events = part->events();
72
for (iEvent i = events->begin(); i != events->end(); ++i)
75
if (ev.isNote() && ev.pitch() == pitch && ((ev.tick() + ev.lenTick() + part->tick()) == tick))
78
e.setLenTick(ev.lenTick() + len);
79
operations.push_back(UndoOp(UndoOp::ModifyEvent, e,ev, part, false, false));
83
chord_timer_set_to_tick = tick + step;
87
lasttick=tick+len - part->tick();
88
goto steprec_record_foot;
93
if (tick<=part->endTick())
95
// if we already entered the note, delete it
96
// if we would find a note after part->lenTick(), the above "if"
97
// avoids this. this has to be avoided because then part->hasHiddenEvents() is true
98
// which results in forbidding any action beyond its end
99
EventRange range = events->equal_range(tick - part->tick());
100
for (iEvent i = range.first; i != range.second; ++i)
102
Event ev = i->second;
103
if (ev.isNote() && ev.pitch() == pitch)
105
MusEGlobal::audio->msgDeleteEvent(ev, part, true, false, false);
109
chord_timer_set_to_tick = tick + step;
110
chord_timer->start();
120
e.setTick(tick - part->tick());
124
operations.push_back(UndoOp(UndoOp::AddEvent, e, part, false, false));
125
lasttick=e.endTick();
127
if (! (MusEGlobal::globalKeyState & Qt::ShiftModifier))
129
chord_timer_set_to_tick = tick + step;
130
chord_timer->start();
133
goto steprec_record_foot; // this is actually unneccessary, but for clarity
135
else // equals if (pitch==MusEGlobal::rcSteprecNote)
137
bool held_notes=false;
138
if (note_held_down!=NULL)
140
for (int i=0;i<128;i++)
141
if (note_held_down[i]) { held_notes=true; break; }
151
// extend len of last note(s)
154
set<Event*> extend_set;
155
EventList* events = part->events();
156
for (iEvent i = events->begin(); i != events->end(); ++i)
158
Event& ev = i->second;
159
if (ev.isNote() && note_held_down[ev.pitch()] && ((ev.tick() + ev.lenTick() + part->tick()) == tick))
160
extend_set.insert(&ev);
163
for (set<Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++)
166
Event e = ev.clone();
167
e.setLenTick(ev.lenTick() + len);
168
operations.push_back(UndoOp(UndoOp::ModifyEvent,e, ev, part, false, false));
173
chord_timer_set_to_tick = tick + step;
174
chord_timer->start();
177
lasttick=tick+len - part->tick();
178
goto steprec_record_foot; // this is actually unneccessary, but for clarity
180
else // equals if (!held_notes)
184
// simply proceed, inserting a rest
185
Pos p(MusEGlobal::song->cpos() + step, true);
186
MusEGlobal::song->setPos(0, p, true, false, true);
193
if (!((lasttick > part->lenTick()) && part->hasHiddenEvents())) // allowed?
195
if (lasttick > part->lenTick()) // we have to expand the part?
196
schedule_resize_all_same_len_clone_parts(part, lasttick, operations);
198
MusEGlobal::song->applyOperationGroup(operations);
202
} // namespace MusECore