Csound Csound-dev Csound-tekno Search About

Re: [Csnd] code share: string machine

Date2020-06-12 10:30
FromMikoláš Štrajt
SubjectRe: [Csnd] code share: string machine
Thanks a lot!

It was me who asked for this. I tested your code yesterday and it sounds good.

I am not 100% sure what is does, but this is at my side as I not yet learned how to use ftgen.

--
Mikoláš / Severák

Sometime ago there was a question here about divide down oscillators etc, and I mentioned
that a multiplier scheme was possible instead. So here’s the full example of an
emulation of a string machine. It’s commented so it should be more or less
self-explanatory. There are five parts to the code

1. Creating the bandlimited tables for each octave
2. The phase generation instrument, which produces the lowest octave phases
in twelve instances recursively launched, placed in an audio-rate array
3. The note generator, which picks up one of the phase signals, scales it up
to the right octave and looks up the table waveform
4. The single VCA which applies an envelope controlled by a gate signal
5. The stereo chorus.

It is set up so you can play it from a MIDI controller.

I hope it’s entertaining.

<CsoundSynthesizer>
<CsOptions>
-odac -d -Ma --midi-key-pch=5 --midi-velocity-amp=4
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

massign 1,2
massign 2,2
massign 3,2
massign 4,2

// phase signals
gaphs[] init 12
// lowest oct
ioct init 4
// partial arrays
iarr[] init sr/(2*cpspch(ioct+1))

// sawtooth table generation
while ioct < 12 do
// reset partial table
icnt = 0
while icnt < lenarray(iarr) do
iarr[icnt] = 0
icnt += 1
od
// fill partial table
icnt = 1
while icnt <= sr/(2*cpspch(ioct+1)) do
iarr[icnt-1] = 1/icnt
icnt += 1
od
// create bandlimited table
ifn ftgen ioct,0,16384,10,iarr
ioct += 1
od

// 12 phase signals
instr 1
inst = p4/100
gaphs[p4] = phasor:a(cpspch(inst))
if p4 < 11 then
inst += .01
schedule(1+inst,0,p3,p4+1)
endif
endin
schedule(1.,0,-1,0)

// note generator
gasig init 0
instr 2
indx = round(frac(p5)*100)
ioct = int(p5)
itab = ioct < 4 ? 4 : (ioct > 12 ? 12 : ioct)
a1 = tablei:a(gaphs[indx]*2^ioct,itab,1,0,1)
gasig += a1*linenr:a(p4,0,.2,.01)
endin

// VCA
instr 3
kact active 2
kgate = kact > 0 ? 1 : 0
if kgate > 0 then
kht = .2
else
kht = .1
endif
kenv = portk(kgate,kht)
gasig *= kenv
endin
schedule(3,0,-1)

// chorus
instr 4
amod1 = randi:a(3,.75)+oscili(2,.35)+31
amod2 = randi:a(2,.65)+oscili(3,.55)+29
a1 = vdelay(gasig*.5,amod1,35)
a2 = vdelay(gasig*.5,amod2,35)
out((gasig + a1),(gasig + a2))
gasig = 0
endin
schedule(4,0,-1)

</CsInstruments>
</CsoundSynthesizer>





========================
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

Date2020-06-12 11:03
FromVictor Lazzarini
SubjectRe: [Csnd] [EXTERNAL] [Csnd] code share: string machine
Thanks. All ftgen does is in this case call GEN10 to produce the bandlimited wavetables for each
octave, so that when we play a note there is not aliasing. There are 8 octaves, and 8 tables.

I keep wondering about a true divide down and how it could be implemented, but in my head
I can’t think of any way to do this without a lot of oversampling.
========================
Prof. Victor Lazzarini
Maynooth University
Ireland

