< Back to IRCAM Forum

user-defined inlets

In another thread Ashia mentioned that in order to use user-defined inlets he needs to give us more information.

I would love to use those for a project I’m working on:
I’ve made a pd patch that outputs all kinds of data about the incoming audio. (For example the dominant formant frequency of the input)
I would like to use that data to let Antescofo track the tempo even when the pitches that are sung are improvised. And/or way out of tune! ;).

Another patch I made extracts the chord sequence from incoming midi notes, and stores it in an array, one chord per beat. It then tries to find any repetitions in the chord sequence, and if there are any, it can make an educated guess as to which chord is coming next.
That information is very handy when doing algorithmic automatic accompaniment.
This patch has some bugs at the moment and I was wondering if Antescofo could be adapted to do this better.

Bart,

You attempt to synchronize your actions/queues to a sequence different from the traditional “score” used in the score following jargon. There are two ways to do this in Antescofo: (1) using “user-defined inlet” types, and (2) by binding actions to outside variables using whenever or the like in Antescofo language.

The first approach has been existing for some time. The second is very elegant and new. I attempt to describe the first here but feel free to ask for the second (since it’ll force us to document and publish an example!!).

An instantiated Antescofo object without any @inlets definition will create an object expecting audio input (for polyphonic pitch). If you use @inlets then you can either use existing keywords (KL for polyphonic audio, MIDI for polyphonic MIDI input, hz for continuous pitch frequency input for Sigmund~ and the like) or a user-defined keyword! For example, creating an Antescofo object as [antescofo~ @inlets foo] in Max/Pd will create an object expecting the user-defined FOO input type.

Once this is done, the rest is the same as before! Especially, your score structure stays the same. The only difference is that from here on, the score event sequence has a different semantic. You should think of regular NOTE, CHORD, TRILL and MULTI as mere data-containers. Once the score is constructed, then it is just a matter of STARTing the score and sending your numerical data to the object as numerical lists for it to work.

This is how basic Event score commands change their meaning in a user-defined scenario:

  • NOTE: indicates a “scalar” input
  • CHORD: indicates vector input (polyphony!)
  • TRILL: combination of scalar and vector that can enter in any order
  • MULTI: combination of above but ordered
  • VARIANCE: sensitivity/tolerance to scalar data (in audio/midi mode it’s in midicents!)

Note that the syntax does not change AT ALL. It’s just the meaning of “pitch” which is replaced by your own definition! That’s why I suggest thinking about containers.

Everything works! You can also define several inlet types and CHANGE between them inside your score using @inlet command as you mentioned in previous posts. The only thing that does not work for the time being is the combination of highly continuous input (audio) with highly discrete input (MIDI) in the same score which causes boundary problems in recognition (I should find some time to finish this up!).

Thank you very much for that explanation.
I will try it out this afternoon.

Of course I would love to learn the other method as well… :slight_smile:

Resurrecting this thread with a related issue :slight_smile:

I’m toying around with sync-ing Antescofo to a looped audiofile. The patch & score are attached; here’s my code:

BPM 69  
NOTE 10 1 START @hook  
NOTE 20 1 TWO  
NOTE 30 1 DREI  
NOTE 40 1 QUATRO @jump START

I had to use the MIDI @inlet to “trick” antescofo into reacting to my input… I tried a generic FOO list but that didn’t work, or maybe I’m missing something.

Anyway, for the first iteration of the loop the system reacts as expected, but afterwards you see many (most) NOTEs being triggered simultaneously for every new jump.

Is there maybe a better way for achieving this behaviour?

Grig,

As of version 0.90 onwards, we have disabled the User-defined Inlet recognition for a very simple reason: This is much easier to implement using a variable entering Antescofo from Max/PD using setvar messages, and a whenever construction inside your code that actually implements how and what you want to recognize and what to do as a consequence (for example by using a switch). In fact, several Antescofo users lately have developped their own MIDI followers using the same procedure… .

This should be relatively easy to implement. Let us know if you need any help with this… .

Arshia

Thanks Arshia! I was vaguely aware about the deprecation of the user-defined inlets, but wasn’t entirely sure…

Just for reference, I think I got my desired result using this code:

@tempovar $t (69, 1)  

whenever ($a) {  
	$t := $a  
	print "pos " ($t.position)  
	print "tempo " ($t.tempo)  
	group beat @sync $t {  
		print one  
		0.5 print two  
	}  
}

Now, for every “setvar $1” message I send into the antescofo~ object, the user-defined tempo $t gets updated and can serve as a sync source.

Cheers,
Grig