public synchronized int available()
    throws IOException
  {
    int avail = super.available();
    int unencoded = precount - prepos + in.available();
    if (encoder.getEncoder().getVbr()) {
      switch (mode) {
        case 0: // Narrowband
          // ogg header size = 27 + packetsPerOggPage
          // count 1 byte (min 5 bits) for each block available
          return avail + (27 + 2 * packetsPerOggPage) *
                         (unencoded / (packetsPerOggPage*framesPerPacket*320));
        case 1: // Wideband
          // ogg header size = 27 + packetsPerOggPage
          // count 2 byte (min 9 bits) for each block available
          return avail + (27 + 2 * packetsPerOggPage) *
                         (unencoded / (packetsPerOggPage*framesPerPacket*640));
        case 2: // Ultra wideband
          // ogg header size = 27 + packetsPerOggPage
          // count 2 byte (min 13 bits) for each block available
          return avail + (27 + 3 * packetsPerOggPage) *
                         (unencoded / (packetsPerOggPage*framesPerPacket*1280));
        default:
          return avail;
      }
    }
    else {
      // Calculate size of a packet of Speex data.
      int spxpacketsize = encoder.getEncoder().getEncodedFrameSize();
      if (channels > 1) {
        spxpacketsize += 17; // 1+4(14=inband)+4(9=stereo)+8(stereo data)
      }
      spxpacketsize *= framesPerPacket;
      spxpacketsize = (spxpacketsize + 7) >> 3; // convert bits to bytes
      // Calculate size of an Ogg packet containing X Speex packets.
      // Ogg Packet = Ogg header + size of each packet + Ogg packets 
      int oggpacketsize = 27 + packetsPerOggPage * (spxpacketsize + 1);
      int pcmframesize; // size of PCM data necessary to encode 1 Speex packet.
      switch (mode) {
        case 0: // Narrowband
          // 1 frame = 20ms = 160ech * channels = 320bytes * channels
          pcmframesize = framesPerPacket * 320 * encoder.getChannels();
          avail += oggpacketsize *
                   (unencoded / (packetsPerOggPage * pcmframesize));
          return avail;
        case 1: // Wideband
          // 1 frame = 20ms = 320ech * channels = 640bytes * channels
          pcmframesize = framesPerPacket * 640 * encoder.getChannels();
          avail += oggpacketsize *
                   (unencoded / (packetsPerOggPage * pcmframesize));
          return avail;
        case 2: // Ultra wideband
          // 1 frame = 20ms = 640ech * channels = 1280bytes * channels
          pcmframesize = framesPerPacket * 1280 * encoder.getChannels();
          avail += oggpacketsize *
                   (unencoded / (packetsPerOggPage * pcmframesize));
          return avail;
        default:
          return avail;
      }
    }
  }