Click here to Skip to main content
15,797,923 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
For reasons, I cannot simply generate a Triangle Wave of the frequency I need, but I have a sine wave and a square wave at that frequency.

I cannot keep additional state.

I need an algorithm to compute a triangle wave from a sine wave or a square wave

Triangle wave - HandWiki[^]

This contains math formalisms for it, but I do not understand math formalisms.

I was hoping someone could apply the relevant concepts contained therein to some code. I don't care what language, as long as it is portable to something else.

What I have tried:

I tried generating the triangle wave by itself, but I need to generate it in chunks at a time and keep the phase continuous between chunks so I don't get clicks. I have a sine wave that tracks using an ever increasing integer multiplied by a delta value based on the frequency, but that isn't an up and down motion - it's more like a saw tooth if I apply a modulo to it, but again, I need the triangle.
Updated 24-Jul-22 7:50am
Peter_in_2780 23-Jul-22 17:29pm    
A symmetric triangle wave is the mathematical integral of a square wave (symmetrical about 0 amplitude), so use your square wave process and keep adding them up. You'll need to figure out a starting value/phase to keep it on the island.
honey the codewitch 23-Jul-22 17:47pm    
but if i add up the square waves they will compute a tri wav at a much lower frequency and much higher amplitude. The amplitude I can scale, but the frequency issue is problematic. I was hoping I could just "straighten out the curves" in the sin wave and work from that. Barring that, I'd need to bisect the square wave. Computing tangents I guess would work? But I'm not great at math. I was in my 20s before I learned that trig was based around triangles. *hides*
Peter_in_2780 23-Jul-22 17:55pm    
No, the triangle wave is the same frequency as the square wave.

Square wave: +1 +1 +1 +1 +1 -1 -1 -1 -1 -1 +1 +1 +1 +1 +1 -1 -1 -1 -1 -1 ....
Running sum: +1 +2 +3 +4 +5 +4 +3 +2 +1 +0 +1 +2 +3 +4 +5 +4 +3 +2 +1 +0 ....
Shift and scale to your taste...
honey the codewitch 23-Jul-22 17:58pm    
Oh okay. I *think* I get it. Time to go get dangerous.
merano99 23-Jul-22 19:08pm    
"I have a sine wave and a square wave at that frequency." Do you know the frequency?
If we assume that it is easier to generate a triangle signal from a symmetrical square wave signal, you would have to sample the signal with a fairly exact timing. You need a lot of information about the signal to be sampled. Latencies and other effects occur as a result of the sampling and the calculation.

If you have a square wave of which you know the amplitude and period, can't you just create the triangle wave from that using simple geometry?
Triangle wave - HandWiki[^]
If the rise start point of the TW is synced with the rise of the SW, then all you are doing is drawing the diagonal from BL to TR, then TL to BR which is trivial and should be fast and space efficient.

If the sync is "stepped" as per the diagram in the link, then that's just an offset start point you need to cater for - again simple geometry.
Share this answer
honey the codewitch 24-Jul-22 10:29am    
Yeah I solved it this way earlier thanks to Peter. I just wasn't able to come at the problem the right way. Funny how something so simple can get so complicated.
OriginalGriff 24-Jul-22 10:53am    
We've all over complicated stuff - it's probably part of the job description ... :D
From Wikipedia:
It is possible to approximate a triangle wave with additive synthesis by summing odd harmonics of the fundamental while multiplying every other odd harmonic by −1 (or, equivalently, changing its phase by π) and multiplying the amplitude of the harmonics by one over the square of their mode number, n (which is equivalent to one over the square of their relative frequency to the fundamental).
That's a straightforward algorithm, and the article says it converges on a triangle wave fairly quickly. (EDIT: The fundamental is the sine wave, but you probably know that.)
Share this answer
honey the codewitch 24-Jul-22 10:28am    
Whoops. my reply was meant for Griff
I probably would go for a table based approach.
Simply storing the values of the function you want over the domain of interest.
This typically yields the fastest execution without any timing issues, at the expense of some storage space.
Share this answer
merano99 24-Jul-22 13:05pm    
A table-based approach for a signal that consists of two straight lines, i.e. is rather easy to calculate, would probably be a waste of space. The author probably forgot to indicate that he is working on a microcontroller. In general, however, this is really a high-performance approach for complex signals.
Luc Pattyn 24-Jul-22 13:10pm    
the way I understood it, the function should equal the inverse of a sine: periodically sample the given sine wave, and use that as the index into the lookup table.

And doing so, inaccuracies of the sampling time would automatically be compensated for.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900