bisqwit / adlmidi

ADLMIDI is a MIDI player that uses OPL3 emulation.
62 stars 10 forks source link

very low volume playback #12

Open fenugrec opened 7 months ago

fenugrec commented 7 months ago

on archlinux, with an ordinary alsa / pulseaudio configuration, adlmidi plays back audio at a barely audible volume. Running with -w produces a .wav file with a very low volume as well.

Wohlstand commented 7 months ago

That's because the gaining is needed (in the code I mean) to resolve this problem. Also, you could disable the reverbation that also reduces the volume.

fenugrec commented 7 months ago

Thanks. Unfortunately, running with -nr gives a segfault :

/usr/include/c++/13.2.1/string_view:258: constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_reference = consAborted (core dumped)
Wohlstand commented 7 months ago

This, seems, an another and unrelated bug...

bisqwit commented 7 months ago

The default settings in reverb reduce the gain in order to avoid clipping problems. This could be helped by doing some DC offset removal before running reverb (and would be a good idea in general).

fenugrec commented 7 months ago

The default settings in reverb reduce the gain in order to avoid clipping problems.

Thanks for the explanation. I'm surprised it needs this much attenuation, it sounds about 30dB too quiet...

bisqwit commented 7 months ago

I agree, but DC offset can make all the difference. If you don't know what I mean, consider this. If the sound alternates only between values +2 and –1, its amplitude would only be 3. Now, if you multiply that with just 1.0001, you get an alternation between +2 and –1. If you express this in 16 bits, you still get –2 and +1, an amplitude of 3. However, if the sound alternates only between values -32765 and -32768, yes, its amplitude would still only be 3. However, if you multiply that with just 1.0001 (same as before), you get an alternation between –32768 and –32771. If you express this in 16 bits, you get values –32768 and +32764, an amplitude of 65514, which is many orders of magnitudes larger than before. This is why the DC offset can make all the difference.

Wohlstand commented 7 months ago

Another solution is just an output as Float32. Unlike integer formats, float allows to clip and don't distort the result.

bisqwit commented 7 months ago

Yes, float32 format is a way of saying it’s someone else’s problem now. (I don’t know why ADLMIDI doesn’t use float32 for WAVs.) ADLMIDI actually does make an attempt at negating the DC offset, but it is not perfect.