From ea68a817c1947b2001775d42755d260d66f4d37f Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Thu, 7 Jan 2021 14:09:38 +0800 Subject: Wait voice now checks for output level instead of polyphony. Fluidsynth sometimes screw up the number of currently sounding voices. --- core/qmpmidioutfluid.cpp | 23 ++++++++++++++++++++++- core/qmpmidioutfluid.hpp | 2 ++ qmidiplayer-desktop/qmpmainwindow.cpp | 4 ++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/core/qmpmidioutfluid.cpp b/core/qmpmidioutfluid.cpp index bfa6016..22f4aa2 100644 --- a/core/qmpmidioutfluid.cpp +++ b/core/qmpmidioutfluid.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -66,7 +67,22 @@ void qmpMidiOutFluid::deviceInit() fluid_set_log_function(FLUID_WARN, nullptr, nullptr); fluid_set_log_function(FLUID_ERR, fluid_default_log_function, nullptr); fluid_set_log_function(FLUID_PANIC, fluid_default_log_function, nullptr); - adriver = new_fluid_audio_driver(settings, synth); + adriver = new_fluid_audio_driver2(settings, + [](void *t, int l, int nfx, float *fx[], int nout, float *out[])->int + { + qmpMidiOutFluid *self = static_cast(t); + fluid_synth_process(self->synth, l, nfx, fx, nout, out); + double s = 0; + for (int i = 0; i < nout; ++i) + { + for (int j = 0; j < l; ++j) + { + s += out[i][j] * out[i][j] / l; + } + } + self->output_level = 20 * log10(sqrt(s)); + } + , this); if (!adriver) { fputs("Error creating fluidsynth audio driver!", stderr); @@ -301,6 +317,11 @@ int qmpMidiOutFluid::getMaxPolyphone() { return synth ? fluid_synth_get_polyphony(synth) : 0; } + +double qmpMidiOutFluid::getOutputLevel() +{ + return output_level; +} void qmpMidiOutFluid::setGain(double gain) { if (settings) diff --git a/core/qmpmidioutfluid.hpp b/core/qmpmidioutfluid.hpp index acefb68..4fdceff 100644 --- a/core/qmpmidioutfluid.hpp +++ b/core/qmpmidioutfluid.hpp @@ -29,6 +29,7 @@ private: std::vector drivers; int default_driver = -1; void update_preset_list(); + double output_level; public: qmpMidiOutFluid(); ~qmpMidiOutFluid(); @@ -58,6 +59,7 @@ public: int getPolyphone(); int getMaxPolyphone(); + double getOutputLevel(); void setGain(double gain); void getChannelInfo(int ch, int *b, int *p, char *s); void getReverbPara(double *r, double *d, double *w, double *l); diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 05b7ec3..1c825ee 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -379,7 +379,7 @@ void qmpMainWindow::switchTrack(QString s, bool interrupt) { player->playerThread(); if (settings->getOptionBool("Midi/WaitVoice") && player->isFinished()) - while (internalfluid->getPolyphone() > 0) + while (internalfluid->getOutputLevel() > -100) std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); #ifdef _WIN32 @@ -534,7 +534,7 @@ void qmpMainWindow::on_pbPlayPause_clicked() { player->playerThread(); if (settings->getOptionBool("Midi/WaitVoice") && player->isFinished()) - while (internalfluid->getPolyphone() > 0) + while (internalfluid->getOutputLevel() > -100) std::this_thread::sleep_for(std::chrono::milliseconds(10)); }); #ifdef _WIN32 -- cgit v1.2.3