File: idiotseditor.h

package info (click to toggle)
nted 1.10.18-13
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 15,300 kB
  • sloc: cpp: 50,840; ansic: 10,195; sh: 4,552; makefile: 207; sed: 16
file content (335 lines) | stat: -rw-r--r-- 13,367 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/****************************************************************************************/
/*											*/
/* This program is free software; you can redistribute it and/or modify it under the	*/
/* terms of the GNU General Public License as published by the Free Software		*/
/* Foundation; either version 2 of the License, or (at your option) any later version.	*/
/*											*/
/* This program is distributed in the hope that it will be useful, but WITHOUT ANY	*/
/* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A	*/
/* PARTICULAR PURPOSE. See the GNU General Public License for more details.		*/
/*											*/
/* You should have received a copy of the GNU General Public License along with this	*/
/* program; (See "COPYING"). If not, If not, see <http://www.gnu.org/licenses/>.        */
/*											*/
/*--------------------------------------------------------------------------------------*/
/*											*/
/*  Copyright   Joerg Anders, TU Chemnitz, Fakultaet fuer Informatik, GERMANY           */
/*		ja@informatik.tu-chemnitz.de						*/
/*											*/
/*											*/
/****************************************************************************************/

#ifndef IDIOTSEDITOR_H

#define IDIOTSEDITOR_H
#include "config.h"
#include <X11/X.h>
#include <X11/Xlib.h>
#include <sys/time.h>
#include <gtk/gtk.h>
#include <cairo.h>
#include <cairo-features.h>
#include "resource.h"
#include "paths.h"

class NedIdiotsEditor;
class NedIdCommandHistory;

class pitch_info {
	public:
		int m_pitch, m_line;
		bool m_tiebackward;
		unsigned int m_state;
};

class NedIdNote {
	public:
		NedIdNote(int f_pitch, int volume, unsigned long long sta, unsigned long long sto) :
			m_midi_start(sta), m_midi_stop(sto), m_max_stop(0), 
			m_ori_start(sta), m_ori_stop(sto),
			m_tri_start_numerator(0), m_chordnotes(NULL),
				m_pitch(f_pitch), m_valid(true), m_is_triplet_note(false), fix_start(false), fix_end(false), m_volume(volume), m_line(3 /* dummy */), m_tiedbackward(false) {
					m_tripletnotes[0] = m_tripletnotes[1] = m_tripletnotes[2] = NULL;
				}
			
		NedIdNote(int f_pitch, int volume, unsigned long long sta) :
			m_midi_start(sta), m_midi_stop(sta), m_max_stop(0),
			m_ori_start(sta), m_tri_start_numerator(0), m_chordnotes(NULL),
				m_pitch(f_pitch), m_valid(false), m_is_triplet_note(false), fix_start(false), fix_end(false), m_volume(volume), m_line(3 /* dummy */), m_tiedbackward(false) {
					m_tripletnotes[0] = m_tripletnotes[1] = m_tripletnotes[2] = NULL;
			}

		NedIdNote *cloneWithDifferentTime(unsigned long long sta, unsigned long long sto);
		bool isInRect(double x, double y, double zoom_value, double xleft, double ytop);
		void determineLines(int clef, int octave_shift, int key, char *offs_array);

		~NedIdNote();

		void addPitch(int pitch, bool tiebackward);

		void closeNote(unsigned long long  sto) {
			if (sto > m_midi_start) {
				m_midi_stop = sto;
				m_valid = true;
			}
		}

		static int compare_note_start(NedIdNote *n1, NedIdNote *n2) {
			if (n1->m_midi_start < n2->m_midi_start) return -1;
			if (n1->m_midi_start < n2->m_midi_start) return 0;
			return 1;
		}
		unsigned long long m_midi_start, m_midi_stop, m_max_stop;
		unsigned long long m_ori_start, m_ori_stop;
		unsigned long long m_tri_start;
		int m_tri_start_numerator;
		GList *m_chordnotes;
		NedIdNote *m_tripletnotes[3];
		int m_pitch;
		bool m_valid;
		bool  m_is_triplet_note;
		bool fix_start, fix_end;
		unsigned int m_state;
		int m_volume;
		int m_line;
		bool m_tiedbackward;
};

