[Csnd] Vocoder

Chatting with Rory over a beer last Thursday in Vienna and he mentioned that a large Csound example for the vocoder had been shown earlier in the day as an example of how Csound was verbose.

Well, I don’t need many lines to write a vocoder. I wrote an example on the flight back home, 20 lines of Csound code (18 if you don’t care about 80-column format).
Here it is in action: https://www.youtube.com/watch?v=jjFjRJmYdpE

The full CSD:

<CsoundSynthesizer>
<CsOptions>
-M0 -odac
</CsOptions>
<CsInstruments>

// MIDI vocoder
// instr 1 - channel dispatcher, input receiver
// instr 2 - MIDI-controlled synth source
// instr 3 - channel bands and output

massign 0, 2
instr 1 // dispatch
cf:i = p4
band:i = 3
while cf < p5 do
  schedule(band, 0, -1, cf, p6)
  band, cf = band + 0.001, cf*2^(p7/12)
od
chnset(diskin:a("fox.wav",1,0,1), "input")
chnclear("excite")
endin
schedule(1, 0, -1, 80, 8000, 8, 4)

instr 2 // MIDI synth
fo:k cpsmidib 2
chnmix(linenr:a(ampmidi(8), 0.01, 0.1, 0.01)*
        (vco2(1, fo*0.99) + vco2(1, fo*1.01)), "excite")
endin

instr 3 // vocoder band
out(butterbp(butterbp(chnget:a("excite"), p4, p4/p5), p4, p4/p5) *
     rms(butterbp(butterbp(chnget:a("input"), p4, p4/p5), p4, p4/p5)))
endin

</CsInstruments>
</CsoundSynthesizer>

Thanks also for the nice Csound7 language demo!
tarmo

Kontakt Victor Lazzarini (<000010b17ddd988e-dmarc-request@listserv.heanet.ie>) kirjutas kuupäeval N, 26. september 2024 kell 12:53:

Chatting with Rory over a beer last Thursday in Vienna and he mentioned that a large Csound example for the vocoder had been shown earlier in the day as an example of how Csound was verbose.

Well, I don’t need many lines to write a vocoder. I wrote an example on the flight back home, 20 lines of Csound code (18 if you don’t care about 80-column format).
Here it is in action: https://www.youtube.com/watch?v=jjFjRJmYdpE

The full CSD:

-M0 -odac

// MIDI vocoder
// instr 1 - channel dispatcher, input receiver
// instr 2 - MIDI-controlled synth source
// instr 3 - channel bands and output

massign 0, 2
instr 1 // dispatch
cf:i = p4
band:i = 3
while cf < p5 do
schedule(band, 0, -1, cf, p6)
band, cf = band + 0.001, cf*2^(p7/12)
od
chnset(diskin:a(“fox.wav”,1,0,1), “input”)
chnclear(“excite”)
endin
schedule(1, 0, -1, 80, 8000, 8, 4)

instr 2 // MIDI synth
fo:k cpsmidib 2
chnmix(linenr:a(ampmidi(8), 0.01, 0.1, 0.01)*
(vco2(1, fo0.99) + vco2(1, fo1.01)), “excite”)
endin

instr 3 // vocoder band
out(butterbp(butterbp(chnget:a(“excite”), p4, p4/p5), p4, p4/p5) *
rms(butterbp(butterbp(chnget:a(“input”), p4, p4/p5), p4, p4/p5)))
endin

========================
Prof. Victor Lazzarini
Maynooth University
Ireland

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

Lovely sounding and…

it is cool to see the functional syntax for variables cf:i =

Thanks!

wow --- thanks for the great example victor! very instructive and also easy to modify for live input.

this is the kind of examples i would like to see at Examples running live with WASM csound. do you know whether MIDI and live input would be possible then?

My original code used “inch(1)” instead of diskin:a(), so the idea was to emulate a vocoder like the VP340 with a mic input. I did not have a mic input to do the demo, so I used fox.wav.
I have used MIDI and live input with Csound WASM without a problem.

I remember having an issue with Csound 6 where the Web IDE did not like CSDs without a <CsScore> section for some reason, that’s the only thing I guess it needs to be checked for the code I posted.

