-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rivalium integration. #3
Conversation
Made a first pass at implementing |
Found the issue (OggOpusWriter expects a byte-view of an array of shorts, rather than the array of shorts itself.) |
Also, make `recv()` work with the latest PyOgg.
6f756fd
to
82fc015
Compare
Avoids underruns between segments.
I noticed that |
Exiting during `rivalium.send()` is less annoying now.
Avoids underruns while playing `rivalium.send()`.
Your encoder probably isn't compressing enough, in the current version I do a huge amount of compression (down to 12000hz resample then a 12kbps bitrate, and only using 1 channel) and this gets it down to around 2kb per 1 sec segment, and anything double that size is rejected by the server. This will be changing in the next version, as I have received continual requests to allow for slightly higher quality audio, and I think it's still reasonable for weak/expensive connections to access ~7kb segments, which uses settings of 64kbps (variable) bit rate and doesn't downsample (48k hz), still using 1 channel. Additionally, with the new design, the 1 second (+80ms pre-skip, excluded before passing to decoding buffer) segment size will be a strict amount as the decoding buffer will be limited to a size of 1 second at the output sample rate. |
Okay, thanks for the info. In that case, I'll add a |
@drohen Okay, I think this includes everything we discussed last week. |
Sorry for the delay, short of time at the moment and want to give this a proper test. Will let you know by the end of this weekend. |
Code looks good, I could mostly follow along with the implementation. Did you record the audio for "4hb496kn6yh" directly to rivalium using aleatora? Took a bit of effort to get started, but that was mostly due to me trying to figure out installing from source and vscode not playing nicely. when running:
I tried variations of this,
when running:
when running:
I hear the random white noise, however I also get:
Maybe if you could share a test script I can run with |
No, that's just from me playing around with Rivalium in the browser. I used that for testing
Sorry about that; let me know what steps were missing or unclear, and I'll document them. Setup problems are also the cause of this issue:
PyOgg requires
This is due to the regex that parses the descriptor. I had the impression that stream/group IDs were alphanumeric, so it uses However, the last variation you tried ("VDK-rWa2dsm1fC70sRn5") works for me. Did it also fail with an HTTPError, or a PyOggError?
You're using
Sure, here's a quick example: from aleatora import *
from aleatora.thirdparty import rivalium
# Create an Aleatora stream, and a Rivalium stream.
wavy = osc(200 + 20 * osc(0.2))
upload_wavy, public_url, admin_url = rivalium.send(wavy)
# Play 10 seconds while uploading to Rivalium stream.
# To *just* upload (without playing), use `upload_wavy[:10.0].run()` instead.
run(upload_wavy[:10.0])
print(f"Open this link in a browser: https://rvm.sh/0{rivalium.extract_id(public_url)[1]}") Save as |
I noticed the playback is a bit weird for: https://rvm.sh/0whdg9f4nn9f. It's weird that playback length is coming back as 0.25s, because it clearly is not. Seems like some encoder weirdness. Also page duration in yours is longer, not sure it matters though.
The main point where I got stuck was installing from git using pip, because it didn't seem to install the correct branch. Then when I clone the project to the same dir and installed it that way, it confused vscode, but I think that was just an edge case.
I use nanoid, and the older IDs used the standard library, the new one excludes a bunch of characters.
Ah yeah I think it was PyOggError as after installing the missing opus lib it now works. So I can confirm it works as expected in this case. |
I think you're right (and thanks for the opusinfo output).
Okay. It looks like nanoid indeed uses the alphabet
👍 |
just wanted to check in to see if you were going to update any more on this? I think the only issue remaining was consistency with the pre-skip length. I don't think the playback length issue should affect the browser decoder, it's more of a semantic issue. Other than that I think this is mostly in a good place. |
Hey, thanks for the prodding - got a bit busy and had this on the back burner. |
I took a look at this tonight, with no luck. Even with increased pre-skip, there's a small gap at the start, regardless of the sample rate. PyOgg's high-level API for opus encoding seems generally somewhat flaky, which is fair enough, as it hasn't been pushed out in a stable release yet. At this point, I think the simplest approach to get correct output is to either use the C bindings provided by PyOgg directly, or just call out to an external tool like ffmpeg or opusenc. |
Alright, got this working with |
@drohen Let me know if this works for you. |
Apologies again for the delay, I don't have much time beyond my weekend to review stuff, and even then I have a long list of stuff I often need to do. I tested with you above example and a couple of my own, mostly sounds great on my end (at least as good as I think it will sound for the current rvm system). Two issues I encountered:
|
Additionally, I remembered why the pre-skip thing was important. In the update version, in order to splice the audio together correctly (rather than cross-fade) the pre-skip needs to be known so these initial samples can be dropped from the decode buffer. Does ffmpeg decoder drop these automatically? It seems the browser tool doesn't, and hence I can simply infer (by using the hardcoded 80ms in the browser encoder) that I can drop these samples, but I guess if this will vary, then I'll need to find a way to probe the file for the pre-skip length, or have it sent with the file data. Speaking of file data. Although unrelated to this PR, I'm currently trying to find an effective way to split up segments so they can be spliced together again, but from what I can see its probably only possible with inconsistent segment lengths that split always at the zero crossing. I'm not certain of this though, but I simply can't figure out how to get the join point to stitch together nicely while also not losing any samples (my current design has pre-skip of previous audio that gets chopped, and 1 second of current audio that gets chopped at the beginning and end to its zero crossing, which is only usually a few hundred samples at most). I haven't found a way to get a consistent sine wave to not "throb" but my next experiment will attempt attempt the inconsistent length approach. I wonder if you have any thoughts on this, and if you think this will create much complexity in aleatora. |
No worries, I'm in the same boat. 🚣
Glad to hear it!
Yep - fixed, thanks.
No. I've heard occasional hiccups near the start, but I haven't encountered playback stopping completely.
Yes, ffmpeg will drop whatever pre-skip is declared in the file (as reported by opusinfo).
Yeah, not sure what opus-recorder does here. I did a little experiment, and it seems that the browser itself (as in the
Yes, if you want to avoid both clicks and throwing away (or enveloping) samples, I think you'll need inconsistent lengths. Say, for each segment, you lop off everything after the last zero-crossing and tack it on to the next segment. If the segments are played back in order, you just get the original sequence of samples back, but if the segments are played back out-of-order, you avoid clicks at the boundaries (because all segments begin and end with a zero-crossing). Presumably this segment-shifting will happen either before encoding + upload or after download + decoding. Either will add a little complexity to aleatora's rivalium module, but probably not much more than the current zero-crossing crop approach. In the meantime, I think this PR is ready to go. |
Yeah I agree, go ahead and merge and lets jam sometime to try it all out. re decodeAudioData, yeah when I first built this wasn't working as expected, but maybe I know more now and is probably the superior option. Makes me think I should see if MediaRecorder is also now supporting opus on all platforms (I think safari didn't last I checked). re zero crossing, could avoid the further issue just by ensuring the cut is at each neg - pos zero crossing. |
Good idea.
Sweet, shoot me an email to let me know when! |
Resolves #1.