# Combining two wave generation formulas does not work as expected (MATLAB/OCTAVE)

I'm trying to convert sawtooth wave calculation formula to Octave/Matlab language. Here are the original formulas. My Desmos take is here. I've got formulas for triangle wave and square wave working but, sawtooth won't work in either way like showed in Desmos sheet (two last formulas there).

Here's my Octave code (active saw calculation is simplified version of the above equation in comments):

function saw = saw_wave_trig(fs, f0, s, m, w)
% fs = sample rate
% f0 = fundamental frequency
% s  = 'sharpness'
% w  = 'width'
% m  = 'tooth direction'
% example: saw = saw_wave_trig(44100, 440, 0.03, -2, 1);

t = 0:1/fs:1;
##saw = m .* ((1.+ triangle_wave_trig(fs, (2*(f0/w)+1)/4, s, w) .* ...
##              square_wave_trig(fs, f0/2, s, w))./2) ...
##     .- sign(m);

##saw =  m .* ...
##            (1 .+ ...
##                  ((1.-(2.*acos((1-s) .* sin((2*pi*((2*(f0/w)+1)/4)).*t')))./pi) .* ...
##                       (2 .* atan(sin((2*pi*(f0/w/2)) .* t')./s))./pi)) ./ ...
##                         2 .- sign(m);

saw = (4.*asin((s-1).*sin((pi*t'.*(2*f0+w))./ ...
(2*w))).*acot(s*csc((pi*f0.*t')./w)))./pi^2-sign(m)-1;

audiowrite('test_saw_trig_wave.wav',saw, fs);
plot(t, saw);


which (the commented calculations as well) produces kind of morph from negative side triangle wave to correct looking sawtooth wave, as seen in attached plot (Audacity used):

So, as my knowledge in math and Octave/Matlab is quite limited, there sure is some basics done wrong in my Octave/Matlab code. Maybe the multiplication of triangle and square needs to be done differently?

Any help in solving this is appreciated.

NOTE! This method is part of the experiment I'm doing with various methods out there to synthesize sawtooth (and other type) waves for audio use.

EDIT: Here are those triangle_wave_trig() and square_wave_trig() functions (f1() and f2() in Desmos sheet) which of both works correctly:

function tri = triangle_wave_trig(fs, f0, s, w)
% fs = sample rate
% f0 = fundamental frequency
% s  = 'sharpness'
% w  = 'width'
% example: tri = triangle_wave_trig(44100, 440, 0.03, 1);

t = 0:1/fs:1;
tri = 1 .- (2 .* acos((1 - s) .* sin((2 * pi * (f0 / w)) .* t')) ./ pi);

audiowrite('test_triangle_wave.wav',tri, fs);
plot(t, tri);

function sqw = square_wave_trig(fs, f0, s, w)
% fs = sample rate
% f0 = fundamental frequency
% s  = 'sharpness'
% w  = 'width'
% example: sqw = square_wave_trig(44100, 440, 0.03, 1);

t = 0:1/fs:1;
sqw = 2.0 .* (atan(sin((2 * pi * (f0 / w)) .* t') ./ s) ./ pi);

audiowrite('test_square_wave_trig.wav',sqw, fs);
plot(t, sqw);
hold on;
plot(t, square(2*pi*f0*t'));


sqw = square_wave_trig(44100, 440, 0.03, 1); looks like this:

and generated wave file looks OK (same with the triangle wave function).

• Any reason not to use Matlab's sawtooth function directly?
– MBaz
May 27 at 22:15
• Hmm... to synthesise sawtooth waves for audio use? No, this is experimenting I'm doing with various methods out there (I would use BLEPs in real work). May 28 at 2:48
• Is your sampling rate large enough? I would start with fs = 20*f0.
– MBaz
May 28 at 13:01
• Sampling rate should be OK (edited my post). May 28 at 13:38

I had put the variable t to a wrong location in both (triangle and square wave) formulas. Here's the correct formula for calculation of saw:
saw = -(2.*m.*asin((s-1)*cos((pi*f0*t)/w)).*acot(s.*csc((pi*f0*t)/w)))./pi^2.-sign(m).+m./2;