class NedIdSpecial {
	public:
		NedIdSpecial(int type, unsigned long long time, int measure_number) : 
			m_type(type), m_time(time), m_measure_number(measure_number) {}
		int m_type;
#define ID_SPEC_TIME_SIG_CHANGE 1
#define ID_SPEC_TEMPO_CHANGE    2
#define ID_SPEC_VOLUME_CHANGE   3
#define ID_SPEC_KEYSIG_CHANGE   4
		unsigned long long m_time;
		int m_measure_number;
		static int compare_specials(NedIdSpecial *m1, NedIdSpecial *m2) {
			if (m1->m_time == m2->m_time) return 0;
			if (m1->m_time < m2->m_time) return -1;
			return 1;
		}
};

class NedIdTimesigChange : public NedIdSpecial {
	public:
		NedIdTimesigChange(unsigned long long time, int measure_number, int numerator, int denominator) :
			NedIdSpecial(ID_SPEC_TIME_SIG_CHANGE, time, measure_number), m_numerator(numerator), m_denominator(denominator) {}
		int m_numerator, m_denominator;
};

class NedIdTempoChange : public NedIdSpecial {
	public:
		NedIdTempoChange(unsigned long long time, int measure_number, int tempo) :
			NedIdSpecial(ID_SPEC_TEMPO_CHANGE, time, measure_number), m_tempo(tempo), m_used(false) {}
		int m_tempo;
		bool m_used;
};

class NedIdVolumeChange : public NedIdSpecial {
	public:
		NedIdVolumeChange(unsigned long long time, int measure_number, int volume) :
			NedIdSpecial(ID_SPEC_VOLUME_CHANGE, time, measure_number), m_volume(volume), m_taken(false) {}
		int m_volume;
		bool m_taken;
};

class NedIdKeysigChange : public NedIdSpecial {
	public:
		NedIdKeysigChange(unsigned long long time, int measure_number, int key) :
			NedIdSpecial(ID_SPEC_KEYSIG_CHANGE, time, measure_number), m_key(key) {}
		int m_key;
};

#define MAX_INST_NAME 12
#define MAX_64TH 640

