How to save results of FFT analysis to file?

Hello!
I want to continuesly send FFT data to file (or to some data structure like list or array to then move to file), to process later.

My Idea is combine FFT Ugens with SendReply to send data from server to language, but I have problems with data consistency.

(
OSCdef(\listener, {|msg|
  var data = msg[3..];
  data.do(_.postln);
}, '/fft');
)

f = {
  var tRate = 200;
  var fftSize = 512;
  var f = 220;
  var n = 8;
  var fDiv = {rrand(0.9, 0.1)}!n;
  var sig = Mix(SinOsc.ar(f * fDiv));
  var chain = FFT(LocalBuf(fftSize), sig);

  chain.pvcalc(fftSize, {
	| mags, phases |
	SendTrig.kr(Impulse.kr(tRate), '/fft', [mags, phases]);
	[mags, phases];
  }, frombin: 0, tobin: 5, zeroothers: 0);

  0;
}.play;

In this case I have output like this:

0.0
0.87183380126953
-2.3812713623047
0.50964814424515
0.49460834264755
0.43831858038902
152.01528930664
163.86853027344
251.84725952148
75.071601867676
19.306264877319
9.2933320999146
0.0
1.7317938804626
-2.3740260601044
0.21117898821831
0.23013909161091
0.20611572265625
64.259635925293
188.65330505371
405.52630615234
92.881492614746
24.96888923645
12.289628982544
0.0

And it is actually looks like phases and magnitudes, but any structure is totally lost.
I think that my problem is that SendReply using a trigger as first argument and it should be somehow in sync with pvcalc.

Do you have any ideas how to do it or, maybe, tatally different solution?

You can look at PV_RecordBuf in sc3-plugins. Also, there is a PVAna class in there too that will do analysis out in non-real time.

Josh

PV_RecordBuf can be solution, but if I plan to analyze live performance, so I’ll need to allocate really huge buffer (in hour for example).

Also I need something like text file and PV_RecordBuf saves to sound file

yep! that’s what it’s made for. You allocate the buffer ahead of time and just write in to it, then save it at the end. I’ve done 25 minutes of this in the past and it was fine… though keep in mind if you are saving the raw audio as well, you can write that out then just do the FFT on it later (no need for double duty - the analysis will be the same either way)

Or allocate two buffers and write their contents alternately (when recording reaches the end of one buffer, switch recording to the other buffer and write the one that just finished). Then RAM wouldn’t limit total recording time.

(Btw use “float” sample format for PV data – values are not guaranteed to be constrained to -1 … +1 as is usually the case for audio… mentioning just in case.)

SoundFile in the language can read the values directly from an audio file. Then you can write to whatever text format you need. PV_RecordBuf buffers are in this format (btw I was looking at this only last week, I don’t always keep this info handy :laughing: ) –

  • 0: Frame size = n
  • 1: Hop size (e.g. 0.5 for 2x overlap)
  • 2: Window type as in FFT
  • 3: Frame 0 DC magnitude
  • 4: Frame 0 Nyquist magnitude
  • 5: Frame 0 bin 1 phase
  • 6: Frame 0 bin 1 magnitude
  • 7: Frame 0 bin 2 phase
  • …
  • 1+n: Frame 0 bin n/2 - 1 phase
  • 2+n: Frame 0 bin n/2 - 1 magnitude
  • 3+n: Frame 1 DC magnitude etc

hjh

Hi @Bjornmossa,

You might also checkout the FluidBufSTFT object that is part of the FluCoMa package. Let me know if you have any questions about it!

Cheers,

Ted

1 Like