static void UpdateFrame(CP_INSTANCE *cpi){ double CorrectionFactor; /* Reset the DC predictors. */ cpi->pb.LastIntraDC = 0; cpi->pb.InvLastIntraDC = 0; cpi->pb.LastInterDC = 0; cpi->pb.InvLastInterDC = 0; /* Initialise bit packing mechanism. */ #ifndef LIBOGG2 oggpackB_reset(cpi->oggbuffer); #else oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate); #endif /* mark as video frame */ oggpackB_write(cpi->oggbuffer,0,1); /* Write out the frame header information including size. */ WriteFrameHeader(cpi); /* Copy back any extra frags that are to be updated by the codec as part of the background cleanup task */ CopyBackExtraFrags(cpi); /* Encode the data. */ EncodeData(cpi); /* Adjust drop frame trigger. */ if ( GetFrameType(&cpi->pb) != KEY_FRAME ) { /* Apply decay factor then add in the last frame size. */ cpi->DropFrameTriggerBytes = ((cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1)) / DF_CANDIDATE_WINDOW) + oggpackB_bytes(cpi->oggbuffer); }else{ /* Increase cpi->DropFrameTriggerBytes a little. Just after a key frame may actually be a good time to drop a frame. */ cpi->DropFrameTriggerBytes = (cpi->DropFrameTriggerBytes * DF_CANDIDATE_WINDOW) / (DF_CANDIDATE_WINDOW-1); } /* Test for overshoot which may require a dropped frame next time around. If we are already in a drop frame condition but the previous frame was not dropped then the threshold for continuing to allow dropped frames is reduced. */ if ( cpi->DropFrameCandidate ) { if ( cpi->DropFrameTriggerBytes > (cpi->frame_target_rate * (DF_CANDIDATE_WINDOW+1)) ) cpi->DropFrameCandidate = 1; else cpi->DropFrameCandidate = 0; } else { if ( cpi->DropFrameTriggerBytes > (cpi->frame_target_rate * ((DF_CANDIDATE_WINDOW*2)-2)) ) cpi->DropFrameCandidate = 1; else cpi->DropFrameCandidate = 0; } /* Update the BpbCorrectionFactor variable according to whether or not we were close enough with our selection of DCT quantiser. */ if ( GetFrameType(&cpi->pb) != KEY_FRAME ) { /* Work out a size correction factor. */ CorrectionFactor = (double)oggpackB_bytes(cpi->oggbuffer) / (double)cpi->ThisFrameTargetBytes; if ( (CorrectionFactor > 1.05) && (cpi->pb.ThisFrameQualityValue < cpi->pb.QThreshTable[cpi->Configuration.ActiveMaxQ]) ) { CorrectionFactor = 1.0 + ((CorrectionFactor - 1.0)/2); if ( CorrectionFactor > 1.5 ) cpi->BpbCorrectionFactor *= 1.5; else cpi->BpbCorrectionFactor *= CorrectionFactor; /* Keep BpbCorrectionFactor within limits */ if ( cpi->BpbCorrectionFactor > MAX_BPB_FACTOR ) cpi->BpbCorrectionFactor = MAX_BPB_FACTOR; } else if ( (CorrectionFactor < 0.95) && (cpi->pb.ThisFrameQualityValue > VERY_BEST_Q) ){ CorrectionFactor = 1.0 - ((1.0 - CorrectionFactor)/2); if ( CorrectionFactor < 0.75 ) cpi->BpbCorrectionFactor *= 0.75; else cpi->BpbCorrectionFactor *= CorrectionFactor; /* Keep BpbCorrectionFactor within limits */ if ( cpi->BpbCorrectionFactor < MIN_BPB_FACTOR ) cpi->BpbCorrectionFactor = MIN_BPB_FACTOR; } } /* Adjust carry over and or key frame context. */ if ( GetFrameType(&cpi->pb) == KEY_FRAME ) { /* Adjust the key frame context unless the key frame was very small */ AdjustKeyFrameContext(cpi); } else { /* Update the frame carry over */ cpi->CarryOver += ((ogg_int32_t)cpi->frame_target_rate - (ogg_int32_t)oggpackB_bytes(cpi->oggbuffer)); } cpi->TotalByteCount += oggpackB_bytes(cpi->oggbuffer); }
void Trimmer::CutTrack(string outputFLACFile, unsigned int leftSecond, unsigned int rightSecond) { /* if (bs.GetString(3) == "ID3") { bs.Skip(3); uint32_t id3size = 0; uint32_t b1 = 0, b2 = 0, b3 = 0, b4 = 0; bs.GetInteger(&b1, 8); bs.GetInteger(&b2, 8); bs.GetInteger(&b3, 8); bs.GetInteger(&b4, 8); id3size = (b1 << 21) | (b2 << 14) | (b3 << 7) | b4; bs.Skip(id3size); }*/ BitIStream bis(fileName); BitOStream bos(outputFLACFile); FLACMetaStreamInfo msi; if (bis.ReadString(4) != "fLaC") { throw NoFLACFile(); } bos.WriteString("fLaC"); FLACMetaBlockHeader mbh; mbh.IsLastBlock = false; while (!mbh.IsLastBlock) { ReadMetaBlockHeader(bis, &mbh); WriteMetaBlockHeader(bos, &mbh); switch (mbh.BlockType) { case FLAC_META_STREAMINFO: ReadStreamInfo(bis, &msi); WriteStreamInfo(bos, &msi); break; case FLAC_META_SEEKTABLE: case FLAC_META_APPLICATION: case FLAC_META_VORBIS_COMMENT: case FLAC_META_CUESHEET: case FLAC_META_PADDING: CopyBytes(bis, bos, mbh.BlockSize); break; default: cerr << "Warning: unknown block type" << endl; CopyBytes(bis, bos, mbh.BlockSize); break; } } for (int i = 0; i < 10; i++) { //Frame start FLACFrameHeader fh; ReadFrameHeader(bis, &fh); WriteFrameHeader(bos, &fh); if (fh.SyncCode != 0b11111111111110) { cout << "Invalid sync code" << endl; throw NoFLACFile(); } for (int subframeN = 0; subframeN <= msi.ChannelsCount; subframeN++) { FLACSubframeHeader sfh; ReadSubframeHeader(bis, &sfh); WriteSubframeHeader(bos, &sfh); switch (sfh.Type) { case FLAC_SF_CONSTANT: cout << "const" << endl; CopyConstantSubframe(bis, bos, &fh, &msi); break; case FLAC_SF_VERBATIM: cout << "verbatim" << endl; CopyVerbatimSubframe(bis, bos, &fh, &msi); break; case FLAC_SF_FIXED: cout << "fixed" << endl; CopyFixedSubframe(bis, bos, &fh, &msi, &sfh); break; case FLAC_SF_LPC: cout << "lpc" << endl; CopyLPCSubframe(bis, bos, &fh, &msi, &sfh); break; default: break; } } bos.AlignByte(); uint16_t crc16; bis.ReadInteger(&crc16, 16); bos.WriteInteger(crc16, 16); /*ReadFrameHeader(bis, &fh); cout << fh.SyncCode << endl;*/ //Frame end } }