OSDN Git Service

WIP: Add loop events
authorStarg <starg@users.osdn.me>
Thu, 12 Dec 2019 23:10:59 +0000 (08:10 +0900)
committerStarg <starg@users.osdn.me>
Sat, 1 Feb 2020 20:23:13 +0000 (05:23 +0900)
timidity/output.h
timidity/playmidi.c
timidity/playmidi.h
timidity/readmidi.c
timidity/vorbis_a.c

index 640c966..0e2947e 100644 (file)
@@ -125,6 +125,13 @@ enum {
 
     PM_REQ_DIVISIONS,    /* ARG: int32* - pointer to divisions number
                          */
+
+    PM_REQ_LOOP_START,    /* ARG: int32
+              * offset of ME_LOOP_EXPANSION_START in samples
+              */
+    PM_REQ_LOOP_END,      /* ARG: int32
+              * offset of ME_LOOP_EXPANSION_END in samples
+              */
 };
 
 
index 1cf0d89..f54bad0 100644 (file)
@@ -841,6 +841,8 @@ static char *event_name(int type)
        EVENT_NAME(ME_SHERRY);
        EVENT_NAME(ME_BARMARKER);
        EVENT_NAME(ME_STEP);
+       EVENT_NAME(ME_LOOP_EXPANSION_START);
+       EVENT_NAME(ME_LOOP_EXPANSION_END);
        EVENT_NAME(ME_LAST);
        EVENT_NAME(ME_EOT);
        }
@@ -13171,6 +13173,14 @@ int play_event(MidiEvent *ev){
                set_cuepoint(ch, current_event->a, current_event->b);
                break;
 
+       case ME_LOOP_EXPANSION_START:
+               play_mode->acntl(PM_REQ_LOOP_START, (void *)current_event->time);
+               break;
+
+       case ME_LOOP_EXPANSION_END:
+               play_mode->acntl(PM_REQ_LOOP_END, (void *)current_event->time);
+               break;
+
        case ME_EOT:
                ctl_mode_event(CTLE_CURRENT_TIME_END, 0, (long)(current_sample / (midi_time_ratio * play_mode->rate)), 0);
                return midi_play_end();
index 8c5fa29..b5d75e7 100644 (file)
@@ -162,6 +162,9 @@ enum midi_event_t
        ME_SHERRY,                              /* for Sherry WRD tracer */
        ME_BARMARKER,
        ME_STEP,                                /* for Metronome */
+
+       ME_LOOP_EXPANSION_START, /* start of expanded loops */
+       ME_LOOP_EXPANSION_END,  /* end of expanded loops */
        
        ME_LAST = 254,                  /* Last sequence of MIDI list.
                                                         * This event is reserved for realtime player.
index aa6f91c..f5290ec 100644 (file)
@@ -5727,7 +5727,7 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
     };
     int loop_type;
     const int loop_filter = opt_use_midi_loop_repeat;
-    int loop_startflag;
+    int loop_startflag;        // 1 == end, 2 == start
 #endif /* SUPPORT_LOOPEVENT */
 
     move_channels(chidx);
@@ -6651,10 +6651,11 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                           "ME_LOOP_START: %d", loop_begin_time);
                 groomed_list = lp =
                     (MidiEvent*) safe_large_realloc(groomed_list, sizeof(MidiEvent) * (event_count +
-                        (loop_end_event_count - loop_begin_event_count) *
+                        (loop_end_event_count - loop_begin_event_count + 1) *
                             loop_repeat_counter + 1));
                 lp += our_event_count;
-            }
+                               loop_startflag = 2;
+                       }
             skip_this_event = 1;
             break;
 
@@ -6670,7 +6671,8 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                     loop_begin_time = meep->event.time;
                     loop_startmeep = meep;
                     loop_begin_event_count = i;
-                }
+                                       loop_startflag = 2;
+                               }
             }
             skip_this_event = 1;
             break;
@@ -6686,7 +6688,7 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                         loop_end_event_count = i;
                         groomed_list = lp =
                             (MidiEvent*) safe_large_realloc(groomed_list, sizeof(MidiEvent) * (event_count +
-                                (loop_end_event_count - loop_begin_event_count) *
+                                (loop_end_event_count - loop_begin_event_count + 1) *
                                     loop_repeat_counter + 1));
                         lp += our_event_count;
                     }
