~ubuntu-branches/ubuntu/wily/muse/wily-proposed

« back to all changes in this revision

Viewing changes to muse/steprec.cpp

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2011-12-03 17:12:54 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20111203171254-28b1j4lpb46r5jtl
Tags: 2.0~rc1-1
* New upstream RC release.
* Refresh patches, remove those patches not needed anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//  steprec.cpp
 
5
//  (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)
 
6
//
 
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.
 
11
//
 
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.
 
16
//
 
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.
 
20
//
 
21
//=========================================================
 
22
 
 
23
#include "steprec.h"
 
24
#include "part.h"
 
25
#include "event.h"
 
26
#include "globals.h"
 
27
#include "functions.h"
 
28
 
 
29
#include "song.h"
 
30
#include "audio.h"
 
31
 
 
32
#include <set>
 
33
 
 
34
#define CHORD_TIMEOUT 75
 
35
 
 
36
namespace MusECore {
 
37
 
 
38
StepRec::StepRec(bool* note_held_down_array)
 
39
{
 
40
        note_held_down=note_held_down_array;
 
41
 
 
42
        chord_timer=new QTimer(this);
 
43
        chord_timer->setSingleShot(true);
 
44
        chord_timer->setInterval(CHORD_TIMEOUT);
 
45
        chord_timer->stop();
 
46
        connect(chord_timer, SIGNAL(timeout()), SLOT(timeout()));
 
47
}
 
48
 
 
49
void StepRec::timeout()
 
50
{
 
51
        if (chord_timer_set_to_tick != MusEGlobal::song->cpos())
 
52
        {
 
53
                Pos p(chord_timer_set_to_tick, true);
 
54
                MusEGlobal::song->setPos(0, p, true, false, true);
 
55
        }
 
56
}
 
57
 
 
58
void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift)
 
59
{
 
60
        unsigned tick = MusEGlobal::song->cpos();
 
61
        unsigned lasttick=0;
 
62
        Undo operations;
 
63
        
 
64
        if (pitch!=MusEGlobal::rcSteprecNote) 
 
65
        {
 
66
                chord_timer->stop();
 
67
 
 
68
                // extend len of last note?
 
69
                EventList* events = part->events();
 
70
                if (ctrl)
 
71
                {
 
72
                        for (iEvent i = events->begin(); i != events->end(); ++i)
 
73
                        {
 
74
                                Event ev = i->second;
 
75
                                if (ev.isNote() && ev.pitch() == pitch && ((ev.tick() + ev.lenTick() + part->tick()) == tick))
 
76
                                {
 
77
                                        Event e = ev.clone();
 
78
                                        e.setLenTick(ev.lenTick() + len);
 
79
                                        operations.push_back(UndoOp(UndoOp::ModifyEvent, e,ev, part, false, false));
 
80
                                        
 
81
                                        if (!shift)
 
82
                                        {
 
83
                                                chord_timer_set_to_tick = tick + step;
 
84
                                                chord_timer->start();
 
85
                                        }
 
86
                                        
 
87
                                        lasttick=tick+len - part->tick();
 
88
                                        goto steprec_record_foot;
 
89
                                }
 
90
                        }
 
91
                }
 
92
 
 
93
                if (tick<=part->endTick())
 
94
                {
 
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)
 
101
                        {
 
102
                                Event ev = i->second;
 
103
                                if (ev.isNote() && ev.pitch() == pitch)
 
104
                                {
 
105
                                        MusEGlobal::audio->msgDeleteEvent(ev, part, true, false, false);
 
106
 
 
107
                                        if (!shift)
 
108
                                        {
 
109
                                                chord_timer_set_to_tick = tick + step;
 
110
                                                chord_timer->start();
 
111
                                        }
 
112
                                        
 
113
                                        return;
 
114
                                }
 
115
                        }
 
116
                }
 
117
                
 
118
                                
 
119
                Event e(Note);
 
120
                e.setTick(tick - part->tick());
 
121
                e.setPitch(pitch);
 
122
                e.setVelo(velo);
 
123
                e.setLenTick(len);
 
124
                operations.push_back(UndoOp(UndoOp::AddEvent, e, part, false, false));
 
125
                lasttick=e.endTick();
 
126
 
 
127
                if (! (MusEGlobal::globalKeyState & Qt::ShiftModifier))
 
128
                {
 
129
                        chord_timer_set_to_tick = tick + step;
 
130
                        chord_timer->start();
 
131
                }
 
132
                
 
133
                goto steprec_record_foot; // this is actually unneccessary, but for clarity
 
134
        }
 
135
        else  // equals if (pitch==MusEGlobal::rcSteprecNote)
 
136
        {
 
137
                bool held_notes=false;
 
138
                if (note_held_down!=NULL)
 
139
                {
 
140
                        for (int i=0;i<128;i++)
 
141
                        if (note_held_down[i]) { held_notes=true; break; }
 
142
                }
 
143
                else
 
144
                        held_notes=false;
 
145
                         
 
146
 
 
147
                if (held_notes)
 
148
                {
 
149
                        chord_timer->stop();
 
150
                        
 
151
                        // extend len of last note(s)
 
152
                        using std::set;
 
153
                        
 
154
                        set<Event*> extend_set;
 
155
                        EventList* events = part->events();
 
156
                        for (iEvent i = events->begin(); i != events->end(); ++i)
 
157
                        {
 
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);
 
161
                        }
 
162
                        
 
163
                        for (set<Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++)
 
164
                        {
 
165
                                Event& ev=**it;
 
166
                                Event e = ev.clone();
 
167
                                e.setLenTick(ev.lenTick() + len);
 
168
                                operations.push_back(UndoOp(UndoOp::ModifyEvent,e, ev, part, false, false));
 
169
                        }
 
170
 
 
171
                        if (!shift)
 
172
                        {
 
173
                                chord_timer_set_to_tick = tick + step;
 
174
                                chord_timer->start();
 
175
                        }
 
176
                        
 
177
                        lasttick=tick+len - part->tick();
 
178
                        goto steprec_record_foot; // this is actually unneccessary, but for clarity
 
179
                }
 
180
                else // equals if (!held_notes)
 
181
                {
 
182
                        chord_timer->stop();
 
183
 
 
184
                        // simply proceed, inserting a rest
 
185
                        Pos p(MusEGlobal::song->cpos() + step, true);
 
186
                        MusEGlobal::song->setPos(0, p, true, false, true);
 
187
                        
 
188
                        return;
 
189
                }
 
190
        }
 
191
        
 
192
        steprec_record_foot:
 
193
        if (!((lasttick > part->lenTick()) && part->hasHiddenEvents())) // allowed?
 
194
        {
 
195
                if (lasttick > part->lenTick()) // we have to expand the part?
 
196
                        schedule_resize_all_same_len_clone_parts(part, lasttick, operations);
 
197
                
 
198
                MusEGlobal::song->applyOperationGroup(operations);
 
199
        }
 
200
}
 
201
 
 
202
} // namespace MusECore