PlextorReaderScan.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:6k
源码类别:
SCSI/ASPI
开发平台:
MultiPlatform
- /* cdrdao - write audio CD-Rs in disc-at-once mode
- *
- * Copyright (C) 1998 Andreas Mueller <mueller@daneb.ping.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*
- * $Log: PlextorReaderScan.cc,v $
- * Revision 1.4 1999/04/05 18:49:22 mueller
- * Added driver options.
- * Added option to read Q sub-channel data instead of raw PW sub-channel
- * data for 'read-toc'.
- *
- * Revision 1.3 1999/03/27 20:56:39 mueller
- * Changed toc analysis interface.
- * Added support for toc analysis of data disks.
- *
- * Revision 1.2 1998/09/27 19:20:05 mueller
- * Added retrieval of control nibbles for track with 'analyzeTrack()'.
- *
- * Revision 1.1 1998/09/07 15:15:40 mueller
- * Initial revision
- *
- */
- static char rcsid[] = "$Id: PlextorReaderScan.cc,v 1.4 1999/04/05 18:49:22 mueller Exp mueller $";
- #include <config.h>
- #include <string.h>
- #include <assert.h>
- #include "PlextorReaderScan.h"
- #include "PWSubChannel96.h"
- #include "PQSubChannel16.h"
- #include "Toc.h"
- #include "util.h"
- PlextorReaderScan::PlextorReaderScan(ScsiIf *scsiIf, unsigned long options)
- : PlextorReader(scsiIf, options)
- {
- int i;
- driverName_ = "Plextor CD-ROM Reader (scanning) - Version 1.0";
- for (i = 0; i < maxScannedSubChannels_; i++) {
- if (options_ & OPT_PLEX_USE_PQ)
- scannedSubChannels_[i] = new PQSubChannel16;
- else
- scannedSubChannels_[i] = new PWSubChannel96;
- }
- }
- PlextorReaderScan::~PlextorReaderScan()
- {
- int i;
- for (i = 0; i < maxScannedSubChannels_; i++) {
- delete scannedSubChannels_[i];
- scannedSubChannels_[i] = NULL;
- }
- }
- // static constructor
- CdrDriver *PlextorReaderScan::instance(ScsiIf *scsiIf, unsigned long options)
- {
- return new PlextorReaderScan(scsiIf, options);
- }
- Toc *PlextorReaderScan::readDisk(int session, const char *fname)
- {
- Toc *toc = CdrDriver::readDisk(session, fname);
- setBlockSize(MODE1_BLOCK_LEN);
- return toc;
- }
- int PlextorReaderScan::analyzeTrack(TrackData::Mode mode, int trackNr,
- long startLba,
- long endLba, Msf *indexIncrements,
- int *indexIncrementCnt, long *pregap,
- char *isrcCode, unsigned char *ctl)
- {
- int ret = analyzeTrackScan(mode, trackNr, startLba, endLba,
- indexIncrements, indexIncrementCnt, pregap,
- isrcCode, ctl);
- if ((options_ & OPT_PLEX_READ_ISRC) ||
- ((options_ & OPT_PLEX_USE_PQ) && !(options_ & OPT_PLEX_PQ_BCD))) {
- // The ISRC code is usually not usable if the PQ channel data is
- // converted to hex numbers by the drive. Read them with the
- // appropriate command in this case
- *isrcCode = 0;
- if (mode == TrackData::AUDIO)
- readIsrc(trackNr, isrcCode);
- }
- return ret;
- }
- int PlextorReaderScan::readSubChannels(long lba, long len, SubChannel ***chans,
- Sample *audioData)
- {
- unsigned char cmd[12];
- int i;
- int retries = 5;
- long blockLen;
- if (options_ & OPT_PLEX_USE_PQ)
- blockLen = AUDIO_BLOCK_LEN + 16;
- else
- blockLen = AUDIO_BLOCK_LEN + 96;
- cmd[0] = 0xd8; // READ CDDA
- cmd[1] = 0;
- cmd[2] = lba >> 24;
- cmd[3] = lba >> 16;
- cmd[4] = lba >> 8;
- cmd[5] = lba;
- cmd[6] = 0;
- cmd[7] = len >> 16;
- cmd[8] = len >> 8;
- cmd[9] = len;
- if (options_ & OPT_PLEX_USE_PQ)
- cmd[10] = 0x01;
- else
- cmd[10] = 0x02;
- cmd[11] = 0;
- while (1) {
- if (sendCmd(cmd, 12, NULL, 0, transferBuffer_, len * blockLen,
- retries == 0 ? 1 : 0) != 0) {
- if (retries == 0)
- return 1;
- }
- else {
- break;
- }
- retries--;
- }
- #if 0
- if (lba > 5000) {
- char fname[200];
- sprintf(fname, "testout_%ld", lba);
- FILE *fp = fopen(fname, "w");
- fwrite(transferBuffer_, blockLen, len, fp);
- fclose(fp);
- }
- #endif
- unsigned char *p = transferBuffer_ + AUDIO_BLOCK_LEN;
- for (i = 0; i < len; i++) {
- if (options_ & OPT_PLEX_USE_PQ) {
- if (!(options_ & OPT_PLEX_PQ_BCD)) {
- // Numbers in sub-channel data are hex instead of BCD.
- // We have to convert them back to BCD for the 'SubChannel' class.
- p[1] = SubChannel::bcd(p[1]);
- p[2] = SubChannel::bcd(p[2]);
- p[3] = SubChannel::bcd(p[3]);
- p[4] = SubChannel::bcd(p[4]);
- p[5] = SubChannel::bcd(p[5]);
- p[6] = SubChannel::bcd(p[6]);
- p[7] = SubChannel::bcd(p[7]);
- p[8] = SubChannel::bcd(p[8]);
- p[9] = SubChannel::bcd(p[9]);
- }
- ((PQSubChannel16*)scannedSubChannels_[i])->init(p);
- if (scannedSubChannels_[i]->type() != SubChannel::QMODE_ILLEGAL) {
- // the CRC of the sub-channel data is usually invalid -> mark the
- // sub-channel object that it should not try to verify the CRC
- scannedSubChannels_[i]->crcInvalid();
- }
- }
- else {
- ((PWSubChannel96*)scannedSubChannels_[i])->init(p);
- }
- p += blockLen;
- }
- if (audioData != NULL) {
- p = transferBuffer_;
- for (i = 0; i < len; i++) {
- memcpy(audioData, p, AUDIO_BLOCK_LEN);
- p += blockLen;
- audioData += SAMPLES_PER_BLOCK;
- }
- }
- *chans = scannedSubChannels_;
- return 0;
- }
- int PlextorReaderScan::readAudioRange(int fd, long start, long end,
- int startTrack, int endTrack,
- TrackInfo *trackInfo)
- {
- if (!onTheFly_) {
- if ((options_ & OPT_PLEX_READ_ISRC) ||
- ((options_ & OPT_PLEX_USE_PQ) && !(options_ & OPT_PLEX_PQ_BCD))) {
- int t;
- message(1, "Analyzing...");
- for (t = startTrack; t <= endTrack; t++) {
- message(1, "Track %d...", t + 1);
- trackInfo[t].isrcCode[0] = 0;
- readIsrc(t + 1, trackInfo[t].isrcCode);
- if (trackInfo[t].isrcCode[0] != 0)
- message(1, "Found ISRC code.");
- }
- message(1, "Reading...");
- }
- }
- return CdrDriver::readAudioRangeParanoia(fd, start, end, startTrack,
- endTrack, trackInfo);
- }