void FloatArray::convolve(FloatArray operand2, FloatArray destination, int offset, int samples){ ASSERT(destination.size >= size + operand2.size -1, "Destination array too small"); //TODO: change this condition to the actual size being written(will be samples+ tail) /// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a> #ifdef ARM_CORTEX //TODO: I suspect a bug in arm_conv_partial_f32 //it seems that destination[n] is left unchanged for n<offset //and the result is actually stored from destination[offset] onwards //that is, in the same position where they would be if a full convolution was performed. //This requires (destination.size >= size + operand2.size -1). Ideally you would want destination to be smaller arm_conv_partial_f32(data, size, operand2.data, operand2.size, destination.getData(), offset, samples); #else //this implementations reproduces the (buggy?) behaviour of arm_conv_partial (see comment above and inline comments below) /* This implementation is just a copy/paste/edit from the overloaded method */ int size2=operand2.getSize(); for (int n=offset; n<offset+samples; n++){ int n1=n; destination[n] =0; //this should be [n-offset] for(int k=0; k<size2; k++){ if(n1>=0 && n1<size) destination[n]+=data[n1]*operand2[k];//this should be destination[n-offset] n1--; } } #endif /* ARM_CORTEX */ }
void trigger(FloatArray samples){ for(int i=0; i<samples.getSize(); ++i) if(volts.sampleToVolts(samples[i]) > threshold && !state){ state = true; env->trigger(i); }else{ state = false; } }
void ComplexFloatArray::setMagnitude(FloatArray magnitude, int offset, int count, ComplexFloatArray destination){ ASSERT(getSize()==magnitude.getSize(),"wrong size0"); ASSERT(getSize()==destination.getSize(),"wrong size1"); ASSERT(offset+count<=destination.getSize(), "Wrong size2"); ASSERT(offset+count<=getSize(), "Wrong size3"); for(int n=offset; n<count+offset; n++){ destination.getData()[n].setPolar(magnitude[n], getData()[n].getPhase()); } }
void FloatArray::rectify(FloatArray& destination){ //this is actually "copy data with rectifify" /// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a> #ifdef ARM_CORTEX arm_abs_f32(data, destination.getData(), size); #else int minSize= min(size,destination.getSize()); //TODO: shall we take this out and allow it to segfault? for(int n=0; n<minSize; n++){ destination[n] = fabs(data[n]); } #endif }
void getSamples(FloatArray samples){ for(int i=0; i<samples.getSize(); ++i){ if(volts.sampleToVolts(samples[i]) > threshold){ if(!state){ state = true; drum->trigger(); } }else{ state = false; } samples[i] = drum->getNextSample(); } }
void ComplexFloatArray::complexByRealMultiplication(FloatArray& operand2, ComplexFloatArray& result){ int minSize= min(size,operand2.getSize()); //TODO: shall we take this out and allow it to segfault? #ifdef ARM_CORTEX arm_cmplx_mult_real_f32 ( (float*)data, (float*)operand2, (float*)result, minSize ); #else float *pSrcCmplx=(float*)data; float *pSrcReal=(float*)operand2; float *pCmplxDst=(float*)result; for(int n=0; n<size; n++) { pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n]; pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n]; } #endif }
void gate(FloatArray samples){ for(int i=0; i<samples.getSize(); ++i){ if(volts.sampleToVolts(samples[i]) > threshold){ if(!state){ env->gate(true, i); state = true; } }else{ if(state){ env->gate(false, i); state = false; } } } }
void FloatArray::convolve(FloatArray operand2, FloatArray destination){ ASSERT(destination.size >= size + operand2.size -1, "Destination array too small"); /// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a> #ifdef ARM_CORTEX arm_conv_f32(data, size, operand2.data, operand2.size, destination); #else int size2=operand2.getSize(); for (int n=0; n<size+size2-1; n++){ int n1=n; destination[n] =0; for(int k=0; k<size2; k++){ if(n1>=0 && n1<size) destination[n]+=data[n1]*operand2[k]; n1--; } } #endif /* ARM_CORTEX */ }
void FloatArray::copyFrom(FloatArray source){ /// @note When built for ARM Cortex-M processor series, this method uses the optimized <a href="http://www.keil.com/pack/doc/CMSIS/General/html/index.html">CMSIS library</a> copyFrom(source, min(size, source.getSize())); }
/* Copies real part to a FloatArray */ void ComplexFloatArray::copyTo(FloatArray destination){ for(int n=0; n<min(size,destination.getSize()); n++){ destination[n]=data[n].re; } }
/* Copies real values from a FloatArray, sets imaginary values to 0 */ void ComplexFloatArray::copyFrom(FloatArray source){ for(int n=0; n<min(size,source.getSize()); n++){ data[n].re=source[n]; data[n].im=0; } }