News:

SMF for DIYStompboxes.com!

Main Menu

Audio Effects DSP Board

Started by markseel, June 13, 2016, 11:53:46 AM

Previous topic - Next topic

markseel

The effects example for the FlexFX kit is mostly finished.  It's a multi-effect with preamp, tone stack, chorus/flanger/delay, reverb, and cab-sim.  The effect parameters (22 of them) can be adjusted and updated in real-time via the HTML file using Google Chrome and USB.  Parameter changes are automatically stored to XMOS FLASH so that they're preserved across power cycles and so you can implement presets.  It's a big example but it pretty much demonstrates anything one would do - or at least gives you a good start on your own effects.  The effects source code (example.c) and the HTML effects controller (example.html) as well as a screen capture of the controller (effects.png) are in the FlexFX repository: https://github.com/flexfx/flexfx.github.io.  I'll make a short video next.


markseel

On a similar note here's the C99 effect KickStarter video.  The FlexFX example mentioned in the previous post is a mono version of the C99 (C99 is stereo output and has two separate preamp/tone/chorus/reverb/cabsim signal chains for left/right with separate volume and balance controls)
https://www.kickstarter.com/projects/632112529/68367638?ref=4368q4&token=cc393f2e

markseel

#362
Here's the final FlexFX module and how to hook it up (this is what's used in the C99 pedal BTW).  You can use this module standalone for your own effects or you can use it with the FlexFX kit main board that has audio jacks, pots, USB jack, and power jack for experimentation and convenience.  When using the module standalone and if you're not using the USB connector you can still program the board using the XMOS JTAG adapter (XTAG-2 or XTAG-3) - costs about $20.



markseel

#363
Here's a video showing the FlexFX example being controlled with Google Chrome.
https://vimeo.com/335274835

amplificadorguitarra2000

@markseel your links don't go anywhere, is it just me or does it happen to more people?    :icon_question:

markseel

Thanks for the heads-up!  I logged out of KickStarter and Vimeo and tried the links - they work for me.  Anyone else?

amplificadorguitarra2000

markseel, it was some mistake of mine, I have restarted and I am doing perfectly, thank you very much and sorry for the inconvenience

markseel

No problem.  I'm just happy that someone other than me posted something in this thread  :D

markseel

Here's the FlexFX multi-effect being controlled using an Android phone.
https://vimeo.com/335530975

EBK

Quote from: markseel on May 10, 2019, 04:38:06 PM
No problem.  I'm just happy that someone other than me posted something in this thread  :D
I'm always lurking when you post updates.  I might not respond, but you have an audience.  :icon_wink:
  • SUPPORTER
Technical difficulties.  Please stand by.

micromegas

Hi Mark,

Add me to the list of permanent lurkers on your project.

The board looks (and sounds) really cool and I that gui control seems really usable.

I was at Superbooth in Berlin this week and passed by the Chase Bliss Audio stand hoping to see a prototype of the Blooper and to get to play with it, but they didn't have any hooked up and there was no one guarding the booth at the moment, but I must say it looks like an interesting piece of gear for what I got from the youtube videos.

It all seems very exciting, can't wait to see this projects grow!
Software Developer @ bela.io

markseel

Too bad you couldn't play with the Blooper and talk with Joel - the Blooper is really fun and Joel is a great guy :-)

add4

+1 about the audience thingy.
I myself find it really interesting to have a view on the way a professional guy designs his boards, thinks and develops.
I'm learning a lot reading this and I hope I can learn fast enough to at least be able to post something worth being read about digital.
Currently learning PIC32, so, technology-wise i'm stuck in 2007 at the moment.

Learning DSP is the next step, give me a few dozens of years and i'll be back with something interesting to say.



markseel

#373
Quote from: add4 on May 14, 2019, 08:20:05 AM
Learning DSP is the next step, give me a few dozens of years and i'll be back with something interesting to say.

But your post *was* interesting ... and insightful :-)  I hope folks don't feel like they can't ask questions in this thread ... even basic ones ... about DSP, 'C' programming, hardware design, PCB layout, effects algorithms, XMOS, etc.  I also hope there's a lot of people who want to learn DSP, 'C', and effects algorithms because it's really fun to experiment with them and hear the results.

