savonet / liquidsoap

Liquidsoap is a statically typed scripting general-purpose language with dedicated operators and backend for all thing media, streaming, file generation, automation, HTTP backend and more.
http://liquidsoap.info
GNU General Public License v2.0
1.4k stars 130 forks source link

"rotate" operator gets triked by safe fallbacks and doesn't respect weights #1327

Closed matteo-daddi closed 4 years ago

matteo-daddi commented 4 years ago

Describe the bug This is a bit hard to explain but it happens systematically: It seems that if you define some weights for the rotate operator and the resulting source (let's call it "rotation") is used by another operator (for example "fallback" or mksafe or maybe others) that switch to another source (let's call it "safety") in case of unavailability of "rotation", the "rotate" operator award the "safety" track to itself causing weights to be unrespected (obviously in the case "safety" is played back, otherwise weights are respected!). May be related to #1279.

To Reproduce

#I've used synth waves to let others easily test the script
#Please read the inline comments and start the test when your computer clock is between 0s-5s

#In a real use case this is a playlist (in the test you can recognize when this is playing because they are all harmonic SINE waves)
mainSINEPlaylist = sequence([sine(duration=5.),sine(duration=5.,880.),sine(duration=5.),sine(duration=5.,880.),sine(duration=5.),sine(duration=5.,880.)])
#In a real use case this is a playlist (in the test you can recognize when this is playing because they are all high SAW waves)
sideSAWPlaylist = sequence([saw(duration=5.,1320.),saw(duration=5.,1760.)])

#We expect 3 sine waves and one saw wave per round
rotation = rotate(weights=[3,1], transition_length=0., [mainSINEPlaylist, sideSAWPlaylist])

#If you will start this test script as suggested in 0s-5s the following hack make "rotation" unavailable till 10s
notReadyAtStart = switch(transition_length=0.,track_sensitive=true,[({10s-59s},rotation)])

#If you have respected all the advices this fallback SHOULD start outputting "noise()" (to be honest it all depends on your computer speed but is reasonable to not considet this variable!)
radio = fallback(transition_length=0.,track_sensitive=false,[notReadyAtStart, noise()])

#bufferize is set to false otherwise alsa will prebuffer frames introducing latency (am I right?)
#Note that bufferize value SHOULD not be important, it is set to false just to have time respected as much as possible.
#also fallible value should not be significant
output.alsa(bufferize=false,fallible=true,radio)

#To see more or less the same script working as desired (considering rotation behavior) you can edit the switch condition from "{10s-59s}" to "{true}" and rotation SHOULD work as expected (tested on my machine)

Expected behavior Without the BUG you should hear: noise in 0s-10s then 5 seconds of a 440Hz sine wave, 5 seconds of a 880Hz sine wave, 5 seconds of a 440Hz sine wave, ...Then rotate should switch to: 5 seconds of a 1320 saw wave ...Then rotate should switch to: 5 seconds of a 880Hz sine wave [...]

But, due to the supposed BUG you'll probably hear: noise in 0s-10s then 5 seconds of a 440Hz sine wave, 5 seconds of a 880Hz sine wave, ...Then rotate should switch to: #HERE's the BUG, rotate seems to count noise as one of it's child source 5 seconds of a 1320 saw wave ...Then rotate should switch to: 5 seconds of a 440Hz sine wave [...]

Here's the log of previous script:

