1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2020 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __AGS_NOTE_H__
21 #define __AGS_NOTE_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <alsa/asoundlib.h>
27 
28 #include <ags/libags.h>
29 
30 G_BEGIN_DECLS
31 
32 #define AGS_TYPE_NOTE                (ags_note_get_type())
33 #define AGS_NOTE(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_NOTE, AgsNote))
34 #define AGS_NOTE_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_NOTE, AgsNoteClass))
35 #define AGS_IS_NOTE(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), AGS_TYPE_NOTE))
36 #define AGS_IS_NOTE_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE((class), AGS_TYPE_NOTE))
37 #define AGS_NOTE_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), AGS_TYPE_NOTE, AgsNoteClass))
38 
39 #define AGS_NOTE_GET_OBJ_MUTEX(obj) (&(((AgsNote *) obj)->obj_mutex))
40 
41 #define AGS_NOTE_DEFAULT_TICKS_PER_QUARTER_NOTE (16.0)
42 
43 typedef struct _AgsNote AgsNote;
44 typedef struct _AgsNoteClass AgsNoteClass;
45 
46 /**
47  * AgsNoteFlags:
48  * @AGS_NOTE_GUI: gui format
49  * @AGS_NOTE_RUNTIME: runtime format
50  * @AGS_NOTE_HUMAN_READABLE: human readable format
51  * @AGS_NOTE_DEFAULT_LENGTH: default length
52  * @AGS_NOTE_IS_SELECTED: is selected
53  * @AGS_NOTE_FEED: feed note
54  * @AGS_NOTE_ENVELOPE: do envelope
55  *
56  * Enum values to control the behavior or indicate internal state of #AgsNote by
57  * enable/disable as flags.
58  */
59 typedef enum{
60   AGS_NOTE_GUI             = 1,
61   AGS_NOTE_RUNTIME         = 1 <<  1,
62   AGS_NOTE_HUMAN_READABLE  = 1 <<  2,
63   AGS_NOTE_DEFAULT_LENGTH  = 1 <<  3,
64   AGS_NOTE_IS_SELECTED     = 1 <<  4,
65   AGS_NOTE_FEED            = 1 <<  5,
66   AGS_NOTE_ENVELOPE        = 1 <<  6,
67 }AgsNoteFlags;
68 
69 struct _AgsNote
70 {
71   GObject gobject;
72 
73   guint flags;
74   guint key_format;
75 
76   GRecMutex obj_mutex;
77 
78   gboolean is_minor;
79   guint sharp_flats;
80 
81   // gui format, convert easy to visualization
82   guint x[2];
83   guint y;
84 
85   guint64 rt_offset;
86   guint rt_attack;
87 
88   gdouble stream_delay;
89   gdouble stream_attack;
90   guint64 stream_frame_count;
91 
92   AgsComplex attack;
93   AgsComplex decay;
94   AgsComplex sustain;
95   AgsComplex release;
96 
97   AgsComplex ratio;
98 
99   gchar *note_name;
100   gdouble frequency;
101 };
102 
103 struct _AgsNoteClass
104 {
105   GObjectClass gobject;
106 };
107 
108 GType ags_note_get_type();
109 
110 GRecMutex* ags_note_get_obj_mutex(AgsNote *note);
111 
112 gboolean ags_note_test_flags(AgsNote *note, guint flags);
113 void ags_note_set_flags(AgsNote *note, guint flags);
114 void ags_note_unset_flags(AgsNote *note, guint flags);
115 
116 gint ags_note_sort_func(gconstpointer a,
117 			gconstpointer b);
118 
119 gboolean ags_note_get_is_minor(AgsNote *note);
120 void ags_note_set_is_minor(AgsNote *note, gboolean is_minor);
121 
122 guint ags_note_get_sharp_flats(AgsNote *note);
123 void ags_note_set_sharp_flats(AgsNote *note, guint sharp_flats);
124 
125 guint ags_note_get_x0(AgsNote *note);
126 void ags_note_set_x0(AgsNote *note, guint x0);
127 
128 guint ags_note_get_x1(AgsNote *note);
129 void ags_note_set_x1(AgsNote *note, guint x1);
130 
131 guint ags_note_get_y(AgsNote *note);
132 void ags_note_set_y(AgsNote *note, guint y);
133 
134 guint64 ags_note_get_rt_offset(AgsNote *note);
135 void ags_note_set_rt_offset(AgsNote *note, guint64 rt_offset);
136 
137 guint ags_note_get_rt_attack(AgsNote *note);
138 void ags_note_set_rt_attack(AgsNote *note, guint rt_attack);
139 
140 AgsComplex* ags_note_get_attack(AgsNote *note);
141 void ags_note_set_attack(AgsNote *note, AgsComplex *attack);
142 
143 AgsComplex* ags_note_get_sustain(AgsNote *note);
144 void ags_note_set_sustain(AgsNote *note, AgsComplex *sustain);
145 
146 AgsComplex* ags_note_get_decay(AgsNote *note);
147 void ags_note_set_decay(AgsNote *note, AgsComplex *decay);
148 
149 AgsComplex* ags_note_get_release(AgsNote *note);
150 void ags_note_set_release(AgsNote *note, AgsComplex *release);
151 
152 AgsComplex* ags_note_get_ratio(AgsNote *note);
153 void ags_note_set_ratio(AgsNote *note, AgsComplex *ratio);
154 
155 GList* ags_note_find_prev(GList *note,
156 			  guint x0, guint y);
157 GList* ags_note_find_next(GList *note,
158 			  guint x0, guint y);
159 
160 glong ags_note_length_to_smf_delta_time(guint note_length,
161 					gdouble bpm, gdouble delay_factor,
162 					glong nn, glong dd, glong cc, glong bb,
163 					glong tempo);
164 guint ags_note_smf_delta_time_to_length(glong delta_time,
165 					glong nn, glong dd, glong cc, glong bb,
166 					glong tempo,
167 					gdouble bpm, gdouble delay_factor);
168 
169 guchar* ags_note_to_raw_midi(AgsNote *note,
170 			     gdouble bpm, gdouble delay_factor,
171 			     guint *buffer_length);
172 guchar* ags_note_to_raw_midi_extended(AgsNote *note,
173 				      gdouble bpm, gdouble delay_factor,
174 				      glong nn, glong dd, glong cc, glong bb,
175 				      glong tempo,
176 				      guint *buffer_length);
177 snd_seq_event_t* ags_note_to_seq_event(AgsNote *note,
178 				       gdouble bpm, gdouble delay_factor,
179 				       guint *n_events);
180 snd_seq_event_t* ags_note_to_seq_event_extended(AgsNote *note,
181 						gdouble bpm, gdouble delay_factor,
182 						glong nn, glong dd, glong cc, glong bb,
183 						glong tempo,
184 						guint *n_events);
185 
186 GList* ags_note_from_raw_midi(guchar *raw_midi,
187 			      gdouble bpm, gdouble delay_factor,
188 			      guint length);
189 GList* ags_note_from_raw_midi_extended(guchar *raw_midi,
190 				       glong nn, glong dd, glong cc, glong bb,
191 				       glong tempo,
192 				       gdouble bpm, gdouble delay_factor,
193 				       guint length);
194 GList* ags_note_from_seq_event(snd_seq_event_t *event,
195 			       gdouble bpm, gdouble delay_factor,
196 			       guint n_events);
197 GList* ags_note_from_seq_event_extended(snd_seq_event_t *event,
198 					glong nn, glong dd, glong cc, glong bb,
199 					glong tempo,
200 					gdouble bpm, gdouble delay_factor,
201 					guint n_events);
202 
203 AgsNote* ags_note_duplicate(AgsNote *note);
204 
205 AgsNote* ags_note_new();
206 AgsNote* ags_note_new_with_offset(guint x0, guint x1,
207 				  guint y,
208 				  gdouble stream_delay, gdouble stream_attack);
209 
210 G_END_DECLS
211 
212 #endif /*__AGS_NOTE_H__*/
213