1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 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_MIDI_FILE_H__
21 #define __AGS_MIDI_FILE_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <ags/libags.h>
27 
28 #include <stdio.h>
29 
30 G_BEGIN_DECLS
31 
32 #define AGS_TYPE_MIDI_FILE                (ags_midi_file_get_type ())
33 #define AGS_MIDI_FILE(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_MIDI_FILE, AgsMidiFile))
34 #define AGS_MIDI_FILE_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_MIDI_FILE, AgsMidiFileClass))
35 #define AGS_IS_MIDI_FILE(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_MIDI_FILE))
36 #define AGS_IS_MIDI_FILE_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_MIDI_FILE))
37 #define AGS_MIDI_FILE_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), AGS_TYPE_MIDI_FILE, AgsMidiFileClass))
38 
39 #define AGS_MIDI_FILE_GET_OBJ_MUTEX(obj) (&(((AgsMidiFile *) obj)->obj_mutex))
40 
41 #define AGS_MIDI_FILE_TRACK(ptr) ((AgsMidiFileTrack *)(ptr))
42 
43 #define AGS_MIDI_FILE_MAX_TEXT_LENGTH (4096)
44 #define AGS_MIDI_FILE_MTHD "MThd"
45 #define AGS_MIDI_FILE_MTRK "MTrk"
46 
47 #define AGS_MIDI_FILE_DEFAULT_OFFSET (0)
48 #define AGS_MIDI_FILE_DEFAULT_FORMAT (1)
49 #define AGS_MIDI_FILE_DEFAULT_BEATS (120)
50 #define AGS_MIDI_FILE_DEFAULT_FPS (30)
51 #define AGS_MIDI_FILE_DEFAULT_TICKS (384)
52 
53 typedef struct _AgsMidiFile AgsMidiFile;
54 typedef struct _AgsMidiFileClass AgsMidiFileClass;
55 typedef struct _AgsMidiFileTrack AgsMidiFileTrack;
56 
57 typedef enum{
58   /* channel messages */
59   AGS_MIDI_FILE_KEY_OFF           = 0x80,
60   AGS_MIDI_FILE_KEY_ON            = 0x90,
61   AGS_MIDI_FILE_KEY_PRESSURE      = 0xa0,
62   AGS_MIDI_FILE_CHANGE_PARAMETER  = 0xb0,
63   AGS_MIDI_FILE_CHANGE_PROGRAM    = 0xc0,
64   AGS_MIDI_FILE_CHANNEL_PRESSURE  = 0xd0,
65   AGS_MIDI_FILE_CHANGE_PITCH_BEND = 0xe0,
66   /* status messages */
67   AGS_MIDI_FILE_SYSEX             = 0xf0,
68   AGS_MIDI_FILE_QUARTER_FRAME     = 0xf1,
69   AGS_MIDI_FILE_SONG_POSITION     = 0xf2,
70   AGS_MIDI_FILE_SONG_SELECT       = 0xf3,
71   AGS_MIDI_FILE_UNDEFINED_0       = 0xf4,
72   AGS_MIDI_FILE_UNDEFINED_1       = 0xf5,
73   AGS_MIDI_FILE_TUNE_REQUEST      = 0xf6,
74   AGS_MIDI_FILE_SYSEX_END         = 0xf7,
75   AGS_MIDI_FILE_META_EVENT        = 0xff,
76 }AgsMidiFileStatus;
77 
78 typedef enum{
79   AGS_MIDI_FILE_EOF               = 1,
80   AGS_MIDI_FILE_SMTPE             = 1 <<  1,
81   AGS_MIDI_FILE_DROP_FRAME        = 1 <<  2,
82 }AgsMidiFileFlags;
83 
84 #define AGS_MIDI_FILE_ERROR (ags_midi_file_error_quark())
85 
86 typedef enum{
87   AGS_MIDI_FILE_ERROR_PREMATURE_EOF,
88 }AgsMidiFileError;
89 
90 struct _AgsMidiFile
91 {
92   GObject gobject;
93 
94   guint flags;
95 
96   GRecMutex obj_mutex;
97 
98   gchar *filename;
99   FILE *file;
100 
101   unsigned char *buffer;
102   guint buffer_length;
103 
104   unsigned char *iter;
105 
106   guint offset;
107   guint format;
108   guint count;
109   guint division;
110   guint times;
111   guint beat;
112   guint clicks;
113 
114   GList *track;
115 
116   AgsMidiFileTrack *current_track;
117 
118   GList *notation;
119   GList *midi;
120 };
121 
122 struct _AgsMidiFileClass
123 {
124   GObjectClass gobject;
125 };
126 
127 struct _AgsMidiFileTrack
128 {
129   GObject *sequencer;
130 
131   gchar *track_name;
132   unsigned char *buffer;
133 };
134 
135 GType ags_midi_file_get_type(void);
136 
137 GQuark ags_midi_file_error_quark();
138 
139 gboolean ags_midi_file_open(AgsMidiFile *midi_file,
140 			    gchar *filename);
141 gboolean ags_midi_file_open_from_data(AgsMidiFile *midi_file,
142 				      unsigned char *data, guint buffer_length);
143 gboolean ags_midi_file_rw_open(AgsMidiFile *midi_file,
144 			       gchar *filename,
145 			       gboolean create);
146 
147 void ags_midi_file_close(AgsMidiFile *midi_file);
148 
149 unsigned char* ags_midi_file_read(AgsMidiFile *midi_file);
150 void ags_midi_file_write(AgsMidiFile *midi_file,
151 			 unsigned char *data, guint buffer_length);
152 void ags_midi_file_seek(AgsMidiFile *midi_file, guint position, gint whence);
153 void ags_midi_file_flush(AgsMidiFile *midi_file);
154 
155 unsigned char ags_midi_file_read_byte(AgsMidiFile *midi_file,
156 				      GError **error);
157 gint16 ags_midi_file_read_gint16(AgsMidiFile *midi_file,
158 				 GError **error);
159 gint32 ags_midi_file_read_gint24(AgsMidiFile *midi_file,
160 				 GError **error);
161 gint32 ags_midi_file_read_gint32(AgsMidiFile *midi_file,
162 				 GError **error);
163 long ags_midi_file_read_varlength(AgsMidiFile *midi_file,
164 				  GError **error);
165 unsigned char* ags_midi_file_read_text(AgsMidiFile *midi_file,
166 				       gint length,
167 				       GError **error);
168 
169 void ags_midi_file_write_byte(AgsMidiFile *midi_file, unsigned char val);
170 void ags_midi_file_write_gint16(AgsMidiFile *midi_file, gint16 val);
171 void ags_midi_file_write_gint24(AgsMidiFile *midi_file, gint32 val);
172 void ags_midi_file_write_gint32(AgsMidiFile *midi_file, gint32 val);
173 void ags_midi_file_write_varlength(AgsMidiFile *midi_file, long val);
174 void ags_midi_file_write_text(AgsMidiFile *midi_file,
175 			      gchar *text, guint length);
176 
177 unsigned char* ags_midi_file_read_header(AgsMidiFile *midi_file,
178 					 guint *buffer_length,
179 					 GError **error);
180 void ags_midi_file_write_header(AgsMidiFile *midi_file,
181 				unsigned char *buffer, guint buffer_length);
182 
183 unsigned char* ags_midi_file_read_track_data(AgsMidiFile *midi_file,
184 					     guint *buffer_length,
185 					     GError **error);
186 void ags_midi_file_write_track_data(AgsMidiFile *midi_file,
187 				    unsigned char *buffer, guint buffer_length);
188 
189 void ags_midi_file_read_notation(AgsMidiFile *midi_file);
190 void ags_mid_file_read_midi(AgsMidiFile *midi_file);
191 
192 AgsMidiFile* ags_midi_file_new(gchar *filename);
193 
194 G_END_DECLS
195 
196 #endif /*__AGS_MIDI_FILE_H__*/
197