2020/08/14 09:06:01 >>> LOG START 2020/08/14 09:06:01 [main:3] Liquidsoap 1.4.3+git@9086335c 2020/08/14 09:06:01 [main:3] Using: bytes=[distributed with OCaml 4.02 or above] pcre=7.4.3 sedlex=2.2 menhirLib=20200624 dtools=0.4.2 duppy=0.8.0 cry=0.6.5 mm=0.5.0 ogg=0.5.2 vorbis=0.7.1 mad=0.4.5 dynlink=[distributed with Ocaml] lame=0.3.3 alsa=0.2.3 samplerate=0.1.4 taglib=0.3.6 camomile=1.0.2 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [main:3] DISCLAIMER: This version of Liquidsoap has been 2020/08/14 09:06:01 [main:3] compiled from a snapshot of the development code. 2020/08/14 09:06:01 [main:3] As such, it should not be used in production 2020/08/14 09:06:01 [main:3] unless you know what you are doing! 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [main:3] We are, however, very interested in any feedback 2020/08/14 09:06:01 [main:3] about our development code and committed to fix 2020/08/14 09:06:01 [main:3] issues as soon as possible. 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [main:3] If you are interested in collaborating to 2020/08/14 09:06:01 [main:3] the development of Liquidsoap, feel free to 2020/08/14 09:06:01 [main:3] drop us a mail at savonet-devl@lists.sf.net 2020/08/14 09:06:01 [main:3] or to join the slack chat at http://slack.liquidsoap.info. 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [main:3] Please send any bug report or feature request 2020/08/14 09:06:01 [main:3] at https://github.com/savonet/liquidsoap/issues. 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [main:3] We hope you enjoy this snapshot build of Liquidsoap! 2020/08/14 09:06:01 [main:3] 2020/08/14 09:06:01 [dynamic.loader:3] Could not find dynamic module for fdkaac encoder. 2020/08/14 09:06:01 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz master. 2020/08/14 09:06:01 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples. 2020/08/14 09:06:01 [frame:3] Targetting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks. 2020/08/14 09:06:01 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks. 2020/08/14 09:06:01 [sandbox:3] Sandboxing disabled 2020/08/14 09:06:01 [video.converter:3] Couldn't find preferred video converter: gavl. 2020/08/14 09:06:01 [audio.converter:3] Using samplerate converter: libsamplerate. 2020/08/14 09:06:01 [alsa_out(default):3] Using ALSA 1.1.3. 2020/08/14 09:06:01 [alsa_out(default):2] Falling back on interleaved S16LE 2020/08/14 09:06:01 [alsa_out(default):3] Samplefreq=44100Hz, Bufsize=1764B, Frame=4B, Periods=55 2020/08/14 09:06:01 [clock.wallclock_alsa:3] Streaming loop starts, synchronized by active sources. 2020/08/14 09:06:01 [fallback_7436:3] Switch to noise_7435. 2020/08/14 09:06:10 [fallback_7436:3] Switch to switch_7433 with transition. 2020/08/14 09:06:10 [switch_7433:3] Switch to rotate_7431. 2020/08/14 09:06:10 [rotate_7431:3] Switch to sequence_7421. 2020/08/14 09:06:20 [rotate_7431:3] Switch to sequence_7429 with forgetful transition. 2020/08/14 09:06:25 [rotate_7431:3] Switch to sequence_7421 with forgetful transition. 2020/08/14 09:06:40 [rotate_7431:3] Switch to sequence_7429 with forgetful transition. 2020/08/14 09:06:45 [rotate_7431:3] Switch to sequence_7421 with forgetful transition. 2020/08/14 09:06:46 [main:3] Shutdown started! 2020/08/14 09:06:46 [main:3] Waiting for main threads to terminate... 2020/08/14 09:06:46 [clock.wallclock_alsa:3] Streaming loop stopped. 2020/08/14 09:06:46 [main:3] Threads terminated. 2020/08/14 09:06:46 [threads:3] Shutting down scheduler... 2020/08/14 09:06:46 [threads:3] Scheduler shut down. 2020/08/14 09:06:46 [threads:3] Waiting for queue threads to terminate... 2020/08/14 09:06:46 [threads:3] Queues shut down 2020/08/14 09:06:46 [main:3] Cleaning downloaded files... 2020/08/14 09:06:46 [main:3] Freeing memory... 2020/08/14 09:06:46 >>> LOG END

Version details Ubuntu server 18.04 Liquidsoap 1.4.3+git@9086335c

Install method opam

toots commented 4 years ago

Thanks for the report. I'll have a look shortly.

toots commented 4 years ago

Thanks for the report! It was fixed in 9a3e7f8!