use of org.jaudiotagger.audio.ogg.util.OggPageHeader in project MusicDNA by harjot-oberai.
the class OggVorbisTagWriter method write.
public void write(Tag tag, RandomAccessFile raf, RandomAccessFile rafTemp) throws CannotReadException, CannotWriteException, IOException {
logger.config("Starting to write file:");
//1st Page:Identification Header
logger.fine("Read 1st Page:identificationHeader:");
OggPageHeader pageHeader = OggPageHeader.read(raf);
raf.seek(pageHeader.getStartByte());
//Write 1st page (unchanged) and place writer pointer at end of data
rafTemp.getChannel().transferFrom(raf.getChannel(), 0, pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
rafTemp.skipBytes(pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
logger.fine("Written identificationHeader:");
//2nd page:Comment and Setup if there is enough room, may also (although not normally) contain audio frames
OggPageHeader secondPageHeader = OggPageHeader.read(raf);
//2nd Page:Store the end of Header
long secondPageHeaderEndPos = raf.getFilePointer();
logger.fine("Read 2nd Page:comment and setup and possibly audio:Header finishes at file position:" + secondPageHeaderEndPos);
//Get header sizes
raf.seek(0);
OggVorbisTagReader.OggVorbisHeaderSizes vorbisHeaderSizes = reader.readOggVorbisHeaderSizes(raf);
//Convert the OggVorbisComment header to raw packet data
ByteBuffer newComment = tc.convert(tag);
//Compute new comment length(this may need to be spread over multiple pages)
int newCommentLength = newComment.capacity();
//Calculate new size of new 2nd page
int newSecondPageDataLength = vorbisHeaderSizes.getSetupHeaderSize() + newCommentLength + vorbisHeaderSizes.getExtraPacketDataSize();
logger.fine("Old 2nd Page no of packets: " + secondPageHeader.getPacketList().size());
logger.fine("Old 2nd Page size: " + secondPageHeader.getPageLength());
logger.fine("Old last packet incomplete: " + secondPageHeader.isLastPacketIncomplete());
logger.fine("Setup Header Size: " + vorbisHeaderSizes.getSetupHeaderSize());
logger.fine("Extra Packets: " + vorbisHeaderSizes.getExtraPacketList().size());
logger.fine("Extra Packet Data Size: " + vorbisHeaderSizes.getExtraPacketDataSize());
logger.fine("Old comment: " + vorbisHeaderSizes.getCommentHeaderSize());
logger.fine("New comment: " + newCommentLength);
logger.fine("New Page Data Size: " + newSecondPageDataLength);
//Second Page containing new vorbis, setup and possibly some extra packets can fit on one page
if (isCommentAndSetupHeaderFitsOnASinglePage(newCommentLength, vorbisHeaderSizes.getSetupHeaderSize(), vorbisHeaderSizes.getExtraPacketList())) {
//we dont care if the last audio packet is split on next page as long as we preserve it
if ((secondPageHeader.getPageLength() < OggPageHeader.MAXIMUM_PAGE_DATA_SIZE) && (((secondPageHeader.getPacketList().size() == 2) && (!secondPageHeader.isLastPacketIncomplete())) || (secondPageHeader.getPacketList().size() > 2))) {
logger.fine("Header and Setup remain on single page:");
replaceSecondPageOnly(vorbisHeaderSizes, newCommentLength, newSecondPageDataLength, secondPageHeader, newComment, secondPageHeaderEndPos, raf, rafTemp);
} else //Original 2nd page spanned multiple pages so more work to do
{
logger.fine("Header and Setup now on single page:");
replaceSecondPageAndRenumberPageSeqs(vorbisHeaderSizes, newCommentLength, newSecondPageDataLength, secondPageHeader, newComment, raf, rafTemp);
}
} else //Bit more complicated, have to create more than one new page and renumber subsequent audio
{
logger.fine("Header and Setup with shift audio:");
replacePagesAndRenumberPageSeqs(vorbisHeaderSizes, newCommentLength, secondPageHeader, newComment, raf, rafTemp);
}
}
Aggregations