Advertisement
Le_BuG63

Untitled

Jun 19th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.28 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <byteswap.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8.  
  9. #define DEBUG
  10.  
  11. enum error_type {
  12.     UNKNOWN,
  13.     SUCCESS,
  14.     NO_FILE,
  15.     NO_PERM,
  16.     END_OF_FILE
  17. };
  18.  
  19. struct header_chunk {
  20.     char    type[4];
  21.     uint32_t length;
  22.    
  23.     uint16_t format;
  24.     uint16_t ntrks;
  25.     uint16_t division;
  26. /*
  27.     union {
  28.         int8_t smpte;
  29.         int8_t ticks_per_frame;
  30.        
  31.         int16_t ticks_per_quater_note;
  32.     };*/
  33. } __attribute__((__packed__));
  34.  
  35. struct track_event {
  36.     uint32_t delta_time;
  37.     uint8_t  event_type;
  38.  
  39.     struct {
  40.         uint8_t     type;
  41.         uint32_t    length;
  42.     } meta;
  43. };
  44.  
  45. struct track_chunk {
  46.     char     type[4];
  47.     uint32_t length;
  48.    
  49.     struct track_event *events;
  50.     size_t              events_maxsize;
  51.     uint32_t            events_size;
  52. } __attribute__((__packed__));
  53.  
  54.  
  55. struct list_track_chunk {
  56.     struct track_chunk *tracks;
  57.  
  58.     size_t      maxsize;
  59.     uint32_t    size;
  60. };
  61.  
  62. void debug_header_chunk(struct header_chunk hdr) {
  63. #ifdef DEBUG
  64.     printf("HEADER CHUNK\n");
  65.     printf("\tType: %s\n\tLength: %d\n\tFormat: %d\n\tNtrks: %d\n\tDivision: %d\n", hdr.type, hdr.length, hdr.format, hdr.ntrks, hdr.division);
  66. #endif
  67. }
  68.  
  69. void debug_track_chunck(struct track_chunk trc) {
  70. #ifdef DEBUG
  71.     printf("TRACK CHUNK\n");
  72.     printf("\tType: %s\n\tLength: %d\n", trc.type, trc.length);
  73. #endif
  74. }
  75.  
  76. void debug_track_event(struct track_event tre) {
  77. #ifdef DEBUG
  78.     printf("\n\tTRACK EVENT\n");
  79.     printf("\t\tDelta time: %d\n\t\tEvent type: %#2X", tre.delta_time, tre.event_type);
  80. #endif
  81. }
  82.  
  83. void format_header_chunk(struct header_chunk *hdr) {
  84. /*        if((hdr->division & (1 << 15)) == 1) {
  85.             hdr->smpte = (hdr->division  & 0b0111111100000000);
  86.             hdr->ticks_per_frame = hdr->division & 0b0000000011111111;
  87.  
  88.             hdr->smpte = __bswap_16(hdr->smpte);
  89.             hdr->ticks_per_frame = __bswap_16(hdr->ticks_per_frame);
  90.  
  91.             printf("%d %d\n\n", hdr->smpte, hdr->ticks_per_frame);
  92.         }
  93. */
  94.     hdr->length = __bswap_32(hdr->length);
  95.     hdr->format = __bswap_16(hdr->format);
  96.     hdr->ntrks = __bswap_16(hdr->ntrks);
  97.     hdr->division = __bswap_16(hdr->division);
  98. }
  99.  
  100.  
  101. void format_track_chunk(struct track_chunk *trc) {
  102.     trc->length = __bswap_32(trc->length);
  103. }
  104.  
  105. void format_track_event(struct track_event *tre) {
  106.     tre->delta_time = __bswap_32(tre->delta_time);
  107. }
  108.  
  109. enum error_type read_data(int fd, void *data, size_t size, uint32_t *total_byte_reads) {
  110.     int bytes_read = read(fd, data, size);
  111.  
  112.     total_byte_reads += size;
  113.  
  114.     if(bytes_read == 0)
  115.         return END_OF_FILE;
  116.  
  117.     return SUCCESS;
  118. }
  119.  
  120.  
  121. uint32_t read_variable_length(int fd, uint32_t *total_byte_reads) {
  122.     uint8_t     byte;
  123.     uint32_t    pos_cmptr = 0;
  124.     uint32_t    val;
  125.    
  126.     read_data(fd, &val, sizeof(uint8_t), total_byte_reads);
  127.  
  128.     if(val & 0x80) {
  129.         int8_t c;
  130.  
  131.         val &= 0x7F;
  132.         //val = (val << 7) + (c & 0x7F);
  133.  
  134.         do {
  135.             read_data(fd, &c, sizeof(int8_t), total_byte_reads);
  136.  
  137.             val = (val << 7) + (c & 0x7F);
  138.         } while(c & 0x80);
  139.     }
  140.  
  141.     val = __bswap_32(val);
  142.  
  143.     return val;
  144. }
  145.  
  146. void skip_bytes_file(int fd, uint32_t n) {
  147.     lseek(fd, n, SEEK_CUR);
  148. }
  149.  
  150. enum error_type manage_meta_events(int fd, struct track_event *tre, uint32_t *total_byte_reads) {
  151.     enum error_type err = SUCCESS;
  152.    
  153.     err = read_data(fd, &tre->meta.type, sizeof(uint8_t), total_byte_reads);
  154.     if(err != SUCCESS) return err;
  155.  
  156.     err = read_data(fd, &tre->meta.length, sizeof(uint8_t), total_byte_reads);
  157.     if(err != SUCCESS) return err;
  158.  
  159.     switch(tre->meta.type) {
  160.     case 0x00:
  161.         break;
  162.     case 0x20:
  163.         break;
  164.     case 0x2F:
  165.             skip_bytes_file(fd, tre->meta.length);
  166.             *total_byte_reads +=  tre->meta.length;
  167.         break;
  168.     case 0x51:
  169.             skip_bytes_file(fd, tre->meta.length);
  170.             *total_byte_reads +=  tre->meta.length;
  171.         break;
  172.     case 0x58:
  173.             skip_bytes_file(fd, tre->meta.length);
  174.             *total_byte_reads +=  tre->meta.length;
  175.         break;
  176.     default:
  177.             skip_bytes_file(fd, tre->meta.length);
  178.             *total_byte_reads +=  tre->meta.length;
  179.         break;
  180.     }
  181.  
  182.     return err;
  183. }
  184.  
  185. enum error_type read_track_chunk(int fd, struct track_chunk *trc) {
  186.     enum error_type err = SUCCESS;
  187.  
  188.     uint32_t total_byte_reads = 0;
  189.    
  190.     trc->events_maxsize = 20;
  191.     trc->events_size = 0;
  192.     trc->events = malloc(trc->events_maxsize * sizeof(struct track_event));
  193.  
  194.     while(total_byte_reads < trc->length) {
  195.         struct track_event tre;
  196.  
  197.         tre.delta_time = read_variable_length(fd, &total_byte_reads);
  198.  
  199.         err = read_data(fd, &tre.event_type, sizeof(tre.event_type), &total_byte_reads);
  200.         if(err != SUCCESS) return err;
  201.  
  202.         format_track_event(&tre);
  203.        
  204.         if(tre.event_type == 0xFF) {
  205.             err = manage_meta_events(fd, &tre, &total_byte_reads);
  206.             if(err != SUCCESS) return err;
  207.         }
  208.         else if(tre.event_type == 0xF0) {
  209.             uint32_t l;
  210.             l = read_variable_length(fd, &total_byte_reads);
  211.             skip_bytes_file(fd, l);
  212.         }
  213.         else if(tre.event_type == 0xF7) {
  214.             uint32_t l;
  215.             l = read_variable_length(fd, &total_byte_reads);
  216.             skip_bytes_file(fd, l);
  217.         }
  218.  
  219.         trc->events[trc->events_size++] = tre;
  220.  
  221.         if(trc->events_size >= trc->events_maxsize) {
  222.             trc->events_maxsize *= 2;
  223.             trc->events = realloc(trc->events, trc->events_maxsize);
  224.         }
  225.     }
  226.  
  227. #ifdef DEBUG
  228.     printf("\tEvents read: %d\n\n", trc->events_size);
  229. #endif
  230.     return SUCCESS;
  231. }
  232.  
  233.  
  234. int main(void) {
  235.     enum error_type err = SUCCESS;
  236.  
  237.     struct header_chunk hdr;
  238.  
  239.     int    fd;
  240.  
  241.     fd = open("riverflowsinyou.mid", O_RDONLY);
  242.    
  243.     if(fd > 0) {
  244.         uint32_t total_byte_reads = 0;
  245.  
  246.         struct list_track_chunk list_tracks;
  247.  
  248.         list_tracks.maxsize = 5;
  249.         list_tracks.size = 0;
  250.         list_tracks.tracks = malloc(list_tracks.maxsize * sizeof(struct track_chunk));
  251.  
  252.         read_data(fd, &hdr, sizeof(struct header_chunk), &total_byte_reads);
  253.         format_header_chunk(&hdr);
  254.         debug_header_chunk(hdr);
  255.  
  256.         while(err != END_OF_FILE) {
  257.             struct track_chunk trc;
  258.            
  259.             err = read_data(fd, &trc, 8, &total_byte_reads);
  260.             if(err != SUCCESS) return err;
  261.  
  262.             format_track_chunk(&trc);
  263.             debug_track_chunck(trc);
  264.  
  265.             total_byte_reads = 0;
  266.  
  267.             err = read_track_chunk(fd, &trc);
  268.             if(err != SUCCESS) {printf("ok"); break;}
  269.  
  270.             list_tracks.tracks[list_tracks.size] = trc;
  271.  
  272.             if(list_tracks.size >= list_tracks.maxsize) {
  273.                 list_tracks.maxsize *= 2;
  274.                 list_tracks.tracks = realloc(list_tracks.tracks, list_tracks.maxsize * sizeof(struct track_chunk));
  275.             }
  276.         }
  277.  
  278.         for(int i = 0; i < list_tracks.size; ++i) {
  279.             free(list_tracks.tracks[i].events);
  280.         }
  281.  
  282.         free(list_tracks.tracks);
  283.     }
  284.     else {
  285.          err = NO_FILE;
  286.     }
  287.  
  288.     return 0;
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement