MTG / essentia

C++ library for audio and music analysis, description and synthesis, including Python bindings
http://essentia.upf.edu
GNU Affero General Public License v3.0
2.81k stars 525 forks source link

Streaming mode slower than standard in C++ batch processing #320

Open carthach opened 8 years ago

carthach commented 8 years ago

So I do a lot of batch processing within C++ which I mostly do in standard mode as outlined below the comments (normally I just pass vectors of audio retrieved from elsewhere).

I make declare some variables, algorithms and set the inputs/outputs of the algorithms to those variables, iterate through the files declaring a new audio algorithm for each file, resetting and recomputing.

For this kind of work it should make more sense to use a network right? Just set up the connections create a network then reassign the audio file, reset the network and run for each file in the list? Right?

The only problem is it's twice as slow. Is this generally the case for streaming versus standard? On ~500 44100 WAV files of ~10s in length it's 17s versus 33 seconds. Is my back procedure for the network correct? (code below).

// =========================
// Streaming
//==========================

//Declare algorithms and connect

Network n(audio);

for(auto & filename : filenames) {
    pool.clear();

    n.reset();
    audio->configure("filename", filename);

    n.run();

    //Aggregation
}

n.clear();

// =========================
// Standard
//==========================

//Setup algorithms and variables and set input outputs

for(auto & file : files)
{
    pool.clear();

    audioBuffer.clear();
    Algorithm* audio = factory.create("MonoLoader",
                                      "filename", file,
                                      "sampleRate", sampleRate);
    audio->output("audio").set(audioBuffer);

    fc->reset();
    w->reset();
    spec->reset();
    mfcc->reset();

    audio->compute();

    while (true) {

        // compute a frame
        fc->compute();

        // if it was the last one (ie: it was empty), then we're done.
        if (!frame.size()) {
            break;
        }

        // if the frame is silent, just drop it and go on processing
        if (isSilent(frame)) continue;

        w->compute();
        spec->compute();
        mfcc->compute();                
    }

    //Aggregation
}
dbogdanov commented 7 years ago

Can you still reproduce that?

carthach commented 7 years ago

Good question. I'll try again this week and report back.

dbogdanov commented 5 years ago

There may be some overhead due to the very large buffers possibly used in the computation chain (https://github.com/MTG/essentia/blob/master/src/essentia/streaming/phantombuffer.h#L69). We'll need to verify that, and if this is an issue, find better buffer sizes, or even make those configurable.