aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2021-01-07 14:09:38 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2021-01-07 14:09:38 +0800
commitea68a817c1947b2001775d42755d260d66f4d37f (patch)
tree3ad0650984c5f442f94fd573a7c74616f193048f
parent327526848c930c5cca7fafbde36d60ea45b786db (diff)
downloadQMidiPlayer-ea68a817c1947b2001775d42755d260d66f4d37f.tar.xz
Wait voice now checks for output level instead of polyphony.
Fluidsynth sometimes screw up the number of currently sounding voices.
-rw-r--r--core/qmpmidioutfluid.cpp23
-rw-r--r--core/qmpmidioutfluid.hpp2
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp4
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 <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
@@ -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<qmpMidiOutFluid*>(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<std::string> 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