Nyquist Ripping Stems from Stereo Loop Using Labels

Thanks Steve for all your suggestions and support (and keeping the thread open for me to try things out). I spent some time digesting and trying things out with the added assistance.
Here is an update on my progress/attempts…

I was trying to access data outside of the original selection (as you noticed) which may be the real challenge instead of actually repeating the audio.
I did not yet try using the AUD-DO command to reselect part way through the script.


From your suggestion I decided to make a macro of it in Audacity first and then convert that to a Nyquist Macro.

Here is the Audacity Macro exported:

Repeat:Count="10"
Invert:Use_Preset="<Factory Defaults>"
ShiftUp:
MixAndRenderToNewTrack:
PrevTrack:
Toggle:
PrevTrack:
Toggle:
LastTrack:
Toggle:
CursorRight:
MoveToNextLabel:
MoveToNextLabel:
MoveToNextLabel:

SplitNew:
NewMonoTrack:
MoveToPrevLabel:
Silence:Use_Preset="<Current Settings>"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
TrackClose:
PrevTrack:
TrackClose:
LastTrack:
Toggle:
Repeat:Count="10"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
PrevTrack:
TrackClose:
Toggle:
LastTrack:
Toggle:
MoveToNextLabel:
MoveToNextLabel:
MoveToNextLabel:

SplitNew:
NewMonoTrack:
MoveToPrevLabel:
Silence:Use_Preset="<Current Settings>"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
TrackClose:
PrevTrack:
TrackClose:
LastTrack:
Toggle:
Repeat:Count="10"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
PrevTrack:
TrackClose:
Toggle:
LastTrack:
Toggle:
MoveToNextLabel:
MoveToNextLabel:
MoveToNextLabel:

SplitNew:
NewMonoTrack:
MoveToPrevLabel:
Silence:Use_Preset="<Current Settings>"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
TrackClose:
PrevTrack:
TrackClose:
LastTrack:
Toggle:
Repeat:Count="10"
PrevTrack:
Toggle:
MixAndRenderToNewTrack:
PrevTrack:
PrevTrack:
TrackClose:
Toggle:
LastTrack:
Toggle:
MoveToNextLabel:
MoveToNextLabel:
MoveToNextLabel:

I could not find a “way to loop” sections of the macro N times using the built-in “Macros…” managing tool so I used the samples and resources you provided to do just that in a Nyquist Macro along with a simple control menu.

Here is roughly the same macro but translated to a Nyquist Macro using the Nyquist Prompt and AUD-DO command:

;nyquist plug-in
;version 4
;type tool
;name "OutSTEMming RIP From Loop"
;author "A Cat"
;release 3.1.3

;control numberofloopsinaudio "Number of Loops in Recording" int " --- " 27 0 50
;control numberoffunctionrepeats "Unique Label of Stem Amount " int " --- " 10 0 25

(aud-do  (format nil "Repeat: Count=~S" numberofloopsinaudio))
(aud-do  "Invert:Use_Preset=<Factory Defaults>")
(aud-do  "ShiftUp:")
(aud-do  "MixAndRenderToNewTrack:")
(aud-do  "PrevTrack:")
(aud-do  "Toggle:")
(aud-do  "PrevTrack:")
(aud-do  "Toggle:")
(aud-do  "LastTrack:")
(aud-do  "Toggle:")
;(aud-do  "CursorRight:")

(let (
		(repeattimes numberofloopsinaudio )
	)
	
	(dotimes (i numberoffunctionrepeats)
		(setf repeattimes
			(- repeattimes 1)
		)

		(aud-do  "MoveToNextLabel:")
		(aud-do  "MoveToNextLabel:")
		(aud-do  "MoveToNextLabel:")
		(aud-do  "SplitNew:")
		(aud-do  "NewMonoTrack:")
		(aud-do  "MoveToPrevLabel:")
		(aud-do  "Silence:Use_Preset=<Current Settings>")
		(aud-do  "PrevTrack:")
		(aud-do  "Toggle:")
		(aud-do  "MixAndRenderToNewTrack:")
		(aud-do  "PrevTrack:")
		(aud-do  "TrackClose:")
		(aud-do  "PrevTrack:")
		(aud-do  "TrackClose:")
		(aud-do  "LastTrack:")
		(aud-do  "Toggle:")
		(aud-do  "Invert:Use_Preset=<Factory Defaults>")
		(aud-do  (format nil "Repeat: Count=~S" repeattimes))
		(aud-do  "PrevTrack:")
		(aud-do  "Toggle:")
		(aud-do  "MixAndRenderToNewTrack:")
		(aud-do  "PrevTrack:")
		(aud-do  "PrevTrack:")
		(aud-do  "TrackClose:")
		(aud-do  "Toggle:")
		(aud-do  "LastTrack:")
		(aud-do  "Toggle:")
	)
""
)

(print "COMPLETED")

They both work (from my designated starting point), but the Nyquist Macro allows for me to loop sections of the Macro functions easily.
I then performed the same operations on the same sample data using both the Audacity Macro (68seconds) and the Nyquist Macro (161seconds). The Nyquist Macro was 2.367x times slower.

This gif is at 10x speed using the Audacity Macro.
https://drive.google.com/file/d/1QQz9B-sh5QbHkgC-NtXKIA7PNKJPdE87/view?usp=sharing

I predict this time difference has something to do with Audacity caching AUD-DO commands as memory allocation when using the Nyquist Prompt. It is a noticeable difference however the process still worked on the sample data and was automated. So I consider it acceptable as a solution.
I have yet to apply it to larger audio data.

I do receive these WARNING MESSAGES though it does not stop the process:
AudacityErrorModuleNotFound.PNG
.
https://drive.google.com/file/d/1QQz9B-sh5QbHkgC-NtXKIA7PNKJPdE87/view?usp=sharing
To do this successfully I was using a single label track seen briefly at the start and top of the gif linked directly above.


In general the macro:

  1. Navigates to the label that spans the section of the next stem-instrument
  2. Splits it onto another track
  3. Creates another (mono) track
  4. Selects the wider label which represents the loop segment
  5. Creates silence for that duration
  6. Combines the two newly made tracks
  7. Inverts the track
  8. Repeats the track N times
  9. Mix and renders the inverted stem out of the loop
  10. Rinse and repeat…

Step 1 and 4 are important in that process.
This procedure requires the labels to be all in one label track.

Originally I found through your “Export Labels” forum post (https://forum.audacityteam.org/t/export-labels/54745/1) that I could export and re-import labels to merge all the label tracks into one. Which turned out to be unnecessary as I can simply double-click to select a loop segment and use the hotkey Ctrl+B to create a label spanning the exact required location.



Which leads me to my next challenge.

Since I require the Step 6 Mix and Rendered track to be the same loop length of a loop for when it gets to be repeated in Step 8 I suppose that for most applications I could simply place a label of the loop “over top” the stem segment. In theory that would work however there are times when these labels would be butted-up together so my next step has become

Use the resources provided on label reading and creation - which, yes, seems to be a pain - to read all the labels and split any labels that span across two loop segments into two segments.
You may be able to see what I’m suggesting in the following picture:
AudacityAlignmentSummary.PNG
.
After that I believe I can focus on the original assumption in the first post which is aligning the track at the start (which has been done manually so far). In summary for that the process will be to shift samples and take the shifted position where the subtraction of the two audio signals produce the lowest result. Then find the length of the loop by comparing and aligning with a third loop iteration.
AudacityCreateAndSplitLoopLabels.PNG