I hope the FlexFX kit gets traction.  If you look at 'xio.h' which defines where you put your effects algorithm code and where you put the parameter control code and it doesn't make sense let me know.  I tried to isolate every bit of USB/MIDI and audio flow stuff from the effects 'creator/programmer'.  That leaves you with writing the algorithm(s) and the code to change parameters.  But it is in 'C' and it's fixed point math and those will no doubt be a hurdle for some.

But if you can get over that hurdle you could use this little board to do extraordinary stuff just by adding some external components (jacks, pots, switches, LED's)

I just finished a delay effect that has eight separate delay lines all with their own delay time modulation LFO and feedback.  Each single delay line runs at 48 kHz and each can be used to make a flanger or chorus.  There's a feedback path that distributes the output of each delay line back to the inputs of all delay lines using a matrix of gain coefficients (search FDN reverbs in Google).  Accessing delayed samples (for fractional delay) in each delay line is done by reading three adjacent samples and performing Lagrange interpolation (Google it).  Sounds hard but it's not really that bad.

This effect sounds fantastic and it takes just 1/5th of the processing power (one of five processing threads - see the 'xio_thread' functions in 'xio.h').  I could post this and walk through it if anyone's interested.  But the point is that the board has a *lot* of power and with it we can put as much - or more - DSP power in a small stompbox form factor than anyone has date ... including the big guys.



elseif

Wow.  I'm new to this board and just discovered this project.  I wonder - could this thing be a porting target for a project I shelved about a year ago?  It was running in a TI TMS320C6748 LCDK, but the idea of building that into a pedal severely dampened my enthusiasm, so I bought a Ventilator II and shelved the project.

The main processing load involves running ten FIR filters for every sample at an internal rate of 24 ksps.  Currently the filters are of length 750, though due to bandwidth limitations of the source material the filter length and sample rate could be reduced in some cases.

I'd like to find some processing benchmarks.  Any pointers as to where to look?

-- bradley

markseel

One XMOS core can do 672 taps at 48 kHz (already tested that). Maybe/probably could do 720.  There's five cores available for DSP.  So two 672 tap FIRs per core (10 FIRs total) at 24 kHz Fs should be fine and it may be possible to do 10 720 tap FIRs (2 per core) at 24kHz Fs. I could write a quick test and find out.

EBK

I think this might have been mentioned briefly before, but could you implement a phase vocoder with this board? 

I'd love to be able to do some pitch and speed shifting.
  • SUPPORTER
Technical difficulties.  Please stand by.

markseel

Here's the 10 FIR test code (some code left out and replaced with ... to shorten up the text so that this message board would accept it).  I'll run this tonight if I have time :-)


#include <stdint.h>
#include <math.h>
#include <string.h>
#include "xio.h"

const char* product_name_string   = "Test";
const int   audio_sample_rate     = 24000;
const int   flexfx_unit_number    = 0;
const int   audio_clock_mode      = 1; // 0=internal/master,1=external/master,2=slave
const int   usb_output_chan_count = 2; // 2 USB audio class 2.0 output channels
const int   usb_input_chan_count  = 2; // 2 USB audio class 2.0 input channels
const int   i2s_channel_count     = 2; // Channels per SDIN/SDOUT wire (2,4,or 8)
const int   i2s_sync_word[8]      = { 0xFFFFFFFF,0x00000000,0,0,0,0,0,0 };

// FQ converts Q28 fixed-point to floating point, QF converts floating-point to Q28

#define QQ 28
#define FQ(hh) (((hh)<0.0)?((int)((double)(1u<<QQ)*(hh)-0.5)):((int)(((double)(1u<<QQ)-1)*(hh)+0.5)))
#define QF(xx) (((int)(xx)<0)?((double)(int)(xx))/(1u<<QQ):((double)(xx))/((1u<<QQ)-1))

