musikinformatik / SoundFileAnalysis

A simple system for non realtime soundfile analysis in SuperCollider
GNU General Public License v2.0
14 stars 1 forks source link

last block of analysis is not written #2

Open olafklingt opened 4 years ago

olafklingt commented 4 years ago

I realized that the last block of the analysis is not written to the file. here a easy reproducer:

(
var fn=Platform.resourceDir +/+ "sounds/a11wlk01.wav";
var f=SoundFile.openRead(fn);
var nf= f.numFrames.debug(\numFrames);
a=SoundFileAnalysis();      
a.add(\pn, \trig, { |sig|
    var trig = (sig>0)&(Delay1.ar(sig)<=0);
    var count = PulseCount.ar(trig);
    var phase = Phasor.ar(0,1,0,nf) - nf +2;
    Poll(phase,count);
    [phase, count]});
    x=a.analyzeFile(fn,0,f.duration, callback: {x.postln});
)

the easiest way to overcome the problem is to set the server blockSize to 1.

telephon commented 4 years ago

thanks! Could you check the reproducer? Ot doesn't work …

olafklingt commented 4 years ago

It should work now. [ok now i could test it and finally it works ... sorry]

telephon commented 4 years ago

Hm, for me this runs now, but it doesn't find any triggers:

(
var fn=Platform.resourceDir +/+ "sounds/a11wlk01.wav";
var f=SoundFile.openRead(fn);
var nf= f.numFrames.debug(\numFrames);
a = SoundFileAnalysis();        
a.add(\pn, \trig, { |sig|
    var trig = (sig>0) & (Delay1.ar(sig) <= 0);
    var count = PulseCount.ar(trig);
    var phase = Phasor.ar(0, 1, 0, nf) - nf + 2;
    //Poll(phase,count);
    [phase, count]
});
x = a.analyzeFile(fn, 0, f.duration, callback: { x.postln });
)

x[\pn] // ->  FloatArray[  ]
olafklingt commented 4 years ago

exactly. you will only find a result if you set server.blockSize_(1) in the NRT server. the trigger is at the end of the sound file. but this trigger is within the last calculation block. the duration of the sample is a bit smaller than blockSize*N. somehow this affects what is written to the file. so when this message is set it is called a bit too early to write the analysis of the last block.

score.add([analysisDuration, buf.writeMsg(path, headerFormat: "AIFF", sampleFormat: "float")]);

so one solution would be:

score.add([analysisDuration + THAT AMOUNT OF SAMPLES NEEDED TO REACH THE END OF THE BLOCK, buf.writeMsg(path, headerFormat: "AIFF", sampleFormat: "float")]);

but i guess that would affect the average value calculations ...

telephon commented 4 years ago

Probably the duration should be rounded up to the block size. This can be a setting.

EDIT: or truncated, then it is more consistent.

olafklingt commented 4 years ago

To truncate would be the current situation, right?

In my use case I need in addition to a complete analysis of the sound-file a analysis that is one sample longer than the sound-file length. So the problem is rather how the analysis is automatically trimmed. So it could be an option to trim the given duration or not. In addition one could provide a server options.

analyzeFile { |path, start = (0), duration, which, callback, maxDataPoints = (1000),trimDuration=\roundDown, serverOptions|

I like this solution because it avoids unclear settings. But would make the user have to think a lot to find the right solution.

I feel like there is no a good naming convention the options

trimDuration = \roundUp, 0,\roundDown

0 or nil for don't trim at all automatically. Which still would imply that the user have to be aware that they have to choose a good duration for their (maybe overlapping) analysis of sections of a sound-file.

telephon commented 4 years ago

Good idea. The usual way is to use nil for "nothing" (e.g. in linlin(clip: nil)). And because we have integers here, it might be also possible to use floor and ceil, which are shorter. But your suggestion using roundUp is also very clear, so it is fine with me. Do you want to give it a try and fix it?

olafklingt commented 4 years ago

Ok will make a pull request

On 11 May 2020 15:05:33 GMT+08:00, Julian Rohrhuber notifications@github.com wrote:

Good idea. The usual way is to use nil for "nothing" (e.g. in linlin(clip: nil)). And because we have integers here, it might be also possible to use floor and ceil, which are shorter. But your suggestion using roundUp is also very clear, so it is fine with me. Do you want to give it a try and fix it?

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/musikinformatik/SoundFileAnalysis/issues/2#issuecomment-626513070