class NedIdiotsInstrument {
	public:
		NedIdiotsInstrument(NedIdiotsEditor *id_edit,  int channel, int orig_channel, int midi_nr, int volume_change_density);
		~NedIdiotsInstrument();
		GList* trySplitInstrument(bool force_piano, bool dont_split);
		void setInstNumber(int nr)  {m_inst_number = nr;}
		void draw(Display *dpy, Window win, GC xgc, GC border_gc, double zoom_value, double xleft, double ytop, double visible_start_pos, double visible_end_pos);
		void draw_specials(cairo_t *cr, double zoom_value, double xleft, double ytop, double visible_start_pos, double visible_end_pos);
		void closeNote(int pitch, unsigned long long end_time, int midi_nr);
		int specCount();
		void addNote(int pitch, int volume, unsigned long long  start, int midi_nr);
		void addNote(NedIdNote *note);
		void addKeySig(NedIdKeysigChange *kc);
		void handle_button_press (GdkEventButton *event, double xleft, double ytop, double visible_start_pos, double visible_end_pos);
		void enlargeNotesWithUnusualLength(NedIdiotsEditor *id);
		void recognizeTriplets(NedIdiotsEditor *id);
		void enlargeNotesToAvoidSmallRests(NedIdiotsEditor *id);
		void generateVolumeSigns(int volume_change_density);
		int getMidiNr() {return m_midi_nr;}
		void setMidiNr(int midi_nr) {m_midi_nr = midi_nr;}
		void setInstrumentName(char *name);
		void snapStartOfNotes(NedIdiotsEditor *id);
		void computeVolume();
		void recomputeNotes(double zoom_value, double xleft, double ytop);
		int getChannel() {return m_channel;}
		int getClef() {return m_clef;}
		int getOctaveShift() {return m_octave_shift;}
		int getVolume() {return m_volume;}
		int getOrigChannel() {return m_orig_channel;}
		void setOrigChannel(int chan) {m_orig_channel = chan;}
		void setChannel(int chan) {m_channel = chan;}
		void determineLines(NedIdiotsEditor *id);
		void findConflictingNotes();
		void findChords(bool all_voices);
		void addSpecial(NedIdSpecial *spec);
		GList *clone_specials();
		GList *convertToNtEdNotes(NedIdiotsEditor *id, bool place_tempo_sigs, bool place_volume_or_key_signs,
				int voice_nr, unsigned long long last_time);
		char *getInstrumentName();
	private:
		void splitNotesAtMeasureStart(NedIdiotsEditor *id);
		int compute_weight(unsigned long long sta, unsigned long long sto, bool is_rest);
		unsigned long long findEndTime(unsigned long long sta, unsigned long long sto, unsigned long long max_stop, unsigned long long rest_end, unsigned long long measure_start);
		bool newVolumeNeeded(unsigned long long time, int *new_volume);
		NedIdNote *findNote(GList *start, unsigned long long start_time, unsigned long long end_time, NedIdNote *not_note1, NedIdNote *not_note2);
                void notesAus(char *s, int i);
		NedIdiotsEditor *m_id_edit;
		int m_clef, m_octave_shift;
		GList *m_notes[VOICE_COUNT];
		GList *m_specials;
		NedIdNote *m_selected_note;
		int m_inst_number;
		int m_volume_change_density;
		int m_midi_nr;
		int m_channel;
		int m_orig_channel;
		int m_volume;
		char m_inst_name[MAX_INST_NAME];
		char m_dist_array[4][MAX_64TH];
		static int m_mid_lines[4];
};
			


class NedIdiotsEditor {
	public:
		NedIdiotsEditor(int tempo_change_density, int volume_change_density, bool force_piano, bool sort_instruments, bool dont_split, bool X11Version = false);
		~NedIdiotsEditor();
		void setLastTime(unsigned long long last_time);
		void closeNote(int pitch, unsigned long long end_time, int midi_nr, int chan);
		void addNote(int pitch, int volume, unsigned long long  start, int midi_nr, int chan);
		void addTimeSigChange(unsigned long long time, int numerator, int denominator);
		void addTempoChange(unsigned long long time, int tempo);
		void addKeySig(unsigned long long time, int measure_number, int key);
		void setInstrumentName(char *name);
		void computeTimeSigMeasureNumbers(NedMainWindow *main_window);
		int getVolumeChangeDensity() {return m_volume_change_density;}
		void computeTempo();
		bool newTempoNeeded(unsigned long long current_time, int *newtempo, int current_tempo, unsigned long long  *last_tempo_test);
		bool newVolumeNeeded(int *current_volume, int volume); 
		bool newKeyNeeded(unsigned long long current_time, int *newkey, unsigned long long  *last_key_test);
		void printMeasures();
		void getMeasureNumber(unsigned long long start_time, int *num, int *denom);
		void computeVolumes();
		void changeChannelAndPgm(int staff_nr, int chan, int pgm);
		unsigned long long getMeasureStart(unsigned long long sample_time, bool endtime);
		unsigned long long getFirstSplitTime(unsigned long long start_time, unsigned long long end_time);
		char* getInstrumentName(int staff_nr);
		int getNumerator();
		int getDenominator();
		int getPartCount();
		int determine_key(unsigned long long time, int channel);
		void trySplitInstruments();
		void snapStartOfNotes();
		void recognizeTriplets();
		GList *convertToNtEdNotes(int staff_nr, int voice_nr);
		GList *colone_specials();
		int getClef(int staff_nr);
		int getOctaveShift(int staff_nr);
		int getMidiPgm(int staff_nr);
		int getChannel(int staff_nr);
		int getVolume(int staff_nr);
		int getKeySig(int staff_nr);
		GtkWidget *getDrawingArea() {return m_drawing_area;}
		GdkCursor *getPointCursor() {return m_pointer;}
		GdkCursor *getFleurCursor() {return m_fleur;}
		GdkCursor *getDoubldArrowCursor() {return m_double_arrow;}
		NedIdCommandHistory *getCommandHistory() {return m_command_history;}
		double getOffX() {return m_off_x;}
		double getOffY() {return m_off_y;}
		double getZoomValue() {return m_zoom_value;}
		unsigned int getMinDenom() {return m_min_denom;}
		