best

Works great with inch(1) too!

My students are going to love this when we get to the channel vocoder in DSP class.

THANKS!

Would a recursive UDO be even more succinct?

Hi Victor!
Sep 26 2024, Victor Lazzarini has written:
...

Here it is in action: https://www.youtube.com/watch?v=jjFjRJmYdpE

...
Thank you for sharing this code. It is good to read the new syntax and
the quality of that vocoder is really good and clear.

Best wishes and thanks again,

Jeanette

yes, we could do that, but as far as I can see, using instruments in this case is more efficient as there is less copying of
data. With pass-by-reference, a UDO would be as efficient.

Note that we can also do recursion in this code to make it slightly shorter (I quite like this kind of thing):

instr 1 // dispatch
schedule(3, 0, -1, p4, p5, p6, p7)
chnset(diskin:a("fox.wav",1,0,1), "input")
chnclear("excite")
endin
schedule(1, 0, -1, 80, 8000, 8, 4)

instr 3 // recursive vocoder bands
out(butterbp(butterbp(chnget:a("excite"), p4, p4/p6), p4, p4/p6) *
     rms(butterbp(butterbp(chnget:a("input"), p4, p4/p6), p4, p4/p6)))
nxt:i = p4*2^(p7/12)
if nxt < p5 then
  schedule(p1+0.001, 0, -1, nxt, p5, p6, p7)
endif
endin

yes, we could do that, but as far as I can see, using instruments in this case is more efficient as there is less copying of
data. With pass-by-reference, a UDO would be as efficient.

Note that we can also do recursion in this code to make it slightly shorter (I quite like this kind of thing):

instr 1 // dispatch
schedule(3, 0, -1, p4, p5, p6, p7)
chnset(diskin:a("fox.wav",1,0,1), "input")
chnclear("excite")
endin
schedule(1, 0, -1, 80, 8000, 8, 4)

instr 3 // recursive vocoder bands
out(butterbp(butterbp(chnget:a("excite"), p4, p4/p6), p4, p4/p6) *
    rms(butterbp(butterbp(chnget:a("input"), p4, p4/p6), p4, p4/p6)))
nxt:i = p4*2^(p7/12)
if nxt < p5 then
schedule(p1+0.001, 0, -1, nxt, p5, p6, p7)
endif
endin

victor, could you again look at this code?
i get a division by zero detected when i run it (and no output).
the first code ran perfectly.
thanks -
  joachim

Did you add instr 2 to this? It doesn't show it but of course it's dependent on that.

Prof. Victor Lazzarini
Maynooth University
Ireland

ah ok i get it. yes adding this instrument and also the massign does the trick =)
thanks -
  j

Hi to all,
Happy to write to you again after such a long time!
How could I run Victor’s vocoder?
This error message appears in Csound 6.16.
(Funcional syntax error? Why?)

csound -odac vocoder.csd
0dBFS level = 32768.0
–Csound version 6.16 (double samples) Jul 17 2021
[commit: fb5bdb3681e15f56c216b4e4487b45848aa6b9f4]
libsndfile-1.0.31
UnifiedCSD: vocoder.csd
STARTING FILE
Creating options
Creating orchestra
closing tag
scoreless operation
rtaudio: PortAudio module enabled …
using callback interface
rtmidi: PortMIDI module enabled

error: syntax error, unexpected ‘:’ (token “:”) from file vocoder.csd (1)
line 14:

cf: <<<
Unexpected untyped word cf when expecting a variable
Parsing failed due to invalid input!
Stopping on parser failure
cannot compile orchestra

because victor already used csound7 code.
in csound7 you can define the type of a variable (i/k/a) in the way you see in victor's example. no need any more to start a variable name with i or k or a.

you can change the example to csound6 code like this:
rather than
  cf:i = p4
you write:
  icf = p4
and the same with k-variables:
  kfo cpsmidib 2

best -
  joachim

Thank you very much! Csound plays.
Nice, congratulations!

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

BTW: when will there be the official csound 7 release?

We don’t know yet, it’s about 80% done, but it’s only Steven and myself actively writing code now.
So it will be there when we get there.

:+1: thanks a lot for your work! Looking forward to the release!