| | 205 | |
| | 206 | (* |
| | 207 | (** Read a GUS pat file. *) |
| | 208 | let read_pat file = |
| | 209 | let fd = Unix.openfile file [Unix.O_RDONLY] 0o644 in |
| | 210 | let read_bytes n = |
| | 211 | let s = String.create n in |
| | 212 | assert (Unix.read fd s 0 n = n); |
| | 213 | s |
| | 214 | in |
| | 215 | let read_string n = |
| | 216 | let s = read_bytes n ^ "\000" in |
| | 217 | let i = String.index s '\000' in |
| | 218 | String.sub s 0 i |
| | 219 | in |
| | 220 | let advance n = ignore (read_bytes n) in |
| | 221 | let read_byte () = int_of_char (read_bytes 1).[0] in |
| | 222 | let read_uword () = |
| | 223 | let b1 = read_byte () in |
| | 224 | let b2 = read_byte () in |
| | 225 | b1 + 0x100 * b2 |
| | 226 | in |
| | 227 | let read_word () = |
| | 228 | let b = read_uword () in |
| | 229 | if b > 32767 then b - 65536 else b |
| | 230 | in |
| | 231 | let read_int () = |
| | 232 | let b1 = read_byte () in |
| | 233 | let b2 = read_byte () in |
| | 234 | let b3 = read_byte () in |
| | 235 | let b4 = read_byte () in |
| | 236 | b1 + 0x100 * b2 + 0x10000 * b3 + 0x1000000 * b4 |
| | 237 | in |
| | 238 | (* Identification string. *) |
| | 239 | assert (read_bytes 22 = "GF1PATCH110\000ID#000002\000"); |
| | 240 | (* Copyright info. *) |
| | 241 | advance 60; |
| | 242 | (* Number of instruments. *) |
| | 243 | assert (read_byte () = 1); |
| | 244 | (* Volume. *) |
| | 245 | let vol = read_word () in |
| | 246 | advance 40; |
| | 247 | (* Instrument number. *) |
| | 248 | let num_instr = read_word () in |
| | 249 | (* advance 4; (* TODO: hum hum *) *) |
| | 250 | (* Instrument name. *) |
| | 251 | let name = read_string 16 in |
| | 252 | (* Instrument size and layers count. *) |
| | 253 | advance 45; |
| | 254 | (* First layer. *) |
| | 255 | advance 6; |
| | 256 | let num_samples = read_byte () in |
| | 257 | advance 40; |
| | 258 | for i = 0 to num_samples - 1 do |
| | 259 | (* Sample name. *) |
| | 260 | let sample_name = read_string 8 in |
| | 261 | Printf.printf "sample: %s\n%!" sample_name |
| | 262 | done; |
| | 263 | Printf.printf "instr %d vol %d, %s, %d samples\n%!" num_instr vol name num_samples; |
| | 264 | Unix.close fd |
| | 265 | |
| | 266 | let () = |
| | 267 | read_pat "/usr/share/midi/freepats/Tone_000/000_Acoustic_Grand_Piano.pat"; |
| | 268 | exit 69 |
| | 269 | *) |