summaryrefslogtreecommitdiff
path: root/objects/wip
diff options
context:
space:
mode:
Diffstat (limited to 'objects/wip')
-rw-r--r--objects/wip/pitch_detect_fft.axo179
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>