User-Defined Opcode Database

Tuner

Tunes a given fundamental to a user-provided scale

Download UDO File

Description

Tuner picks a fundamental frequency and adjusts it to fit a given 7-note scale. The scale is to be given in pitch classes on a function table. For instance:

f1 0 8 2 0 2 4 5 7 9 11 12

defines a major scale (in C). The last note of the scale is ignored.

Syntax

kfout Tuner kfr,ksm,kfn,ktrans

Performance

kfr - input frequency (in Hz)
ksm - smoothing time (in secs)
kfn - function table containing the scale to be fitted to
ktrans - scale transposition in semitones

kfout - adjusted freq in Hz

Code

opcode Tuner, k, kkkk

kfr,ksm,kfn,ktrans  xin

if (kfr > 10) kgoto ok
kfr = 440
ok: 
knot = pchoct(octcps(kfr))
ktmp = frac(knot)*100
koct = int(knot)
kpch = int(ktmp)

kpos init 0
test:
knote tablekt kpos, kfn     ; get a pitch class
knote = (knote+ktrans)%12
if kpch == knote kgoto next ; test match
kpos = kpos + 1           ; increment table pos
if kpos >= 7  kgoto shift ; shift by a semitone
kgoto test                ; loop back

shift:
if (ktmp >= kpch) kgoto plus
kpch = kpch - 1
kgoto next
plus:
kpch = kpch + 1

next:
kpos = 0

ktarget = cpspch(koct+kpch/100)
kratio = ktarget/kfr
kratioport portk kratio,ksm 
       xout  kratioport     
endop

Examples

<CsoundSynthesizer>
<CsOptions>
-odac -iadc
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 32
nchnls = 1
0dbfs=1


opcode  PitchShifter, a, akki 
 setksmps 1
 asig,kpitch,kf,iwin  xin 
 
 if kf < 100 then
   kf = 100
 endif
 kdel = 1/(kf*0.5)
 kdelrate = (kpitch-1)/kdel 
 avdel   phasor -kdelrate           
 avdel2  phasor -kdelrate, 0.5           
 afade  tablei avdel, iwin, 1, 0, 1     
 afade2 tablei avdel2,iwin, 1, 0, 1 
 adump  delayr 0.1                  
 atap1  deltap3 avdel*kdel    
 atap2  deltap3 avdel2*kdel 
 amix   =   atap1*afade + atap2*afade2  
       delayw  asig
       xout  amix 
endop

opcode Tuner, k, kkkk

kfr,ksm,kfn,ktrans  xin

if (kfr > 10) kgoto ok
kfr = 440
ok: 
knot = pchoct(octcps(kfr))
ktmp = frac(knot)*100
koct = int(knot)
kpch = int(ktmp)

kpos init 0
test:
knote tablekt kpos, kfn     ; get a pitch class
knote = (knote+ktrans)%12
if kpch == knote kgoto next ; test match
kpos = kpos + 1           ; increment table pos
if kpos >= 7  kgoto shift ; shift by a semitone
kgoto test                ; loop back

shift:
if (ktmp >= kpch) kgoto plus
kpch = kpch - 1
kgoto next
plus:
kpch = kpch + 1

next:
kpos = 0

ktarget = cpspch(koct+kpch/100)
kratio = ktarget/kfr
kratioport portk kratio,ksm 
       xout  kratioport     
endop


instr 1

a1 diskin2 p4,1,0,1
kf,ka ptrack a1, 512
kf port kf, 0.01
kt Tuner kf,0.01,3,7
a2 PitchShifter a1,kt,kf,5
   out a2


endin 


</CsInstruments>
<CsScore>
f1 0 16384 10 1 0.5 0.3 0.25 0.2 0.167 0.14 0.125 .111  
f3 0 8 -2  0 2 4 5 7 9 11 12
f4 0 8 -2  0 2 3 5 7 8 10 12
f5 0 16384 7  0  8192 1 8192 0

i1 0 30 "cornetto.wav"   


</CsScore>
</CsoundSynthesizer>

Credits

original idea by Brian Carty, with modifications by V Lazzarini


Previous Home Next
TransGen   Vocoder