@@ -6715,7 +6717,8 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                         loop_begin_time = meep->event.time;
                         loop_startmeep = meep;
                         loop_begin_event_count = i;
-                    }
+                                               loop_startflag = 2;
+                                       }
                     skip_this_event = 1;
                 }
                 if (strcmp(text + 1, "(B)") == 0) {
@@ -6728,7 +6731,7 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                             loop_end_event_count = i;
                             groomed_list = lp =
                                 (MidiEvent*) safe_large_realloc(groomed_list, sizeof(MidiEvent) * (event_count +
-                                    (loop_end_event_count - loop_begin_event_count) *
+                                    (loop_end_event_count - loop_begin_event_count + 1) *
                                         loop_repeat_counter + 1));
                             lp += our_event_count;
                         }
@@ -6751,7 +6754,8 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                         loop_begin_time = meep->event.time;
                         loop_startmeep = meep;
                         loop_begin_event_count = i;
-                    }
+                                               loop_startflag = 2;
+                                       }
                     skip_this_event = 1;
                 }
                 if (strcmp(text + 1, "(Loop_End)") == 0) {
@@ -6764,7 +6768,7 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
                             loop_end_event_count = i;
                             groomed_list = lp =
                                 (MidiEvent*) safe_large_realloc(groomed_list, sizeof(MidiEvent) * (event_count +
-                                    (loop_end_event_count - loop_begin_event_count) *
+                                    (loop_end_event_count - loop_begin_event_count + 1) *
                                         loop_repeat_counter + 1));
                             lp += our_event_count;
                         }
@@ -6901,17 +6905,36 @@ static MidiEvent *groom_list(int32 divisions, int32 *eventsp, int32 *samplesp)
         }
 
         if (loop_startflag) {
-            if (loop_startmeep) {
-                if (loop_end_time == 0)
-                    loop_end_time = at;
-                loop_add_at += (loop_end_time - loop_begin_time);
-                meep = loop_startmeep->next;
-                ctl->cmsg(CMSG_INFO, VERB_DEBUG,
-                          "Loop jump: from %d, to %d",
-                          loop_end_time,
-                          meep->event.time);
-            }
-            loop_repeat_counter--;
+                       if (loop_startflag == 2) {
+                               *lp = meep->event;
+                               lp->time = st;
+                               lp->type = ME_LOOP_EXPANSION_START;
+                               lp->a = loop_type;
+                               lp->b = (opt_use_midi_loop_repeat ? opt_midi_loop_repeat - loop_repeat_counter : 0);
+                               lp++;
+                               our_event_count++;
+                       }
+                       else if (loop_startflag == 1) {
+                               if (loop_startmeep) {
+                                       *lp = meep->event;
+                                       lp->time = st;
+                                       lp->type = ME_LOOP_EXPANSION_END;
+                                       lp->a = loop_type;
+                                       lp->b = (opt_use_midi_loop_repeat ? opt_midi_loop_repeat - loop_repeat_counter : 0);
+                                       lp++;
+                                       our_event_count++;
+
+                                       if (loop_end_time == 0)
+                                               loop_end_time = at;
+                                       loop_add_at += (loop_end_time - loop_begin_time);
+                                       meep = loop_startmeep->next;
+                                       ctl->cmsg(CMSG_INFO, VERB_DEBUG,
+                                               "Loop jump: from %d, to %d",
+                                               loop_end_time,
+                                               meep->event.time);
+                               }
+                               loop_repeat_counter--;
+                       }
             loop_startflag = 0;
         }
 #endif /* SUPPORT_LOOPEVENT */
index be99dff..dec1874 100644 (file)
@@ -107,6 +107,9 @@ static      vorbis_info      vi; /* struct that stores all the static vorbis bitstream
                                settings */
 static vorbis_comment   vc; /* struct that stores all the user comments */
 
+static int32 loopstart;
+static int32 looplength;
+
 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
 extern char *w32g_output_dir;
 extern int w32g_auto_output_mode;
@@ -520,6 +523,13 @@ static int acntl(int request, void *arg)
     return 0;
   case PM_REQ_DISCARD:
     return 0;
+  case PM_REQ_LOOP_START:
+       loopstart = (int32)arg;
+       looplength = 0;
+    return 0;
+  case PM_REQ_LOOP_END:
+       looplength = (int32)arg - loopstart;
+    return 0;
   }
   return -1;
 }