-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPakettiRecorder.lua
745 lines (641 loc) · 33.3 KB
/
PakettiRecorder.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
local contour_sample_timer = nil
function contourShuttleRecord()
local w = renoise.app().window
local t = renoise.song().transport
if not w.sample_record_dialog_is_visible then
w.sample_record_dialog_is_visible = true
t:start_stop_sample_recording()
else
t:start_stop_sample_recording()
-- Clean up existing timer if any
if contour_sample_timer and renoise.tool():has_timer(contourShuttleRecordMonitor) then
renoise.tool():remove_timer(contourShuttleRecordMonitor)
contour_sample_timer = nil
end
-- Start new timer to monitor recording completion
contour_sample_timer = renoise.tool():add_timer(contourShuttleRecordMonitor, 100)
end
end
function contourShuttleRecordMonitor()
local s = renoise.song()
if s.selected_sample and s.selected_sample.sample_buffer.has_sample_data then
-- Recording finished, set properties
s.selected_sample.autoseek = true
s.selected_sample.autofade = true
-- Stop monitoring
contour_sample_timer = nil
renoise.tool():remove_timer(contourShuttleRecordMonitor)
return false
end
-- Continue monitoring
return true
end
renoise.tool():add_keybinding{name="Global:Paketti:Contour Shuttle Record On/Off", invoke=function() contourShuttleRecord() end}
----
-- Keep track of the active timer
local paketti_sample_timer = nil
function PakettiSampleAndToSampleEditor()
local w=renoise.app().window
local t=renoise.song().transport
local s=renoise.song()
if w.sample_record_dialog_is_visible==false then
-- Check if there's already a selected sample and create new instrument if needed
if s.selected_sample then
local new_instrument_index=s.selected_instrument_index + 1
s:insert_instrument_at(new_instrument_index)
s.selected_instrument_index=new_instrument_index
end
-- Start recording
w.sample_record_dialog_is_visible=true
t:start_stop_sample_recording()
else
-- Stop recording and start monitoring for completion
t:start_stop_sample_recording()
-- Clean up existing timer if any
if paketti_sample_timer and renoise.tool():has_timer(PakettiSampleAndToSampleEditorMonitor) then
renoise.tool():remove_timer(PakettiSampleAndToSampleEditorMonitor)
paketti_sample_timer = nil
end
-- Start new timer
paketti_sample_timer = renoise.tool():add_timer(PakettiSampleAndToSampleEditorMonitor, 100)
end
end
function PakettiSampleAndToSampleEditorMonitor()
local s=renoise.song()
if s.selected_sample and s.selected_sample.sample_buffer.has_sample_data then
PakettiSampleAndToSampleEditorFinish()
-- Stop monitoring
paketti_sample_timer = nil
renoise.tool():remove_timer(PakettiSampleAndToSampleEditorMonitor)
return false
end
-- Continue monitoring
return true
end
function PakettiSampleAndToSampleEditorFinish()
local w=renoise.app().window
w.active_upper_frame=1
w.active_middle_frame=5
w.lock_keyboard_focus=true
renoise.song().selected_sample.autoseek=true
renoise.song().selected_sample.autofade=true
end
renoise.tool():add_keybinding{name="Global:Paketti:Start Sampling and Sample Editor (Record)", invoke=function() PakettiSampleAndToSampleEditor() end}
renoise.tool():add_menu_entry{name="Sample Editor:Paketti..:Record..:Start Sampling and Sample Editor (Record)", invoke=function() PakettiSampleAndToSampleEditor() end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Record..:Start Sampling and Sample Editor (Record)", invoke=function() PakettiSampleAndToSampleEditor() end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Record..:Start Sampling and Sample Editor (Record)", invoke=function() PakettiSampleAndToSampleEditor() end}
renoise.tool():add_menu_entry{name="Instrument Box:Paketti..:Record..:Start Sampling and Sample Editor (Record)", invoke=function() PakettiSampleAndToSampleEditor() end}
-------
-----
function instrument_is_empty(instrument)
local inst = renoise.song().instruments[instrument]
local has_sample_data = false
for sample in ipairs(inst.samples) do
has_sample_data = has_sample_data or inst.samples[sample].sample_buffer.has_sample_data
end
if inst.plugin_properties.plugin_loaded or inst.midi_output_properties.device_name ~= "" or has_sample_data then return false else return true end
end
function search_empty_instrument()
local proc = renoise.song()
for empty_instrument = 1, #proc.instruments do local samples = false
for i = 1,#proc.instruments[empty_instrument].samples do
local temp_buffer = proc.instruments[empty_instrument].samples[i].sample_buffer
if temp_buffer.has_sample_data then samples = true break end
end
local plugin = proc.instruments[empty_instrument].plugin_properties.plugin_loaded
local midi_device = proc.instruments[empty_instrument].midi_output_properties.device_name
if ((samples == false) and (plugin == false) and (midi_device == nil or midi_device == "")) then
return empty_instrument end
end
proc:insert_instrument_at(#proc.instruments+1)
return #proc.instruments
end
--------------------------------------------------------------------------------------------------------
-- delay(3)
-- renoise.song().transport:trigger_sequence(1)
---
--t:panic()
--t:start(renoise.Transport.PLAYMODE_RESTART_PATTERN)
-- startpos.line = renoise.song().selected_line_index
-- startpos.sequence = renoise.song().selected_sequence_index
-- renoise.song().transport.playback_pos = startpos
-- t:start(renoise.Transport.PLAYMODE_CONTINUE_PATTERN)
-- ss.sample_buffer_observable:remove_notifier(finalrecord)
--[[ if ss.sample_buffer_observable:has_notifier(finalrecord) then
ss.sample_buffer_observable:remove_notifier(finalrecord)
return
end
end
]]--
---------------------------------------------------------------------------------
-- Paketti: Record to Current Track+Plus (Complete Version with max_columns)
--
-- This script:
-- - Toggles recording (start/stop) with three parameters:
-- use_metronome (bool), use_lineinput (bool), max_columns (number)
-- - If row1 has reached "max_columns" used columns, creates a new track
-- after the current one
-- - Optionally creates a new instrument if the current one isn't empty
-- - Names the track as "overdubXX"
-- - Names the instrument as "overdubXX PTN:<len> BPM:<bpm> LPB:<lpb>"
-- - Adds / removes #Line Input if use_lineinput == true
-- - Enables / disables the metronome if use_metronome == true
-- - Places a note on row1 of the pattern
-- - Trims 959 frames from the end of the recorded sample, sets autofade/autoseek
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Globals / State
--------------------------------------------------------------------------------
local am_i_recording = false
local recording_instrument = nil
local paketti_record_timer = nil
local monitor_has_printed = nil
-- These store the user's choices per recording session
local record_use_metronome = false
local record_use_lineinput = false
local record_max_columns = 12 -- default to 12 columns if not specified
--------------------------------------------------------------------------------
-- recordtocurrenttrack(use_metronome, use_lineinput, max_columns)
--
-- Toggles start/stop recording based on am_i_recording.
-- If am_i_recording == false, we start recording.
-- If am_i_recording == true, we stop recording.
-- We also:
-- - turn metronome on/off if requested
-- - add/remove line input if requested
-- - optionally create a new instrument if current one isn't empty
-- - store "max_columns" for deciding if row1 is "full"
--------------------------------------------------------------------------------
function recordtocurrenttrack(use_metronome, use_lineinput, max_columns)
local s = renoise.song()
local t = s.transport
local track = s.selected_track
-- If user omitted max_columns, default to 12
if (max_columns == nil) then
max_columns = 12
end
print("=== recordtocurrenttrack() called ===")
print(" am_i_recording:", am_i_recording)
print(" use_metronome:", use_metronome,
" use_lineinput:", use_lineinput,
" max_columns:", max_columns)
print(" Selected track idx:", s.selected_track_index,
" Selected instrument idx:", s.selected_instrument_index)
------------------------------------------------------------------------------
-- START RECORDING
------------------------------------------------------------------------------
if (not am_i_recording) then
am_i_recording = true
print("== START RECORDING ==")
-- Remember user choices so finalrecord() can see them
record_use_metronome = use_metronome
record_use_lineinput = use_lineinput
record_max_columns = max_columns
-- 1) Check if the selected track is a sequencer track
if track.type ~= renoise.Track.TRACK_TYPE_SEQUENCER then
renoise.app():show_status("Please select a normal sequencer track with note columns.")
print(" Selected track is not a sequencer track. Aborting.")
am_i_recording = false
return
end
-- 2) If user wants metronome, enable it
if record_use_metronome then
t.metronome_enabled = true
print(" Turned ON the metronome.")
end
-- 3) Show the Sample Recorder dialog
renoise.app().window.sample_record_dialog_is_visible = true
-- 4) If user wants line input, ensure #Line Input is present
if record_use_lineinput then
local has_line_input = false
for _, device in ipairs(track.devices) do
if (device.name == "#Line Input") then
has_line_input = true
break
end
end
if not has_line_input then
loadnative("Audio/Effects/Native/#Line Input")
print(" Added #Line Input to the current track.")
end
end
-- 5) Check if the current instrument is empty; if not, create a new instrument
local curr_instr_idx = s.selected_instrument_index
local curr_instr = s.instruments[curr_instr_idx]
local is_empty_instrument =
(#curr_instr.samples == 0) and
(not curr_instr.plugin_properties.plugin_loaded)
if not is_empty_instrument then
-- Insert a new instrument at "current index + 1"
local new_instr_idx = curr_instr_idx + 1
if new_instr_idx > (#s.instruments + 1) then
new_instr_idx = #s.instruments + 1
end
s:insert_instrument_at(new_instr_idx)
s.selected_instrument_index = new_instr_idx
print((" Current instrument not empty; created new instr at index %d."):
format(new_instr_idx))
end
pakettiPreferencesDefaultInstrumentLoader()
-- 6) Store the index of the instrument we are recording into
recording_instrument = s.selected_instrument_index
print(" Recording instrument set to:", recording_instrument)
-- 7) Start Renoise’s sample recording
t:start_stop_sample_recording()
------------------------------------------------------------------------------
-- STOP RECORDING
------------------------------------------------------------------------------
else
am_i_recording = false
print("== STOP RECORDING ==")
-- 1) Stop sample recording
local t = renoise.song().transport
t:start_stop_sample_recording()
-- 2) Add a timer to monitor sample data
if recording_instrument then
if renoise.tool():has_timer(recordtocurrenttrackMonitor) then
print(" Timer already exists, not adding another.")
else
renoise.tool():add_timer(recordtocurrenttrackMonitor, 100)
paketti_record_timer = true
print(" Added recordtocurrenttrackMonitor timer.")
end
else
print(" No recording_instrument set; unexpected scenario.")
end
end
end
--------------------------------------------------------------------------------
-- recordtocurrenttrackMonitor()
-- Checks every 100 ms if the sample buffer is ready, or if user closed the dialog.
--------------------------------------------------------------------------------
function recordtocurrenttrackMonitor()
local s = renoise.song()
local w = renoise.app().window
-- If user forcibly closed the recorder while we still think we're recording
if am_i_recording and (not w.sample_record_dialog_is_visible) then
print(">> Detected user closed the sample recorder dialog.")
renoise.app():show_status(
"Detected Sample Recorder was closed. Catching recorded sample..."
)
am_i_recording = false
-- Check if sample data is present
if s.selected_sample
and s.selected_sample.sample_buffer
and s.selected_sample.sample_buffer.has_sample_data
and (s.selected_instrument_index == recording_instrument)
then
print(" Some sample data is present; calling finalrecord().")
finalrecord()
else
print(" No sample data found => aborting silently.")
cleanupMonitorAndVars()
end
return false
else
-- Normal polling for sample data
if not monitor_has_printed then
print("Monitoring for sample data in instrument:", recording_instrument)
monitor_has_printed = true
else
io.write(".")
io.flush()
end
if s.selected_sample
and s.selected_sample.sample_buffer
and s.selected_sample.sample_buffer.has_sample_data
and (s.selected_instrument_index == recording_instrument)
then
print("\nSample data found, calling finalrecord()...")
print ("123 and " .. renoise.song().selected_sample.sample_buffer.number_of_frames)
finalrecord()
return false
end
return true
end
end
--------------------------------------------------------------------------------
-- finalrecord()
-- We remove line input if requested, turn off metronome if requested,
-- place the note (row1 only). If row1 has "record_max_columns" used columns,
-- we create a new track after the old one, place the note, rename track & instrument,
-- etc. Also trims 959 frames from the end of the recorded sample, sets autofade/autoseek.
--------------------------------------------------------------------------------
function finalrecord()
print(">>> finalrecord triggered!")
local s = renoise.song()
local curr_track_idx = s.selected_track_index
local curr_track = s.selected_track
-- A) If track is not sequencer, fail.
if curr_track.type ~= renoise.Track.TRACK_TYPE_SEQUENCER then
renoise.app():show_status("Please select a normal sequencer track. Aborting finalrecord.")
print(" Current track not a sequencer track, aborting finalrecord.")
cleanupMonitorAndVars()
return
end
local pattern_idx = s.selected_pattern_index
local pattern_track = s.patterns[pattern_idx].tracks[curr_track_idx]
local line1 = pattern_track.lines[1]
-- B) If we used line input, remove it
if record_use_lineinput then
for i, device in ipairs(curr_track.devices) do
if (device.name == "#Line Input") then
curr_track:delete_device_at(i)
print(" Removed #Line Input from track.")
break
end
end
end
-- C) If we used metronome, turn it off
if record_use_metronome then
s.transport.metronome_enabled = false
print(" Turned OFF the metronome.")
end
------------------------------------------------------------------------------
-- D) Place the note in row1. If row1 is full (meaning record_max_columns used),
-- create a new track. Then rename track & instrument. Also do sample trimming.
------------------------------------------------------------------------------
local right_instrument_value = s.selected_instrument_index - 1
local target_column = 1
-- We search only up to record_max_columns
for i = 1, record_max_columns do
if line1.note_columns[i].note_string ~= "---" then
target_column = i + 1
end
end
-- If target_column > record_max_columns => row1 is "full"
if target_column > record_max_columns then
local new_track_index = curr_track_idx + 1
if new_track_index > (#s.tracks + 1) then
new_track_index = #s.tracks + 1
end
s:insert_track_at(new_track_index)
s.selected_track_index = new_track_index
print((" The old track is full (row1 has %d used columns). " ..
"Created new track AFTER old track at index %d."):
format(record_max_columns, new_track_index))
local new_track = s.selected_track
if new_track.type ~= renoise.Track.TRACK_TYPE_SEQUENCER then
renoise.app():show_status("New track is not a sequencer track. Aborting note placement.")
print(" New track is not a sequencer track, aborting note placement.")
cleanupMonitorAndVars()
return
end
local new_pattern_track = s.patterns[pattern_idx].tracks[new_track_index]
local new_line1 = new_pattern_track.lines[1]
-- Place note in col1
new_line1.note_columns[1].note_string = "C-4"
new_line1.note_columns[1].instrument_value = right_instrument_value
new_line1.effect_columns[1].number_string = "0G"
new_line1.effect_columns[1].amount_string = "01"
-- Visible columns = 1 (a brand new track normally starts with 1 column)
s.tracks[new_track_index].visible_note_columns = 1
local col_count = s.tracks[new_track_index].visible_note_columns
s.tracks[new_track_index].name = ("Overdub%02d"):format(col_count)
local pat_length = s.patterns[s.selected_pattern_index].number_of_lines
local current_bpm = math.floor(s.transport.bpm)
local current_lpb = s.transport.lpb
local new_instr_name =
("Overdub%02d PTN:%d BPM:%d LPB:%d"):format(col_count, pat_length, current_bpm, current_lpb)
s.instruments[s.selected_instrument_index].name = new_instr_name
print((" Placed C-4 (instr %d) in col1 of new track's row1. " ..
"Track named '%s', instrument named '%s'."):
format(
right_instrument_value,
s.tracks[new_track_index].name,
new_instr_name
))
else
-- Not full => place note in the old track at target_column
s.tracks[curr_track_idx].visible_note_columns = target_column
line1.note_columns[target_column].note_string = "C-4"
line1.note_columns[target_column].instrument_value = right_instrument_value
line1.effect_columns[1].number_string = "0G"
line1.effect_columns[1].amount_string = "01"
----------------------------------------------------------------------------
-- Trim sample
----------------------------------------------------------------------------
local sample_buffer = s.selected_sample.sample_buffer
print ("ABC" .. sample_buffer.number_of_frames)
renoise.song().selected_sample.sample_buffer:prepare_sample_data_changes()
local sample_buffer = s.selected_sample.sample_buffer
print ("DEF" .. sample_buffer.number_of_frames)
if sample_buffer and sample_buffer.has_sample_data then
local current_frames = sample_buffer.number_of_frames
local new_length = current_frames
local current_framesv2=renoise.song().selected_sample.sample_buffer.number_of_frames
-- Special case for 336960 frames
if current_framesv2 == 336960 then
new_length = 336000
else
-- For all other cases, remove 3500 frames from the end
new_length = current_framesv2 - 3500
end
if new_length > 0 then
local sample_rate = sample_buffer.sample_rate
local bit_depth = sample_buffer.bit_depth
local num_channels = sample_buffer.number_of_channels
local temp_data = {}
for channel = 1, num_channels do
temp_data[channel] = {}
for frame = 1, new_length do
temp_data[channel][frame] = sample_buffer:sample_data(channel, frame)
end
end
print("Oh I'm definitely doing something to the sample now.")
sample_buffer:delete_sample_data()
local success = sample_buffer:create_sample_data(
sample_rate,
bit_depth,
num_channels,
new_length)
if success and sample_buffer.has_sample_data then
for channel = 1, num_channels do
for frame = 1, new_length do
sample_buffer:set_sample_data(channel, frame, temp_data[channel][frame])
end
end
end
end
end
renoise.song().selected_sample.sample_buffer:finalize_sample_data_changes()
-- Set autofade / autoseek
s.selected_sample.autofade = true
local amf=renoise.app().window.active_middle_frame
renoise.app().window.active_middle_frame = amf
--s.selected_sample.autoseek = true
----------------------------------------------------------------------------
-- Rename track & instrument
----------------------------------------------------------------------------
local col_count = s.tracks[curr_track_idx].visible_note_columns
s.tracks[curr_track_idx].name = ("Overdub%02d"):format(col_count)
local pat_length = s.patterns[s.selected_pattern_index].number_of_lines
local current_bpm = math.floor(s.transport.bpm)
local current_lpb = s.transport.lpb
local new_instr_name =
("Overdub%02d PTN:%d BPM:%d LPB:%d"):format(col_count, pat_length, current_bpm, current_lpb)
s.instruments[s.selected_instrument_index].name = new_instr_name
print((" Placed C-4 (instrument %d) in col %d of old track's row1. " ..
"Renamed track to '%s', instrument to '%s'."):
format(
right_instrument_value,
target_column,
s.tracks[curr_track_idx].name,
new_instr_name
))
end
-- E) Cleanup
print ("Sample is name: " .. renoise.song().selected_sample.name)
cleanupMonitorAndVars()
print("finalrecord complete. Timer removed, variables cleared.")
print ("Sample is frames: " .. renoise.song().selected_sample.sample_buffer.number_of_frames)
print (renoise.song().instruments[renoise.song().selected_instrument_index].samples[1].name)
end
--------------------------------------------------------------------------------
-- cleanupMonitorAndVars()
--------------------------------------------------------------------------------
function cleanupMonitorAndVars()
if renoise.tool():has_timer(recordtocurrenttrackMonitor) then
renoise.tool():remove_timer(recordtocurrenttrackMonitor)
end
paketti_record_timer = nil
recording_instrument = nil
monitor_has_printed = nil
am_i_recording = false
-- Reset our booleans for the next usage
record_use_metronome = false
record_use_lineinput = false
record_max_columns = 12
end
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 12 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,12)
end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 12 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,12) end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 12 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,12) end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 12 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,12) end}
renoise.tool():add_menu_entry{name="--Pattern Editor:Paketti..:Paketti Overdub 12 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,12) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 12 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,12) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 12 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,12) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 12 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,12) end}
renoise.tool():add_menu_entry{name="--Mixer:Paketti..:Paketti Overdub 12 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,12) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 12 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,12) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 12 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,12) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 12 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,12) end}
renoise.tool():add_menu_entry{name="--Pattern Matrix:Paketti..:Paketti Overdub 12 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,12) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 12 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,12) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 12 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,12) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 12 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,12) end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 12 (Metronome/Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(true, true,12) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 12 (Metronome/no Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(true, false,12) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 12 (No Metronome/Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(false, true,12) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 12 (No Metronome/No Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(false, false,12) end end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 01 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 01 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 01 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,1) end}
renoise.tool():add_keybinding{name="Global:Paketti:Paketti Overdub 01 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,1) end}
renoise.tool():add_menu_entry{name="--Pattern Editor:Paketti..:Paketti Overdub 01 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,1) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 01 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,1) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 01 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,1) end}
renoise.tool():add_menu_entry{name="Pattern Editor:Paketti..:Paketti Overdub 01 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,1) end}
renoise.tool():add_menu_entry{name="--Mixer:Paketti..:Paketti Overdub 01 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,1) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 01 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,1) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 01 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,1) end}
renoise.tool():add_menu_entry{name="Mixer:Paketti..:Paketti Overdub 01 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,1) end}
renoise.tool():add_menu_entry{name="--Pattern Matrix:Paketti..:Paketti Overdub 01 (Metronome/Line Input)",invoke=function() recordtocurrenttrack(true, true,1) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 01 (Metronome/No Line Input)",invoke=function() recordtocurrenttrack(true, false,1) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 01 (No Metronome/Line Input)",invoke=function() recordtocurrenttrack(false, true,1) end}
renoise.tool():add_menu_entry{name="Pattern Matrix:Paketti..:Paketti Overdub 01 (No Metronome/No Line Input)",invoke=function() recordtocurrenttrack(false, false,12) end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 01 (Metronome/Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(true, true,1) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 01 (Metronome/no Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(true, false,1) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 01 (No Metronome/Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(false, true,1) end end}
renoise.tool():add_midi_mapping{name="Paketti:Paketti Overdub 01 (No Metronome/No Line Input)",invoke=function(message) if message:is_trigger() then recordtocurrenttrack(false, false,1) end end}
---
function recordfollow()
local w=renoise.app().window
local t=renoise.song().transport
local pe=renoise.ApplicationWindow.MIDDLE_FRAME_PATTERN_EDITOR
if not t.playing then t.playing = true end
w.active_middle_frame=pe
--w.lower_frame_is_visible = true
--w.upper_frame_is_visible = true
-- Case 1: Not editing but following
if not t.edit_mode and t.follow_player then
t.edit_mode = true
t.follow_player = false
return
end
-- Case 2: Editing and following
if t.edit_mode and t.follow_player then
t.follow_player = false
return
end
-- Case 3: All other cases (false/false or true/false)
t.edit_mode = true
t.follow_player = true
end
renoise.tool():add_keybinding{name="Global:Paketti:Record Follow",invoke=function() recordfollow() end}
-------------
function simpleplayrecordfollow()
local w=renoise.app().window
local t=renoise.song().transport
local pe=renoise.ApplicationWindow.MIDDLE_FRAME_PATTERN_EDITOR
-- w.upper_frame_is_visible=false
-- w.active_middle_frame=1
-- w.lower_frame_is_visible=true -- if lower frame is hidden, don't reshow it.
if t.playing and t.follow_player and t.edit_mode and w.active_middle_frame==pe
then t.follow_player=false
t.edit_mode=false return
else t.follow_player=true
t.edit_mode=true
w.active_middle_frame=pe end
if t.playing==true -- if playback is on, continue playback and follow player, toggle edit, display pattern editor
then t.follow_player=true
t.edit_mode=true
w.active_middle_frame=pe
else t.playing=true -- if playback is off, start playback and follow player, toggle edit, display pattern editor
t.follow_player=true
t.edit_mode=true
w.active_middle_frame=pe end
end
renoise.tool():add_keybinding{name="Global:Paketti:Simple Play Record Follow",invoke=function() simpleplayrecordfollow() end}
renoise.tool():add_keybinding{name="Global:Paketti:Simple Play Record Follow (2nd)",invoke=function() simpleplayrecordfollow() end}
-- PD use
renoise.tool():add_keybinding{name="Global:Paketti:TouchOSC Sample Recorder and Record", invoke=function() handle_sample_recording() end}
renoise.tool():add_keybinding{name="Global:Paketti:TouchOSC Pattern Editor", invoke=function() renoise.app().window.active_middle_frame=renoise.ApplicationWindow.MIDDLE_FRAME_PATTERN_EDITOR end}
renoise.tool():add_keybinding{name="Global:Paketti:TouchOSC Sample Editor", invoke=function() renoise.app().window.active_middle_frame=renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EDITOR end}
-------------
--renoise.app().window.active_middle_frame=sampleEditor
-- Function to handle starting and stopping sample recording
function handle_sample_recording()
local dialog_visible = renoise.app().window.sample_record_dialog_is_visible
local song = renoise.song()
renoise.app().window.active_middle_frame=renoise.ApplicationWindow.MIDDLE_FRAME_INSTRUMENT_SAMPLE_EDITOR
if not dialog_visible then
renoise.app().window.sample_record_dialog_is_visible = true
renoise.song():insert_instrument_at(renoise.song().selected_instrument_index+1)
renoise.song().selected_instrument_index=renoise.song().selected_instrument_index+1
pakettiPreferencesDefaultInstrumentLoader()
renoise.song().selected_sample.loop_mode = 2
song.transport:start_stop_sample_recording()
return
else
song.transport:start_stop_sample_recording()
local sample=renoise.song().selected_sample
end
-- renoise.song().selected_sample_index=1
local sample=renoise.song().selected_sample
-- sample.mute_group = 1
sample.interpolation_mode=preferences.pakettiLoaderInterpolation.value
sample.beat_sync_enabled = false
sample.beat_sync_mode = 2
renoise.song().selected_instrument.sample_modulation_sets[1].filter_type=preferences.pakettiLoaderFilterType.value
if preferences.pakettiPitchbendLoaderEnvelope.value then renoise.song().selected_instrument.sample_modulation_sets[1].devices[2].is_active = true else end
sample.oversample_enabled = preferences.pakettiLoaderOverSampling.value
sample.autofade = preferences.pakettiLoaderAutoFade.value
sample.autoseek = preferences.pakettiLoaderAutoseek.value
sample.oneshot = preferences.pakettiLoaderOneshot.value
sample.loop_mode = preferences.pakettiLoaderLoopMode.value
sample.new_note_action = preferences.pakettiLoaderNNA.value
sample.loop_mode = 2
sample.loop_release = preferences.pakettiLoaderLoopExit.value
end
renoise.tool():add_keybinding{name="Global:Paketti:Start/Stop Sample Recording and Pakettify",invoke=function() handle_sample_recording() end}