{"action":"created","issue":{"url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/9","labels_url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/9/labels{/name}","comments_url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/9/comments","events_url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/9/events","html_url":"https://github.com/chris-rudmin/Recorderjs/issues/9","id":70776287,"number":9,"title":"varying encoder bitrates","user":{"login":"lepinsk","id":154543,"avatar_url":"https://avatars.githubusercontent.com/u/154543?v=3","gravatar_id":"","url":"https://api.github.com/users/lepinsk","html_url":"https://github.com/lepinsk","followers_url":"https://api.github.com/users/lepinsk/followers","following_url":"https://api.github.com/users/lepinsk/following{/other_user}","gists_url":"https://api.github.com/users/lepinsk/gists{/gist_id}","starred_url":"https://api.github.com/users/lepinsk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lepinsk/subscriptions","organizations_url":"https://api.github.com/users/lepinsk/orgs","repos_url":"https://api.github.com/users/lepinsk/repos","events_url":"https://api.github.com/users/lepinsk/events{/privacy}","received_events_url":"https://api.github.com/users/lepinsk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-04-24T19:37:39Z","updated_at":"2015-04-24T21:25:57Z","closed_at":null,"body":"Hey Chris,\r\n\r\nI'm loving the work you've done here.\r\n\r\nI've played around with changing the target bitrate of the encoder, which seems to be working reasonably well. Right now my modifications to ```initCodec``` look something like this: \r\n\r\n```js\r\nOggOpus.prototype.initCodec = function() {\r\n  this.encoder = _opus_encoder_create( this.outputSampleRate, this.numberOfChannels, this.encoderApplication, allocate(4, 'i32', ALLOC_STACK) );\r\n\r\n  // here we go\r\n  var targetBitrate = 192000;\r\n  var bitrateLocation = _malloc(4);\r\n  HEAP32[bitrateLocation >>> 2] = targetBitrate;\r\n  _opus_encoder_ctl(\r\n    this.encoder,\r\n    4002, // this translates to 'OPUS_SET_BITRATE_REQUEST'\r\n    bitrateLocation)\r\n  ;\r\n  _free(bitrateLocation);\r\n  // all done\r\n\r\n  this.encoderBufferIndex = 0;\r\n  this.encoderSamplesPerChannelPerPacket = this.outputSampleRate * this.encoderFrameSize / 1000;\r\n  this.encoderBufferLength = this.encoderSamplesPerChannelPerPacket * this.numberOfChannels;\r\n  this.encoderBufferPointer = _malloc( this.encoderBufferLength * 4 );\r\n  this.encoderBuffer = HEAPF32.subarray( this.encoderBufferPointer >> 2, (this.encoderBufferPointer >> 2) + this.encoderBufferLength );\r\n  this.encoderOutputMaxLength = 4000; \r\n  this.encoderOutputPointer = _malloc( this.encoderOutputMaxLength );\r\n  this.encoderOutputBuffer = HEAPU8.subarray( this.encoderOutputPointer, this.encoderOutputPointer + this.encoderOutputMaxLength );\r\n};\r\n```\r\n\r\nAt higher bitrates, however, this seems to be producing files that ```opusinfo``` identifies some problems with. For example, after setting ```targetBitrate = 192000``` above:\r\n\r\n```\r\nlappy486:Desktop theoffice$ opusinfo 192k.ogg \r\nProcessing file \"192k.ogg\"...\r\n\r\nNew logical stream (#1, serial: 00000539): type opus\r\nEncoded with Recorder\r\nWARNING: Sample count ahead of granule (364800>363840) in stream 1\r\nWARNING: Sample count ahead of granule (606720>605760) in stream 1\r\nWARNING: Sample count ahead of granule (842880>841920) in stream 1\r\nWARNING: Sample count ahead of granule (1562880>1561920) in stream 1\r\nWARNING: Sample count ahead of granule (1801920>1800960) in stream 1\r\nWARNING: Sample count ahead of granule (1922880>1921920) in stream 1\r\nWARNING: Sample count ahead of granule (2164800>2163840) in stream 1\r\nWARNING: Sample count ahead of granule (2409600>2408640) in stream 1\r\nWARNING: Sample count ahead of granule (2526720>2525760) in stream 1\r\nWARNING: Sample count ahead of granule (3010560>3009600) in stream 1\r\nWARNING: Sample count ahead of granule (3130560>3129600) in stream 1\r\nWARNING: Sample count ahead of granule (3248640>3247680) in stream 1\r\nWARNING: Sample count ahead of granule (3493440>3492480) in stream 1\r\nWARNING: Sample count ahead of granule (3615360>3614400) in stream 1\r\nWARNING: Sample count ahead of granule (3737280>3736320) in stream 1\r\nWARNING: Sample count ahead of granule (3859200>3858240) in stream 1\r\nWARNING: Sample count ahead of granule (3978240>3977280) in stream 1\r\nWARNING: Sample count ahead of granule (4100160>4099200) in stream 1\r\nWARNING: Sample count ahead of granule (4344960>4344000) in stream 1\r\nWARNING: Sample count ahead of granule (4589760>4588800) in stream 1\r\nWARNING: Sample count ahead of granule (4710720>4709760) in stream 1\r\nWARNING: Sample count ahead of granule (4955520>4954560) in stream 1\r\nWARNING: Sample count ahead of granule (5200320>5199360) in stream 1\r\nWARNING: Sample count ahead of granule (5445120>5444160) in stream 1\r\nWARNING: Sample count ahead of granule (5689920>5688960) in stream 1\r\nWARNING: Sample count ahead of granule (5934720>5933760) in stream 1\r\nWARNING: Sample count ahead of granule (6179520>6178560) in stream 1\r\nWARNING: Sample count ahead of granule (6300480>6299520) in stream 1\r\nWARNING: Sample count ahead of granule (6545280>6544320) in stream 1\r\nWARNING: Sample count ahead of granule (6790080>6789120) in stream 1\r\nWARNING: Sample count ahead of granule (7154880>7153920) in stream 1\r\nWARNING: Sample count ahead of granule (7624320>7623360) in stream 1\r\nWARNING: Sample count ahead of granule (7977600>7976640) in stream 1\r\nWARNING: Sample count ahead of granule (8326080>8325120) in stream 1\r\nWARNING: Sample count ahead of granule (8566080>8565120) in stream 1\r\nWARNING: Sample count ahead of granule (8686080>8685120) in stream 1\r\nWARNING: Sample count ahead of granule (8930880>8929920) in stream 1\r\nWARNING: Sample count ahead of granule (9783360>9782400) in stream 1\r\nWARNING: Sample count ahead of granule (10272000>10271040) in stream 1\r\nWARNING: Sample count ahead of granule (10756800>10755840) in stream 1\r\nWARNING: Sample count ahead of granule (10878720>10877760) in stream 1\r\nWARNING: Sample count ahead of granule (10998720>10997760) in stream 1\r\nWARNING: Sample count ahead of granule (11243520>11242560) in stream 1\r\nWARNING: Sample count ahead of granule (11364480>11363520) in stream 1\r\nWARNING: Sample count ahead of granule (11485440>11484480) in stream 1\r\nWARNING: Sample count ahead of granule (11607360>11606400) in stream 1\r\nWARNING: Sample count ahead of granule (11727360>11726400) in stream 1\r\nWARNING: Sample count ahead of granule (11846400>11845440) in stream 1\r\nWARNING: Sample count ahead of granule (12320640>12319680) in stream 1\r\nOpus stream 1:\r\n\tPre-skip: 3840\r\n\tPlayback gain: 0 dB\r\n\tChannels: 1\r\n\tOriginal sample rate: 44100Hz\r\n\tPacket duration:   20.0ms (max),   20.0ms (avg),   20.0ms (min)\r\n\tPage duration:   2560.0ms (max), 2492.4ms (avg),   40.0ms (min)\r\n\tTotal data length: 6203394 bytes (overhead: 0.466%)\r\n\tPlayback length: 4m:16.639s\r\n\tAverage bitrate: 193.4 kb/s, w/o overhead: 192.5 kb/s\r\nLogical stream 1 ended\r\n```\r\n\r\nI've poked around a bit further, and noticed [this snippet](https://github.com/chris-rudmin/Recorderjs/blob/b4a16320dafd765a9c712a4d1cc885fcd2fb5756/oggopus.js#L107-L111) in ```OggOpus.prototype.generatePage```:\r\n\r\n```js\r\n  // Number of samples upto and including this page at 48000Hz, into 64 bits\r\n  pageBufferView.setUint32( 6, granulePosition, true );\r\n  if ( granulePosition > 4294967296 || granulePosition < 0 ) {\r\n    pageBufferView.setUint32( 10, Math.floor( granulePosition/4294967296 ), true );\r\n  }\r\n```\r\n\r\nIs it possible that these are related? I'm a bit out of my depth here and trying to figure out whether there are other changes that need to be made to support varying the encoder bitrate. I'd love to hear any thoughts you have on this."},"comment":{"url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/comments/96069347","html_url":"https://github.com/chris-rudmin/Recorderjs/issues/9#issuecomment-96069347","issue_url":"https://api.github.com/repos/chris-rudmin/Recorderjs/issues/9","id":96069347,"user":{"login":"chris-rudmin","id":506755,"avatar_url":"https://avatars.githubusercontent.com/u/506755?v=3","gravatar_id":"","url":"https://api.github.com/users/chris-rudmin","html_url":"https://github.com/chris-rudmin","followers_url":"https://api.github.com/users/chris-rudmin/followers","following_url":"https://api.github.com/users/chris-rudmin/following{/other_user}","gists_url":"https://api.github.com/users/chris-rudmin/gists{/gist_id}","starred_url":"https://api.github.com/users/chris-rudmin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chris-rudmin/subscriptions","organizations_url":"https://api.github.com/users/chris-rudmin/orgs","repos_url":"https://api.github.com/users/chris-rudmin/repos","events_url":"https://api.github.com/users/chris-rudmin/events{/privacy}","received_events_url":"https://api.github.com/users/chris-rudmin/received_events","type":"User","site_admin":false},"created_at":"2015-04-24T21:25:56Z","updated_at":"2015-04-24T21:25:56Z","body":"It seems the warning is thrown because there are more samples than granule position reports. It's possible there was an error encountered and the granule position wasn't updated for a packet. I don't have any error handling in my code, so if something went wrong i don't know what to expect.  Do you see any errors in the console?\r\n\r\nThe difference is 960 samples which is exactly the length of one opus packet. Is it always this amount?\r\nDoes it always happen even with extremely short recordings? To really get to the bottom of this, you might have to open the debugger and step through the oggopus code while it is encoding to find out where we lose track of one packet."}}