I did similar thing a while ago, had to subclass the MonitorNode class and doing fft separately for each channel inside the new node class.

some code:

in new node’s initialize function:

```
{
MonitorNode::initialize();
if( mFftSize < mWindowSize )
mFftSize = mWindowSize;
if( ! isPowerOf2( mFftSize ) )
mFftSize = nextPowerOf2( static_cast<uint32_t>( mFftSize ) );
mFft = unique_ptr<dsp::Fft>( new dsp::Fft( mFftSize ) );
mFftBuffer = audio::Buffer( mFftSize );
mBufferSpectral = audio::BufferSpectral( mFftSize );
mMagSpectrum.resize(getNumChannels());
for(int i = 0; i < getNumChannels(); i++){
mMagSpectrum[i].resize( mFftSize / 2 );
}
mWindowingTable = makeAlignedArray<float>( mWindowSize );
generateWindow( mWindowType, mWindowingTable.get(), mWindowSize );
}
```

prepareprocessing function:

```
void MultiChannelSpectralNode::prepareProcessing(){
uint64_t numFramesProcessed = getContext()->getNumProcessedFrames();
if( mLastFrameMagSpectrumComputed == numFramesProcessed )
return;
mLastFrameMagSpectrumComputed = numFramesProcessed;
fillCopiedBuffer();
}
```

and finally the getMagSpectrum function:

```
const std::vector<float>& MultiChannelSpectralNode::getMagSpectrum(size_t channel){
if(channel >= getNumChannels()) return mMagSpectrum[0];
// window the copied buffer and compute forward FFT transform
dsp::mul( mCopiedBuffer.getChannel(channel), mWindowingTable.get(), mFftBuffer.getData(), mWindowSize );
mFft->forward( &mFftBuffer, &mBufferSpectral );
float *real = mBufferSpectral.getReal();
float *imag = mBufferSpectral.getImag();
// remove Nyquist component
imag[0] = 0.0f;
// compute normalized magnitude spectrum
const float magScale = 10.f / mFft->getSize();
const size_t specSize = mMagSpectrum[channel].size();
for( size_t i = 0; i < specSize; i++ ) {
float re = real[i];
float im = imag[i];
mMagSpectrum[channel][i] = mMagSpectrum[channel][i] * mSmoothingFactor + std::sqrt( re * re + im * im ) * magScale * ( 1 - mSmoothingFactor );
}
return mMagSpectrum[channel];
}
```

hope this helps.

-seph