docs: function( socket, options ) {
      var self = this;
      this.socket = new MumbleSocket( socket );
      this.options = options;
      socket.on( 'close', this.disconnect.bind( this ) );
      socket.on( 'error', function( err ) {
          self.emit( 'error', err );
      } );
  
      // Set up the encoders we use for encoding our audio.
      this.opusEncoder = new OpusEncoder( this.SAMPLING_RATE );
      this.celtEncoder = new CeltEncoder( this.SAMPLING_RATE, this.FRAME_SIZE );
  
      this.currentEncoder = this.opusEncoder;
      this.codec = MumbleConnection.codec.Opus;
  
      // Set up the ping loop.
      this.pingInterval = setInterval( function() { self._ping(); }, 1000 );
  
      // Member fields.
      this.channels = {};
      this.users = {};
      this.packetBuffer = new Buffer( this.FRAME_SIZE * 2 );
      this.voiceBuffer = [];
      this.voiceBufferLength = 0;
      this.voiceSequence = 0;
      this.authSent = false;
  
      this.lastProcess = Date.now();
      this.processInterval = setInterval(
          this._processAudio.bind( this ),
          this.FRAME_LENGTH );
  
      // Initialize the debug files if we specified MUMBLE_FILEOUT option.
      if( process.env.MUMBLE_FILEOUT ) {
          var fs = require( 'fs' );
          var fname = process.env.MUMBLE_FILEOUT;
          this.out_pcm = fs.createWriteStream( fname + '_out.pcm' );
          this.out_celt = fs.createWriteStream( fname + '_out.celt' );
          this.in_celt = fs.createWriteStream( fname + '_in.celt' );
          this.in_jitter_celt = fs.createWriteStream( fname + '_in_jitter.celt' );
      }
  
      // Start waiting for the init messages.
      this.initPending = [ 'ServerSync', 'ServerConfig' ];
  
      // Start queueing for a message prefix.
      this._waitForPrefix( this );
  }