Gemini replies:

It appears Tejas has identified a crucial bottleneck: the *Teensy Audio
Library’s metadata and memory overhead for UI elements*.

When you use hslider, nentry, or vslider in Faust, the compiler generates
metadata strings and internal variables to map these to a UI. On a
microcontroller like the Teensy, each of these elements consumes a portion
of the *DMAMEM* or *RAM* used by the Audio Library to manage the "patch
cord" system. If you have many instances of a Faust object, ...

On Tue, Mar 3, 2026 at 8:28 PM Tejas Rode <[email protected]> wrote:

> Haha! Thank you for sharing that! :)
>
> Unfortunately, neither of the recommendations of Gemini worked. What
> worked, again weirdly, is removing hslider() from the code. When I set
> freq, duty and phase to constants (namely 440, 0.5 and 0.5), I was able to
> create innumerable instances of triangle. I think what's coming in the way
> is not related to Teensy memory at all, but related to Faust's UI, where
> there's probably an upper limit on the number of UI elements that Faust
> allows. Since teensy doesn't need UI elements, I removed them from the
> code. However, I obviously don't want freq, duty and phase to have fixed
> values. I tried nentry(), but that being a UI element too, has the same
> problem. What is the ideal way I could initialize the three variables in
> this case?
>
> I'll get to smoothing once this gets fixed.
>
> Thanks!
> Tejas
>
> On Tue, Mar 3, 2026 at 7:29 PM Julius Smith <[email protected]>
> wrote:
>
>> Being obsessed with AI assistance nowadays, I had Gemini answer this one
>> directly in Chrome.  Gemini clearly knows more than me about life on a
>> Teensy, so I delegate that, but the topics I do know about sound correct to
>> me, so consider those "checked by someone who should know presuming he
>> really paid attention" :-).
>>
>> Regarding the smoothing making the artifact worse, please post a
>> standalone Faust program that illustrates it as simply as possible.
>> There's probably a simple problem to fix.  We smoothly use interpolated
>> delay lines all the time.
>>
>> --- Begin Gemini Weigh-In ---
>>
>> Based on the Faust documentation for Teensy
>> <https://faustdoc.grame.fr/tutorials/teensy/>, the issue Tejas is
>> experiencing with the fourth instance of the triangle wave is likely
>> related to *RAM (memory) constraints*.
>>
>> Here is a breakdown of why this is happening and how to address it:
>> Why the limit exists
>>
>> While the Teensy 4.1 is powerful, it has limited internal RAM.
>> Faust-generated objects, especially those using delay-based oscillators or
>> high-order interpolation (like squareND which Julius suggested), can
>> have a larger memory footprint than expected.
>>
>>    -
>>
>>    If your code compiles but fails to execute (e.g., stops at the "Test"
>>    print or crashes before setup), it usually means the global objects
>>    are exceeding the available *DTCM (Data Tightly Coupled Memory)*,
>>    causing the microcontroller to hang during initialization.
>>
>> Potential Solutions
>>
>>    1.
>>
>>    *Reduce Table Sizes:* If your triangle wave uses a large lookup
>>    table, reduce its size. The default Faust oscillators often use a table
>>    size of $2^{16}$ (65,536 samples), which is too large for multiple
>>    instances on a Teensy. You can try reducing it to $2^{15}$ or $2^{14}$
>>    in your .dsp file:
>>    Code snippet
>>
>>    // Example: reducing table size to 32768
>>    tablesize = 1 << 15;
>>
>>    2.
>>
>>    *Optimize Delay Lines:* Since Tejas mentioned using fdelay, it's
>>    important to know that every delay line allocates memory based on its
>>    maximum delay length. If you don't specify a maximum, Faust might default
>>    to a large value. You can use the -dlt (delay line threshold)
>>    compiler option to manage how memory is allocated for these.
>>    3.
>>
>>    *Check Memory Usage:* In the Arduino IDE, check the memory report
>>    after compilation. If "Global variables use..." is very high (near 100%),
>>    adding one more instance will push it over the edge.
>>    4.
>>
>>    *Use AudioMemory:* Ensure you have enough audio blocks allocated in
>>    your .ino file. While Tejas's snippet doesn't show the AudioMemory()
>>    call for the triangle instances, the tutorial recommends increasing this
>>    number if you have multiple audio inputs/outputs.
>>    C++
>>
>>    void setup() {
>>      AudioMemory(12); // Try increasing this value
>>      Serial.begin(115200);
>>      Serial.println("Test");
>>    }
>>
>>
>> For more details on managing memory for Faust on Teensy, you can refer to
>> the *Notes About Computational Power and Memory Footprint
>> <https://www.google.com/search?q=https://faustdoc.grame.fr/tutorials/teensy/%23notes-about-computational-power-and-memory-footprint>*
>> section of the official tutorial.
>>
>> On Tue, Mar 3, 2026 at 4:00 PM Tejas Rode <[email protected]> wrote:
>>
>>> Thank you for the suggestion, Julius! I tried using both fdelay and
>>> si.smoo(), but it worsened the artifact. I guess it's because the phase
>>> changed more often with those approaches, as compared to using just delay.
>>>
>>> On a different note, I'm trying to run this on teensy 4.1. I've followed
>>> this approach: https://faustdoc.grame.fr/tutorials/teensy/ . There is a
>>> weird problem, though, where I'm able to create at most three instances of
>>> the triangle. If I create a fourth instance, the code compiles, but doesn't
>>> do anything. Is there really an upper limit on the number of instances that
>>> could be created? How could I change the limit, if any? Here is the code:
>>>
>>> #include <Audio.h>
>>>
>>> #include "FaustTriangle.h"
>>>
>>> FaustTriangle faustTriangle[4];  // "Test" is printed only when the
>>> number of instances here are <= 3
>>>
>>> void setup() {
>>>
>>>   Serial.begin(115200);
>>>
>>>   Serial.println("Test");
>>>
>>> }
>>>
>>> void loop() {}
>>>
>>>
>>> Regards,
>>>
>>> Tejas
>>>
>>> On Thu, Feb 26, 2026 at 1:57 AM Julius Smith <[email protected]>
>>> wrote:
>>>
>>>> N is the order of interpolation.  It sounds like you want N=1, but
>>>> maybe compare to higher N when everything is done.
>>>>
>>>> Instead of delay, use fdelay, and run its delay parameter through a
>>>> smoother (e.g., si.smoo(), IIRC)
>>>>
>>>> On Thu, Feb 26, 2026 at 12:49 AM Tejas Rode <[email protected]>
>>>> wrote:
>>>>
>>>>> Thanks for the hint! This is what I have put together. It runs, but I
>>>>> have further questions.
>>>>>
>>>>> import("stdfaust.lib");
>>>>> freq = hslider("freq", 440, 11, 880, 1);
>>>>> N = 1;  // tried up to 4
>>>>> duty = hslider("duty", 0.5, 0, 1, 0.01);
>>>>> phase = hslider("phase", 0.5, 0, 1, 0.001);
>>>>> triangleND(N,freq,duty,phase) = squareND(N,freq,duty,phase) :
>>>>> fi.pole(p) : *(gain) with {
>>>>>   gain = 4.0*freq/ma.SR;
>>>>>   p = 0.999;
>>>>> };
>>>>> squareND(N,freq,duty,phase) = os.pulsetrainN(N,freq,duty) @
>>>>> round(phase*ma.SR/freq);  // phase has audible jumps
>>>>> process = triangleND(N,freq,duty,phase);
>>>>>
>>>>> I have two questions.
>>>>> 1. How does the value of N affect how the output sounds? I tried N=1
>>>>> to N=4, but didn't hear an audible difference. What value of N should I 
>>>>> set
>>>>> as default?
>>>>> 2. When I move the phase slider, there are audible jumps. It's
>>>>> probably because the phase is rounding to the nearest integer. Is there a
>>>>> way to make the phase change sound smooth?
>>>>>
>>>>> I'm quite new to FAUST. Thank you for all the help!
>>>>>
>>>>> Regards,
>>>>> Tejas
>>>>>
>>>>> On Sun, Feb 22, 2026 at 2:11 AM Julius Smith <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> I think I would just use a delay.  Search for "phase" in
>>>>>> oscillators.lib and you'll see various approaches.
>>>>>>
>>>>>> On Sat, Feb 21, 2026 at 9:43 PM Tejas Rode <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Julius,
>>>>>>>
>>>>>>> I have a followup question. If I want to add phase value as an
>>>>>>> argument to this triangleND function, what is the best way to do that?
>>>>>>>
>>>>>>> Thanks!
>>>>>>> Tejas
>>>>>>>
>>>>>>> On Fri, Feb 13, 2026 at 4:08 PM Julius Smith <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi Tejas,
>>>>>>>>
>>>>>>>> You might try modifying os.triangleN(N,freq) to add a duty factor,
>>>>>>>> where N is the order of the aliasing suppression.
>>>>>>>> It's based on the paper "Alias-Suppressed Oscillators based on
>>>>>>>> Differentiated Polynomial Waveforms" by Valimaki et al.
>>>>>>>>
>>>>>>>> My guess:
>>>>>>>>
>>>>>>>> triangleND(N,freq,duty) = squareND(N,freq,duty) : fi.pole(p) :
>>>>>>>> *(gain) with {
>>>>>>>>   gain = 4.0*freq/ma.SR; // for aproximate unit peak amplitude
>>>>>>>>   p = 0.999;
>>>>>>>> };
>>>>>>>> squareND(N,freq,duty) = pulsetrainN(N,freq,duty);
>>>>>>>>
>>>>>>>> Then your 25% case would be os.triangleND(N,freq,0.25);
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> - Julius
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Feb 13, 2026 at 10:39 AM Tejas Rode <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hello,
>>>>>>>>>
>>>>>>>>> I want to create an anti-aliased dfdsdg triangle wave with 25%
>>>>>>>>> duty cycle for use in a teensy project. I'm new to faust. Is there a
>>>>>>>>> resource that I can refer to? Any ideas that can help me start 
>>>>>>>>> implementing
>>>>>>>>> this?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Tejas
>>>>>>>>> _______________________________________________
>>>>>>>>> Faudiostream-users mailing list
>>>>>>>>> [email protected]
>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> AI has taken my job, but only I know what it is.
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> AI has taken my job, but only I know what it is.
>>>>>>
>>>>>
>>>>
>>>> --
>>>> AI has taken my job, but only I know what it is.
>>>>
>>>
>>
>> --
>> AI has taken my job, but only I know what it is.
>>
>

-- 
AI has taken my job, but only I know what it is.
_______________________________________________
Faudiostream-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to