First time here? Check out the FAQ!
x

Markers as Audio Sample Triggers

+2 votes
701 views
I was investigating using markers in an audio file to point out features by using the markers to trigger other audio  samples (like a 'ping' or impulse tick sound). Markers act like accurate triggers that highlight features/events contained in the audio file by serving as a gate parameter for Sample.  The goal is to simultaneously use a 0th order data sonification audio file as a control signal (working great) but also to trigger audio samples that indicate a feature in the audio/data through leveraging markers.

Maybe this is the wrong idea, but I thought about collecting markers and using as SortedCollection with something like

(1 repeatingRamp: 1.05s) tripWIres: #(markers)

where length is the same duration of the audio file (and then later on become dynamic) and markers is the array of marker times (probably between 0-1 to work with tripWires?)

Using markers as event triggers could be paired with the same audio features, but not necessarily.  I'm digging the idea of leveraging markers as trigger as a first step.

 

I have some Capytalk working that generates an array with normalized values between 0 and 1 from marker samples. It just doesn't play nicely with tripWires: array.

| filename markerSamplePosition  |
filename := 'Axial_Seamount_dbar_MEAN0MAXABS1_forMarkers.aif' asSamplesFile.

markerSamplePosition := (filename markers values asSet asSortedCollection) collect: [:i | (i / (filename sampleFrames)) asFloat].

self debugWithLabel: 'markers' value: (markerSamplePosition).

(1 repeatingRamp: 1.05s) tripWIres: #(markerSamplePosition)

 

Any guidance is appreciated! Other ways to attack the problem?
asked Jan 19, 2022 in Using Kyma by jonbellona (Adept) (1,360 points)
I kind of have an answer. A lot more manual work, but I have a proof of concept.
https://kyma.symbolicsound.com/library/embedded-markers-as-audio-triggers/

Steps
1. Embed markers in audio
2. Run the Capytalk and write down the times that are shown in debug window.
3. Copy the times into "tripWires: #()" array, used as gate for audio sample trigger
4. Playback. sounds are triggered exactly when they should be. no matter how much time stretching you do on the audio file.

I didn't quite completely answer my own question as I'm still looking to dynamically use the generated collection as the tripWires array, not a lot of manual copying/pasting (steps 2-3 above).  

Reframing a simpler question, how would I use an ordered collection variable name as Capytalk array "#()"?

1 Answer

+1 vote

Try:


(1 repeatingRamp: 1.05s) tripWIres: markerSamplePosition asArray

 

If you put #(markerSamplePosition) it doesn't convert the OrderedCollection into an Array. Instead it creates an array with a single item (ED: the symbol #markerSamplePosition and not an OrderedCollection as I originally suggested, see SSC's comment below) - which is not something tripWires: can handle - it needs an Array of numbers. 

answered Jan 22, 2022 by alan-jackson (Virtuoso) (15,840 points)
edited Jan 23, 2022 by alan-jackson
Yes Alan! Thanks!

Here's the final code, working
it's placed inside the Gate parameter of an Audio Sample that I want triggered from markers.

"create collection of markers based upon audio file with markers"
| filename markerSamplePosition  |
filename := 'Axial_Seamount_dbar_MEAN0MAXABS1_markers.aif' asSamplesFile.

"show ALL markers including loop points, false positives"
"self debugWithLabel: 'Names and sample positions of the Markers' value:  (filename markers)."

"collect in order and normalize 0-1 value"
markerSamplePosition := (filename markers values asSet asSortedCollection) collect: [:i | (i / (filename sampleFrames)) asFloat].

"the list normalized 0-1"
"self debugWithLabel: 'markers' value: (markerSamplePosition)."

"this is the working code to get sample accurate triggering. +1 Alan"
(1 ramp: 5s) tripWires: markerSamplePosition asArray


Thank you. Thank you.

I'm updating my Kyma Sound library with example. https://kyma.symbolicsound.com/library/embedded-markers-as-audio-triggers/
Thanks, Alan! Your asArray message is a good solution.
To be precise, #(markerSamplePosition) is an Array containing the Symbol #markerSamplePosition, rather than an Array containing an OrderedCollection. Variable values are not substituted inside Literals like #() or {}.
Thanks SSC. noted.
Ah! yes of course, thanks SSC
...