• R/O
  • HTTP
  • SSH
  • HTTPS

Alchemusica: Commit

Free MIDI Sequencer for Mac


Commit MetaInfo

Revisión8e83768f0bb0fe4427586e689eaca24b075c6eea (tree)
Tiempo2022-08-06 22:35:51
AutorToshi Nagata <alchemist.2005@nift...>
CommiterToshi Nagata

Log Message

Move selected events command is implemented

Cambiar Resumen

Diferencia incremental

--- a/Ruby_Scripts/200.commands.rb
+++ b/Ruby_Scripts/200.commands.rb
@@ -293,9 +293,58 @@ def create_tremolo
293293 end
294294 end
295295
296+@@move_selected_events_to_track_no = 1
297+
298+def move_selected_events_to_track
299+ values = [@@move_selected_events_to_track_no]
300+ names = []
301+ each_with_index { |tr, i|
302+ next if i == 0
303+ names.push("#{i}:#{tr.name}")
304+ }
305+ hash = Dialog.run("Move to Track") {
306+ layout(1,
307+ layout(2,
308+ item(:text, :title=>"To track"),
309+ item(:popup, :subitems=>names, :tag=>"totrack", :value=>values[0] - 1)))
310+ }
311+ # p hash
312+ if hash[:status] == 0
313+ count = 0
314+ each_with_index { |tr, i|
315+ next if i == 0
316+ if tr.selection.length > 0
317+ count = count + 1
318+ end
319+ }
320+ if count == 0
321+ message_box("No movable events", "Cannot move events", :ok, :error)
322+ return
323+ end
324+ if count > 1
325+ if !message_box("Selected events are contained in #{count} tracks. Do you want to move all selected events to one track?")
326+ return
327+ end
328+ end
329+ totrack = hash["totrack"].to_i + 1
330+ @@move_selected_events_to_track_no = totrack
331+ trnew = Track.new
332+ trdest = track(totrack)
333+ each_with_index { |tr, i|
334+ next if i == 0 || tr.selection.length == 0
335+ tr.each_selected { |p|
336+ trnew.add(p.tick, p)
337+ }
338+ tr.cut(tr.selection)
339+ }
340+ trdest.merge(trnew)
341+ end
342+end
343+
296344 end
297345
298346 register_menu("Change Timebase...", :change_timebase)
299347 register_menu("Randomize Ticks...", :randomize_ticks, 1)
300348 register_menu("Thin Selected Events...", :thin_events, 1)
301349 register_menu("Create tremolo...", :create_tremolo, 1)
350+register_menu("Move selected events to track...", :move_selected_events_to_track, 1)
--- a/Ruby_bindings/MDRubyTrack.m
+++ b/Ruby_bindings/MDRubyTrack.m
@@ -725,6 +725,7 @@ s_raise_if_missing_parameter(int argc, int expect_argc, const char *msg)
725725 * call-seq:
726726 * track.add(tick, type, data,...) -> self
727727 * track << [tick, type, data,...] -> self
728+ * track.add(tick, pointer) -> self
728729 *
729730 * Create a new midi event. Type is an integer or a note-number string for note events,
730731 * and a symbol for other events.
@@ -745,6 +746,7 @@ s_raise_if_missing_parameter(int argc, int expect_argc, const char *msg)
745746 * :pitch_bend value (-8192..8191)
746747 * :channel_pressure value
747748 * :key_pressure note_on (Integer) or note_name (String), value
749+ * If the second argument is a pointer, then a copy of the event is created and added to the track.
748750 */
749751 static VALUE
750752 s_MRTrack_Add(VALUE self, VALUE sval)
@@ -767,199 +769,205 @@ s_MRTrack_Add(VALUE self, VALUE sval)
767769 tick = NUM2INT(rb_Integer(argv[0]));
768770 if (tick < 0)
769771 rb_raise(rb_eArgError, "the tick value must be non-negative");
770- kind = MREventKindAndCodeFromEventSymbol(argv[1], &code, &is_generic);
771- if (kind < 0) {
772- volatile VALUE v = rb_inspect(argv[1]);
773- rb_raise(rb_eArgError, "unknown event type: %s", StringValuePtr(v));
774- }
775- eobj = [[[MDEventObject alloc] init] autorelease];
776- ep = [eobj eventPtr];
777- MDSetTick(ep, tick);
778- MDSetKind(ep, kind);
779- argc -= 2;
780- argv += 2;
781- switch (kind) {
782- case kMDEventNote:
783- if (is_generic) {
784- s_raise_if_missing_parameter(argc, 3, "note number, duration, velocity");
785- if (FIXNUM_P(argv[0]))
786- code = FIX2INT(argv[0]);
787- else
788- code = MDEventNoteNameToNoteNumber(StringValuePtr(argv[0]));
789- if (code < 0 || code >= 128)
790- rb_raise(rb_eArgError, "note number (%d) out of range", code);
791- argc--;
792- argv++;
793- } else s_raise_if_missing_parameter(argc, 2, "duration, velocity");
794- MDSetCode(ep, code);
795- n1 = NUM2INT(rb_Integer(argv[0]));
796- n2 = NUM2INT(rb_Integer(argv[1]));
797- if (n1 <= 0)
798- rb_raise(rb_eArgError, "note duration (%d) must be positive", n1);
799- if (n2 <= 0 || n2 >= 128)
800- rb_raise(rb_eArgError, "note velocity (%d) is out of range", n2);
801- MDSetDuration(ep, n1);
802- MDSetNoteOnVelocity(ep, n2);
803- if (argc > 2) {
804- n1 = NUM2INT(rb_Integer(argv[2]));
805- if (n1 < 0 || n1 >= 128)
806- rb_raise(rb_eArgError, "release velocity (%d) is out of range", n1);
807- MDSetNoteOffVelocity(ep, n1);
808- }
809- break;
810- case kMDEventTempo:
811- s_raise_if_missing_parameter(argc, 1, "tempo");
812- MDSetTempo(ep, (float)NUM2DBL(rb_Float(argv[0])));
813- break;
814- case kMDEventTimeSignature:
815- s_raise_if_missing_parameter(argc, 2, "n/m");
816- ucp = MDGetMetaDataPtr(ep);
817- ucp[0] = NUM2INT(rb_Integer(argv[0]));
818- ucp[1] = NUM2INT(rb_Integer(argv[1]));
819- if (argc > 2)
820- ucp[2] = NUM2INT(rb_Integer(argv[2]));
821- if (argc > 3)
822- ucp[3] = NUM2INT(rb_Integer(argv[3]));
823- break;
824- case kMDEventKey:
825- s_raise_if_missing_parameter(argc, 2, "number of accidentals, major/minor");
826- ucp = MDGetMetaDataPtr(ep);
827- ucp[0] = NUM2INT(rb_Integer(argv[0]));
828- if (ucp[0] + 7 > 14)
829- rb_raise(rb_eArgError, "number of accidentals (%d) is out of range", (int)(signed char)ucp[0]);
830- if ((n1 = TYPE(argv[1])) == T_STRING || n1 == T_SYMBOL) {
831- p = StringValuePtr(argv[1]);
832- if (strcasecmp(p, "major") == 0)
833- ucp[1] = 0;
834- else if (strcasecmp(p, "minor") == 0)
835- ucp[1] = 1;
836- else
837- rb_raise(rb_eArgError, "unknown word '%s' for key specification", p);
838- } else ucp[1] = (0 != NUM2INT(rb_Integer(argv[1])));
839- break;
840- case kMDEventSMPTE:
841- s_raise_if_missing_parameter(argc, 5, "hour, min, sec, frame, subframe");
842- smp = MDGetSMPTERecordPtr(ep);
843- smp->hour = NUM2INT(rb_Integer(argv[0]));
844- smp->min = NUM2INT(rb_Integer(argv[1]));
845- smp->sec = NUM2INT(rb_Integer(argv[2]));
846- smp->frame = NUM2INT(rb_Integer(argv[3]));
847- smp->subframe = NUM2INT(rb_Integer(argv[4]));
848- break;
849- case kMDEventPortNumber:
850- s_raise_if_missing_parameter(argc, 1, "port number");
851- MDSetData1(ep, NUM2INT(rb_Integer(argv[0])));
852- break;
853- case kMDEventMetaText:
854- if (is_generic) {
855- s_raise_if_missing_parameter(argc, 2, "text kind number (0-15), string");
856- code = NUM2INT(rb_Integer(argv[0]));
857- argc--;
858- argv++;
859- } else s_raise_if_missing_parameter(argc, 1, "string");
860- if (code < 0 || code > 15)
861- rb_raise(rb_eArgError, "text kind number (%d) is out of range", code);
862- MDSetCode(ep, code);
863- StringValue(argv[0]);
864- MDSetMessageLength(ep, (int)RSTRING_LEN(argv[0]));
865- MDSetMessage(ep, (unsigned char *)(RSTRING_PTR(argv[0])));
866- break;
867- case kMDEventMetaMessage:
868- case kMDEventSysex:
869- case kMDEventSysexCont:
870- if (kind == kMDEventMetaMessage) {
871- s_raise_if_missing_parameter(argc, 2, "code, string or array of integers");
872- code = NUM2INT(rb_Integer(argv[0]));
873- if (code < 16 || code > 127)
874- rb_raise(rb_eArgError, "meta code (%d) is out of range", code);
875- MDSetCode(ep, code);
876- argc--;
877- argv++;
878- } else {
879- s_raise_if_missing_parameter(argc, 1, "string or array of integers");
880- }
881- if ((n1 = TYPE(argv[0])) == T_STRING) {
882- n2 = (int)RSTRING_LEN(argv[0]);
883- ucp = (unsigned char *)(RSTRING_PTR(argv[0]));
884- } else {
885- val = rb_ary_to_ary(argv[0]);
886- n2 = (int)RARRAY_LEN(val);
887- ucp = (unsigned char *)malloc(n2);
888- for (n3 = 0; n3 < n2; n3++)
889- ucp[n3] = NUM2INT(rb_Integer(RARRAY_PTR(val)[n3]));
890- }
891- if (n2 > 0) {
892- if (kind == kMDEventSysex || kind == kMDEventSysexCont) {
893- if (kind == kMDEventSysex) {
894- if (ucp[0] != 0xf0)
895- rb_raise(rb_eArgError, "sysex must start with 0xf0");
896- n3 = 1;
897- } else n3 = 0;
898- for ( ; n3 < n2; n3++) {
899- if (ucp[n3] >= 128 && (n3 != n2 - 1 || ucp[n3] != 0xf7))
900- rb_raise(rb_eArgError, "sysex must not contain numbers >= 128");
901- }
902- }
903- }
904- MDSetMessageLength(ep, n2);
905- MDSetMessage(ep, ucp);
906- if (n1 != T_STRING)
907- free(ucp);
908- break;
909- case kMDEventProgram:
910- s_raise_if_missing_parameter(argc, 1, "program number");
911- n1 = NUM2INT(rb_Integer(argv[0]));
912- if (n1 < 0 || n1 >= 128)
913- rb_raise(rb_eArgError, "program number (%d) is out of range", n1);
914- MDSetData1(ep, n1);
915- break;
916- case kMDEventControl:
917- if (is_generic) {
918- s_raise_if_missing_parameter(argc, 2, "control number, value");
919- code = NUM2INT(rb_Integer(argv[0]));
920- argc--;
921- argv++;
922- } else s_raise_if_missing_parameter(argc, 1, "control value");
923- if (code < 0 || code >= 128)
924- rb_raise(rb_eArgError, "control code (%d) is out of range", code);
925- n1 = NUM2INT(rb_Integer(argv[0]));
926- if (n1 < 0 || n1 >= 128)
927- rb_raise(rb_eArgError, "control value (%d) is out of range", n1);
928- MDSetCode(ep, code);
929- MDSetData1(ep, n1);
930- break;
931- case kMDEventPitchBend:
932- s_raise_if_missing_parameter(argc, 1, "pitch bend");
933- n1 = NUM2INT(rb_Integer(argv[0]));
934- if (n1 < -8192 || n1 >= 8192)
935- rb_raise(rb_eArgError, "pitch bend value (%d) is out of range", n1);
936- MDSetData1(ep, n1);
937- break;
938- case kMDEventChanPres:
939- s_raise_if_missing_parameter(argc, 1, "channel pressure");
940- n1 = NUM2INT(rb_Integer(argv[0]));
941- if (n1 < 0 || n1 >= 128)
942- rb_raise(rb_eArgError, "channel pressure value (%d) is out of range", n1);
943- MDSetData1(ep, n1);
944- break;
945- case kMDEventKeyPres:
946- s_raise_if_missing_parameter(argc, 2, "note number, key pressure");
947- if (FIXNUM_P(argv[0]))
948- code = FIX2INT(argv[0]);
949- else
950- code = MDEventNoteNameToNoteNumber(StringValuePtr(argv[0]));
951- if (code < 0 || code >= 128)
952- rb_raise(rb_eArgError, "note number (%d) out of range", code);
953- n1 = NUM2INT(rb_Integer(argv[1]));
954- if (n1 < 0 || n1 >= 128)
955- rb_raise(rb_eArgError, "key pressure value (%d) is out of range", n1);
956- MDSetCode(ep, code);
957- MDSetData1(ep, n1);
958- break;
959- default:
960- rb_raise(rb_eArgError, "internal error? unknown event kind (%d)", kind);
961- }
962-
772+ eobj = [[[MDEventObject alloc] init] autorelease];
773+ ep = [eobj eventPtr];
774+ MDSetTick(ep, tick);
775+ if (rb_obj_is_kind_of(argv[1], rb_cMRPointer)) {
776+ MDPointer *ptsrc = MDPointerFromMRPointerValue(argv[1]);
777+ MDEvent *epsrc = MDPointerCurrent(ptsrc);
778+ MDEventCopy(ep, epsrc, 1);
779+ } else {
780+ kind = MREventKindAndCodeFromEventSymbol(argv[1], &code, &is_generic);
781+ if (kind < 0) {
782+ volatile VALUE v = rb_inspect(argv[1]);
783+ rb_raise(rb_eArgError, "unknown event type: %s", StringValuePtr(v));
784+ }
785+ MDSetKind(ep, kind);
786+ argc -= 2;
787+ argv += 2;
788+ switch (kind) {
789+ case kMDEventNote:
790+ if (is_generic) {
791+ s_raise_if_missing_parameter(argc, 3, "note number, duration, velocity");
792+ if (FIXNUM_P(argv[0]))
793+ code = FIX2INT(argv[0]);
794+ else
795+ code = MDEventNoteNameToNoteNumber(StringValuePtr(argv[0]));
796+ if (code < 0 || code >= 128)
797+ rb_raise(rb_eArgError, "note number (%d) out of range", code);
798+ argc--;
799+ argv++;
800+ } else s_raise_if_missing_parameter(argc, 2, "duration, velocity");
801+ MDSetCode(ep, code);
802+ n1 = NUM2INT(rb_Integer(argv[0]));
803+ n2 = NUM2INT(rb_Integer(argv[1]));
804+ if (n1 <= 0)
805+ rb_raise(rb_eArgError, "note duration (%d) must be positive", n1);
806+ if (n2 <= 0 || n2 >= 128)
807+ rb_raise(rb_eArgError, "note velocity (%d) is out of range", n2);
808+ MDSetDuration(ep, n1);
809+ MDSetNoteOnVelocity(ep, n2);
810+ if (argc > 2) {
811+ n1 = NUM2INT(rb_Integer(argv[2]));
812+ if (n1 < 0 || n1 >= 128)
813+ rb_raise(rb_eArgError, "release velocity (%d) is out of range", n1);
814+ MDSetNoteOffVelocity(ep, n1);
815+ }
816+ break;
817+ case kMDEventTempo:
818+ s_raise_if_missing_parameter(argc, 1, "tempo");
819+ MDSetTempo(ep, (float)NUM2DBL(rb_Float(argv[0])));
820+ break;
821+ case kMDEventTimeSignature:
822+ s_raise_if_missing_parameter(argc, 2, "n/m");
823+ ucp = MDGetMetaDataPtr(ep);
824+ ucp[0] = NUM2INT(rb_Integer(argv[0]));
825+ ucp[1] = NUM2INT(rb_Integer(argv[1]));
826+ if (argc > 2)
827+ ucp[2] = NUM2INT(rb_Integer(argv[2]));
828+ if (argc > 3)
829+ ucp[3] = NUM2INT(rb_Integer(argv[3]));
830+ break;
831+ case kMDEventKey:
832+ s_raise_if_missing_parameter(argc, 2, "number of accidentals, major/minor");
833+ ucp = MDGetMetaDataPtr(ep);
834+ ucp[0] = NUM2INT(rb_Integer(argv[0]));
835+ if (ucp[0] + 7 > 14)
836+ rb_raise(rb_eArgError, "number of accidentals (%d) is out of range", (int)(signed char)ucp[0]);
837+ if ((n1 = TYPE(argv[1])) == T_STRING || n1 == T_SYMBOL) {
838+ p = StringValuePtr(argv[1]);
839+ if (strcasecmp(p, "major") == 0)
840+ ucp[1] = 0;
841+ else if (strcasecmp(p, "minor") == 0)
842+ ucp[1] = 1;
843+ else
844+ rb_raise(rb_eArgError, "unknown word '%s' for key specification", p);
845+ } else ucp[1] = (0 != NUM2INT(rb_Integer(argv[1])));
846+ break;
847+ case kMDEventSMPTE:
848+ s_raise_if_missing_parameter(argc, 5, "hour, min, sec, frame, subframe");
849+ smp = MDGetSMPTERecordPtr(ep);
850+ smp->hour = NUM2INT(rb_Integer(argv[0]));
851+ smp->min = NUM2INT(rb_Integer(argv[1]));
852+ smp->sec = NUM2INT(rb_Integer(argv[2]));
853+ smp->frame = NUM2INT(rb_Integer(argv[3]));
854+ smp->subframe = NUM2INT(rb_Integer(argv[4]));
855+ break;
856+ case kMDEventPortNumber:
857+ s_raise_if_missing_parameter(argc, 1, "port number");
858+ MDSetData1(ep, NUM2INT(rb_Integer(argv[0])));
859+ break;
860+ case kMDEventMetaText:
861+ if (is_generic) {
862+ s_raise_if_missing_parameter(argc, 2, "text kind number (0-15), string");
863+ code = NUM2INT(rb_Integer(argv[0]));
864+ argc--;
865+ argv++;
866+ } else s_raise_if_missing_parameter(argc, 1, "string");
867+ if (code < 0 || code > 15)
868+ rb_raise(rb_eArgError, "text kind number (%d) is out of range", code);
869+ MDSetCode(ep, code);
870+ StringValue(argv[0]);
871+ MDSetMessageLength(ep, (int)RSTRING_LEN(argv[0]));
872+ MDSetMessage(ep, (unsigned char *)(RSTRING_PTR(argv[0])));
873+ break;
874+ case kMDEventMetaMessage:
875+ case kMDEventSysex:
876+ case kMDEventSysexCont:
877+ if (kind == kMDEventMetaMessage) {
878+ s_raise_if_missing_parameter(argc, 2, "code, string or array of integers");
879+ code = NUM2INT(rb_Integer(argv[0]));
880+ if (code < 16 || code > 127)
881+ rb_raise(rb_eArgError, "meta code (%d) is out of range", code);
882+ MDSetCode(ep, code);
883+ argc--;
884+ argv++;
885+ } else {
886+ s_raise_if_missing_parameter(argc, 1, "string or array of integers");
887+ }
888+ if ((n1 = TYPE(argv[0])) == T_STRING) {
889+ n2 = (int)RSTRING_LEN(argv[0]);
890+ ucp = (unsigned char *)(RSTRING_PTR(argv[0]));
891+ } else {
892+ val = rb_ary_to_ary(argv[0]);
893+ n2 = (int)RARRAY_LEN(val);
894+ ucp = (unsigned char *)malloc(n2);
895+ for (n3 = 0; n3 < n2; n3++)
896+ ucp[n3] = NUM2INT(rb_Integer(RARRAY_PTR(val)[n3]));
897+ }
898+ if (n2 > 0) {
899+ if (kind == kMDEventSysex || kind == kMDEventSysexCont) {
900+ if (kind == kMDEventSysex) {
901+ if (ucp[0] != 0xf0)
902+ rb_raise(rb_eArgError, "sysex must start with 0xf0");
903+ n3 = 1;
904+ } else n3 = 0;
905+ for ( ; n3 < n2; n3++) {
906+ if (ucp[n3] >= 128 && (n3 != n2 - 1 || ucp[n3] != 0xf7))
907+ rb_raise(rb_eArgError, "sysex must not contain numbers >= 128");
908+ }
909+ }
910+ }
911+ MDSetMessageLength(ep, n2);
912+ MDSetMessage(ep, ucp);
913+ if (n1 != T_STRING)
914+ free(ucp);
915+ break;
916+ case kMDEventProgram:
917+ s_raise_if_missing_parameter(argc, 1, "program number");
918+ n1 = NUM2INT(rb_Integer(argv[0]));
919+ if (n1 < 0 || n1 >= 128)
920+ rb_raise(rb_eArgError, "program number (%d) is out of range", n1);
921+ MDSetData1(ep, n1);
922+ break;
923+ case kMDEventControl:
924+ if (is_generic) {
925+ s_raise_if_missing_parameter(argc, 2, "control number, value");
926+ code = NUM2INT(rb_Integer(argv[0]));
927+ argc--;
928+ argv++;
929+ } else s_raise_if_missing_parameter(argc, 1, "control value");
930+ if (code < 0 || code >= 128)
931+ rb_raise(rb_eArgError, "control code (%d) is out of range", code);
932+ n1 = NUM2INT(rb_Integer(argv[0]));
933+ if (n1 < 0 || n1 >= 128)
934+ rb_raise(rb_eArgError, "control value (%d) is out of range", n1);
935+ MDSetCode(ep, code);
936+ MDSetData1(ep, n1);
937+ break;
938+ case kMDEventPitchBend:
939+ s_raise_if_missing_parameter(argc, 1, "pitch bend");
940+ n1 = NUM2INT(rb_Integer(argv[0]));
941+ if (n1 < -8192 || n1 >= 8192)
942+ rb_raise(rb_eArgError, "pitch bend value (%d) is out of range", n1);
943+ MDSetData1(ep, n1);
944+ break;
945+ case kMDEventChanPres:
946+ s_raise_if_missing_parameter(argc, 1, "channel pressure");
947+ n1 = NUM2INT(rb_Integer(argv[0]));
948+ if (n1 < 0 || n1 >= 128)
949+ rb_raise(rb_eArgError, "channel pressure value (%d) is out of range", n1);
950+ MDSetData1(ep, n1);
951+ break;
952+ case kMDEventKeyPres:
953+ s_raise_if_missing_parameter(argc, 2, "note number, key pressure");
954+ if (FIXNUM_P(argv[0]))
955+ code = FIX2INT(argv[0]);
956+ else
957+ code = MDEventNoteNameToNoteNumber(StringValuePtr(argv[0]));
958+ if (code < 0 || code >= 128)
959+ rb_raise(rb_eArgError, "note number (%d) out of range", code);
960+ n1 = NUM2INT(rb_Integer(argv[1]));
961+ if (n1 < 0 || n1 >= 128)
962+ rb_raise(rb_eArgError, "key pressure value (%d) is out of range", n1);
963+ MDSetCode(ep, code);
964+ MDSetData1(ep, n1);
965+ break;
966+ default:
967+ rb_raise(rb_eArgError, "internal error? unknown event kind (%d)", kind);
968+ }
969+ }
970+
963971 /* Insert the new event to the track */
964972 if (ip->doc != nil) {
965973 [ip->doc insertEvent: eobj toTrack: ip->num];
Show on old repository browser