< Back to IRCAM Forum

Macros and Delays

Today I encountered a problem which leaves me clueless. I tried out many variants but I couldn’t found the reason of the problem or a solution. The delay in the third line of the following group is ignored and the macro is instead executed immediately:

NOTE 6400 2/3 ; E4
group TremQuart_1 {
VZ1 play $offms 1
@fi_fast(“VZ1”, -1, 40) // first macro
($durms)ms @fo_late(“VZ1”, -1, 75) // second macro, delay ignored!
75ms VZ1 play -1
}

I could verify that the value of $durms is about 3000, as expected. I also replaced the delay in millis by 2 beats, what didn’t help either: The sound produced by VZ1 is always stopped immediately instead only after 3 s (or 2 beats). If I replace the first macro with a message line, the result is (almost) as expected.

NOTE 6400 2/3 ; E4
group TremQuart_1 {
VZ1 play $offms 1
inmix VZ1 -1 40 // message instead of macro
($durms)ms @fo_late(“VZ1”, -1, 75) // delayed as specified
75ms VZ1 play -1
}

I don’t understand why. Is there something wrong in the syntax of the macros?

@MACRO_DEF fi_fast($object, $tolevel, $millis) {
group {
@local $fil
curve
@grain := 5ms
@action := {
group {
inmix $object $fil 5
}
}{
$fil
{
{ -96 } @type “circ_out”
($millis)ms { $tolevel }
}
}
}
}

@MACRO_DEF fo_late($object, $fromlevel, $millis) {
group {
@local $fol
curve
@grain := 5ms
@action := {
group {
inmix $object $fol 5
}
}{
$fol
{
{ $fromlevel } @type “exp_in”
($millis)ms { -96 }
}
}
}
}

Update: Sorry, I confused two of the many variants which I tried out. The working version is the one which follows here.

NOTE 6400 2/3 ; E4
group TremQuart_1 {
VZ1 play $offms 1
inmix VZ1 -1 40 // message instead of macro
}
($durms)ms group TremQuart_1_end { // delay on another group
@fo_late(“VZ1”, -1, 75) // delayed as specified
75ms VZ1 play -1
}

Hello Kyl.

It works here as expected. Can you send the version number of your object ? (send an “info” message to antescofo~ and you will see in the console the information needed).

If you send a printfwd message to antescofo~, it will open a text window with the listing of the actual score after the macros have been expanded. So you can check that everything is as you think. I give below the expansion of the fragment of your code. With respect to the initial code fragment you give, I just added initialization for $offms and $durms, a print message print “FROM HERE wait " $durms " ms” between the two macro calls and added a print START $NOW at the beginning of the fo_late macro definition. The result of the expansion is:

  
NOTE 6400 2/3     	; beatcum = 0 IOI = 0.666667 ScoreTempo = 1 index/cuenum = 1 notenum = 1 Jumps = no 	 line 42  
    Group TremQuart_1    
    {  
        VZ1 play $offms 1   
        Group __anonymous8_group    
        {  
            @local $fil  

            Curve __anonymous7_curve  @Grain := 0.005 s, @Action :=  
                    {  
                        inmix "VZ1" $fil 5   
                    }  
            {  
                $fil  
                {  
                       { -96 } @type "circ_out"  
                    0.04 s { -1 }  
                }  
            }  
        }  
        print "FROM HERE wait " $durms " ms"   
        ($durms / 1000.0) s Group __anonymous14_group    
        {  
            @local $fol  

            print START $NOW   
            Curve __anonymous13_curve  @Grain := 0.005 s, @Action :=  
                    {  
                        inmix "VZ1" $fol 5   
                    }  
            {  
                $fol  
                {  
                       { -1 } @type "exp_in"  
                    0.075 s { -96 }  
                }  
            }  
        }  
        0.075 s VZ1 play -1   
    }  

and the corresponding trace emitted (in play mode) is:

VZ1 play 0 1  
inmix 1 0.0 "VZ1" -96.0 5  
print "FROM HERE wait " 3000 " ms"  
inmix "VZ1" -50.0083 5  
inmix "VZ1" -33.1634 5  
inmix "VZ1" -21.8407 5  
inmix "VZ1" -13.7276 5  
inmix "VZ1" -7.93265 5  
inmix "VZ1" -4.01664 5  
inmix "VZ1" -1.74511 5  
inmix "VZ1" -1 5  
print START 3  
inmix "VZ1" -1.0 5  
inmix "VZ1" -1.14727 5  
inmix "VZ1" -1.23377 5  
inmix "VZ1" -1.37109 5  
inmix "VZ1" -1.58907 5  
inmix "VZ1" -1.9351 5  
inmix "VZ1" -2.48438 5  
inmix "VZ1" -3.3563 5  
inmix "VZ1" -4.74039 5  
inmix "VZ1" -6.9375 5  
inmix "VZ1" -10.4252 5  
inmix "VZ1" -15.9616 5  
inmix "VZ1" -24.75 5  
inmix "VZ1" -38.7008 5  
inmix "VZ1" -60.8462 5  
inmix "VZ1" -96.0 5  
VZ1 play -1  

which seems ok.

Dear JLG,

thank you for your quick reply. It’s embarrassing but it’s working now also in my set-up. It seems that the problem lies somewhere in the Max environment. For example, I also observe that the Max freqshift~ object sometimes goes stray after having run Max for a longer time (three or more hours). It produces other frequencies than it should, even after a “clear” message to reset its internal quadrature filter. It seems that something goes wrong within the state of the Max patch in the application, e.g. caches or whatever. But yesterday’s behaviour with the omitted delay doesn’t really fit into this track, because the delays etc. should of course be managed in Antescofo’s own internal memory. Both my Max (7.2.3) and Antescofo (0.92) are up to date; the OS is Yosemite (10.10.5). Vector sizes currently are rather slack (2048 for I/O, 8 for the signals) but I can’t imagine how these could have an influence in the errors after some hours of use. Actually, it feels like hardware having got too hot. Of course this raises some doubt in the reliability of software-based sound synthesis. I consider reliability very important, so I really would like to understand the problems.

Maybe you have an idea what could be the cause. Many thanks again for your assistance.

Hmm strange indeed.
The macro @fo_late is not launched if $durms is not a number. This may happen if the initialization code of $durms is not correctly performed for some reason, or if the memory is trashed by a bugged object. A signal vector size of 8 is low and some deadlines were perhaps not meet (even if the deadline corresponding to the audio vector size are meet). In this case, some messages can be lost which may compromise the logic of the application. Messages are also lost if they are too many in the same logical instant.

@KYL: Jean-Louis is right. A Signal Vector size of 8 is overkill and will certainly cause unpredictable behavior on big patches. If you want to be generous, depending on what kind of signal processing you use in your patch, I wouldn’t use a Sig VS of less than 64 (which is what the most expensive sound cards provide anyway).

Low Signal vector size will reduce reaction time of Max for Control computation. So if you do a lot of them, they might be missed or delayed depending on whether you have Overdrive on or not (BTW, you should always keep that on!).

Thank you for this advice. I’ve now set the size of the signal vector to 128. However, it’s at least not obvious how it affects performance only after some hours of application up-time. But it might be due to the interplay of diverse factors, the Sig VS being one of them.