Skip to main content
Topic: Continuous modem transport (Read 8489 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Continuous modem transport

Hi,

In my application I have a continuous RF modem with maximum bitrate 84 kbps.

I would like to send a real time audio stream using this link.

Of course I could use - - hard-cbr but if possible I would like to use a vbr mode.

When I played around with - - save-range and plotted packet sizes and the resulting instantaneous bandwidth I noticed that neither - - vbr nor - - cvbr limits the bandwidth over any predictable number of frames. Expected for vbr of course but cvbr is only constrained in the sense that any frame may not exceed twice the average bandwidth.

Ideally I would like a mode that prohibits  bandwidths exceeding a set maximum for any N frames. This way it seems I could accommodate complex frames with a latency penalty of say 100ms which is acceptable.

Is this feasible?

Re: Continuous modem transport

Reply #1
This is why there is hard CBR ;)  CVBR is a bit reservoir so up to an extra frame can be used, which is why you see a maximum of double the frame size.  Opus is very adaptive, and struggles to encode certain types of audio, hence VBR is *very* variable.  Hold your nose and use CBR.

Re: Continuous modem transport

Reply #2
Ah, yes. I suspected as much.

Reading this: https://arxiv.org/pdf/1602.04845.pdf

I also see why decisions were made they way they were.

Would be interesting to know how bit allocations are decided on a frame level. There must be some error function that limits the frame size such that for a large sample of frames we arrive at the desired average bitrate. The paper above only describes CBR encoded frames and explicitly points out that the decoder makes decisions on a per frame basis according to how the bitstream is encoded. So VBR is CBR with varying packet size, frames are always the same length.

 

Re: Continuous modem transport

Reply #3
OK, I found the code responsible for this in celt_encoder.c in the compute_vbr(...) function.

It's pretty ad-hoc and even says so in the code. Just don't allow instantaneous rate to exceed twice the target rate for any one frame.

I changed it to IMIN(base_target,target) and recompiled and it works fine. This is kind of what I was after since CBR is not really helpful. I need to transfer other data as well, not only audio. This other data is not time critical so I would lke Opus to gobble up as many bits as possible in order to maximize quality for those problematic frames.

Like I stated in my first question ideally there would be an encoding mode where for some number of frames the available bandwidth must never be exceeded.

Doesn't look to be trivial to implement though.

Code: [Select]
 
  /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate
      for long. Needs tuning. */
   if ((!has_surround_mask||lfe) && constrained_vbr)
   {
      target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target);
   }

   if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))
   {
      opus_val16 amount;
      opus_val16 tvbr_factor;
      amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate)));
      tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT);
      target += (opus_int32)MULT16_32_Q15(tvbr_factor, target);
   }

   /* Don't allow more than doubling the rate */
  // target = IMIN(2*base_target, target); 
     target = IMIN(base_target, target);  // <----- Never exceed available bandwidth

Re: Continuous modem transport

Reply #4
After playing around with it some more I realize what I need is really a prefetch mechanism. This should be easier to implement than changing how Opus itself behaves and allows me to operate in the VBR mode.

Re: Continuous modem transport

Reply #5
Actually, the Opus API allows setting a maximum number of bytes for the packet you're about to encode. That means you can set the encoder to VBR and say "never exceed X compressed bytes". That's it. No fiddling with the code is necessary.

Re: Continuous modem transport

Reply #6
Actually, the Opus API allows setting a maximum number of bytes for the packet you're about to encode. That means you can set the encoder to VBR and say "never exceed X compressed bytes". That's it. No fiddling with the code is necessary.

Yes, I saw this option!

But doesn’t this mean that the frames encoded with max packet size will have lower quality and it’s precisely those frames that needed the extra bandwidth the most?

My points is that given a bit pipe of certain bandwidth, and a half duplex RF digital modem is such an example, wouldn’t it be better to allow for the larger packet size and then transfer extra bits in the preceding packets?

Of course you could just transfer the whole file but this is a real time application so latency can not be ignored.

Re: Continuous modem transport

Reply #7
My points is that given a bit pipe of certain bandwidth, and a half duplex RF digital modem is such an example, wouldn’t it be better to allow for the larger packet size and then transfer extra bits in the preceding packets?

Of course you could just transfer the whole file but this is a real time application so latency can not be ignored.

If what you're after is the equivalent of "CBR with bit reservoir" that some MPEG codecs (e.g. MP3) have, then CVBR is what you want. It's a VBR more that makes sure to never cause more than 1 frame extra latency when going over the target bandwidth. i.e. if you have a 64 kb/s channel and ask for 64 kb/s CVBR, the bitrate spikes will cause at most 1 frame (20 ms) of delay.

Re: Continuous modem transport

Reply #8
CVBR doesn't deliver nearly as much quality as VBR, in my experience. 64 kbps VBR by default can spike up into the 100s but manage to stay within 80 overall. Increasing the potential latency of having to send a little more before averaging out allows more quality and vice versa. It may require some trial and error to find what you're comfortable with.

Re: Continuous modem transport

Reply #9
If what you're after is the equivalent of "CBR with bit reservoir" that some MPEG codecs (e.g. MP3) have, then CVBR is what you want. It's a VBR more that makes sure to never cause more than 1 frame extra latency when going over the target bandwidth. i.e. if you have a 64 kb/s channel and ask for 64 kb/s CVBR, the bitrate spikes will cause at most 1 frame (20 ms) of delay.

CVBR with N frames of extra latency is how I would describe it.

CBR is no (extra) latency but demanding frames suffer in quality
VBR will violate maximum instantaneous bandwidth due to packet size spikes
CVBR is great but as you mentioned it's limited to 1 frame of extra latency.

So would it be possible to have a mode with say 8 frames of extra latency?

 
SimplePortal 1.0.0 RC1 © 2008-2019