Actually added the files this time. More smf read support.
[orgux.git] / smf.c
blobb70c4af81acbe4b643b9d7d7a54d7c38370498c6
1 /* smf */
3 #include "orgux.h"
5 #define STRING_MAX 256
7 typedef unsigned char octet;
8 typedef int (*reader)(octet* buf, int count);
11 int bytes2short(octet arr[2]){
12 return (arr[1]<<8) | arr[0];
15 int bytes2int(octet arr[4]){
16 return (arr[3]<<24) | (arr[2]<<16) | (arr[1]<<8) | arr[0];
20 /* read a bunch of bytes and discard */
21 void skip_ahead(reader pull, int count){
22 const int W = 256;
23 char buf[W];
25 int C = count;
27 while(C > W){
28 pull(buf,W);
29 C -= W;
31 pull(buf,C);
34 octet read_one(reader pull){
35 octet byte[1];
36 pull(byte,1);
37 return byte[0];
40 int get_delta(reader pull){
41 octet a = read_one(pull);
42 if(a<0x80){return a;}
44 octet b = read_one(pull);
45 if(b<0x80){return ((a&0x7f)<<7) | b;}
47 octet c = read_one(pull);
48 if(c<0x80){return ((a&0x7f)<<14) | ((b&0x7f)<<7) | c;}
50 octet d = read_one(pull);
51 return ((a&0x7f)<<21) | ((b&0x7f)<<14) | ((c&0x7f)<<7) | d;
55 int orgux_load_song(orgux_state* S, int (*pull) (unsigned char* buf, int bytes)){
57 char buf[16];
58 char string[STRING_MAX];
59 int e;
60 int n;
62 /*MThd*/
63 if(pull(buf,4)<0) return -1;
65 /*0x00000006*/
66 if(pull(buf,4)<0) return -1;
68 /*format type: 0x0000 0x0001 or 0x0002*/
69 if(pull(buf,2)<0) return -1;
71 /*number of tracks*/
72 if(pull(buf,2)<0) return -1;
73 int track_count = bytes2short(buf);
75 /* time division */
76 if(pull(buf,2)<0) return -1;
77 //code to figure out time division
79 for(int i=0; i<track_count; i++){
81 /*MTrk*/
82 if(pull(buf,4)<0) return -1;
84 /* chunk size */
85 if(pull(buf,4)<0) return -1;
86 int chunk_size = bytes2int(buf);
88 int tick = 0;
89 while(1){
90 int delta = get_delta(pull);
91 if(1) break;
96 /* get ticks per beat */
97 /* get time signature */
98 /* get us per quarter note */
99 /* get time format */
102 /* for each track, each event, append event */
104 /* check for LoopStart and LoopEnd */
106 /* sort queue */