Hello,<br><br>I am trying to implement a realtime encoding then streaming solution using the vorbis codec (would be wrapped in a &quot;7F&quot; type for minimal framing overhead) for sending audio over a low bit rate wireless link.
<br><br>since we need a constant bittrate (i.e. constant packet size) for this solution we want to run the alg in constant bitrate mode;<br><br>for evaluation of the codec I followed the following procedure;<br><br><ul><li>
encode and decode using examples provided (still wrapped in ogg)</li><li>remove the ogg wrapping code, encode a file in vorbis, decode it again.</li></ul>The problem is that constant bittrate does not seem to be constant, the packet size varies greatly on the encode (it should be constant if using CBR). My assumption is that your resoviour algorithm provides an average bittrate over multiple frames of audio data, rather than encoding each frame to the same number of bits.
<br><br>my tests on changing the different parameters for encoding shows that no matter what settings i use (at least i can think of) do I get a constant packet size out of the encode.<br><br>also when getting a block to encode from the vd structure the encode seems to require multiple reads of the imput to get enough data to get a block for encode
<br><br>#define READ 882 (20ms)<br>&nbsp; struct ovectl_ratemanage2_arg rma;<br><br>&nbsp; fp_infile&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; fopen(infile,&quot;rb&quot;);<br>&nbsp; fp_outfile&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; fopen(outfile,&quot;wb&quot;);<br>&nbsp; fp_enc_info = fopen(&quot;enc_info.txt&quot;,&quot;w&quot;);
<br><br>&nbsp; printf(&quot;%s %s\n&quot;,infile,outfile);<br>&nbsp; num_blocks = 0;<br>&nbsp; num_bytes&nbsp;&nbsp;&nbsp; = 0;<br>&nbsp; num_packets = 0;<br>&nbsp; //num_mseconds = 0;<br><br>&nbsp; rma.management_active = 1;<br>&nbsp; rma.bitrate_limit_max_kbps = 3*128000;
<br>&nbsp; rma.bitrate_limit_min_kbps = 3*128000;<br>&nbsp; rma.bitrate_limit_reservoir_bits = 0;<br>&nbsp; rma.bitrate_limit_reservoir_bias = 0;<br>&nbsp; rma.bitrate_average_kbps = 3*128000;<br><br>&nbsp; <br><br>&nbsp; /* skip over header */<br>&nbsp; readbuffer[0] = &#39;\0&#39;;
<br>&nbsp; for (i=0, founddata=0; i&lt;30 &amp;&amp; ! feof(fp_infile) &amp;&amp; ! ferror(fp_infile); i++)<br>&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp; fread(readbuffer,1,2,fp_infile);<br>&nbsp;&nbsp;&nbsp; &nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp; if ( ! strncmp((char*)readbuffer, &quot;da&quot;, 2) )
<br>&nbsp;&nbsp;&nbsp; &nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; founddata = 1;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; fread(readbuffer,1,6,fp_infile);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; break;<br>&nbsp;&nbsp;&nbsp; &nbsp; }<br>&nbsp; }<br><br><br>&nbsp; vorbis_info_init(&amp;vi);<br><br>&nbsp; //ret = vorbis_encode_init(&amp;vi,2,44100,3*128000,3*128000,3*128000);//setup for constant bittrate
<br>&nbsp; //vorbis_encode_ctl(&amp;vi,OV_ECTL_RATEMANAGE_HARD,&amp;rma);<br>&nbsp; //ret=vorbis_encode_init_vbr(&amp;vi,2,44100,0.1);<br>&nbsp;&nbsp; //ret = vorbis_encode_init(&amp;vi,2,44100,-1,128000,-1);<br>&nbsp;// ret = ( vorbis_encode_setup_managed(&amp;vi,2,44100,128000,128000,128000) ||
<br>&nbsp;&nbsp; // vorbis_encode_ctl(&amp;vi,OV_ECTL_RATEMANAGE2_SET,&amp;rma) ||<br>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vorbis_encode_setup_init(&amp;vi));<br>&nbsp; ret = vorbis_encode_setup_managed(&amp;vi,2,44100,3*128000,3*128000,3*128000);<br>&nbsp; ret = ret||vorbis_encode_ctl(&amp;vi,OV_ECTL_RATEMANAGE_HARD,&amp;rma);
<br>&nbsp; ret = ret||vorbis_encode_setup_init(&amp;vi);<br><br>&nbsp; if(ret)exit(1);<br><br>&nbsp; /* set up the analysis state and auxiliary encoding storage */<br>&nbsp; vorbis_analysis_init(&amp;vd,&amp;vi);<br>&nbsp; vorbis_block_init(&amp;vd,&amp;vb);
<br>&nbsp; //encode loop<br>&nbsp; total_samples_consumed = 0;<br>&nbsp; num_reads=0;<br>&nbsp; while(!feof(fp_infile)){<br>&nbsp;// num_mseconds = 0;<br>&nbsp;&nbsp;&nbsp; long i;<br>&nbsp;&nbsp;&nbsp; long bytes=fread(readbuffer,1,READ*4,fp_infile); /* stereo hardwired here */
<br>&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* expose the buffer to submit data */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float **buffer=vorbis_analysis_buffer(&amp;vd,READ);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* uninterleave samples */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;bytes/4;i++){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; buffer[0][i]=((readbuffer[i*4+1]&lt;&lt;8)|
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00ff&amp;(int)readbuffer[i*4]))/32768.f;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; buffer[1][i]=((readbuffer[i*4+3]&lt;&lt;8)|<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00ff&amp;(int)readbuffer[i*4+2]))/32768.f;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* tell the library how much we actually submitted */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vorbis_analysis_wrote(&amp;vd,i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total_samples_consumed = total_samples_consumed+i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; <br><br>&nbsp;&nbsp;&nbsp; /* vorbis does some data preanalysis, then divvies up blocks for<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; more involved (potentially parallel) processing.&nbsp; Get a single
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block for encoding now */<br>&nbsp;&nbsp;&nbsp; num_reads++;<br>&nbsp;&nbsp;&nbsp; &nbsp; while(vorbis_analysis_blockout(&amp;vd,&amp;vb)==1){<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* analysis, assume we want to use bitrate management */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vorbis_analysis(&amp;vb,NULL);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vorbis_bitrate_addblock(&amp;vb);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num_blocks++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(fp_enc_info,&quot;num_reads per blockout:%d\t&quot;,num_reads);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num_reads=0;<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num_packets = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(vorbis_bitrate_flushpacket(&amp;vd,&amp;op)){&nbsp;&nbsp;&nbsp; 
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* push packed into file */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; fwrite(op.packet,op.bytes,1,fp_outfile);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num_packets++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(fp_enc_info,&quot;samples consumed:%d\tnum blocks:%d\tbytes written:%d\tpackets written for block:%d\n&quot;,total_samples_consumed,num_blocks,
op.bytes,num_packets);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp; }<br><br>&nbsp; has debug output:<br>num_reads per blockout:3&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:1&nbsp;&nbsp;&nbsp; bytes written:138&nbsp;&nbsp;&nbsp; packets written for block:1<br>
num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:2&nbsp;&nbsp;&nbsp; bytes written:1115&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:3&nbsp;&nbsp;&nbsp; bytes written:152&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:4&nbsp;&nbsp;&nbsp; bytes written:138&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:5&nbsp;&nbsp;&nbsp; bytes written:144&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:6&nbsp;&nbsp;&nbsp; bytes written:135&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:7&nbsp;&nbsp;&nbsp; bytes written:137&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:8&nbsp;&nbsp;&nbsp; bytes written:139&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:9&nbsp;&nbsp;&nbsp; bytes written:144&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:2646&nbsp;&nbsp;&nbsp; num blocks:10&nbsp;&nbsp;&nbsp; bytes written:141&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:1&nbsp;&nbsp;&nbsp; samples consumed:3528&nbsp;&nbsp;&nbsp; num blocks:11&nbsp;&nbsp;&nbsp; bytes written:133&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:3528&nbsp;&nbsp;&nbsp; num blocks:12&nbsp;&nbsp;&nbsp; bytes written:145&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:3528&nbsp;&nbsp;&nbsp; num blocks:13&nbsp;&nbsp;&nbsp; bytes written:138&nbsp;&nbsp;&nbsp; packets written for block:1
<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:3528&nbsp;&nbsp;&nbsp; num blocks:14&nbsp;&nbsp;&nbsp; bytes written:136&nbsp;&nbsp;&nbsp; packets written for block:1<br>num_reads per blockout:0&nbsp;&nbsp;&nbsp; samples consumed:3528&nbsp;&nbsp;&nbsp; num blocks:15&nbsp;&nbsp;&nbsp; bytes written:145&nbsp;&nbsp;&nbsp; packets written for block:1...
<br>..... plus more<br><br><br>the expected behaviour of CBR is that we put in say 20ms of audio (882) samples and for a CBR compression to 384kbs should produce 960 Byte packets iof compressed audio.<br><br>any help on setting up CBR correctly would be greatly appreciated.
<br><br>thanks - Ian<br><br>