No worries man,

Here ya go,

-- 
Edward Costello

On Monday 27 February 2012 at 18:09, joachim heintz wrote:

hi ed -
i would like to test your code, but get a lot of errors - probably due
to copying from the email. can you attach the .csd?
thanks -
joachim

Am 27.02.2012 16:04, schrieb Edward Costello:
Hey List,

I made a UDO over the weekend implementing Yin pitch detection
algorithm, with a good bit of help from looking at the Aubio library's
version, it seems to work pretty well and is comparable in accuracy with
the pvspitch and ptrack opcodes, it doesn't use too much cpu either.
Anyways heres the code with an example, the threshold value for the
opcode is a number between 0 and 1,


<CsoundSynthesizer>
<CsOptions>
</CsOptions>
<CsInstruments>

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



opcode QuadraticInterpolation, k, ik

i_YinBuffer, k_Period xin

k_x0 = k_Period < 1 ? k_Period : k_Period - 1

k_x2 = k_Period + 1 < ftlen(i_YinBuffer) ? k_Period + 1 : k_Period
if k_x0 == k_Period then
k_bufferAtPeriod tab k_Period, i_YinBuffer
k_bufferAtx2 tab k_x2, i_YinBuffer
k_Pitch = k_bufferAtPeriod <= k_bufferAtx2 ? k_Period : k_x2
elseif k_x2 == k_Period then
k_bufferAtPeriod tab k_Period, i_YinBuffer
k_bufferAtx0 tab k_x0, i_YinBuffer
k_Pitch = k_bufferAtPeriod <= k_bufferAtx0 ? k_Period : k_x0
else
k_s0 tab k_x0, i_YinBuffer
k_s1 tab k_Period, i_YinBuffer
k_s2 tab k_x2, i_YinBuffer
k_Pitch = k_Period + 0.5 * (k_s2 - k_s0) / (k_s2 - 2.0 * k_s1 + k_s0)
endif


xout k_Pitch


endop



opcode Yin, k, aii

a_In, i_YinBuffer, i_Threshold xin
k_tmp2 = 0
k_Tau = 1
k_PitchFound = 0

until k_Tau >= ftlen(i_YinBuffer) || k_PitchFound == 1 do
k_Index = 0
until k_Index >= ftlen(i_YinBuffer) do
k_1 vaget k_Index, a_In
k_2 vaget k_Index + k_Tau, a_In
k_tmp = k_1 - k_2
k_3 tab k_Tau, i_YinBuffer
tabw k_3 + (k_tmp * k_tmp), k_Tau, i_YinBuffer
k_Index = k_Index + 1
od
k_1 tab k_Tau, i_YinBuffer

k_tmp2 = k_tmp2 + k_1
k_2 = k_1 * (k_Tau / k_tmp2)
tabw k_2, k_Tau, i_YinBuffer
k_Period = k_Tau - 3

if k_Tau > 4 then
k_BufferAtPeriod tab k_Period, i_YinBuffer
k_BufferAtPeriodPlusOne tab k_Period + 1, i_YinBuffer
if k_BufferAtPeriod < i_Threshold && k_BufferAtPeriod <
k_BufferAtPeriodPlusOne then
k_Pitch QuadraticInterpolation i_YinBuffer, k_Period
k_Pitch = sr / k_Pitch
k_PitchFound = 1

else
k_PitchFound = 0
endif
endif
k_Tau = k_Tau + 1
od
if k_PitchFound == 0 then
k_Index = 0
k_Period = 0
k_tmp tab 0, i_YinBuffer
until k_Index >= ftlen(i_YinBuffer) do
k_0 tab k_Index, i_YinBuffer
k_Period = k_tmp < k_0 ? k_Period : k_Index
k_tmp = k_tmp < k_0 ? k_tmp : k_0
k_Index = k_Index + 1
od
k_Pitch QuadraticInterpolation i_YinBuffer, k_Period
endif

xout k_Pitch

endop


instr Init, 1
i_WindowSize = ksmps
i_Threshold = .04
gi_AudioBuffer ftgen 0, 0, i_WindowSize, 16, 0, 0
gi_YinBuffer ftgen 0, 0, i_WindowSize / 2, 16, 0, 0
Sfile = "Sound.wav"
i_Length filelen Sfile

gi_AudioIn ftgen 0, 0, -(sr * i_Length), 1, Sfile, 0, 0, 0
a_Line line 0, i_Length, ftlen(gi_AudioIn)
a_Out table a_Line, gi_AudioIn
k_Pitch Yin a_Out, gi_YinBuffer, i_Threshold

k_Pitch tonek k_Pitch, 10

a_Tone vco2 .2, k_Pitch , 12
outs a_Out, a_Tone
endin



</CsInstruments>
<CsScore>

i "Init" 0 10

</CsScore>
</CsoundSynthesizer>


Cheers,

Ed


Send bugs reports to the Sourceforge bug tracker
https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"