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