comparison host/vamp-simple-host.cpp @ 318:2ed36547e1bf

Patch from Dan Stowell to permit vamp-simple-host to read data of unknown length (for streaming input)
author Chris Cannam
date Thu, 18 Aug 2011 12:21:30 +0100
parents 5940dd0a399f
children 97387af51350
comparison
equal deleted inserted replaced
317:5cb298435765 318:2ed36547e1bf
274 SF_INFO sfinfo; 274 SF_INFO sfinfo;
275 memset(&sfinfo, 0, sizeof(SF_INFO)); 275 memset(&sfinfo, 0, sizeof(SF_INFO));
276 276
277 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo); 277 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
278 if (!sndfile) { 278 if (!sndfile) {
279 cerr << myname << ": ERROR: Failed to open input file \"" 279 cerr << myname << ": ERROR: Failed to open input file \""
280 << wavname << "\": " << sf_strerror(sndfile) << endl; 280 << wavname << "\": " << sf_strerror(sndfile) << endl;
281 return 1; 281 return 1;
282 } 282 }
283 283
284 ofstream *out = 0; 284 ofstream *out = 0;
285 if (outfilename != "") { 285 if (outfilename != "") {
286 out = new ofstream(outfilename.c_str(), ios::out); 286 out = new ofstream(outfilename.c_str(), ios::out);
337 } else { 337 } else {
338 blockSize = stepSize; 338 blockSize = stepSize;
339 } 339 }
340 cerr << blockSize << endl; 340 cerr << blockSize << endl;
341 } 341 }
342 int overlapSize = blockSize - stepSize;
343 sf_count_t currentStep = 0;
344 int finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
342 345
343 int channels = sfinfo.channels; 346 int channels = sfinfo.channels;
344 347
345 float *filebuf = new float[blockSize * channels]; 348 float *filebuf = new float[blockSize * channels];
346 float **plugbuf = new float*[channels]; 349 float **plugbuf = new float*[channels];
367 RealTime rt; 370 RealTime rt;
368 PluginWrapper *wrapper = 0; 371 PluginWrapper *wrapper = 0;
369 RealTime adjustment = RealTime::zeroTime; 372 RealTime adjustment = RealTime::zeroTime;
370 373
371 if (outputs.empty()) { 374 if (outputs.empty()) {
372 cerr << "ERROR: Plugin has no outputs!" << endl; 375 cerr << "ERROR: Plugin has no outputs!" << endl;
373 goto done; 376 goto done;
374 } 377 }
375 378
376 if (outputNo < 0) { 379 if (outputNo < 0) {
377 380
411 // PluginInputDomainAdapter::getTimestampAdjustment 414 // PluginInputDomainAdapter::getTimestampAdjustment
412 PluginInputDomainAdapter *ida = 415 PluginInputDomainAdapter *ida =
413 wrapper->getWrapper<PluginInputDomainAdapter>(); 416 wrapper->getWrapper<PluginInputDomainAdapter>();
414 if (ida) adjustment = ida->getTimestampAdjustment(); 417 if (ida) adjustment = ida->getTimestampAdjustment();
415 } 418 }
416 419
417 for (sf_count_t i = 0; i < sfinfo.frames; i += stepSize) { 420 // Here we iterate over the frames, avoiding asking the numframes in case it's streaming input.
421 do {
418 422
419 int count; 423 int count;
420 424
421 if (sf_seek(sndfile, i, SEEK_SET) < 0) { 425 if ((blockSize==stepSize) || (currentStep==0)) {
422 cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl; 426 // read a full fresh block
423 break; 427 if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
424 } 428 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
425 429 break;
426 if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) { 430 }
427 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl; 431 if (count != blockSize) --finalStepsRemaining;
428 break; 432 } else {
433 // otherwise shunt the existing data down and read the remainder.
434 memmove(filebuf, filebuf + (stepSize * channels), overlapSize * channels * sizeof(float));
435 if ((count = sf_readf_float(sndfile, filebuf + (overlapSize * channels), stepSize)) < 0) {
436 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
437 break;
438 }
439 if (count != stepSize) --finalStepsRemaining;
440 count += overlapSize;
429 } 441 }
430 442
431 for (int c = 0; c < channels; ++c) { 443 for (int c = 0; c < channels; ++c) {
432 int j = 0; 444 int j = 0;
433 while (j < count) { 445 while (j < count) {
438 plugbuf[c][j] = 0.0f; 450 plugbuf[c][j] = 0.0f;
439 ++j; 451 ++j;
440 } 452 }
441 } 453 }
442 454
443 rt = RealTime::frame2RealTime(i, sfinfo.samplerate); 455 rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
444 456
445 printFeatures 457 printFeatures
446 (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate), 458 (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
447 sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt), 459 sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
448 out, useFrames); 460 out, useFrames);
449 461
450 int pp = progress; 462 if (sfinfo.frames > 0){
451 progress = lrintf((float(i) / sfinfo.frames) * 100.f); 463 int pp = progress;
452 if (progress != pp && out) { 464 progress = lrintf((float(currentStep * stepSize) / sfinfo.frames) * 100.f);
453 cerr << "\r" << progress << "%"; 465 if (progress != pp && out) {
454 } 466 cerr << "\r" << progress << "%";
455 } 467 }
468 }
469
470 ++currentStep;
471
472 } while (finalStepsRemaining > 0);
473
456 if (out) cerr << "\rDone" << endl; 474 if (out) cerr << "\rDone" << endl;
457 475
458 rt = RealTime::frame2RealTime(sfinfo.frames, sfinfo.samplerate); 476 rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
459 477
460 printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate), 478 printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
461 sfinfo.samplerate, outputNo, 479 sfinfo.samplerate, outputNo,
462 plugin->getRemainingFeatures(), out, useFrames); 480 plugin->getRemainingFeatures(), out, useFrames);
463 481