How to extract all the car's from the elements of a list-of-lists?

57 Views Asked by At

If I create several empty labels on an Audacity 2.4.2 audio track (by clicking at various points along the track, and pressing Ctrl-B after each click), the Nyquist Prompt evaluates the expression

(cadar (aud-get-info "Labels"))

...to a list L whose elements are, in turn, 3-element sublists. For the sake of this description, I will refer to these 3-element sublists as "triples".

As it happens, for each of these triples, the first two elements are identical floating point numbers, and last element is the empty string.

Thus, a typical instance of such a list L may begin with something like

((0.12345 0.12345 "") (6.78901 6.78901 "") (23.45678 23.45678 "") ...

How can I create a new list consisting of all the first elements of such a list L?

For example, if my initial list L begins as shown above, what Nyquist expression involving the list L will evaluate to a list beginning as shown below?

(0.12345 6.78901 23.45678 ...)

(I tried stuff like (mapc (lambda (x) x) (cadar (aud-get-info "Labels"))), which not only failed to produce the desired result, but in some cases actually caused the addition of several new labels to the track, something I find completely bewildering. Therefore, as strange as this may sound, I must stress that I am looking for solutions that leave the original interface unchanged, and, in particular, do not add any new labels the currently selected track.)

1

There are 1 best solutions below

0
On

I'm using the current Audacity 3.1.3 version, but this should all be the same for Audacity 2.4.2.

In the Nyquist Prompt, if you run with the Debug button:

(print (aud-get-info "Labels"))

You will see an output similar to:

((1 ((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 ""))))

The first "1" is the track number (zero indexed). If there are two label tracks, it will look something like:

((1 ((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 "")))
 (3 ((0.449153 0.449153 ""))))

Each label is in the form: (start-time end-time "Label text") (Observe that the second label in track 1 is a region label.)

Thus the format of the data returned by (aud-get-info "Labels") is in the form:

(list (list track-num (list (first-label) (second-label) ...))
      (list track-num (list (first-label) ...)))

To get a list of labels from each track:

(let ((label-info (aud-get-info "Labels")))
  (dolist (track label-info)
    (print (second track))))

which, in the above case, will print to the Debug window:

((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 ""))
((0.449153 0.449153 ""))

To create a list of each label start times:

(let ((output-list ())
      (label-info (aud-get-info "Labels")))
  (dolist (track label-info)  ;step through each track in label-info
    (setf labels (second track))
    (dolist (label labels)     ;step through each label in labels
      (setf start-time (first label))
      (push start-time output-list)))
  ;; Print the list:
  (format nil "~a" output-list))

Which, in the above example. prints: (0.449153 2.25424 0.654661 0.184322)