> On 12 Jun 2020, at 10:30, Mikoláš Štrajt  wrote:
> 
> WARNINGThis email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> Thanks a lot!
> 
> It was me who asked for this. I tested your code yesterday and it sounds good.
> 
> I am not 100% sure what is does, but this is at my side as I not yet learned how to use ftgen.
> 
> -- 
> Mikoláš / Severák
> ---------- Původní e-mail ----------
> Od: Victor Lazzarini 
> Komu: CSOUND@LISTSERV.HEANET.IE
> Datum: 11. 6. 2020 23:49:00
> Předmět: [Csnd] code share: string machine
> 
> Sometime ago there was a question here about divide down oscillators etc, and I mentioned 
> that a multiplier scheme was possible instead. So here’s the full example of an 
> emulation of a string machine. It’s commented so it should be more or less 
> self-explanatory. There are five parts to the code 
> 
> 1. Creating the bandlimited tables for each octave 
> 2. The phase generation instrument, which produces the lowest octave phases 
> in twelve instances recursively launched, placed in an audio-rate array 
> 3. The note generator, which picks up one of the phase signals, scales it up 
> to the right octave and looks up the table waveform 
> 4. The single VCA which applies an envelope controlled by a gate signal 
> 5. The stereo chorus. 
> 
> It is set up so you can play it from a MIDI controller. 
> 
> I hope it’s entertaining. 
> 
>  
>  
> -odac -d -Ma --midi-key-pch=5 --midi-velocity-amp=4 
>  
>  
> 
> sr = 44100 
> ksmps = 32 
> nchnls = 2 
> 0dbfs = 1 
> 
> massign 1,2 
> massign 2,2 
> massign 3,2 
> massign 4,2 
> 
> // phase signals 
> gaphs[] init 12 
> // lowest oct 
> ioct init 4 
> // partial arrays 
> iarr[] init sr/(2*cpspch(ioct+1)) 
> 
> // sawtooth table generation 
> while ioct < 12 do 
> // reset partial table 
> icnt = 0 
> while icnt < lenarray(iarr) do 
> iarr[icnt] = 0 
> icnt += 1 
> od 
> // fill partial table 
> icnt = 1 
> while icnt <= sr/(2*cpspch(ioct+1)) do 
> iarr[icnt-1] = 1/icnt 
> icnt += 1 
> od 
> // create bandlimited table 
> ifn ftgen ioct,0,16384,10,iarr 
> ioct += 1 
> od 
> 
> // 12 phase signals 
> instr 1 
> inst = p4/100 
> gaphs[p4] = phasor:a(cpspch(inst)) 
> if p4 < 11 then 
> inst += .01 
> schedule(1+inst,0,p3,p4+1) 
> endif 
> endin 
> schedule(1.,0,-1,0) 
> 
> // note generator 
> gasig init 0 
> instr 2 
> indx = round(frac(p5)*100) 
> ioct = int(p5) 
> itab = ioct < 4 ? 4 : (ioct > 12 ? 12 : ioct) 
> a1 = tablei:a(gaphs[indx]*2^ioct,itab,1,0,1) 
> gasig += a1*linenr:a(p4,0,.2,.01) 
> endin 
> 
> // VCA 
> instr 3 
> kact active 2 
> kgate = kact > 0 ? 1 : 0 
> if kgate > 0 then 
> kht = .2 
> else 
> kht = .1 
> endif 
> kenv = portk(kgate,kht) 
> gasig *= kenv 
> endin 
> schedule(3,0,-1) 
> 
> // chorus 
> instr 4 
> amod1 = randi:a(3,.75)+oscili(2,.35)+31 
> amod2 = randi:a(2,.65)+oscili(3,.55)+29 
> a1 = vdelay(gasig*.5,amod1,35) 
> a2 = vdelay(gasig*.5,amod2,35) 
> out((gasig + a1),(gasig + a2)) 
> gasig = 0 
> endin 
> schedule(4,0,-1) 
> 
>  
>  
> 
> 
> 
> 
> 
> ======================== 
> 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


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