liquidsoap icon indicating copy to clipboard operation
liquidsoap copied to clipboard

Crossfade is not working

Open artur-shaik opened this issue 3 months ago • 1 comments

Describe the bug Crossfade just stop playing previous track and starts next one. This behavior occur only in v2.2.4+ version and works as expected in v2.2.3.

To Reproduce Here is my script. In my env reproducible with this code and with uncommented also. With any output formats.

last_meta = ref([])
queue = request.queue()

security = single("/media/data/music_store/failsafe-vinyl.ogg")
radio = mksafe(crossfade(fade_out=0., fade_in=0., duration=3., queue))
# radio = fallback(track_sensitive = false, [radio, security])
# radio = replaygain(radio)
# radio = bass_boost(gain=2.0, radio)
# radio = compress(threshold=-10., ratio=5., attack=1.0, release=2., gain=4., radio)
# radio = limit(pre_gain=8., radio)

radio.on_metadata(fun (m) -> last_meta := m)

def on_track_handler(_) =
    _ = http.post("http://127.0.0.1:8002/on_next_track")
end
radio.on_track(on_track_handler)
radio = insert_metadata(radio)

output.icecast(
    %ogg(%vorbis(quality=0.8,samplerate=48000,channels=2)),
    # %ogg(%opus(samplerate=48000, bitrate=256, channels=2, vbr="none", application="audio", signal="music")),
    # %mp3(bitrate=256),
    mount="/high.ogg",
    send_icy_metadata=true,
    host=icecast_host, port=icecast_port, user="highsrc", password=high_pass,
    radio)

output.icecast(
    %ogg(%vorbis(quality=0.3,samplerate=44100,channels=2)),
    # %ogg(%opus(samplerate=24000, bitrate=96, channels=2, vbr="none", application="audio", signal="music")),
    # %mp3(bitrate=96),
    mount="/low.ogg",
    send_icy_metadata=true,
    host=icecast_host, port=icecast_port, user="lowsrc", password=low_pass,
    radio)

Expected behavior 3 seconds transition without fades.

Version details

  • OS: Docker
  • Version: 2.2.4

Install method Docker

Some logs I could catch:

[mp3float @ 0x7fad2cb6f800] Could not update timestamps for discarded samples.
2024/03/05 19:44:30 [decoder:2] Decoding "/media/data/music_store/roger_shah_-_skyarium.mp3" ended: Ffmpeg_decoder.End_of_file. ID 0).
2024/03/05 19:44:30 [request_queue:3] Prepared "/media/data/music_store/first_state_and_tom_fall_feat._jasmine_maurie_-_moonless_nights.mp3" (RID 2).
[mp3float @ 0x7fad2cb6f800] Could not update timestamps for skipped samples.
2024/03/05 19:44:30 [cross:3] Analysis: -19.938335dB / -18.643796dB (2.98s / 2.98s)
2024/03/05 19:44:30 [cross:3] Computing crossfade duration over overlapping 2.98s buffered data at start and end.
2024/03/05 19:44:30 [crossfade:3] Simple transition: crossed, fade-in, fade-out.
2024/03/05 19:44:30 [source.4:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [audio.add:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [fade_in:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [fade_scale:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [track_amplify.2:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [blank.2:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [on_metadata.2:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [on_track.2:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [cross_after:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [buffer.3:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [fade_out:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [track_amplify:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [on_frame:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [on_metadata:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [on_track:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [cross_before:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [buffer:3] Content type is {audio=pcm(stereo)}.
2024/03/05 19:44:30 [cross_after_tail:3] Content type is {audio=pcm(stereo)}.

Example audio (track switch on 3sec, bear in mind that next track's "fade in" is part of audio file):

file.ogg.zip

artur-shaik avatar Mar 05 '24 14:03 artur-shaik

Thanks for the report. I was out of pocket this week but will have a look soon.

toots avatar Mar 09 '24 00:03 toots

I just wonder, could you reproduce it, or it is problem in my setup?

artur-shaik avatar Apr 05 '24 03:04 artur-shaik

Hi, sorry for the delayed response. We've been working a lot on crossfade in the current rolling-release-v2.2.x. Would you mind giving the latest build a try? It should be available here: https://github.com/savonet/liquidsoap/releases/tag/rolling-release-v2.2.x

toots avatar Apr 05 '24 13:04 toots

tried with docker image

radiost-tms-dev | 2024/04/06 12:13:21 [main:3] Liquidsoap 2.2.5+git@317f191c0

the issue still persist :(

artur-shaik avatar Apr 06 '24 06:04 artur-shaik

I have made some investigation about when this issue represented. And here is docker images:

b573ac2 - issue present, 1 Feb 8d5ab6a - no issue, crossfading works as expected, 31 Jan

artur-shaik avatar Apr 13 '24 06:04 artur-shaik

Thanks for your patience with this.

I'm not sure if this is a bug or the intended behavior after fixing crossfade.

What I see is that you are setting fade.out duration to 0. seconds. This means that 3. seconds of the ending track are buffered but, when the crossfade is computed, it goes immediatly to 0, resulting in the last 3. seconds of the ending song being removed.

It's possible that this behavior was different before.

If your intent is to emulate a sequence transition using crossfade, you might have to use fade_out_delay. I wrote about this here: https://www.liquidsoap.info/blog/2024-02-07-liquidsoap-v2.2.4/

However, my first suggestion would be to use the new autocue feature in 2.2.5. We've been working hard (and still are!) to make sure that it provides a smooth default for all crossfade transitions out of the box, including with short jingles and such.

To enable it all, you have to in your script is:

enable_autocue_metadata()

last_meta = ref([])
queue = request.queue()

security = single("/media/data/music_store/failsafe-vinyl.ogg")
radio = mksafe(crossfade(queue))

toots avatar Apr 14 '24 01:04 toots

Thank you for answer. I gave it a try. But with such script:

enable_autocue_metadata()
radio = cross(duration=3., queue)

It gives me random (not sure if really random, though)) cross time, I don't get 3 seconds transition and this what I wanna get.

Can you explain, how I can easily set fade_in/out delay with crossfade?

artur-shaik avatar May 04 '24 11:05 artur-shaik

Unsure, but possibly related to https://discord.com/channels/760417466450182146/1227018148189048852/1236311158215020586 ?

Moonbase59 avatar May 04 '24 16:05 Moonbase59

If your intent is to emulate a sequence transition using crossfade, you might have to use fade_out_delay

Thanks for hint, I finally figured out how to do it. I just added annotation like so:

        queue.push.uri("annotate:liq_fade_out_delay=\"3.0\":" ^ full_path)

Now transition works as I expected it should work.

artur-shaik avatar May 07 '24 11:05 artur-shaik