Csound Csound-dev Csound-tekno Search About

[Csnd] Dynamic ftable multiplication/windowing

Date2023-08-12 12:59
From"Jeanette C."
Subject[Csnd] Dynamic ftable multiplication/windowing
Hey hey,
I'm playing with windowing waveforms, just like tablexkt does with the sinc 
function, though for several reasons, I would try to avoid this opcode. The 
situation is that the ftable waveform that should be multiplied with a window 
ftable is the result of some morphing method (ftmorf, hvs1, etc.). If the 
waveform is read at a steady frequency and phase, the solution seems to be 
easy, read the window function at the same rate and multiply the resulting 
a-rate signals. But what if the original wave is read with FM or PM? Can the 
same be applied to the window function and the output multiplied?

Best wishes,

Jeanette

-- 
  * Website: http://juliencoder.de - for summer is a state of sound
  * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g
  * Audiobombs: https://www.audiobombs.com/users/jeanette_c
  * GitHub: https://github.com/jeanette-c

Loneliness up ahead, emptiness behind <3
(Britney Spears)

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2023-08-12 21:28
FromST Music
SubjectRe: [Csnd] Dynamic ftable multiplication/windowing
Hi Jeanette,
   I apologize as I'm not fully understanding the question. I'm curious as to whether by "can the same be applied" you mean "is there a method" or "is it necessary".

Best,
Scott

On Sat, Aug 12, 2023, 7:59 a.m. Jeanette C. <julien@mail.upb.de> wrote:
Hey hey,
I'm playing with windowing waveforms, just like tablexkt does with the sinc
function, though for several reasons, I would try to avoid this opcode. The
situation is that the ftable waveform that should be multiplied with a window
ftable is the result of some morphing method (ftmorf, hvs1, etc.). If the
waveform is read at a steady frequency and phase, the solution seems to be
easy, read the window function at the same rate and multiply the resulting
a-rate signals. But what if the original wave is read with FM or PM? Can the
same be applied to the window function and the output multiplied?

Best wishes,

Jeanette

--
  * Website: http://juliencoder.de - for summer is a state of sound
  * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g
  * Audiobombs: https://www.audiobombs.com/users/jeanette_c
  * GitHub: https://github.com/jeanette-c

Loneliness up ahead, emptiness behind <3
(Britney Spears)

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here
Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here

Date2023-08-13 15:40
From"Jeanette C."
SubjectRe: [Csnd] Dynamic ftable multiplication/windowing
Aug 12 2023, ST Music has written:
...
> I'm curious as
> to whether by "can the same be applied" you mean "is there a method" or "is
> it necessary".
...
The question is: if an unwindowed waveform is read with some kind of
modulation, can the same modulation be applied to a window and then
applied to the resulting audio from the wave reading. Take this example:
iWave = ftgen(a wave)
iWindow = ftgen(a window)
aPhasor = phasor:a(kFreq1)
aModulator = some kind of oscillator
aWave = table((aPhasor * aModulator), iWave, 1)
aWindow = table((aPhasor * aModulator), iWindow, 1)
aWinwoedWave = aWave * aWindow
...
Would this be a correct way to apply windowing? In the simplest case I
would do this:
aWave = table(aPhasor, iWave, 1)
aWindow = table(aPhasor, iWindow, 1)
aWindowedWave = aWave * aWindow

Or even just multiply the window and the wave ftable, assuming they have
the same length, and then read the resulting ftable. Seeing that iWave
in practise will be the result of a dynamic morphing process, this
approach seems inefficient, since it involves reading the two ftables
(wave and window) every k-cycle, multiplying them, writing the output to
a new function table and only then use some kind of table/oscil opcode
to read it at the desired frequency to produce audio.

Hm, the more I think about it, the more I see the appeal of tablexkt...

Best wishes,

Jeanette

-- 
  * Website: http://juliencoder.de - for summer is a state of sound
  * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g
  * Audiobombs: https://www.audiobombs.com/users/jeanette_c
  * GitHub: https://github.com/jeanette-c

Give me a sign...
Hit me Baby one more time <3
(Britney Spears)

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2023-08-13 21:01
FromST Music
SubjectRe: [Csnd] Dynamic ftable multiplication/windowing
Hi Jeanette, not sure any of this helps but here are some things I've toyed with that use inharmonic waveforms etc. (for these examples I applied PM) that often don't have zero-crossing start/end values so generally have to be windowed due to artefacts/aliasing :

