diff options
author | rekado <rekado@elephly.net> | 2016-09-06 22:13:03 +0200 |
---|---|---|
committer | rekado <rekado@elephly.net> | 2016-09-06 23:31:22 +0200 |
commit | 8a4bca986c57062e96f1e58281b3eff52a856ee6 (patch) | |
tree | 11b125b567c212739a6585862628f0565f51ce35 /objects/wip |
Initial commit.
Diffstat (limited to 'objects/wip')
-rw-r--r-- | objects/wip/pitch_detect_fft.axo | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/objects/wip/pitch_detect_fft.axo b/objects/wip/pitch_detect_fft.axo new file mode 100644 index 0000000..7692628 --- /dev/null +++ b/objects/wip/pitch_detect_fft.axo @@ -0,0 +1,179 @@ +<objdefs> + <obj.normal id="pitch detect 128" uuid="89eda14ecd003f22288812e9843218f2d020b7ad" sha="e1ec4fbea98f37a5be48b1f7d3522ed1f7fe3229"> + <sDescription>spectral analyzer display using 128 input points fft</sDescription> + <author>Johannes Taelman, Ricardo Wurmus</author> + <license>BSD</license> + <inlets> + <frac32buffer name="in" description="input"/> + <bool32 name="hold" description="hold"/> + </inlets> + <outlets> + <int32 name="pitch" description="pitch"/> + </outlets> + <params/> + <attribs/> + <code.declaration><![CDATA[ +#define N 128 +int32_t inbuf[N]; +int32_t outbuf[N]; +// must be twice as wide because the result is +// stored like {real[0], imag[0], real[1], imag[1]...} +int32_t fftbuf[2*N]; +arm_rfft_instance_q31 rfft; +arm_cfft_radix4_instance_q31 cfft; +int32_t state; +int32_t max_val = 0; +uint32_t max_a = 0; + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + +void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex) +{ +#ifndef ARM_MATH_CM0_FAMILY + + /* Run the below code for Cortex-M4 and Cortex-M3 */ + q31_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex, count; /* loop counter */ + + /* Initialise the count value. */ + count = 0u; + /* Initialise the index value to zero. */ + outIndex = 0u; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + + /* Loop unrolling */ + blkCnt = (blockSize - 1u) >> 2u; + + /* Run the below code for Cortex-M4 and Cortex-M3 */ + while(blkCnt > 0u) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal1 = *pSrc++; + + maxVal2 = *pSrc++; + + /* compare for the maximum value */ + if(out < maxVal1) + { + /* Update the maximum value and its index */ + out = maxVal1; + outIndex = count + 1u; + } + + maxVal1 = *pSrc++; + + /* compare for the maximum value */ + if(out < maxVal2) + { + /* Update the maximum value and its index */ + out = maxVal2; + outIndex = count + 2u; + } + + maxVal2 = *pSrc++; + + /* compare for the maximum value */ + if(out < maxVal1) + { + /* Update the maximum value and its index */ + out = maxVal1; + outIndex = count + 3u; + } + + /* compare for the maximum value */ + if(out < maxVal2) + { + /* Update the maximum value and its index */ + out = maxVal2; + outIndex = count + 4u; + } + + count += 4u; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* if (blockSize - 1u) is not multiple of 4 */ + blkCnt = (blockSize - 1u) % 4u; + +#else + + /* Run the below code for Cortex-M0 */ + q31_t maxVal1, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* loop counter */ + + /* Initialise the index value to zero. */ + outIndex = 0u; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + + blkCnt = (blockSize - 1u); + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + + while(blkCnt > 0u) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal1 = *pSrc++; + + /* compare for the maximum value */ + if(out < maxVal1) + { + /* Update the maximum value and it's index */ + out = maxVal1; + outIndex = blockSize - blkCnt; + } + + /* Decrement the loop counter */ + blkCnt--; + + } + + /* Store the maximum value and its index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +]]></code.declaration> + <code.init><![CDATA[ +int i; +for(i=0;i<N;i++) inbuf[i]=0; +for(i=0;i<N;i++) outbuf[i]=0; +state = 0; +arm_rfft_init_q31(&rfft, &cfft, N,0,1); +]]></code.init> + <code.krate><![CDATA[ +if (state<N){ + // fill buffer + int i; + for(i=0;i<BUFSIZE;i++) { + inbuf[state++] = inlet_in[i]; + } +} else { + // compute FFT + arm_rfft_q31(&rfft, (q31_t *)inbuf, (q31_t *)fftbuf); + // compute magnitude + arm_cmplx_mag_q31(fftbuf, outbuf, N); + + // second half is conjugates, so we only look at N/2 + arm_max_q31(outbuf, N/2, &max_val, &max_a); + + outlet_pitch = max_a; + state = 0; +} +]]></code.krate> + </obj.normal> +</objdefs> |