// MAC performs 32x32 multiply and 64-bit accumulation, SAT saturates a 64-bit result, EXT converts
// a 64-bit result to a 32-bit value, LDn/STn loads/stores two 32-values from/to 64-bit aligned
// 32-bit data arrays at address PP[2*n]. All 32-bit fixed-point values are Q28 fixed-point values.
//
// AH (high) and AL (low) form the 64-bit signed accumulator
// XX, YY, and AA are 32-bit QQQ fixed point values
// PP is a ** 64-bit aligned **  pointer to two 32-bit QQQ values
//
// For CRC: YY and XX are the next and previous results, SS is the seed value, PP is the CRC polynomial.

#define DSP_LD00( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 0]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD01( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 1]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD02( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 2]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD03( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 3]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD04( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 4]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD05( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 5]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD06( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 6]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD07( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 7]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD08( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 8]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD09( pp, xx, yy )    asm volatile("ldd %0,%1,%2[ 9]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD10( pp, xx, yy )    asm volatile("ldd %0,%1,%2[10]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD11( pp, xx, yy )    asm volatile("ldd %0,%1,%2[11]":"=r"(xx),"=r"(yy):"r"(pp));

#define DSP_ST00( pp, xx, yy )    asm volatile("std %0,%1,%2[ 0]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST01( pp, xx, yy )    asm volatile("std %0,%1,%2[ 1]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST02( pp, xx, yy )    asm volatile("std %0,%1,%2[ 2]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST03( pp, xx, yy )    asm volatile("std %0,%1,%2[ 3]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST04( pp, xx, yy )    asm volatile("std %0,%1,%2[ 4]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST05( pp, xx, yy )    asm volatile("std %0,%1,%2[ 5]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST06( pp, xx, yy )    asm volatile("std %0,%1,%2[ 6]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST07( pp, xx, yy )    asm volatile("std %0,%1,%2[ 7]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST08( pp, xx, yy )    asm volatile("std %0,%1,%2[ 8]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST09( pp, xx, yy )    asm volatile("std %0,%1,%2[ 9]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST10( pp, xx, yy )    asm volatile("std %0,%1,%2[10]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST11( pp, xx, yy )    asm volatile("std %0,%1,%2[11]"::"r"(xx), "r"(yy),"r"(pp));

#define DSP_MUL( ah, al, xx, yy ) asm volatile("maccs %0,%1,%2,%3":"=r"(ah),"=r"(al):"r"(xx),"r"(yy),"0"(0),"1"(0) );
#define DSP_MAC( ah, al, xx, yy ) asm volatile("maccs %0,%1,%2,%3":"=r"(ah),"=r"(al):"r"(xx),"r"(yy),"0"(ah),"1"(al) );
#define DSP_EXT( ah, al, xx, qq ) asm volatile("lextract %0,%1,%2,%3,32":"=r"(xx):"r"(ah),"r"(al),"r"(QQ+qq));
#define DSP_SAT( ah, al )         asm volatile("lsats %0,%1,%2":"=r"(ah),"=r"(al):"r"(QQ),"0"(ah),"1"(al));
#define DSP_DIV( qq,rr,ah,al,xx ) asm volatile("ldivu %0,%1,%2,%3,%4":"=r"(qq):"r"(rr),"r"(ah),"r"(al),"r"(xx));
#define DSP_CRC( xx,yy,ss,pp )    asm volatile("crc32 %0,%2,%3":"=r"(xx):"0"(yy),"r"(ss),"r"(pp));

inline int dsp_mult( int xx, int yy ) // RR = XX * YY
{
    int ah; unsigned al; DSP_MUL(ah,al,xx,yy); DSP_EXT(ah,al,xx,0); return xx;
}
inline int dsp_extract( int ah, int al ) // RR = AH:AL >> (64-QQ)
{
    DSP_EXT( ah, al, ah,0 ); return ah;
}

