Csound Csound-dev Csound-tekno Search About

[Csnd] Yin pitch detection UDO

Date2012-02-27 15:04
FromEdward Costello
Subject[Csnd] Yin pitch detection UDO
AttachmentsNone  None  

Date2012-02-27 18:09
Fromjoachim heintz
SubjectRe: [Csnd] Yin pitch detection UDO
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,
> 
> 
> 
> 
> 
> 
> 
> 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
> 
> 
> 
> 
> 
> 
> i "Init" 0 10
> 
> 
> 
> 
> 
> Cheers,
> 
> Ed
> 

Date2012-02-27 22:18
FromEdward Costello
SubjectRe: [Csnd] Yin pitch detection UDO
AttachmentsNone  None  Yin.csd