public void close() throws IOException {
        if(r != null) {
            r = null;
            ogg.close();
            ogg = null;
        }
        if(w != null) {
            w.bufferPacket(info.write(), true);
            w.bufferPacket(tags.write(), false);

            long lastGranule = 0;
            for(SpeexAudioData vd : writtenPackets) {
                // Update the granule position as we go
                if(vd.getGranulePosition() >= 0 &&
                        lastGranule != vd.getGranulePosition()) {
                    w.flush();
                    lastGranule = vd.getGranulePosition();
                    w.setGranulePosition(lastGranule);
                }

                // Write the data, flushing if needed
                w.bufferPacket(vd.write());
                if(w.getSizePendingFlush() > 16384) {
                    w.flush();
                }
            }

            w.close();
            w = null;
            ogg.close();
            ogg = null;
        }
    }