hzeller / gmrender-resurrect

Resource efficient UPnP/DLNA renderer, optimal for Raspberry Pi, CuBox or a general MediaServer. Fork of GMediaRenderer to add some features to make it usable.
GNU General Public License v2.0
841 stars 204 forks source link

Changing playback speed #202

Open ASimb opened 4 years ago

ASimb commented 4 years ago

Hi,

I found a new problem: I have a software, which uses the "AVTransport:setNextURI"-function to set the following song (remark: just mp3-audio). This works fine as long as the sampling rate of all MP3-files is the same. BUT if I play a 44.1kHz-file followed by a 48kHz one, the second sounds like singing smurfs. If I stop the file and restart it, everything is OK. The other way round: If a 44.1-file follows a 48kHz-one the song is noticeable slower. Till now I couldn't find the reason for this behaviour.

regards

Andreas

hzeller commented 4 years ago

The code to deal with subsequent URLs with different sampling frequencies is happening within gstreamer, so I'd first try to get the latest version of gstreamer to see if it is fixed there. Might be also worthwhile looking if there is a bug filed there.

mill1000 commented 4 years ago

@ASimb You've been using Bluetooth before. Does this issue occur when using a local sound device?

ASimb commented 4 years ago

@ASimb You've been using Bluetooth before. Does this issue occur when using a local sound device?

I have 2 devices running. One with BT (bluealsa) and one with the local sound device (both are raspberry PIs).

The code to deal with subsequent URLs with different sampling frequencies is happening within gstreamer, so I'd first try to get the latest version of gstreamer to see if it is fixed there. Might be also worthwhile looking if there is a bug filed there.

After several hours of research I think I found out the reason. Gmrenderer has two ways to set the next song. Either by trapping the "about-to-finish"-signal with void prepare_next_stream, or by "my-bus-callback" at the GST_MESSAGE_EOS. In the first case the gstreamer is NOT stopped and only the next URI is set. Therefore the gstreamer seems to suppose that the sampling-rate does not change, and things run wrong. In the second case the gstreamer is stopped, new URI is set and playing is started again, and everything runs fine. My solution: I removed the setting of the next URI in the "about-to-finish"-callback and secondly I added a code in the GST-MESSAGE-EOS-callback to ensure, that gstreamer REALLY stops. Now everything runs fine.

regards

Andreas

mill1000 commented 4 years ago

Does your control point have gapless playback enabled? You may be able to get the same effect without modifying the code.

ASimb commented 4 years ago

The control point is a self-made PHP-web-application. The application checks every 15s the status of the selected renderer (remark: beside the two raspis there is also a Sony-Bravia in the network, which is also used as media renderer via upnp-AVTransport). The key problem is, that due to this configuration a gapless playback is needed, because the web-application can only check the status of the song played in pre-defined intervals (there is no possibility to transfer a "song has ended"-signal from the renderer => PHP-server => browser in the home-network)

mill1000 commented 4 years ago

@ASimb I haven't been able to reproduce the sample rate issue. Can you confirm if the issue persists when using another control point?

mill1000 commented 4 years ago

Ok so I was able to reproduce this issue using the internal sound card. My normal setup uses an I2S DAC and that does not appear to be effected.

However, the solution proposed in PR #203 breaks gapless playback support because gstreamer is instructed to stop between tracks

mill1000 commented 4 years ago

This issue can be reproduced outside of gmediarender with the following

 gst-play-1.0 --gapless test_48.mp3 test.mp3
ASimb commented 4 years ago

As supposed, it seems to be a bug in the gstreamer. But in my opinion gmrenderer should offer a solution for this as long as this bug is not fixed.

mill1000 commented 4 years ago

Perhaps. But not at the cost of existing functionality.

ASimb commented 4 years ago

You don't loose any functionality, it's just another way to start the next song ...

mill1000 commented 4 years ago

PR #203, particularly the changes to prepare_next_stream, breaks gapless playback. That is a loss of functionality.

With these chagnes, Gstreamer is no longer provided the next URI in response to the about-to-finish signal. Instead it must wait for the End Of Stream message before the next URI is loaded. This produces a short, but noticeable gap in the output.