/** * extract interval tree from vector of FileFragment objects * * @param V fragment vector * @return interval tree **/ static libmaus2::util::IntervalTree::unique_ptr_type toIntervalTree(std::vector<FileFragment> const & V) { if ( ! V.size() ) { libmaus2::util::IntervalTree::unique_ptr_type ptr; return UNIQUE_PTR_MOVE(ptr); } libmaus2::autoarray::AutoArray< std::pair<uint64_t,uint64_t> > H = toIntervalVector(V); libmaus2::util::IntervalTree::unique_ptr_type PIT(new libmaus2::util::IntervalTree(H,0,H.size())); return UNIQUE_PTR_MOVE(PIT); }
void cued_rip_to_file(rip_context_t *rip) { SF_INFO sfinfo; PIT(SNDFILE, sfObj); PIT(int16_t, pbuf); lsn_t currSector, offsetSectors; int wordsToWrite, wordsWritten, i; int offsetWords = rip->offsetWords; track_t track = rip->currentTrack; memset(&sfinfo, 0x00, sizeof(sfinfo)); sfinfo.samplerate = 44100; sfinfo.channels = rip->channels; sfinfo.format = SF_FORMAT_PCM_16 | rip->soundFileFormat; offsetSectors = offsetWords / CD_FRAMEWORDS; rip->firstSector += offsetSectors; rip->lastSector += offsetSectors; offsetWords %= CD_FRAMEWORDS; if (offsetWords < 0) { rip->firstSector -= 1; } else if (offsetWords > 0) { rip->lastSector += 1; } // else offsetWords is zero b/c the offset fell on a sector boundary currSector = rip->firstSector; #ifdef CUED_HAVE_PARANOIA if (ripUseParanoia) { lsn_t seekSector, prc; if (currSector < 0 && !ripReadPregap) { seekSector = 0; } else { seekSector = currSector; } // TODO: paranoia has a problem with reading leadout if (seekSector < rip->endOfDiscSector) { prc = cdio_paranoia_seek(rip->paranoiaRipObj, seekSector, SEEK_SET); cdio2_paranoia_msg(rip->paranoiaCtlObj, "paranoia seek"); if (-1 == prc) { cdio_error("paranoia returned \"%d\" during seek to \"%d\"; skipping track %02d", prc, seekSector, track); return; } } } #endif // CUED_HAVE_PARANOIA if (ripExtract) { // does not return on error (void) format_get_file_path(rip->cdObj, rip->cddbObj, rip->fileNamePattern, cued_fmt_to_ext(rip->soundFileFormat), track, rip->fileNameBuffer, rip->bufferSize ); sfObj = sf_open(rip->fileNameBuffer, SFM_WRITE, &sfinfo); if (!sfObj) { cdio_error("sf_open(\"%s\") returned \"%s\"; skipping extraction of track %02d", rip->fileNameBuffer, sf_strerror(sfObj), track); return; } } for (; currSector <= rip->lastSector; ++currSector) { if ((currSector < 0 && !ripReadPregap) || (currSector >= rip->endOfDiscSector && !ripReadLeadout)) { // N.B. assume that if mmcBuf is not NULL, it is >= sizeof(audio_buffer_t) if (!rip->mmcBuf) { // use twice the audio_buffer_t size for reading 1 sector; // this should accomodate any extra headers/sub-channel data // requested later in the normal read path // rip->mmcBuf = (uint8_t *) malloc(2 * sizeof(audio_buffer_t)); if (rip->mmcBuf) { rip->allocatedSectors = 1; } else { cdio2_abort("out of memory allocating overread sector"); } } memset(rip->mmcBuf, 0x00, sizeof(audio_buffer_t)); pbuf = (int16_t *) rip->mmcBuf; } else { // TODO: need to update track indices on skip of sector (continue) if (ripUseParanoia) { #ifdef CUED_HAVE_PARANOIA pbuf = cdio_paranoia_read_limited(rip->paranoiaRipObj, cdio2_paranoia_callback, rip->retries); cdio2_paranoia_msg(rip->paranoiaCtlObj, "read of audio sector"); if (!pbuf) { cdio_error("paranoia did not return data; skipping extraction of audio sector %d in track %02d", currSector, track); continue; } #endif // CUED_HAVE_PARANOIA } else { if (DRIVER_OP_SUCCESS == cued_read_audio(rip, currSector, 1, NULL, rip->retries)) { pbuf = (int16_t *) rip->mmcBuf; } else { continue; } } } wordsToWrite = CD_FRAMEWORDS; // N.B. firstSector == lastSector is not possible if offsetWords is non-zero // if (rip->firstSector == currSector) { if (offsetWords < 0) { pbuf += CD_FRAMEWORDS + offsetWords; wordsToWrite = -offsetWords; } else if (offsetWords > 0) { pbuf += offsetWords; wordsToWrite -= offsetWords; } } else if (rip->lastSector == currSector) { if (offsetWords < 0) { wordsToWrite += offsetWords; } else if (offsetWords > 0) { wordsToWrite = offsetWords; } } if (ripExtract) { wordsWritten = sf_write_short(sfObj, pbuf, wordsToWrite); if (wordsWritten != wordsToWrite) { // probably out of disk space, which is bad, because most things rely on it cdio2_abort("failed to write to file \"%s\" due to \"%s\"", rip->fileNameBuffer, sf_strerror(sfObj)); } } if (!track && !ripNoisyPregap) { for (i = 0; i < wordsToWrite; ++i) { if (pbuf[i]) { SETF(RIP_F_NOISY_PREGAP, rip->flags); break; } } } } if (!track && !ripNoisyPregap) { SETF(RIP_F_SILENT_PREGAP, rip->flags); } if (ripExtract) { sf_close(sfObj); } }