Tidal icon indicating copy to clipboard operation
Tidal copied to clipboard

Pulse Width Modulation (PWM) for oscillator functions

Open axcmp opened this issue 5 years ago • 5 comments

Another suggestion, regarding the integration of Pulse Width Modulation (PWM) for oscillator functions (i.e. to change the duty cycle of the square and triangle functions)

The range would be from 0.0 to 1.0 for the 0% to 100% duty cycle range values respectively.

squareBy or sqrBy function prototype

sqrBy duty_cycle

d1 $ s "bd*8" # speed (slow 2 $ range 0.5 1.5 sqrBy 0.25)

This example, uses a sqrBy function describing a square wave with 25% “on” and 75% “off” time in a duty cycle.

triBy function prototype

triBy duty_cycle

d1 $ s "bd*8" # speed (slow 2 $ range 0.5 1.5 triBy 0.75)

This example, uses a triBy function describing a triangle wave reaching its peak at 75% of its duty cycle.

axcmp avatar Sep 12 '19 19:09 axcmp

I'm not entirely sure this isn't buggy (there's a bit of weirdness to getting the modulation working), but it seemed OK during my brief testing:

pulse wp = innerJoin $ sig <$> do {
  w <- wp;
  return $ \t -> if ((cyclePos t) > (1-w)) then 1 else 0
}

d1 $ s "cp*8" # shape (pulse "<0.75 0.25>" * 0.8)

bgold-cosmos avatar Sep 13 '19 16:09 bgold-cosmos

No, in this case I am referring to applying PWM to oscillator functions, like described initially, in this case to square and triangle functions.

I can also add, that I didn’t mention saw or isaw because these would be the same as triBy 1 and triBy 0 respectively.

Also I didn’t mention a sineBy function either (which would affect the initial amount of x radians of the sine wave, in order to have an in-between from the initial x == 0 for the sine function and the initial x == 1 for the cosine function), because I think this can be achieved through the use of an offset

d1 $ s "bd*64" # gain (sine)                                                                                                                                                                         
                                                                                                                                                                                                     
d2 $ s "bd*64" # gain (0.5 <~ (sine))      

Besides this, what would probably be an interesting experience in modulation, would be to have log and exp functions available in Tidal.

axcmp avatar Sep 14 '19 13:09 axcmp

What I wrote is a variable-width square wave, where you can control the duty cycle with a pattern. Doing the same with a saw/triangle would be straightforward.

If instead you want to replace a smooth curve with a pulse train that integrates to the same signal, that's a bit of a different problem, but I'm not sure how that could be used in Tidal

bgold-cosmos avatar Sep 17 '19 18:09 bgold-cosmos

@bgold-cosmos I understand, I was expecting it to sound like this

d1 $ s "sn*8" # shape (pulse "<0.75 0.25>*16" * 0.8)

For someone who has your knowledge of Haskell I believe this is all straight forward, thank you.

axcmp avatar Sep 23 '19 20:09 axcmp

Is there still something needed here?

yaxu avatar Nov 12 '21 10:11 yaxu