-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PakettiPatternEditor.lua
4396 lines (3695 loc) · 195 KB
/
PakettiPatternEditor.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
-- Function to mute or unmute the selected note column
function muteUnmuteNoteColumn()
-- Access the song object
local s = renoise.song()
-- Get the selected track and note column indices
local sti = s.selected_track_index
local snci = s.selected_note_column_index
-- Check if a note column is selected
if snci == 0 then
return
else
-- Access the selected track
local track = s:track(sti)
-- Check if the note column is muted and toggle its state
if track:column_is_muted(snci) then
track:set_column_is_muted(snci, false)
else
track:set_column_is_muted(snci, true)
end
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Mute/Unmute Note Column", invoke=function() muteUnmuteNoteColumn() end}
function voloff()
local s = renoise.song()
local currColumn = renoise.song().selected_note_column_index
if renoise.song().selected_effect_column == nil
then renoise.song().selected_effect_column_index=1
else end
local efc = s.selected_effect_column
local currTrak=s.selected_track_index
local currLine=s.selected_line_index
local currPatt=s.selected_pattern_index
local ns=efc.number_string
local as=efc.amount_string
if renoise.song().selected_track.type==2 or renoise.song().selected_track.type==3 or renoise.song().selected_track.type==4 then
return
else
-- if s.selected_effect_column=="" then
if renoise.song().selected_effect_column.number_string=="0L" then
renoise.song().selected_effect_column.number_string ="00"
else
renoise.song().selected_effect_column.number_string ="0L"
renoise.song().selected_effect_column.amount_string ="00"
end
end
renoise.song().selected_note_column_index = 1
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column L00 Track Volume Level 0 On/Off",invoke=function() voloff() end}
---------------
function RecordFollowOffPattern()
local t=renoise.song().transport
local w = renoise.app().window
--w.active_middle_frame = 1
if t.edit_mode == false then t.edit_mode=true else t.edit_mode=false end
if t.follow_player == false then return else t.follow_player=false end end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Record+Follow Off",invoke=function() RecordFollowOffPattern() end}
-- Set Delay +1 / -1 / +10 / -10 on current_row, display delay column
function delayInput(chg)
local s=renoise.song()
local d=s.selected_note_column.delay_value
local nc=s.selected_note_column
local currTrak=s.selected_track_index
s.tracks[currTrak].delay_column_visible=true
--nc.delay_value=(d+chg)
--if nc.delay_value == 0 and chg < 0 then
--move_up(chg)
--elseif nc.delay_value == 255 and chg > 0 then
--move_down(chg)
--else
-- nc.delay_value
nc.delay_value = math.max(0, math.min(255, d + chg))
--end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Delay Column Increase (+1)",invoke=function() delayInput(1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Delay Column Decrease (-1)",invoke=function() delayInput(-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Delay Column Increase (+10)",invoke=function() delayInput(10) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Delay Column Decrease (-10)",invoke=function() delayInput(-10) end}
----
--Quantize +1 / -1
function adjust_quantize(quant_delta)
local t = renoise.song().transport
local counted = nil
counted=t.record_quantize_lines+quant_delta
if counted == 0 then
t.record_quantize_enabled=false return end
if t.record_quantize_enabled==false and t.record_quantize_lines == 1 then
t.record_quantize_lines = 1
t.record_quantize_enabled=true
return end
t.record_quantize_lines=math.max(1, math.min(32, t.record_quantize_lines + quant_delta))
t.record_quantize_enabled=true
renoise.app():show_status("Record Quantize Lines : " .. t.record_quantize_lines)
end
renoise.tool():add_keybinding{name="Global:Paketti:Quantization Decrease (-1)",invoke=function() adjust_quantize(-1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:Quantization Increase (+1)",invoke=function() adjust_quantize(1, 0) end}
-------
-- +1/-1 on Metronome LPB and Metronome BPB (loads of help from dblue)
function adjust_metronome(lpb_delta, bpb_delta)
-- Local reference to transport
local t = renoise.song().transport
t.metronome_lines_per_beat = math.max(1, math.min(16, t.metronome_lines_per_beat + lpb_delta))
t.metronome_beats_per_bar = math.max(1, math.min(16, t.metronome_beats_per_bar + bpb_delta))
-- Show status
t.metronome_enabled = true
renoise.app():show_status("Metronome LPB: " .. t.metronome_lines_per_beat .. " BPB : " .. t.metronome_beats_per_bar) end
--dblue modified to be lpb/tpl
function adjust_lpb_bpb(lpb_delta, tpl_delta)
local t = renoise.song().transport
t.lpb = math.max(1, math.min(256, t.lpb + lpb_delta))
t.tpl = math.max(1, math.min(16, t.tpl + tpl_delta))
-- renoise.song().transport.metronome_enabled = true
renoise.app():show_status("LPB: " .. t.lpb .. " TPL : " .. t.tpl) end
renoise.tool():add_keybinding{name="Global:Paketti:Metronome LPB Decrease (-1)",invoke=function() adjust_metronome(-1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:Metronome LPB Increase (+1)",invoke=function() adjust_metronome(1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:Metronome BPB Decrease (-1)",invoke=function() adjust_metronome(0, -1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Metronome BPB Increase (+1)",invoke=function() adjust_metronome(0, 1) end}
renoise.tool():add_keybinding{name="Global:Paketti:LPB Decrease (-1)",invoke=function() adjust_lpb_bpb(-1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:LPB Increase (+1)",invoke=function() adjust_lpb_bpb(1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:TPL Decrease (-1)",invoke=function() adjust_lpb_bpb(0, -1) end}
renoise.tool():add_keybinding{name="Global:Paketti:TPL Increase (+1)",invoke=function() adjust_lpb_bpb(0, 1) end}
---------------------------
function soloKey()
local s=renoise.song()
s.tracks[renoise.song().selected_track_index]:solo()
if s.transport.playing==false then renoise.song().transport.playing=true end
s.transport.follow_player=true
if renoise.app().window.active_middle_frame~=1 then renoise.app().window.active_middle_frame=1 end
end
renoise.tool():add_keybinding{name="Global:Paketti:Solo Channel + Play + Follow", invoke=function() soloKey() end}
--This script uncollapses everything (all tracks, master, send trax)
function Uncollapser()
local send_track_counter=nil
local s=renoise.song()
send_track_counter=s.sequencer_track_count+1+s.send_track_count
for i=1,send_track_counter do
s.tracks[i].collapsed=false
end
end
--This script collapses everything (all tracks, master, send trax)
function Collapser()
local send_track_counter=nil
local s=renoise.song()
send_track_counter=s.sequencer_track_count+1+s.send_track_count
for i=1,send_track_counter do
s.tracks[i].collapsed=true end
end
renoise.tool():add_menu_entry{name="--Main Menu:Tools:Paketti..:Pattern Editor..:Collapse All Tracks",invoke=function() Collapser() end}
renoise.tool():add_menu_entry{name="Main Menu:Tools:Paketti..:Pattern Editor..:Uncollapse All Tracks",invoke=function() Uncollapser() end}
--Global keyboard shortcuts
renoise.tool():add_keybinding{name="Global:Paketti:Uncollapse All Tracks",invoke=function() Uncollapser() end}
renoise.tool():add_keybinding{name="Global:Paketti:Collapse All Tracks",invoke=function() Collapser() end}
--Menu entries for Pattern Editor and Mixer
renoise.tool():add_menu_entry{name="--Pattern Editor:Paketti..:Uncollapse All Tracks",invoke=function() Uncollapser() end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Collapse All Tracks",invoke=function() Collapser() end}
renoise.tool():add_menu_entry{name="--Mixer:Paketti..:Uncollapse All Tracks",invoke=function() Uncollapser() end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Collapse All Tracks",invoke=function() Collapser() end}
-- Toggle CapsLock Note Off "===" On / Off.
function CapsLok()
local s=renoise.song()
local currLine=s.selected_line_index
local currPatt=s.selected_pattern_index
local currTrak=s.selected_track_index
local currPhra=s.selected_phrase_index
local currInst=s.selected_instrument_index
if renoise.app().window.active_middle_frame==1 then
if renoise.song().selected_note_column_index==nil or renoise.song().selected_note_column_index == 0 then return
else
if renoise.song().patterns[renoise.song().selected_pattern_index].tracks[renoise.song().selected_track_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string=="OFF" then
renoise.song().patterns[renoise.song().selected_pattern_index].tracks[renoise.song().selected_track_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string=""
else
renoise.song().patterns[renoise.song().selected_pattern_index].tracks[renoise.song().selected_track_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string="OFF"
end
end
else if renoise.app().window.active_middle_frame==3 then return
-- i just cut out the phrase writing since it doesn't seem to want to work
end
--local phra=renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index]
if renoise.song().selected_phrase == nil then return else
local phra=renoise.song().selected_phrase
phra.sample_effects_column_visible=false
phra.panning_column_visible=false
phra.delay_column_visible=false
phra.visible_note_columns=1
phra.instrument_column_visible=false
if renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string=="OFF"
then
renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string=""
else
renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index].lines[renoise.song().selected_line_index].note_columns[renoise.song().selected_note_column_index].note_string="OFF"
end
end
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:KapsLock CapsLock Caps Lock Note Off",invoke=function() CapsLok() end}
----------------------------------------------------------------------------------------------------
function ptnLength(number) local rs=renoise.song() rs.patterns[rs.selected_pattern_index].number_of_lines=number end
function phrLength(number) local s=renoise.song()
renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index].number_of_lines=number end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 001 (001)",invoke=function() ptnLength(1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 004 (004)",invoke=function() ptnLength(4) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 006 (006)",invoke=function() ptnLength(6) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 008 (008)",invoke=function() ptnLength(8) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 012 (00C)",invoke=function() ptnLength(12) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 016 (010)",invoke=function() ptnLength(16) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 024 (018)",invoke=function() ptnLength(24) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 032 (020)",invoke=function() ptnLength(32) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 048 (030)",invoke=function() ptnLength(48) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 064 (040)",invoke=function() ptnLength(64) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 096 (060)",invoke=function() ptnLength(96) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 128 (080)",invoke=function() ptnLength(128) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 192 (0C0)",invoke=function() ptnLength(192) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 256 (100)",invoke=function() ptnLength(256) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 384 (180)",invoke=function() ptnLength(384) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Pattern Length to 512 (200)",invoke=function() ptnLength(512) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 001 (001)",invoke=function() phrLength(1) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 004 (004)",invoke=function() phrLength(4) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 006 (006)",invoke=function() phrLength(6) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 008 (008)",invoke=function() phrLength(8) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 012 (00C)",invoke=function() phrLength(12) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 016 (010)",invoke=function() phrLength(16) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 024 (018)",invoke=function() phrLength(24) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 032 (020)",invoke=function() phrLength(32) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 048 (030)",invoke=function() phrLength(48) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 064 (040)",invoke=function() phrLength(64) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 096 (060)",invoke=function() phrLength(96) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 128 (080)",invoke=function() phrLength(128) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 192 (0C0)",invoke=function() phrLength(192) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 256 (100)",invoke=function() phrLength(256) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 384 (180)",invoke=function() phrLength(384) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase Length to 512 (200)",invoke=function() phrLength(512) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 001 (001)",invoke=function() ptnLength(1) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 004 (004)",invoke=function() ptnLength(4) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 006 (006)",invoke=function() ptnLength(6) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 008 (008)",invoke=function() ptnLength(8) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 012 (00C)",invoke=function() ptnLength(12) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 016 (010)",invoke=function() ptnLength(16) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 024 (018)",invoke=function() ptnLength(24) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 032 (020)",invoke=function() ptnLength(32) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 048 (030)",invoke=function() ptnLength(48) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 064 (040)",invoke=function() ptnLength(64) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 096 (060)",invoke=function() ptnLength(96) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 128 (080)",invoke=function() ptnLength(128) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 192 (0C0)",invoke=function() ptnLength(192) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 256 (100)",invoke=function() ptnLength(256) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 384 (180)",invoke=function() ptnLength(384) end}
renoise.tool():add_midi_mapping{name="Paketti:Set Pattern Length to 512 (200)",invoke=function() ptnLength(512) end}
--------------
function efxwrite(effect, x, y)
local s = renoise.song()
local counter = nil
local currentamount = nil
local old_x = nil
local old_y = nil
local new_x = nil
local new_y = nil
if s.selection_in_pattern == nil then
-- If no selection is set, output to the row that the cursor is on
local current_line_index = s.selected_line_index
if s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).amount_value == 0 and (x < 0 or y < 0) then
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).number_string = ""
else
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).number_string = effect
old_y = s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).amount_value % 16
old_x = math.floor(s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).amount_value / 16)
new_x = old_x + x
new_y = old_y + y
if new_x > 15 then new_x = 15 end
if new_y > 15 then new_y = 15 end
if new_y < 1 then new_y = 0 end
if new_x < 1 then new_x = 0 end
counter = (16 * new_x) + new_y
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(current_line_index):effect_column(1).amount_value = counter
end
else
-- If a selection is set, process the selection range
for i = s.selection_in_pattern.start_line, s.selection_in_pattern.end_line do
if s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).amount_value == 0 and (x < 0 or y < 0) then
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).number_string = ""
else
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).number_string = effect
old_y = s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).amount_value % 16
old_x = math.floor(s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).amount_value / 16)
new_x = old_x + x
new_y = old_y + y
if new_x > 15 then new_x = 15 end
if new_y > 15 then new_y = 15 end
if new_y < 1 then new_y = 0 end
if new_x < 1 then new_x = 0 end
counter = (16 * new_x) + new_y
s:pattern(s.selected_pattern_index):track(s.selected_track_index):line(i):effect_column(1).amount_value = counter
end
end
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column AXx Arp Amount Xx (-1)",invoke=function() efxwrite("0A",-1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column AXx Arp Amount Xx (+1)",invoke=function() efxwrite("0A",1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column AxY Arp Amount xY (-1)",invoke=function() efxwrite("0A",0,-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column AxY Arp Amount xY (+1)",invoke=function() efxwrite("0A",0,1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column VXy Vibrato Amount Xy (-1)",invoke=function() efxwrite("0V",-1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column VXy Vibrato Amount Xy (+1)",invoke=function() efxwrite("0V",1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column VxY Vibrato Amount xY (-1)",invoke=function() efxwrite("0V",0,-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column VxY Vibrato Amount xY (+1)",invoke=function() efxwrite("0V",0,1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column TXy Tremolo Amount Xy (-1)",invoke=function() efxwrite("0T",-1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column TXy Tremolo Amount Xy (+1)",invoke=function() efxwrite("0T",1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column TxY Tremolo Amount xY (-1)",invoke=function() efxwrite("0T",0,-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column TxY Tremolo Amount xY (+1)",invoke=function() efxwrite("0T",0,1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column RXy Retrig Amount Xy (-1)",invoke=function() efxwrite("0R",-1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column RXy Retrig Amount Xy (+1)",invoke=function() efxwrite("0R",1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column RxY Retrig Amount xY (-1)",invoke=function() efxwrite("0R",0,-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column RxY Retrig Amount xY (+1)",invoke=function() efxwrite("0R",0,1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column CXy Cut Volume Amount Xy (-1)",invoke=function() efxwrite("0C",-1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column CXy Cut Volume Amount Xy (+1)",invoke=function() efxwrite("0C",1,0) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column CxY Cut Volume Amount xY (-1)",invoke=function() efxwrite("0C",0,-1) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Effect Column CxY Cut Volume Amount xY (+1)",invoke=function() efxwrite("0C",0,1) end}
-----------
function GlobalLPB(number)
renoise.song().transport.lpb=number end
for glpb=1,16 do
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to " .. formatDigits(3,glpb),invoke=function() GlobalLPB(glpb) end}
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 024",invoke=function() GlobalLPB(24) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 032",invoke=function() GlobalLPB(32) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 048",invoke=function() GlobalLPB(48) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 064",invoke=function() GlobalLPB(64) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 128",invoke=function() GlobalLPB(128) end}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Set Global LPB to 256",invoke=function() GlobalLPB(256) end}
function PhraseLPB(number)
renoise.song().instruments[renoise.song().selected_instrument_index].phrases[renoise.song().selected_phrase_index].lpb=number end
for plpb=1,16 do
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to " .. formatDigits(3,plpb),invoke=function() PhraseLPB(plpb) end}
end
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 024",invoke=function() PhraseLPB(24) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 032",invoke=function() PhraseLPB(32) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 048",invoke=function() PhraseLPB(48) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 064",invoke=function() PhraseLPB(64) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 128",invoke=function() PhraseLPB(128) end}
renoise.tool():add_keybinding{name="Phrase Editor:Paketti:Set Phrase LPB to 256",invoke=function() PhraseLPB(256) end}
----------------------------------------------------------------------------------------------------
function computerKeyboardVolChange(number)
local s=renoise.song();if s.transport.keyboard_velocity_enabled==false then s.transport.keyboard_velocity_enabled=true end
local addtovelocity=nil
addtovelocity=s.transport.keyboard_velocity+number
if addtovelocity > 127 then addtovelocity=127 end
if addtovelocity < 1 then s.transport.keyboard_velocity_enabled=false return end
s.transport.keyboard_velocity=addtovelocity
end
renoise.tool():add_keybinding{name="Global:Paketti:Computer Keyboard Velocity (-1)",invoke=function() computerKeyboardVolChange(-1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Computer Keyboard Velocity (+1)",invoke=function() computerKeyboardVolChange(1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Computer Keyboard Velocity (-10)",invoke=function() computerKeyboardVolChange(-10) end}
renoise.tool():add_keybinding{name="Global:Paketti:Computer Keyboard Velocity (+10)",invoke=function() computerKeyboardVolChange(10) end}
local start_velocity = 10
local end_velocity = 70
local step = 10
for velocity = start_velocity, end_velocity, step do
local velocity_hex = formatDigits(2,velocity)
renoise.tool():add_keybinding {name="Global:Paketti:Set Keyboard Velocity to " .. velocity_hex, invoke=function() renoise.song().transport.keyboard_velocity=velocity renoise.app():show_status("Keyboard Velocity set to: " .. velocity_hex) end}
renoise.tool():add_midi_mapping {name="Paketti:Set Keyboard Velocity to " .. velocity_hex, invoke=function(message) if message:is_trigger() then renoise.song().transport.keyboard_velocity=velocity renoise.app():show_status("Keyboard Velocity set to: " .. velocity_hex) end end}
end
renoise.tool():add_keybinding {name="Global:Paketti:Toggle Keyboard Velocity", invoke=function() renoise.song().transport.keyboard_velocity_enabled=not renoise.song().transport.keyboard_velocity_enabled renoise.app():show_status("Keyboard Velocity " .. (renoise.song().transport.keyboard_velocity_enabled and "Enabled" or "Disabled")) end}
renoise.tool():add_midi_mapping {name="Paketti:Toggle Keyboard Velocity", invoke=function(message) if message:is_trigger() then renoise.song().transport.keyboard_velocity_enabled=not renoise.song().transport.keyboard_velocity_enabled renoise.app():show_status("Keyboard Velocity " .. (renoise.song().transport.keyboard_velocity_enabled and "Enabled" or "Disabled")) end end}
renoise.tool():add_keybinding {name="Global:Paketti:Set Keyboard Velocity to 7F (Max)", invoke=function() renoise.song().transport.keyboard_velocity=127 renoise.app():show_status("Keyboard Velocity set to: 7F.") end}
renoise.tool():add_midi_mapping {name="Paketti:Set Keyboard Velocity to 7F (Max)", invoke=function(message) if message:is_trigger() then renoise.song().transport.keyboard_velocity=127 renoise.app():show_status("Keyboard Velocity set to: 7F") end end}
renoise.tool():add_keybinding {name="Global:Paketti:Set Keyboard Velocity to 00 (Min)", invoke=function() renoise.song().transport.keyboard_velocity=0 renoise.app():show_status("Keyboard Velocity set to: 0.") end}
renoise.tool():add_midi_mapping {name="Paketti:Set Keyboard Velocity to 00 (Min)", invoke=function(message) if message:is_trigger() then renoise.song().transport.keyboard_velocity=0 renoise.app():show_status("Keyboard Velocity set to: 0") end end}
--BPM +1 / -1 / +0.1 / -0.1 (2024 update)
function adjust_bpm(bpm_delta)
local t = renoise.song().transport
t.bpm = math.max(20, math.min(999, t.bpm + bpm_delta))
renoise.app():show_status("BPM: " .. t.bpm)
end
renoise.tool():add_keybinding{name="Global:Paketti:BPM Decrease (-1)",invoke=function() adjust_bpm(-1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:BPM Increase (+1)",invoke=function() adjust_bpm(1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:BPM Decrease (-0.1)",invoke=function() adjust_bpm(-0.1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:BPM Increase (+0.1)",invoke=function() adjust_bpm(0.1, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:BPM Decrease (-0.5)",invoke=function() adjust_bpm(-0.5, 0) end}
renoise.tool():add_keybinding{name="Global:Paketti:BPM Increase (+0.5)",invoke=function() adjust_bpm(0.5, 0) end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Decrease (-1)",invoke=function(message) if message:is_trigger() then adjust_bpm(-1, 0) end end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Increase (+1)",invoke=function(message) if message:is_trigger() then adjust_bpm(1, 0) end end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Decrease (-0.1)",invoke=function(message) if message:is_trigger() then adjust_bpm(-0.1, 0) end end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Increase (+0.1)",invoke=function(message) if message:is_trigger() then adjust_bpm(0.1, 0) end end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Decrease (-0.5)",invoke=function(message) if message:is_trigger() then adjust_bpm(-0.5, 0) end end}
renoise.tool():add_midi_mapping{name="Paketti:BPM Increase (+0.5)",invoke=function(message) if message:is_trigger() then adjust_bpm(0.5, 0) end end}
function pakettiPatternDoubler()
-- Retrieve the current song object
local song = renoise.song()
-- Get the currently selected pattern index
local pattern_index = song.selected_pattern_index
-- Get the number of lines in the selected pattern
local old_patternlength = song.selected_pattern.number_of_lines
-- Calculate the new pattern length by doubling the old length
local new_patternlength = old_patternlength * 2
-- Get the currently selected line index
local current_line = song.selected_line_index
-- Check if the new pattern length is within the allowed limit
if new_patternlength <= renoise.Pattern.MAX_NUMBER_OF_LINES then
-- Set the new pattern length
song.selected_pattern.number_of_lines = new_patternlength
-- Loop through each track in the selected pattern
for track_index, pattern_track in ipairs(song.selected_pattern.tracks) do
-- Copy notes in the pattern
if not pattern_track.is_empty then
for line_index = 1, old_patternlength do
-- Copy each line to the corresponding new position
local line = pattern_track:line(line_index)
local new_line = pattern_track:line(line_index + old_patternlength)
new_line:copy_from(line)
end
end
-- Handle automation duplication
local track_automations = song.patterns[pattern_index].tracks[track_index].automation
for param, automation in pairs(track_automations) do
local points = automation.points
local new_points = {} -- Store new points to be added
-- Collect new points to add, adjusting time by old pattern length
for _, point in ipairs(points) do
local new_time = point.time + old_patternlength
-- Ensure new time does not exceed the new pattern length
if new_time <= new_patternlength then
table.insert(new_points, {time = new_time, value = point.value})
end
end
-- Add the new points to the automation
for _, new_point in ipairs(new_points) do
automation:add_point_at(new_point.time, new_point.value)
end
end
end
-- Adjust the selected line index
song.selected_line_index = current_line + old_patternlength
renoise.app():show_status("Pattern doubled successfully.")
else
-- Print a message if the new pattern length exceeds the limit
renoise.app():show_status("New pattern length exceeds " .. renoise.Pattern.MAX_NUMBER_OF_LINES .. " lines, operation cancelled.")
end
end
function pakettiPatternHalver()
local song = renoise.song()
local old_patternlength = song.selected_pattern.number_of_lines
local resultlength = math.floor(old_patternlength / 2)
local current_line = song.selected_line_index
-- Check if the result length is less than 1, which would be invalid
if resultlength < 1 then
print("Resulting pattern length is too small, operation cancelled.")
return
end
-- Set the new pattern length
song.selected_pattern.number_of_lines = resultlength
-- Adjust automation for each track
for track_index, track in ipairs(song.selected_pattern.tracks) do
local track_automations = song.patterns[song.selected_pattern_index].tracks[track_index].automation
for _, automation in pairs(track_automations) do
local points = automation.points
local new_points = {}
-- Collect new points, scaling down the time values
for _, point in ipairs(points) do
local new_time = math.floor((point.time / old_patternlength) * resultlength)
if new_time >= 1 and new_time <= resultlength then
table.insert(new_points, {time = new_time, value = point.value})
end
end
-- Clear existing points and add scaled points
automation:clear_points()
for _, point in ipairs(new_points) do
automation:add_point_at(point.time, point.value)
end
end
end
-- Adjust the cursor position to maintain the same relative distance from the end
local relative_distance_from_end = old_patternlength - current_line
local new_line = resultlength - relative_distance_from_end
-- Ensure the new line is within the valid range
if new_line < 1 then new_line = 1 end
if new_line > resultlength then new_line = resultlength end
song.selected_line_index = new_line
end
-- Add menu entries and keybindings for the tool
renoise.tool():add_menu_entry{name="--Main Menu:Tools:Paketti..:Pattern Editor..:Paketti Pattern Doubler", invoke=pakettiPatternDoubler}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Paketti Pattern Doubler", invoke=pakettiPatternDoubler}
renoise.tool():add_menu_entry{name="--Pattern Editor:Paketti..:Paketti Pattern Doubler", invoke=pakettiPatternDoubler}
renoise.tool():add_keybinding{name="Mixer:Paketti:Paketti Pattern Doubler", invoke=pakettiPatternDoubler}
-- The function can be bound to a menu item or a keybinding within Renoise to make it easily accessible
renoise.tool():add_menu_entry{name="Main Menu:Tools:Paketti..:Pattern Editor..:Paketti Pattern Halver", invoke = pakettiPatternHalver}
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Paketti Pattern Halver", invoke = pakettiPatternHalver}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Pattern Halver", invoke = pakettiPatternHalver}
renoise.tool():add_keybinding{name="Mixer:Paketti:Paketti Pattern Halver", invoke = pakettiPatternHalver}
function get_master_track_index()
for k,v in ripairs(renoise.song().tracks)
do if v.type == renoise.Track.TRACK_TYPE_MASTER then return k end
end
end
function write_bpm()
if renoise.song().transport.bpm < 256 then -- safety check
local column_index = renoise.song().selected_effect_column_index
local t=renoise.song().transport
renoise.song().tracks[get_master_track_index()].visible_effect_columns = 2
if renoise.song().selected_effect_column_index <= 1 then column_index = 2 end
renoise.song().selected_pattern.tracks[get_master_track_index()].lines[1].effect_columns[1].number_string = "ZT"
renoise.song().selected_pattern.tracks[get_master_track_index()].lines[1].effect_columns[1].amount_value = t.bpm
renoise.song().selected_pattern.tracks[get_master_track_index()].lines[1].effect_columns[2].number_string = "ZL"
renoise.song().selected_pattern.tracks[get_master_track_index()].lines[1].effect_columns[2].amount_value = t.lpb
end
end
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:BPM&LPB..:Write Current BPM&LPB to Master Column",invoke=function() write_bpm() end}
function randombpm()
local prefix=nil
local randombpm = {80, 100, 115, 123, 128, 132, 135, 138, 160}
math.randomseed(os.time())
for i = 1, 9 do
prefix = math.random(1, #randombpm)
prefix = randombpm[prefix]
print(prefix)
end
renoise.song().transport.bpm=prefix
if renoise.tool().preferences.RandomBPM.value then
write_bpm()
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Renoise Random BPM & Write BPM/LPB to Master",
invoke = function()
local randombpm = {80, 100, 115, 123, 128, 132, 135, 138, 160}
math.randomseed(os.time())
local prefix = randombpm[math.random(#randombpm)]
renoise.song().transport.bpm = prefix
if renoise.tool().preferences.RandomBPM.value then
write_bpm()
end
end}
function playat75()
renoise.song().transport.bpm=renoise.song().transport.bpm*0.75
write_bpm()
renoise.app():show_status("BPM set to 75% (" .. renoise.song().transport.bpm .. "BPM)")
end
function returnbackto100()
renoise.song().transport.bpm=renoise.song().transport.bpm/0.75
write_bpm()
renoise.app():show_status("BPM set back to 100% (" .. renoise.song().transport.bpm .. "BPM)")
end
renoise.tool():add_keybinding{name="Global:Paketti:Play at 75% Speed (Song BPM)", invoke=function() playat75() end}
renoise.tool():add_keybinding{name="Global:Paketti:Play at 100% Speed (Song BPM)", invoke=function() returnbackto100() end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:BPM&LPB..:Play at 75% Speed (Song BPM)", invoke=function() playat75() end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:BPM&LPB..:Play at 100% Speed (Song BPM)", invoke=function() returnbackto100() end}
renoise.tool():add_keybinding{name="Global:Paketti:Random BPM from List",
invoke = function()
-- Define a list of possible BPM values
local bpmList = {80, 100, 115, 123, 128, 132, 135, 138, 160}
-- Get the current BPM
local currentBPM = renoise.song().transport.bpm
-- Filter the list to exclude the current BPM
local newBpmList = {}
for _, bpm in ipairs(bpmList) do
if bpm ~= currentBPM then
table.insert(newBpmList, bpm)
end
end
-- Select a random BPM from the filtered list
if #newBpmList > 0 then
local selectedBPM = newBpmList[math.random(#newBpmList)]
renoise.song().transport.bpm = selectedBPM
print("Random BPM set to: " .. selectedBPM) -- Debug output to the console
else
print("No alternative BPM available to switch to.")
end
-- Optional: write the BPM to a file or apply other logic
if renoise.tool().preferences.RandomBPM and renoise.tool().preferences.RandomBPM.value then
write_bpm() -- Ensure this function is defined elsewhere in your tool
print("BPM written to file or handled additionally.")
end
end
}
-------------------------
function WipeEfxFromSelection()
local s = renoise.song()
if s.selection_in_pattern == nil then return end
local start_track = s.selection_in_pattern.start_track
local end_track = s.selection_in_pattern.end_track
local start_line = s.selection_in_pattern.start_line
local end_line = s.selection_in_pattern.end_line
local start_column = s.selection_in_pattern.start_column
local end_column = s.selection_in_pattern.end_column
-- Iterate through each selected track
for track_index = start_track, end_track do
local track = s:track(track_index)
local pattern_track = s:pattern(s.selected_pattern_index):track(track_index)
local visible_note_columns = track.visible_note_columns
local visible_effect_columns = track.visible_effect_columns
-- Determine column range to clear for this track
local track_column_start, track_column_end
if track_index == start_track then
-- If it's the first track in the selection, use start_column
track_column_start = start_column
else
-- For subsequent tracks, start at column 1
track_column_start = 1
end
if track_index == end_track then
-- If it's the last track in the selection, use end_column
track_column_end = end_column
else
-- For previous tracks, end at the maximum number of columns
track_column_end = visible_note_columns + visible_effect_columns
end
-- Calculate which effect columns are selected for this track
local effect_column_start = math.max(1, track_column_start - visible_note_columns)
local effect_column_end = math.min(visible_effect_columns, track_column_end - visible_note_columns)
-- Skip if no effect columns are selected for this track
if effect_column_end >= 1 then
-- Iterate through selected lines
for line_index = start_line, end_line do
local line = pattern_track:line(line_index)
if not line.is_empty then
-- Iterate through the selected effect columns and clear them
for effect_column_index = effect_column_start, effect_column_end do
line:effect_column(effect_column_index):clear()
end
end
end
end
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Wipe Effects From Selection",invoke=function() WipeEfxFromSelection() end}
----------------
--rescued from ImpulseBuddy by Protman! I have no idea how many of these were originally a part of Paketti, or something else, but
--hey, more crosspollination, more features.
function delete_effect_column()
local s=renoise.song()
local currTrak = s.selected_track_index
local currPatt = s.selected_pattern_index
local iter = s.pattern_iterator:effect_columns_in_pattern_track(currPatt,currTrak)
for _,line in iter do
if not line.is_empty then
line:clear()
end
end
end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Delete/Wipe/Clear Effect Column Content from Current Track",invoke=function() delete_effect_column() end}
---------------------------
function GenerateDelayValue()
local counter=nil
local s=renoise.song()
s.tracks[s.selected_track_index].delay_column_visible=true
for i=1,s.tracks[s.selected_track_index].visible_note_columns do
counter=256/s.tracks[s.selected_track_index].visible_note_columns*(i-1)
DEC_HEX(counter)
print (counter)
s.patterns[s.selected_pattern_index].tracks[s.selected_track_index].lines[s.selected_line_index].note_columns[i].delay_value=counter end
s.selected_note_column_index=1 end
renoise.tool():add_keybinding{name="Pattern Editor:Paketti:Generate Delay Value on Note Columns",invoke=function() GenerateDelayValue() end}
----------------------------------------------------------------------------------------------------------------------------------------
--from http://lua-users.org/lists/lua-l/2004-09/msg00054.html thax!
function DEC_HEX(IN)
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
while IN>0 do
I=I+1
IN,D=math.floor(IN/B),math.mod(IN,B)+1
OUT=string.sub(K,D,D)..OUT
end
return OUT
end
--from http://lua-users.org/lists/lua-l/2004-09/msg00054.html thax!
----------------------------------------------------------------------------------------------------------------------------------------
-- originally created by joule + danoise
-- http://forum.renoise.com/index.php/topic/47664-new-tool-31-better-column-navigation/
-- ripped into Paketti without their permission. tough cheese.
local cached_note_column_index = nil
local cached_effect_column_index = nil
function toggle_column_type()
local s = renoise.song()
if s.selected_track.type == renoise.Track.TRACK_TYPE_SEQUENCER then
if s.selected_note_column_index ~= 0 then
local col_idx = (cached_effect_column_index ~= 0) and
cached_effect_column_index or 1
if (col_idx <= s.selected_track.visible_effect_columns) then
s.selected_effect_column_index = col_idx
elseif (s.selected_track.visible_effect_columns > 0) then
s.selected_effect_column_index = s.selected_track.visible_effect_columns
else
-- no effect columns available
end
else
local col_idx = (cached_note_column_index ~= 0) and
cached_note_column_index or 1
if (col_idx <= s.selected_track.visible_note_columns) then
s.selected_note_column_index = col_idx
else -- always one note column
s.selected_note_column_index = s.selected_track.visible_note_columns
end end end end
function cache_columns()
-- access song only once renoise is ready
if not pcall(renoise.song) then return end
local s = renoise.song()
if (s.selected_note_column_index > 0) then
cached_note_column_index = s.selected_note_column_index
end
if (s.selected_effect_column_index > 0) then
cached_effect_column_index = s.selected_effect_column_index end end
function cycle_column(direction)
local s = renoise.song()
if direction == "next" then
if (s.selected_note_column_index > 0) and (s.selected_note_column_index < s.selected_track.visible_note_columns) then -- any note column but not the last
s.selected_note_column_index = s.selected_note_column_index + 1
elseif (s.selected_track.visible_note_columns > 0) and (s.selected_note_column_index == s.selected_track.visible_note_columns) and (s.selected_track.visible_effect_columns > 0) then -- last note column when effect columns are available
s.selected_effect_column_index = 1
elseif (s.selected_effect_column_index < s.selected_track.visible_effect_columns) then -- any effect column but not the last
s.selected_effect_column_index = s.selected_effect_column_index + 1
elseif (s.selected_effect_column_index == s.selected_track.visible_effect_columns) and (s.selected_track_index < #s.tracks) then -- last effect column but not the last track
s.selected_track_index = s.selected_track_index + 1
else -- last column in last track
s.selected_track_index = 1 end
elseif direction == "prev" then
if (s.selected_note_column_index > 0) and (s.selected_sub_column_type > 2 and s.selected_sub_column_type < 8) then -- any sample effects column
s.selected_note_column_index = s.selected_note_column_index
elseif (s.selected_note_column_index > 1) then -- any note column but not the first
s.selected_note_column_index = s.selected_note_column_index - 1
elseif (s.selected_effect_column_index > 1) then -- any effect column but not the first
s.selected_effect_column_index = s.selected_effect_column_index - 1
elseif (s.selected_effect_column_index == 1) and (s.selected_track.visible_note_columns > 0) then -- first effect column and note columns exist
s.selected_note_column_index = s.selected_track.visible_note_columns
elseif (s.selected_effect_column_index == 1) and (s.selected_track.visible_note_columns == 0) then -- first effect column and note columns do not exist (group/send/master)
s.selected_track_index = s.selected_track_index - 1
if s.selected_track.visible_effect_columns > 0 then s.selected_effect_column_index = s.selected_track.visible_effect_columns
else s.selected_note_column_index = s.selected_track.visible_note_columns
end
elseif (s.selected_note_column_index == 1) and (s.selected_track_index == 1) then -- first note column in first track
local rns=renoise.song()
s.selected_track_index = #rns.tracks
s.selected_effect_column_index = s.selected_track.visible_effect_columns
elseif (s.selected_note_column_index == 1) then -- first note column
s.selected_track_index = s.selected_track_index - 1
if s.selected_track.visible_effect_columns > 0 then s.selected_effect_column_index = s.selected_track.visible_effect_columns
else s.selected_note_column_index = s.selected_track.visible_note_columns
end end end end
renoise.tool():add_keybinding{name="Pattern Editor:Navigation:Paketti Switch between Note/FX columns",invoke=toggle_column_type}
renoise.tool():add_keybinding{name="Pattern Editor:Navigation:Paketti Jump to Column (Next) (Note/FX)",invoke=function() cycle_column("next") end}
renoise.tool():add_keybinding{name="Pattern Editor:Navigation:Paketti Jump to Column (Previous) (Note/FX)",invoke=function() cycle_column("prev") end}
renoise.tool().app_idle_observable:add_notifier(cache_columns)
-- Pattern Resizer by dblue. some minor modifications.
function resize_pattern(pattern, new_length, patternresize)
-- We need a valid pattern object
if (pattern == nil) then
renoise.app():show_status('Need a valid pattern object!')
return
end
-- Rounding function
local function round(value)
return math.floor(value + 0.5)
end
-- Shortcut to the song object
local rs = renoise.song()
-- Get the current pattern length
local src_length = pattern.number_of_lines
-- Make sure new_length is within valid limits
local dst_length = math.min(512, math.max(1, new_length))
-- If the new length is the same as the old length, then we have nothing to do.
if (dst_length == src_length) then
return
end
-- Set conversation ratio
local ratio = dst_length / src_length
-- Change pattern length
if patternresize==1 then
pattern.number_of_lines = dst_length
end
-- Source
local src_track = nil
local src_line = nil
local src_note_column = nil
local src_effect_column = nil
-- Insert a new track as a temporary work area
rs:insert_track_at(1)
-- Destination
local dst_track = pattern:track(1)
local dst_line_index = 0
local dst_delay = 0
local dst_line = nil
local dst_note_column = nil
local dst_effect_column = nil
-- Misc
local tmp_line_index = 0
local tmp_line_delay = 0
local delay_column_used = false
local track = nil
-- Iterate through each track
for src_track_index = 2, #rs.tracks, 1 do
track = rs:track(src_track_index)
-- Set source track
src_track = pattern:track(src_track_index)
-- Reset delay check
delay_column_used = false
-- Iterate through source lines
for src_line_index = 0, src_length - 1, 1 do
-- Set source line
src_line = src_track:line(src_line_index + 1)
-- Only process source line if it contains data
if (not src_line.is_empty) then
-- Store temporary line index and delay
tmp_line_index = math.floor(src_line_index * ratio)
tmp_line_delay = math.floor(((src_line_index * ratio) - tmp_line_index) * 256)
-- Process note columns
for note_column_index = 1, track.visible_note_columns, 1 do
-- Set source note column
src_note_column = src_line:note_column(note_column_index)
-- Only process note column if it contains data
if (not src_note_column.is_empty) then
-- Calculate destination line and delay
dst_line_index = tmp_line_index
dst_delay = math.ceil(tmp_line_delay + (src_note_column.delay_value * ratio))
-- Wrap note to next line if necessary
while (dst_delay >= 256) do
dst_delay = dst_delay - 256
dst_line_index = dst_line_index + 1
end
-- Keep track of whether the delay column is used
-- so that we can make it visible later if necessary.
if (dst_delay > 0) then
delay_column_used = true
end
dst_line = dst_track:line(dst_line_index + 1)
dst_note_column = dst_line:note_column(note_column_index)
-- Note prioritisation
if (dst_note_column.is_empty) then
-- Destination is empty. Safe to copy
dst_note_column:copy_from(src_note_column)
dst_note_column.delay_value = dst_delay
else
-- Destination contains data. Try to prioritise...
-- If destination contains a note-off...
if (dst_note_column.note_value == 120) then
-- Source note takes priority
dst_note_column:copy_from(src_note_column)
dst_note_column.delay_value = dst_delay
else
-- If the source is louder than destination...
if (src_note_column.volume_value > dst_note_column.volume_value) then
-- Louder source note takes priority