waveWriter.close();
writer.close();
	public static void decode(String inputPath, String outputPath)    throws IOException  {		byte[] header    = new byte[2048];		byte[] payload   = new byte[65536];		byte[] decdat    = new byte[44100*2*2];		final int    HEADERSIZE = 27;		final int    SEGOFFSET  = 26;		final String OGGID      = "OggS";		int segments=0, curseg=0, bodybytes=0, decsize=0; 		int packetNo=0;        // construct a wave writer    waveWriter   = new PcmWaveWriter();    // construct a new decoder    speexDecoder = new SpeexDecoder();    // open the input stream    DataInputStream dis =  new DataInputStream(new FileInputStream(inputPath));    int origchksum;    int chksum;		try {      // read until we get to EOF      while(true) {        if (ogg) {          // read the OGG header          dis.readFully(header, 0, HEADERSIZE);          origchksum = bytestoint(header, 22);          header[22] = 0;          header[23] = 0;          header[24] = 0;          header[25] = 0;          chksum=OggCrc.checksum(0, header, 0, HEADERSIZE);          // make sure its a OGG header          if (!OGGID.equals(new String(header, 0, 4))) {            System.err.println("missing ogg id!");            return;          }                    /* how many segments are there? */          segments = header[SEGOFFSET] & 0xFF;          dis.readFully(header, HEADERSIZE, segments);          chksum=OggCrc.checksum(chksum, header, HEADERSIZE, segments);                    /* decode each segment, writing output to wav */          for (curseg=0; curseg < segments; curseg++) {            /* get the number of bytes in the segment */            bodybytes = header[HEADERSIZE+curseg] & 0xFF;            if (bodybytes==255) {              System.err.println("sorry, don't handle 255 sizes!");               return;            }            dis.readFully(payload, 0, bodybytes);            chksum=OggCrc.checksum(chksum, payload, 0, bodybytes);                        /* decode the segment */            /* if first packet, read the Speex header */            if (packetNo == 0) {              if (readSpeexHeader(payload, 0, bodybytes)) {                /* once Speex header read, initialize the wave writer with output format */                waveWriter.open(outputPath);                  waveWriter.setFormat(speexDecoder.getChannels(),                                     speexDecoder.getSampleRate());                waveWriter.writeHeader();                packetNo++;              }              else {                packetNo = 0;              }            }            else if (packetNo == 1) { // Ogg Comment packet                packetNo++;            }            else {              if (loss>0 && random.nextInt(100)<loss) {                speexDecoder.processData(null, 0, bodybytes);                for (int i=1; i<nframes; i++) {                  speexDecoder.processData(true);                }              }              else {                speexDecoder.processData(payload, 0, bodybytes);                for (int i=1; i<nframes; i++) {                  speexDecoder.processData(false);                }              }              /* get the amount of decoded data */              if ((decsize=speexDecoder.getProcessedData(decdat, 0)) > 0) {                waveWriter.writeData(decdat, 0, decsize);              }              packetNo++;            }          }          if (chksum != origchksum)            throw new IOException("Ogg CheckSums do not match");        }        else  { // Raw Speex          /* if first packet, initialise everything */          if (packetNo == 0) {            /* initialize the Speex decoder */            speexDecoder.init(mode, sampleRate, channels, enhanced);            /* initialize the wave writer with output format */            waveWriter.open(outputPath);            waveWriter.setFormat(channels, sampleRate);            waveWriter.writeHeader();            if (!vbr) {              switch (mode) {                case 0:                  bodybytes = NbEncoder.NB_FRAME_SIZE[NbEncoder.NB_QUALITY_MAP[quality]];                  break;                case 1:                  bodybytes = SbEncoder.NB_FRAME_SIZE[SbEncoder.NB_QUALITY_MAP[quality]];                  bodybytes += SbEncoder.SB_FRAME_SIZE[SbEncoder.WB_QUALITY_MAP[quality]];                  break;                case 2:                  bodybytes = SbEncoder.NB_FRAME_SIZE[SbEncoder.NB_QUALITY_MAP[quality]];                  bodybytes += SbEncoder.SB_FRAME_SIZE[SbEncoder.WB_QUALITY_MAP[quality]];                  bodybytes += SbEncoder.SB_FRAME_SIZE[SbEncoder.UWB_QUALITY_MAP[quality]];                  break;              }              bodybytes = (bodybytes + 7) >> 3;            }            else {              // We have read the stream to find out more              bodybytes = 0;            }            packetNo++;          }          else {            dis.readFully(payload, 0, bodybytes);            if (loss>0 && random.nextInt(100)<loss) {              speexDecoder.processData(null, 0, bodybytes);              for (int i=1; i<nframes; i++) {                speexDecoder.processData(true);              }            }            else {              speexDecoder.processData(payload, 0, bodybytes);              for (int i=1; i<nframes; i++) {                speexDecoder.processData(false);              }            }            /* get the amount of decoded data */            if ((decsize=speexDecoder.getProcessedData(decdat, 0)) > 0) {              waveWriter.writeData(decdat, 0, decsize);            }            packetNo++;          }        }      }		}    catch (EOFException eof) {}		/* close the output file */		waveWriter.close();	}