giTab   ftgen 0, 0, 4096, 9, 1,.4,0, 2.2,.5,0, 3.8,1,0
giSinc  ftgen 0, 0, 4096, 20, 9, 1, 1

instr 1
; amplitude of phase mod.
  kPMA  = linseg:a(0, p3/2, 1, p3/2, 0)
  kPhs  = lfo(kPMA, 220)
  aSig  = osciliktp(220, giTab, kPhs)
  aWin  = osciliktp(220, giSinc, kPhs)
  out(aSig * aWin)
endin

As you can see it "seems" (?) quite efficient in that it eliminates the need for extra table & phasor opcodes etc. The one thing here is that this requires a ksmps of 1. But if run as an UDO instead it's inconsequential as there is very little running at k-rate.

It also eliminates the need for window & waveforms to require the same table size.

However, another possible option is to simply convert the inharm. waveforms using GEN30:

 giInhPrt  ftgen 1, 0, 4096, 9, 1,.4,0, 2.2,.5,0, 3.8,1,0
giHarPrt  ftgen 2, 0, 4096, 30, giInhPrt, 1, 12

instr 1
  kPMA  = linseg:a(0, p3/2, 1, p3/2, 0)
  kPhs  = lfo(kPMA, 220)
  aSig  = osciliktp(220, giHarPrt, kPhs)
  out(aSig)
endin

This then doesn't require the use of a window & can provide essentially brick-wall bandlimiting (it appears slightly more efficiently that the sinc win. - freq. above 20kHz remain below -120dB) without losing almost any audible high freq. overtones. It of course comes with it's own limitations such as setting how many partials to use for GEN30. It also requires converting all waveforms necessary before using something like ftmorf but that's easy to accomplish with an UDO like the one I sent you.

It also eliminates the need for the second osc. used in the previous ex.

The linked inharm. vs harm. file runs at 192000, for demo purposes (for anyone who might choose to view with some type of FFT/spectrogram).

There are 4 parts to the score : PM of sine, inharm. waveform, GEN30 converted waveform and lastly an example that isolates and plays only the frequencies lost from the GEN30 conversion. Hopefully this demonstrates how little is lost by converting the unwindowed inharm. waves, some audible freq. might even be a result of aliasing, even at 192000, but I'm no expert.

The window approach might be more reliable though in regards to some situations, something I still have to test. The GEN30 has it's own benefits (such as when used with waveforms created using something like GEN21 that can't be cleaned up/bandlimited easily using a window) but that's a different issue.

And of course I haven't seen your whole "blueprint" so don't know if these ideas are applicable to your needs or not. 

Here are links to 2 example csd files & a demo video for anyone interested:




Best,
Scott

On Sun, Aug 13, 2023, 10:40 a.m. Jeanette C. <julien@mail.upb.de> wrote:
Aug 12 2023, ST Music has written:
...
> I'm curious as
> to whether by "can the same be applied" you mean "is there a method" or "is
> it necessary".
...
The question is: if an unwindowed waveform is read with some kind of
modulation, can the same modulation be applied to a window and then
applied to the resulting audio from the wave reading. Take this example:
iWave = ftgen(a wave)
iWindow = ftgen(a window)
aPhasor = phasor:a(kFreq1)
aModulator = some kind of oscillator
aWave = table((aPhasor * aModulator), iWave, 1)
aWindow = table((aPhasor * aModulator), iWindow, 1)
aWinwoedWave = aWave * aWindow
...
Would this be a correct way to apply windowing? In the simplest case I
would do this:
aWave = table(aPhasor, iWave, 1)
aWindow = table(aPhasor, iWindow, 1)
aWindowedWave = aWave * aWindow

Or even just multiply the window and the wave ftable, assuming they have
the same length, and then read the resulting ftable. Seeing that iWave
in practise will be the result of a dynamic morphing process, this
approach seems inefficient, since it involves reading the two ftables
(wave and window) every k-cycle, multiplying them, writing the output to
a new function table and only then use some kind of table/oscil opcode
to read it at the desired frequency to produce audio.

Hm, the more I think about it, the more I see the appeal of tablexkt...

Best wishes,

Jeanette

--
  * Website: http://juliencoder.de - for summer is a state of sound
  * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g
  * Audiobombs: https://www.audiobombs.com/users/jeanette_c
  * GitHub: https://github.com/jeanette-c

Give me a sign...
Hit me Baby one more time <3
(Britney Spears)

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here
Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here