		void repaint();
		double m_tempo_inverse;
		int motion_mode;
	private:
		void correct_times_of_specials();
		bool delete_double_specials();
		void initX11();
		GdkCursor *m_double_arrow, *m_pointer, *m_fleur;
		static const char *guiDescription;
		static const GtkActionEntry file_entries[];
		static gboolean handle_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data);
		void  draw_piano(cairo_t *cr, double ytop, int height);
		static void select_instrument(GtkButton *button, gpointer data);
		static void zoom_in(GtkWidget  *widget, void *data);
		static void zoom_out(GtkWidget  *widget, void *data);
		static void size_change_handler(GtkWidget *widget, GtkRequisition *requisition, gpointer data);
		static void handle_scroll(GtkAdjustment *adjustment, gpointer data);
		static gboolean handle_button_press (GtkWidget *widget,
			 GdkEventButton *event, gpointer data);
		static gboolean handle_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data);
		static gboolean handle_button_release (GtkWidget *widget,
			 GdkEventButton *event, gpointer data);
		static void do_undo(GtkWidget  *widget, void *data);
		static void do_redo(GtkWidget  *widget, void *data);
		void getNumDenom(unsigned long long time, unsigned int *num, unsigned int *denom);
		static const char *pitch_tab[];
#ifdef ORIORI
		void draw();
#endif
		void draw_new();
		void draw_specials (cairo_t *cr, double zoom_value, double xleft, double ytop, int width, double visible_start_pos, double visible_end_pos);
		void thin_out_temposigs();
		void setHadjust();
		void setVadjust();
		double m_zoom_value;
		GtkUIManager *m_ui_manager;
		GtkActionGroup *m_menu_action_group;
		GtkWidget *m_main_window;
		GtkWidget *m_drawing_area;
		GtkWidget *m_instrument_toolbar;
		GtkAdjustment *m_hadjust;
		GtkAdjustment *m_vadjust;
		GtkWidget *m_instr_bu;
		double m_paper_len;
		double m_paper_height;
		bool m_force_piano, m_force_one_staff;
		int m_tempo_change_density, m_volume_change_density;
		int m_current_instrument_number;
		unsigned long long m_last_time;
		char m_pending_inst_name[MAX_INST_NAME];
		int m_channel_nr;
		NedIdiotsInstrument *m_last_inserted;
		bool m_sort_according_instrument;
		bool m_dont_split;
		bool m_X11version;
		unsigned int m_min_denom;
		NedIdCommandHistory *m_command_history;

		GList *m_instruments;
		GList *m_specials;

		double m_mouse_x, m_mouse_y;
		double m_off_x, m_off_y;

		Display *m_dpy;
		Window m_win;
		GC m_xgc, m_x_border_gc;
		Pixmap m_back_image;
		int m_screen;

		static void close_i_edit(GtkWidget  *widget, void *data);
};

#endif /* IDIOTSEDITOR_H */