#define dsp_convolve24( ah, al, cc, ss, xx ) \
{ \
    s0 = xx; \
    DSP_LD00( cc, b1, b0 ); DSP_LD00( ss, s2, s1 ); DSP_ST00( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD01( cc, b1, b0 ); DSP_LD01( ss, s0, s3 ); DSP_ST01( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    DSP_LD02( cc, b1, b0 ); DSP_LD02( ss, s2, s1 ); DSP_ST02( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD03( cc, b1, b0 ); DSP_LD03( ss, s0, s3 ); DSP_ST03( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    DSP_LD04( cc, b1, b0 ); DSP_LD04( ss, s2, s1 ); DSP_ST04( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD05( cc, b1, b0 ); DSP_LD05( ss, s0, s3 ); DSP_ST05( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    DSP_LD06( cc, b1, b0 ); DSP_LD06( ss, s2, s1 ); DSP_ST06( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD07( cc, b1, b0 ); DSP_LD07( ss, s0, s3 ); DSP_ST07( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    DSP_LD08( cc, b1, b0 ); DSP_LD08( ss, s2, s1 ); DSP_ST08( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD09( cc, b1, b0 ); DSP_LD09( ss, s0, s3 ); DSP_ST09( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    DSP_LD10( cc, b1, b0 ); DSP_LD10( ss, s2, s1 ); DSP_ST10( ss, s1, s0 ); \
    DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
    DSP_LD11( cc, b1, b0 ); DSP_LD11( ss, s0, s3 ); DSP_ST11( ss, s3, s2 ); \
    DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
    xx = s0; \
}

void xio_startup( void )
{
}

void xio_control( const int rcv_prop[6], int snd_prop[6], int dsp_prop[6] )
{
}

void xio_mixer( const int usb_output_q31[2], int usb_input_q31[2],
                const int adc_output_q31[2], int dac_input_q31[2],
                const int dsp_output_q28[8], int dsp_input_q28[8], const int property[6] )
{
    // Send instrument signal from ADC to each FIR.
    dsp_input_q28[0] = dsp_input_q28[1] = dsp_input_q28[2] = dsp_input_q28[3]
                     = dsp_input_q28[4] = adc_output_q31[0] / 8;
    dsp_input_q28[5] = dsp_input_q28[6] = dsp_input_q28[7] = dsp_input_q28[8]
                     = dsp_input_q28[9] = adc_output_q31[0] / 8;
   
    // Combine FIR outputs and send to the DAC (5 outputs to left channel, other 5 to right).
    dac_input_q31[0] = dsp_output_q28[0] + dsp_output_q28[1] + dsp_output_q28[2]
                     + dsp_output_q28[3] + dsp_output_q28[4];
    dac_input_q31[1] = dsp_output_q28[5] + dsp_output_q28[6] + dsp_output_q28[7]
                     + dsp_output_q28[8] + dsp_output_q28[9];
}

int fir0_coeff[768], fir0_state[768];
int fir1_coeff[768], fir1_state[768];
int fir2_coeff[768], fir2_state[768];
int fir3_coeff[768], fir3_state[768];
int fir4_coeff[768], fir4_state[768];
int fir5_coeff[768], fir5_state[768];
int fir6_coeff[768], fir6_state[768];
int fir7_coeff[768], fir7_state[768];
int fir8_coeff[768], fir8_state[768];
int fir9_coeff[768], fir9_state[768];

void xio_initialize( void )
{
    memset(fir0_coeff,0,sizeof(fir0_coeff)); memset(fir0_state,0,sizeof(fir0_state));
    memset(fir1_coeff,0,sizeof(fir1_coeff)); memset(fir1_state,0,sizeof(fir1_state));
    memset(fir2_coeff,0,sizeof(fir2_coeff)); memset(fir2_state,0,sizeof(fir2_state));
    memset(fir3_coeff,0,sizeof(fir3_coeff)); memset(fir3_state,0,sizeof(fir3_state));
    memset(fir4_coeff,0,sizeof(fir4_coeff)); memset(fir4_state,0,sizeof(fir4_state));
    memset(fir5_coeff,0,sizeof(fir5_coeff)); memset(fir5_state,0,sizeof(fir5_state));
    memset(fir6_coeff,0,sizeof(fir6_coeff)); memset(fir6_state,0,sizeof(fir6_state));
    memset(fir7_coeff,0,sizeof(fir7_coeff)); memset(fir7_state,0,sizeof(fir7_state));
    memset(fir8_coeff,0,sizeof(fir8_coeff)); memset(fir8_state,0,sizeof(fir8_state));
    memset(fir9_coeff,0,sizeof(fir9_coeff)); memset(fir9_state,0,sizeof(fir9_state));
   
    fir0_coeff[0] = fir1_coeff[0] = fir2_coeff[0] = fir3_coeff[0] = fir4_coeff[0] = FQ(1.0);
    fir5_coeff[0] = fir6_coeff[0] = fir7_coeff[0] = fir8_coeff[0] = fir9_coeff[0] = FQ(1.0);
}

void xio_thread1( int samples[32], const int property[6] )
{
    unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;

    ah = 0; al = 1<<(QQ-1); xx = samples[0];
    dsp_convolve24( ah, al, fir0_coeff + 24* 0, fir0_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir0_coeff + 24*28, fir0_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[0],0 );

    ah = 0; al = 1<<(QQ-1); xx = samples[1];
    dsp_convolve24( ah, al, fir1_coeff + 24* 0, fir1_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir1_coeff + 24*28, fir1_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[1],0 );
}

void xio_thread2( int samples[32], const int property[6] )
{
    unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;

    ah = 0; al = 1<<(QQ-1); xx = samples[2];
    dsp_convolve24( ah, al, fir2_coeff + 24* 0, fir2_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir2_coeff + 24*28, fir2_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[2],0 );

    ah = 0; al = 1<<(QQ-1); xx = samples[3];
    dsp_convolve24( ah, al, fir3_coeff + 24* 0, fir3_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir3_coeff + 24*28, fir3_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[3],0 );
}

void xio_thread3( int samples[32], const int property[6] )
{
    unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;

    ah = 0; al = 1<<(QQ-1); xx = samples[4];
    dsp_convolve24( ah, al, fir4_coeff + 24* 0, fir4_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir4_coeff + 24*28, fir4_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[0],0 );

    ah = 0; al = 1<<(QQ-1); xx = samples[5];
    dsp_convolve24( ah, al, fir5_coeff + 24* 0, fir5_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir5_coeff + 24*28, fir5_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[5],0 );
}

void xio_thread4( int samples[32], const int property[6] )
{
    unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;

    ah = 0; al = 1<<(QQ-1); xx = samples[6];
    dsp_convolve24( ah, al, fir6_coeff + 24* 0, fir6_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir6_coeff + 24*28, fir6_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[6],0 );

    ah = 0; al = 1<<(QQ-1); xx = samples[7];
    dsp_convolve24( ah, al, fir7_coeff + 24* 0, fir7_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir7_coeff + 24*28, fir7_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[7],0 );
}

void xio_thread5( int samples[32], const int property[6] )
{
    unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;

    ah = 0; al = 1<<(QQ-1); xx = samples[8];
    dsp_convolve24( ah, al, fir8_coeff + 24* 0, fir8_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir8_coeff + 24*28, fir8_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[8],0 );

    ah = 0; al = 1<<(QQ-1); xx = samples[9];
    dsp_convolve24( ah, al, fir9_coeff + 24* 0, fir9_state + 24* 0, xx );
    ...
    ...
    ...
    dsp_convolve24( ah, al, fir9_coeff + 24*28, fir9_state + 24*28, xx );   
    DSP_EXT( ah, al, samples[9],0 );
}

markseel

Quote from: EBK on May 16, 2019, 01:54:34 PM
... but could you implement a phase vocoder with this board? 

Yeah good question and it sounds really interesting.  I'm not very familiar with that effect yet.

What do you think would be the requirements for the bulk of the DSP stuff?  Like would you use a sliding DFT or rather use short-time FFT's?  For reconstruction then would you then use weighted overlap and IFFT?  Is the FFT/iFFT to be done using complex math? 

If we could nail down how many FFT's/iFFT's per audio block, the audio block size, and the FFT/iFFT length, and the overlap amount and windowing approach then we'd have a good idea on whether or not this would be possible since it seems like these operations would be the majority of the processing load (true?).

More details would also give me an idea of what DSP support code I could write and optimize.