Closed liquidpeter closed 2 months ago
Hi @liquidpeter,
I have very little experience with rms
, but your script seems a bit odd to me.
Here's how I would refactor it:
radio = sine();
def source_rms(s)
r = rms.stereo(s, duration=1.)
rl = rms(stereo.left(radio), duration=1.)
rr = rms(stereo.right(radio), duration=1.)
output.dummy(r)
output.dummy(rl)
output.dummy(rr)
{
rms = r.rms,
rms_left = rl.rms,
rms_right = rr.rms
}
end
r = source_rms(radio)
thread.run({log("#{r.rms()} #{r.rms_left()} #{r.rms_right()}")}, every=1.)
output.dummy(radio)
There are two “defs” that basically try to achieve the same result but cause different problems.
peak
and renamed the defs. Thanks for mixing them, but I cannot see how this helps to analyze the issues.
I think what is happening here is that 2.0.2 and 2.2.4 are different. Lots of stuff has changed and syntax that you try to use in 2.2.4 just doesn't work.
Vito has provided you with 2 working options. How this is not helpful? Haven't you tried it out?
res = r.rms()
is unused and doesn't make sense. Why do you use? what's the point? To solve "def levels" shows the problem with stereo audio when using "rms.stereo".
you have to remove this unused var.def levels()
r = rms.stereo(duration=1., radio)
output.dummy(r)
end
thread.run(every=1., levels)
Still this function makes no sense at all. But now it doesn't show an error.
rl = stereo.left(radio)
rr = stereo.right(radio)
rmsl = rms(duration=1., rl)
rmsr = rms(duration=1., rr)
output.dummy(rmsl)
output.dummy(rmsr)
def levels_wa()
print ("#{rmsl.rms()} #{rmsr.rms()}");
end
thread.run(every=1., levels_wa)
and use #{rmsl.rms()} #{rmsr.rms()}
.
#{resl} #{resr}\n
can't just work. because resl
= rms(duration=1., rl).rms();
which kinda makes no sense too and will not give you the desired result.
Now you've edited your post and pasted this
# peak.stereo: uncaught error: uncaught error: index out of bounds
def test_peak_stereo()
r = peak.stereo(duration=1., radio)
output.dummy(r)
res = r.peak()
end
#thread.run(every=1., test_peak_stereo)
# peak: -nan for sine()
def test_peak_mono()
rl = stereo.left(radio)
rr = stereo.right(radio)
pl = peak(duration=1., rl)
pr = peak(duration=1., rr)
output.dummy(pl)
output.dummy(pr)
resl= pl.peak()
resr= pr.peak()
print ("#{resl} #{resr}\n")
end
#thread.run(every=1., test_peak_mono)
It's all the same again. It's wrong use of functions. If you want it to work - use the right syntax given by @vitoyucepi
radio = sine();
radio = stereo(radio)
r = rms.stereo(radio, duration=1.)
r1 = peak.stereo(duration=1., radio)
rl = rms(stereo.left(radio), duration=1.)
rr = rms(stereo.right(radio), duration=1.)
pl = peak(duration=1., stereo.left(radio))
pr = peak(duration=1., stereo.right(radio))
output.dummy(r)
output.dummy(r1)
output.dummy(rl)
output.dummy(rr)
output.dummy(pl)
output.dummy(pr)
def log_rms_peak()
log("#{r.rms()} #{rl.rms()} #{rr.rms()}")
log("#{r1.peak()} #{pl.peak()} #{pr.peak()}")
end
thread.run(log_rms_peak, every=1.)
output(radio)
or
radio = sine();
def source_rms(s)
r = rms.stereo(s, duration=1.)
rl = rms(stereo.left(radio), duration=1.)
rr = rms(stereo.right(radio), duration=1.)
output.dummy(r)
output.dummy(rl)
output.dummy(rr)
{
rms = r.rms,
rms_left = rl.rms,
rms_right = rr.rms
}
end
def source_peak(s)
p = peak.stereo(s, duration=1.)
pl = peak(stereo.left(radio), duration=1.)
pr = peak(stereo.right(radio), duration=1.)
output.dummy(p)
output.dummy(pl)
output.dummy(pr)
{
peak = p.peak,
peak_left = pl.peak,
peak_right = pr.peak
}
end
r = source_rms(radio)
p = source_peak(radio)
thread.run({log("#{r.rms()} #{r.rms_left()} #{r.rms_right()}\n#{p.peak()} #{p.peak_left()} #{p.peak_right()}")}, every=1.)
output(radio)
Hi Stefan and Vito,
Thank you very much for the clarification, and Vito, and I apologize for my earlier response. I should have tested your code before providing feedback.
I mistakenly conflated the mono and stereo cases in the same function, which led to an oversight on my part. Specifically, I incorrectly used the stereo.rms
, stereo.peak
, and for mono rms
, and peak
functions. These functions are designed to inject the data getters rms()
and peak()
and should only be invoked once. However, my implementation called them repeatedly, causing the data getters to be re-initialized with every call, leading to the observed behavior where no data was collected and the output was incorrect.
The correct approach is to have the thread run frequently and simply read the data from the previously initialized data getters. My mistake was unrelated to the upgrade from version 2.0.2 to 2.2.5 but rather a result of modifications I made to my working script. Now that I've corrected the implementation, everything is functioning as expected. Thank you again for your help!
I have still two questions open
1.)
When I incorrectly called r = rms(stereo.left(radio), duration=1.)
and x=rl.rms()
for mono, it resulted in x=-nan
. I think that is fine. For stereo, I would expect calling r = stereo.rms(radio, duration=1.)
and x=r.rms
frequently to return x=(-nan, -nan)
instead of throwing the "out of index" error. (The error ist independent of doing anything with the rms values. )
While this is an edge case and not critical, it would improve consistency between mono and stereo behavior.
2.) When running Vito's script, it outputs the following:
2024/08/11 10:41:53 [lang:3] (0.707106781187, 0.707106781187) 0.353553390593 0.353553390593
2024/08/11 10:41:53 [lang:3] (0.999999746258, 0.999999746258) 0.499999873129 0.499999873129
In each line, values (1, 2) are from the stereo operators, while values 3 and 4 are from the mono operators. I expected the values to be identical for both mono and stereo channels, whether for peak or RMS calculations. However, it seems that the mono channel values are half as large as the stereo channel values. Could you explain why this discrepancy exists between mono and stereo calculations?
Thanks for your patience!
Hi @liquidpeter.
2024/08/11 10:41:53 [lang:3] (0.707106781187, 0.707106781187) 0.353553390593 0.353553390593 2024/08/11 10:41:53 [lang:3] (0.999999746258, 0.999999746258) 0.499999873129 0.499999873129 In each line, values (1, 2) are from the stereo operators, while values 3 and 4 are from the mono operators. I expected the values to be identical for both mono and stereo channels, whether for peak or RMS calculations. However, it seems that the mono channel values are half as large as the stereo channel values. Could you explain why this discrepancy exists between mono and stereo calculations?
Yeap, it is somehow misleading. Not sure about it at all. I've created an issue https://github.com/savonet/liquidsoap/issues/4090
Thanks for the help y'all! I think that this issue should be moved to a discussion.
Description
I wanted to upgrade my scripts from Liquidsoap 2.0.2 to 2.2.4-1+dev (Ubuntu 24.04 LTS). Unfortunately the
rms
andpeak
operations do not work as expected any more, for both mono and stereo channels.Steps to reproduce
Install ubuntu 24.04 with liquidsoap from packages Remove comments on
thread.run
to show one of the 4 issues (rms mono, rms stereo, peak mono, peak stereo).Test script
Results:
rms.stereo()
:uncaught error: index out of bounds
rms()
:-nan
forsine()
inputpeak.stereo()
:uncaught error: index out of bounds
peak()
:-nan
forsine()
inputdetailed log for
index out of bounds
Expected behavior
The defs
rms
,stereo.rms
,peak
andstereo.peak
results should return valid values.Liquidsoap version
Liquidsoap build config
Installation method
From distribution packages
Additional Info
As I prefer to use deb packages, it would be very helpful to get a fix / backport? package for Ubuntu 24.04 LTS (noble). Thanks in advance and best regards!