Csound Csound-dev Csound-tekno Search About

[Csnd] code share: string machine

Date2020-06-11 22:48
FromVictor Lazzarini
Subject[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

Date2020-06-12 04:07
FromSteven Yi
SubjectRe: [Csnd] code share: string machine
Thanks Victor!

Very clear what's going on and lovely sound to this. (Will plan to make a Blue instrument version of this!)

Plus, I had no idea there was a version of ftgen that took in an array for arguments. So handy!

Thanks again!
Steven


On Thu, Jun 11, 2020 at 5:48 PM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
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
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 05:36
From"Dr. Richard Boulanger"
SubjectRe: [Csnd] code share: string machine
Very nice!  Thanks for sharing.  Lots of interesting and new things in here for me.  Appreciate it very much.

Dr. Richard Boulanger

Professor of Electronic Production and Design

Professional Writing and Technology Division

Berklee College of Music


skype: radiobaton 

facebook: https://www.facebook.com/richard.boulanger.58

about: http://www.boulangerlabs.com/#about

about: http://www.csounds.com/community/developers/dr-richard-boulanger/

music: http://www.csounds.com/community/developers/dr-richard-boulanger/dr-richard-boulanger-music/


Boulanger Labs - http://boulangerlabs.com

The Csound Book http://mitpress.mit.edu/books/csound-book

The Audio Programming Book - http://mitpress.mit.edu/books/audio-programming-book



On Thu, Jun 11, 2020 at 5:48 PM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
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
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 08:42
FromVictor Lazzarini
SubjectRe: [Csnd] [EXTERNAL] Re: [Csnd] code share: string machine
thanks. yes, it's been there for a while, but not documented (it is now). A funny episode actually happened earlier in the year. I asked John if we could have an ftgen that took arrays. He then said he was going to have a look. 

Then he replied there was already one there, and I had added it sometime back in 2018 ;)


Prof. Victor Lazzarini
Maynooth University
Ireland

On 12 Jun 2020, at 04:07, Steven Yi <stevenyi@gmail.com> wrote:



*Warning*

This 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 Victor!

Very clear what's going on and lovely sound to this. (Will plan to make a Blue instrument version of this!)

Plus, I had no idea there was a version of ftgen that took in an array for arguments. So handy!

Thanks again!
Steven


On Thu, Jun 11, 2020 at 5:48 PM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
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
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 17:47
Fromjoachim heintz
SubjectRe: [Csnd] code share: string machine
... me neither ...

On 12/06/2020 05:07, Steven Yi wrote:
> Plus, I had no idea there was a version of ftgen that took in an array 
> for arguments. So handy!

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

Date2021-01-09 01:41
From"Dr. Richard Boulanger"
SubjectRe: [Csnd] code share: string machine
this is such a wonderful instrument - loving it on the Bela too!

-R

Dr. Richard Boulanger

Professor of Electronic Production and Design

Berklee College of Music

Professional Writing and Technology Division




On Thu, Jun 11, 2020 at 5:48 PM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
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
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