From 2b4b28e777fabd90d92c54e10c6bd002085fab95 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 16:14:56 +0100 Subject: [PATCH 01/17] added absolute delay --- src/BMS_DEC.C | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index ee37e65..a6b65d5 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -12,9 +12,12 @@ unsigned char tracknum=0; // on which channel we are currently operating uint8_t current_channel=0; -// number of ticks passed since the last event +// relative delay, i.e. number of ticks passed since the last event int delay=0; +// absolute delay within a track5 +int abs_delay=0; + // number of ticks passed since the last event, only used in the main track (i.e. the // track containing the tempo and metadata events) int basedelay=0; @@ -314,8 +317,16 @@ int parse_ev(FILE * in, FILE * out) } break; case 0x80: - if(inmain==1) basedelay+=getc(in); - else delay+=getc(in); + if(inmain==1) + { + basedelay+=getc(in); + } + else + { + uint8_t d=getc(in); + delay+=d + abs_delay+=d; + } break; case 0x88: { @@ -325,7 +336,9 @@ int parse_ev(FILE * in, FILE * out) } else { - delay += (getc(in)<<8) + getc(in); + uint16_t d=(getc(in)<<8) + getc(in); + delay += d; + abs_delay += d; } } break; @@ -337,8 +350,15 @@ int parse_ev(FILE * in, FILE * out) value=(value&0x7F)<<7; value+=getc(in); } - if(inmain==1) basedelay += value; - else delay += value; + if(inmain==1) + { + basedelay += value; + } + else + { + delay += value; + abs_delay += value; + } } break; case 0x9A: From ce5f750d3da5f85e4125a68029e0a757421fb5db Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 16:22:03 +0100 Subject: [PATCH 02/17] update delay handling --- src/BMS_DEC.C | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index a6b65d5..d917df6 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -277,6 +277,19 @@ void write_ctrl_interpolation(enum ctrl_type type, uint8_t const value, uint8_t delay=-duration; } +void update_delay(uint64_t value) +{ + if(inmain==1) + { + basedelay+=value; + } + else + { + delay+=value; + abs_delay+=value; + } +} + int parse_ev(FILE * in, FILE * out) { unsigned char ev = getc(in); @@ -317,48 +330,24 @@ int parse_ev(FILE * in, FILE * out) } break; case 0x80: - if(inmain==1) - { - basedelay+=getc(in); - } - else - { - uint8_t d=getc(in); - delay+=d - abs_delay+=d; - } - break; + uint8_t d = getc(in); + update_delay(d); + break; case 0x88: { - if(inmain==1) - { - basedelay += (getc(in)<<8) + getc(in); - } - else - { - uint16_t d=(getc(in)<<8) + getc(in); - delay += d; - abs_delay += d; - } + uint16_t d = (getc(in)<<8) + getc(in); + update_delay(d); } break; case 0xF0: { - int value = getc(in); + uint64_t value = getc(in); while(value&0x80) { value=(value&0x7F)<<7; value+=getc(in); } - if(inmain==1) - { - basedelay += value; - } - else - { - delay += value; - abs_delay += value; - } + update_delay(value); } break; case 0x9A: From 0836ca6f70bf9c0503c60854cb98d736bee1c8f5 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 16:24:16 +0100 Subject: [PATCH 03/17] fix build --- src/BMS_DEC.C | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index d917df6..dda6527 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -330,8 +330,10 @@ int parse_ev(FILE * in, FILE * out) } break; case 0x80: + { uint8_t d = getc(in); update_delay(d); + } break; case 0x88: { From f754bf2d24f6526bbd07c74278890622181d3065 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 17:14:36 +0100 Subject: [PATCH 04/17] added struct for storing events to be interpolated --- src/BMS_DEC.C | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index dda6527..30b78e4 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -4,6 +4,8 @@ // not sure how many track there can be? #define TRACKS 255 +#define MAX_CHANNELS 16 + unsigned char notes[8]; // holds the current track we are handling @@ -44,9 +46,19 @@ enum branch enum ctrl_type { VOLUME, - PAN + PAN, + PITCH }; +typedef struct +{ + enum ctrl_type type; + int abs_delay; + int duration; +} interpolated_event + +std::vector interp_events[MAX_CHANNELS] + unsigned char midi_status_note_on(unsigned char chan=current_channel) { // only lower nibble for channel specification @@ -637,7 +649,7 @@ int main(int argc, char ** argv) { // this could be the channel for the corresponding track current_channel = getc(fp); - if (current_channel >=16) + if (current_channel >=MAX_CHANNELS) { fprintf(stderr, "Error: BMS contains more than 15 channels! Exiting."); return -1; From ef6f826f9ec29ad93d495592a994b28ca605a880 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 17:15:14 +0100 Subject: [PATCH 05/17] correctly reset abs_delay --- src/BMS_DEC.C | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 30b78e4..1881498 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -671,6 +671,7 @@ int main(int argc, char ** argv) putc(0x2F,out); putc(0,out); + abs_delay=0; delay=basedelay; fseek(fp,savepos,SEEK_SET); tracknum++; From a462034c69ed210b3499999091052a65a04d66b8 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 17:40:05 +0100 Subject: [PATCH 06/17] maintain interp. events in multimap --- src/BMS_DEC.C | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 1881498..9f1424d 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -1,5 +1,6 @@ #include #include +#include // not sure how many track there can be? #define TRACKS 255 @@ -52,12 +53,11 @@ enum ctrl_type typedef struct { - enum ctrl_type type; int abs_delay; int duration; -} interpolated_event +} interpolated_event; -std::vector interp_events[MAX_CHANNELS] +std::multimap interp_events[MAX_CHANNELS]; unsigned char midi_status_note_on(unsigned char chan=current_channel) { @@ -381,7 +381,11 @@ int parse_ev(FILE * in, FILE * out) printf("pan position change duration in track %u is: %u\n", tracknum, duration); } #endif - write_ctrl_interpolation(PAN, pan_position, duration, out); + +interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; +interp_events[current_channel].insert(std::make_pair(PAN, e)); + +// write_ctrl_interpolation(PAN, pan_position, duration, out); } else { @@ -407,7 +411,10 @@ int parse_ev(FILE * in, FILE * out) printf("volume change duration in track %u is: %u\n", tracknum, duration); } #endif - write_ctrl_interpolation(VOLUME, volume, duration, out); + +interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; +interp_events[current_channel].insert(std::make_pair(VOLUME, e)); +// write_ctrl_interpolation(VOLUME, volume, duration, out); } else if(ev==0x09) // vibrato intensity event? pitch sensitivity event?? { @@ -448,6 +455,9 @@ int parse_ev(FILE * in, FILE * out) putc((pitch>>8)&0x7f,out); tracksz[tracknum]+=3; + +interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; +interp_events[current_channel].insert(std::make_pair(PITCH, e)); } else { From 92877c0515427554b24227caa3022b85fbc6b6b3 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Jan 2016 17:44:44 +0100 Subject: [PATCH 07/17] format --- src/BMS_DEC.C | 114 +++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 9f1424d..7350b9b 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -18,7 +18,7 @@ uint8_t current_channel=0; // relative delay, i.e. number of ticks passed since the last event int delay=0; -// absolute delay within a track5 +// absolute delay within a track int abs_delay=0; // number of ticks passed since the last event, only used in the main track (i.e. the @@ -53,8 +53,8 @@ enum ctrl_type typedef struct { - int abs_delay; - int duration; + int abs_delay; + int duration; } interpolated_event; std::multimap interp_events[MAX_CHANNELS]; @@ -145,15 +145,15 @@ void write_var_len(unsigned long long value, FILE* out) void handle_delay(FILE * out) { - int help=0; - - if(delay<0) - { - puts("Delay was negative!"); - help=delay; - delay=0; - } - + int help=0; + + if(delay<0) + { + puts("Delay was negative!"); + help=delay; + delay=0; + } + if(delay<=0x7F) { write_var_len(delay,out); @@ -238,16 +238,16 @@ void write_ctrl_interpolation(enum ctrl_type type, uint8_t const value, uint8_t break; } if(duration>0) - { - float step = (float)diff/duration; - - // write volume change interpolation step by step - for(float i = oldvol+step; (oldvolvalue); i+=step) { - write_volume((uint8_t)i, out); - delay=1; + float step = (float)diff/duration; + + // write volume change interpolation step by step + for(float i = oldvol+step; (oldvolvalue); i+=step) + { + write_volume((uint8_t)i, out); + delay=1; + } } - } // write final volume state write_volume((uint8_t)value, out); @@ -266,16 +266,16 @@ void write_ctrl_interpolation(enum ctrl_type type, uint8_t const value, uint8_t break; } if(duration>0) - { - float step = (float)diff/duration; - - // write pan position change interpolation step by step - for(float i = oldpan+step; (oldpanvalue); i+=step) { - write_pan((uint8_t)i, out); - delay=1; + float step = (float)diff/duration; + + // write pan position change interpolation step by step + for(float i = oldpan+step; (oldpanvalue); i+=step) + { + write_pan((uint8_t)i, out); + delay=1; + } } - } // write final pan position state write_pan((uint8_t)value, out); @@ -291,15 +291,15 @@ void write_ctrl_interpolation(enum ctrl_type type, uint8_t const value, uint8_t void update_delay(uint64_t value) { - if(inmain==1) - { - basedelay+=value; - } - else - { - delay+=value; - abs_delay+=value; - } + if(inmain==1) + { + basedelay+=value; + } + else + { + delay+=value; + abs_delay+=value; + } } int parse_ev(FILE * in, FILE * out) @@ -342,15 +342,15 @@ int parse_ev(FILE * in, FILE * out) } break; case 0x80: - { - uint8_t d = getc(in); - update_delay(d); - } - break; + { + uint8_t d = getc(in); + update_delay(d); + } + break; case 0x88: { - uint16_t d = (getc(in)<<8) + getc(in); - update_delay(d); + uint16_t d = (getc(in)<<8) + getc(in); + update_delay(d); } break; case 0xF0: @@ -382,8 +382,8 @@ int parse_ev(FILE * in, FILE * out) } #endif -interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; -interp_events[current_channel].insert(std::make_pair(PAN, e)); + interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; + interp_events[current_channel].insert(std::make_pair(PAN, e)); // write_ctrl_interpolation(PAN, pan_position, duration, out); } @@ -412,8 +412,8 @@ interp_events[current_channel].insert(std::make_pair(PAN, e)); } #endif -interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; -interp_events[current_channel].insert(std::make_pair(VOLUME, e)); + interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; + interp_events[current_channel].insert(std::make_pair(VOLUME, e)); // write_ctrl_interpolation(VOLUME, volume, duration, out); } else if(ev==0x09) // vibrato intensity event? pitch sensitivity event?? @@ -455,9 +455,9 @@ interp_events[current_channel].insert(std::make_pair(VOLUME, e)); putc((pitch>>8)&0x7f,out); tracksz[tracknum]+=3; - -interpolated_event e={ .abs_delay = abs_delay, .duration = duration}; -interp_events[current_channel].insert(std::make_pair(PITCH, e)); + + interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; + interp_events[current_channel].insert(std::make_pair(PITCH, e)); } else { @@ -659,12 +659,12 @@ int main(int argc, char ** argv) { // this could be the channel for the corresponding track current_channel = getc(fp); - if (current_channel >=MAX_CHANNELS) - { - fprintf(stderr, "Error: BMS contains more than 15 channels! Exiting."); - return -1; - } - + if (current_channel >=MAX_CHANNELS) + { + fprintf(stderr, "Error: BMS contains more than 15 channels! Exiting."); + return -1; + } + long offset = (getc(fp)<<16) + (getc(fp)<<8) + getc(fp); savepos=ftell(fp); fseek(fp,offset,SEEK_SET); From dd0b9eb1098178e1489ebe6e9dcbe4e2a1215f04 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 12 Jan 2016 18:22:01 +0100 Subject: [PATCH 08/17] implemented writing interpolated events to separate midi tracks --- src/BMS_DEC.C | 148 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 60 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 7350b9b..48dfaef 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -48,12 +48,21 @@ enum ctrl_type { VOLUME, PAN, - PITCH + //PITCH, + MAXCTRL }; typedef struct { int abs_delay; + + // actually we should use a union for value like: + // union{ + // u8 pan, vol; + // s16 pitch; + // } + int16_t value; + int duration; } interpolated_event; @@ -178,7 +187,7 @@ void handle_delay(FILE * out) delay=help; } -void write_volume(uint8_t vol, FILE* out) +void write_volume(int16_t vol, FILE* out) { handle_delay(out); @@ -189,7 +198,7 @@ void write_volume(uint8_t vol, FILE* out) tracksz[tracknum]+=3; } -void write_pan(uint8_t pan, FILE*out) +void write_pan(int16_t pan, FILE*out) { handle_delay(out); @@ -220,73 +229,89 @@ void write_bank(uint16_t bank, FILE*out) // TODO: write all interpolated events to a separate midi track, which overlays the track containing // the midi notes, and by that get completly independent of delay handling/fixing issues, see below -void write_ctrl_interpolation(enum ctrl_type type, uint8_t const value, uint8_t duration, FILE* out) +void write_ctrl_interpolation(FILE* out) { - static uint8_t last_vol[TRACKS]= {0}; - static uint8_t last_pan[TRACKS]= {0}; + static int16_t last_value[MAXCTRL][MAX_CHANNELS] = {0}; + static int last_delay[MAXCTRL][MAX_CHANNELS] = {0}; - switch(type) - { - case VOLUME: - { - uint8_t& oldvol = last_vol[tracknum]; - int8_t diff = value - oldvol; - if(diff==0) - { - // noting to do - break; - } - if(duration>0) - { - float step = (float)diff/duration; + for (uint8_t chan=0; chanvalue); i+=step) + for(uint8_t type=0; type(type)) { - write_volume((uint8_t)i, out); - delay=1; + case PAN: + write_ctrl=&write_pan; + break; + case VOLUME: + write_ctrl=&write_volume; + break; +// case PITCH: +// write_ctrl=&write_pitch; +// break; } - } - // write final volume state - write_volume((uint8_t)value, out); + std::multimap::iterator it = interp_events[chan].find(static_cast(type)); + if(it==interp_events[chan].end()) + { + continue; + } - oldvol = value; - } - break; - case PAN: - { - uint8_t& oldpan = last_pan[tracknum]; - int8_t diff = value - oldpan; + // start track + tracknum++; - if(diff==0) - { - // noting to do - break; - } - if(duration>0) - { - float step = (float)diff/duration; + for(;it!=interp_events[chan].end(); it++) + {// finally interpolate every single event + int16_t& oldvalue = last_value[type][chan]; + int16_t value = it->second.value; + int16_t diff = value - oldvalue; - // write pan position change interpolation step by step - for(float i = oldpan+step; (oldpanvalue); i+=step) - { - write_pan((uint8_t)i, out); - delay=1; + if(diff==0) + { + // noting to do + continue; + } + + // update relative delay, needed for ctrl-writing-functions + delay = it->second.abs_delay - last_delay[type][chan]; + last_delay[type][chan] = delay; + + int16_t duration = it->second.duration; + if(duration>0) + { + float step = (float)diff/duration; + + // write volume change interpolation step by step + for(float i = oldvalue+step; (oldvaluevalue); i+=step) + { + write_ctrl((int16_t)i, out); + delay=1; + } + } + // write final volume state + write_ctrl((int16_t)value, out); + + + oldvalue = value; } - } - // write final pan position state - write_pan((uint8_t)value, out); - oldpan = value; - } - break; + // end track + // 0 delay + write_var_len(0,out); + // end of track + putc(0xFF,out); + putc(0x2F,out); + putc(0,out); + + tracksz[tracknum]+=4; + } } - // all those interpolated events cause a delay in the resulting midi file, that actually doesnt exist - // to avoid that follwing events are influenced by that, and thus pushed into "the future", set delay negative - delay=-duration; + delay=0; } void update_delay(uint64_t value) @@ -382,7 +407,7 @@ int parse_ev(FILE * in, FILE * out) } #endif - interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; + interpolated_event e= { .abs_delay = abs_delay, .value = pan_position, .duration = duration}; interp_events[current_channel].insert(std::make_pair(PAN, e)); // write_ctrl_interpolation(PAN, pan_position, duration, out); @@ -412,7 +437,7 @@ int parse_ev(FILE * in, FILE * out) } #endif - interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; + interpolated_event e= { .abs_delay = abs_delay, .value = volume, .duration = duration}; interp_events[current_channel].insert(std::make_pair(VOLUME, e)); // write_ctrl_interpolation(VOLUME, volume, duration, out); } @@ -456,8 +481,8 @@ int parse_ev(FILE * in, FILE * out) tracksz[tracknum]+=3; - interpolated_event e= { .abs_delay = abs_delay, .duration = duration}; - interp_events[current_channel].insert(std::make_pair(PITCH, e)); + interpolated_event e= { .abs_delay = abs_delay, .value = pitch, .duration = duration}; +// interp_events[current_channel].insert(std::make_pair(PITCH, e)); } else { @@ -697,6 +722,9 @@ int main(int argc, char ** argv) } } fclose(fp); + + write_ctrl_interpolation(out); + fclose(out); FILE * midi_file = fopen(argv[2],"wb"); From fb919e94c10170d1275f8350f4b39a96af2ca0a4 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 14 Jan 2016 11:15:38 +0100 Subject: [PATCH 09/17] fixed several delay bugs --- src/BMS_DEC.C | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 48dfaef..d930d8e 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -1,6 +1,7 @@ #include #include -#include +#include // std::next +#include // std::multimap // not sure how many track there can be? #define TRACKS 255 @@ -234,10 +235,9 @@ void write_ctrl_interpolation(FILE* out) static int16_t last_value[MAXCTRL][MAX_CHANNELS] = {0}; static int last_delay[MAXCTRL][MAX_CHANNELS] = {0}; - - for (uint8_t chan=0; chan::iterator it = interp_events[chan].find(static_cast(type)); - if(it==interp_events[chan].end()) + std::multimap::iterator it = interp_events[current_channel].find(static_cast(type)); + if(it==interp_events[current_channel].end() || it->first!=type) { continue; } @@ -264,9 +264,9 @@ void write_ctrl_interpolation(FILE* out) // start track tracknum++; - for(;it!=interp_events[chan].end(); it++) + for(;it!=interp_events[current_channel].end() && it->first==type; it++) {// finally interpolate every single event - int16_t& oldvalue = last_value[type][chan]; + int16_t& oldvalue = last_value[type][current_channel]; int16_t value = it->second.value; int16_t diff = value - oldvalue; @@ -276,11 +276,33 @@ void write_ctrl_interpolation(FILE* out) continue; } - // update relative delay, needed for ctrl-writing-functions - delay = it->second.abs_delay - last_delay[type][chan]; - last_delay[type][chan] = delay; + // update global relative delay, needed for ctrl-writing-functions + delay = it->second.abs_delay - last_delay[type][current_channel]; + last_delay[type][current_channel] = it->second.abs_delay; int16_t duration = it->second.duration; + + { + std::multimap::iterator next = std::next(it); + if(next != interp_events[current_channel].end() && next->first==static_cast(type)) + { + int delay_to_next_event = next->second.abs_delay - it->second.abs_delay; + if(delay_to_next_event<0) + { + puts("THIS SHOULD NEVER HAPPEN! delay_to_next_event<0"); + } + else + { + // in case the next event arrives before we were able to fully finish the interpolation for this event + if(duration>delay_to_next_event) + { + // interpolate the current event within the time before next event is played + duration=delay_to_next_event; + } + } + } + } + if(duration>0) { float step = (float)diff/duration; From a00c5abcdc8bd5903ca85ba40c43c09ee3bf1621 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 14 Jan 2016 11:23:13 +0100 Subject: [PATCH 10/17] correctly write controls --- src/BMS_DEC.C | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index d930d8e..f6aa68a 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -192,7 +192,7 @@ void write_volume(int16_t vol, FILE* out) { handle_delay(out); - putc(midi_status_control_change(tracknum), out); + putc(midi_status_control_change(), out); putc(0x07, out); //TODO: unsure whether using expression instead of volume change putc(vol&0x7f, out); @@ -203,7 +203,7 @@ void write_pan(int16_t pan, FILE*out) { handle_delay(out); - putc(midi_status_control_change(tracknum), out); + putc(midi_status_control_change(), out); putc(0x0A, out); putc(pan&0x7f, out); @@ -214,14 +214,14 @@ void write_bank(uint16_t bank, FILE*out) { handle_delay(out); - putc(midi_status_control_change(tracknum), out); + putc(midi_status_control_change(), out); putc(0x0, out); // bank coarse putc(bank/128, out); handle_delay(out); - putc(midi_status_control_change(tracknum), out); + putc(midi_status_control_change(), out); putc(0x20, out); // bank fine putc(bank%128, out); From 25adafd957414a072f65d6d20766919f5b7274a8 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 14 Jan 2016 14:28:55 +0100 Subject: [PATCH 11/17] fix another delay bug --- src/BMS_DEC.C | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index f6aa68a..ce3eb65 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -312,6 +312,10 @@ void write_ctrl_interpolation(FILE* out) { write_ctrl((int16_t)i, out); delay=1; + + // ok, we inserted an extra midi event, thus also update olddelay, to avoid + // that further non-interpolated ctrl-events are pushed into the future + last_delay[type][current_channel] += delay; } } // write final volume state From 207970a3d0432b72618489f86f204f31301d46c6 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 14 Jan 2016 14:55:14 +0100 Subject: [PATCH 12/17] readability --- src/BMS_DEC.C | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index ce3eb65..4a4a06e 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -267,6 +267,7 @@ void write_ctrl_interpolation(FILE* out) for(;it!=interp_events[current_channel].end() && it->first==type; it++) {// finally interpolate every single event int16_t& oldvalue = last_value[type][current_channel]; + int& olddelay = last_delay[type][current_channel]; int16_t value = it->second.value; int16_t diff = value - oldvalue; @@ -277,8 +278,8 @@ void write_ctrl_interpolation(FILE* out) } // update global relative delay, needed for ctrl-writing-functions - delay = it->second.abs_delay - last_delay[type][current_channel]; - last_delay[type][current_channel] = it->second.abs_delay; + delay = it->second.abs_delay - olddelay; + olddelay = it->second.abs_delay; int16_t duration = it->second.duration; @@ -315,7 +316,7 @@ void write_ctrl_interpolation(FILE* out) // ok, we inserted an extra midi event, thus also update olddelay, to avoid // that further non-interpolated ctrl-events are pushed into the future - last_delay[type][current_channel] += delay; + olddelay += delay; } } // write final volume state From 0550bc96d1a71286f9fb2f82077fdfc073c0660c Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 14 Jan 2016 17:08:49 +0100 Subject: [PATCH 13/17] cleaup code, add comments --- src/BMS_DEC.C | 67 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 4a4a06e..84664e7 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -135,7 +135,7 @@ unsigned long long to_var_len(unsigned long long value) return buffer; } -void write_var_len(unsigned long long value, FILE* out) +void write_var_len(const unsigned long long value, FILE* out) { unsigned long long buffer = to_var_len(value); @@ -159,7 +159,9 @@ void handle_delay(FILE * out) if(delay<0) { - puts("Delay was negative!"); + puts("THIS SHOULD NEVER HAPPEN! delay<0"); + + // temporarily set delay 0 help=delay; delay=0; } @@ -185,6 +187,7 @@ void handle_delay(FILE * out) tracksz[tracknum]+=4; } + // restore any potential negative value delay=help; } @@ -228,12 +231,35 @@ void write_bank(uint16_t bank, FILE*out) tracksz[tracknum]+=6; } -// TODO: write all interpolated events to a separate midi track, which overlays the track containing -// the midi notes, and by that get completly independent of delay handling/fixing issues, see below +void write_track_end(FILE* out) +{ + // 0 delay + write_var_len(0,out); + // end of track + putc(0xFF,out); + putc(0x2F,out); + putc(0,out); + + tracksz[tracknum]+=4; +} + +/* + * @brief writes all ctrl change events + * + * creates all ctrl change events and writes them to temp file. also handles events to be interpolated. + * all those events are written to their corresponding channel, but to a separate midi track, which + * overlays the track(s) containing the midi notes. by that we get completely independent of delay handling + * issues, that always occurs, when writing interpolated (which actually means additional) events to midi file + * that then cause an additional delay (of one tick) that actually doesnt exist. in this case all events would + * (mistakenly) be pushed into the future. besides, if we would receive an event before we acutally finished + * interpolating another event, we would somehow need to introduce complex merging methods and crap... so lets + * better do it that way :-) + * + */ void write_ctrl_interpolation(FILE* out) { - static int16_t last_value[MAXCTRL][MAX_CHANNELS] = {0}; - static int last_delay[MAXCTRL][MAX_CHANNELS] = {0}; + int16_t last_value[MAXCTRL][MAX_CHANNELS] = {0}; + int last_delay[MAXCTRL][MAX_CHANNELS] = {0}; // yes, iterate over global variable for (current_channel=0; current_channel::iterator it = interp_events[current_channel].find(static_cast(type)); - if(it==interp_events[current_channel].end() || it->first!=type) + if(it==interp_events[current_channel].end() || it->first!=type) { continue; } @@ -283,6 +309,7 @@ void write_ctrl_interpolation(FILE* out) int16_t duration = it->second.duration; + // adjust interpolation duration, if the next event arrives sooner, than we could finish interpolating { std::multimap::iterator next = std::next(it); if(next != interp_events[current_channel].end() && next->first==static_cast(type)) @@ -315,29 +342,22 @@ void write_ctrl_interpolation(FILE* out) delay=1; // ok, we inserted an extra midi event, thus also update olddelay, to avoid - // that further non-interpolated ctrl-events are pushed into the future + // that further ctrl-events are pushed into the future olddelay += delay; } } // write final volume state write_ctrl((int16_t)value, out); - oldvalue = value; } // end track - // 0 delay - write_var_len(0,out); - // end of track - putc(0xFF,out); - putc(0x2F,out); - putc(0,out); - - tracksz[tracknum]+=4; + write_track_end(out); } } + // just to be sure delay=0; } @@ -727,11 +747,7 @@ int main(int argc, char ** argv) if(inmain==1) break; else { - tracksz[tracknum]+=4; - putc(0,out); - putc(0xFF,out); - putc(0x2F,out); - putc(0,out); + write_track_end(out); abs_delay=0; delay=basedelay; @@ -827,12 +843,7 @@ int main(int argc, char ** argv) putc((usec_pqn) & 0xFF,midi_file); } - // 0 delay - write_var_len(0,midi_file); - // end of track - putc(0xFF,midi_file); - putc(0x2F,midi_file); - putc(0,midi_file); + write_track_end(midi_file); } for(int i=0; i Date: Thu, 14 Jan 2016 17:41:05 +0100 Subject: [PATCH 14/17] use uint16 for track count --- src/BMS_DEC.C | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 84664e7..2f74d55 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -11,7 +11,7 @@ unsigned char notes[8]; // holds the current track we are handling -unsigned char tracknum=0; +uint16_t tracknum=0; // on which channel we are currently operating uint8_t current_channel=0; @@ -787,8 +787,8 @@ int main(int argc, char ** argv) putc(1,midi_file); // number of tracks - putc(0,midi_file); - putc(tracknum,midi_file); + putc((tracknum>>8)&0xFF,midi_file); + putc(tracknum&0xFF,midi_file); // ppqn if(ppqn==0) // if unset From 3112a8405f0d4e7b92d2e6661517d8bdba437f1a Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 15 Jan 2016 14:57:57 +0100 Subject: [PATCH 15/17] added 0xD6 event --- src/BMS_DEC.C | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index 2f74d55..a1de8a8 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -388,6 +388,9 @@ int parse_ev(FILE * in, FILE * out) notes[ppid]=note; unsigned char vol = getc(in); putc(vol,out); + + if(note==0x58&¤t_channel==0xb) + {puts("break");} tracksz[tracknum]+=3; } @@ -585,6 +588,10 @@ int parse_ev(FILE * in, FILE * out) /*fall through*/ case 0xCF: /*fall through*/ + case 0xD6: // new + // seems to be always 0x0 + // followed by 0xF0 delay event + /*fall through*/ case 0xDA: /*fall through*/ case 0xDB: From 3a6535322404405ee05443aac774d88d00aaae18 Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 15 Jan 2016 17:03:41 +0100 Subject: [PATCH 16/17] fixed a very ugly bug which can avoid the parser from finding end of tracks --- src/BMS_DEC.C | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index a1de8a8..cbc5316 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -648,8 +648,6 @@ int parse_ev(FILE * in, FILE * out) /*fall through*/ case 0xD8:// NEW! /*fall through*/ - case 0xDD: - /*fall through*/ case 0xEF: fseek(in,3,SEEK_CUR); break; @@ -664,6 +662,10 @@ int parse_ev(FILE * in, FILE * out) /*fall through*/ case 0xC8: /*fall through*/ + case 0xDD: + // HAHA, not 3 bytes but 4 bytes are followed by 0xDD event + // used LuigiSings.bms to verify (at offset 0x1A0) + /*fall through*/ case 0xDF: fseek(in,4,SEEK_CUR); break; From bdb22c0b030ba6964f6d3b4d901f197c231fd5e2 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 16 Jan 2016 14:06:02 +0100 Subject: [PATCH 17/17] added event 0xD9 --- src/BMS_DEC.C | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/BMS_DEC.C b/src/BMS_DEC.C index cbc5316..70808af 100644 --- a/src/BMS_DEC.C +++ b/src/BMS_DEC.C @@ -592,6 +592,9 @@ int parse_ev(FILE * in, FILE * out) // seems to be always 0x0 // followed by 0xF0 delay event /*fall through*/ + case 0xD9: + // LuigiSe.bms + /*fall through*/ case 0xDA: /*fall through*/ case 0xDB: