1
/* cdrdao - write audio CD-Rs in disc-at-once mode
3
* Copyright (C) 1998-2001 Andreas Mueller <mueller@daneb.ping.de>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
#include "PlextorReaderScan.h"
26
#include "PWSubChannel96.h"
27
#include "PQSubChannel16.h"
32
PlextorReaderScan::PlextorReaderScan(ScsiIf *scsiIf, unsigned long options)
33
: PlextorReader(scsiIf, options)
37
driverName_ = "Plextor CD-ROM Reader (scanning) - Version 1.0";
39
for (i = 0; i < maxScannedSubChannels_; i++) {
40
if (options_ & OPT_PLEX_USE_PQ)
41
scannedSubChannels_[i] = new PQSubChannel16;
43
scannedSubChannels_[i] = new PWSubChannel96;
47
PlextorReaderScan::~PlextorReaderScan()
51
for (i = 0; i < maxScannedSubChannels_; i++) {
52
delete scannedSubChannels_[i];
53
scannedSubChannels_[i] = NULL;
58
CdrDriver *PlextorReaderScan::instance(ScsiIf *scsiIf, unsigned long options)
60
return new PlextorReaderScan(scsiIf, options);
63
Toc *PlextorReaderScan::readDisk(int session, const char *fname)
65
Toc *toc = CdrDriver::readDisk(session, fname);
67
setBlockSize(MODE1_BLOCK_LEN);
72
int PlextorReaderScan::analyzeTrack(TrackData::Mode mode, int trackNr,
74
long endLba, Msf *indexIncrements,
75
int *indexIncrementCnt, long *pregap,
76
char *isrcCode, unsigned char *ctl)
78
int ret = analyzeTrackScan(mode, trackNr, startLba, endLba,
79
indexIncrements, indexIncrementCnt, pregap,
82
if ((options_ & OPT_PLEX_READ_ISRC) ||
83
((options_ & OPT_PLEX_USE_PQ) && !(options_ & OPT_PLEX_PQ_BCD))) {
84
// The ISRC code is usually not usable if the PQ channel data is
85
// converted to hex numbers by the drive. Read them with the
86
// appropriate command in this case
89
if (mode == TrackData::AUDIO)
90
readIsrc(trackNr, isrcCode);
96
int PlextorReaderScan::readSubChannels(TrackData::SubChannelMode sm,
97
long lba, long len, SubChannel ***chans,
100
unsigned char cmd[12];
105
if (options_ & OPT_PLEX_USE_PQ)
106
blockLen = AUDIO_BLOCK_LEN + 16;
108
blockLen = AUDIO_BLOCK_LEN + 96;
110
cmd[0] = 0xd8; // READ CDDA
121
if (options_ & OPT_PLEX_USE_PQ)
129
if (sendCmd(cmd, 12, NULL, 0, transferBuffer_, len * blockLen,
130
retries == 0 ? 1 : 0) != 0) {
144
sprintf(fname, "testout_%ld", lba);
145
FILE *fp = fopen(fname, "w");
146
fwrite(transferBuffer_, blockLen, len, fp);
151
unsigned char *p = transferBuffer_ + AUDIO_BLOCK_LEN;
153
for (i = 0; i < len; i++) {
154
if (options_ & OPT_PLEX_USE_PQ) {
155
if (!(options_ & OPT_PLEX_PQ_BCD)) {
156
// Numbers in sub-channel data are hex instead of BCD.
157
// We have to convert them back to BCD for the 'SubChannel' class.
158
p[1] = SubChannel::bcd(p[1]);
159
p[2] = SubChannel::bcd(p[2]);
160
p[3] = SubChannel::bcd(p[3]);
161
p[4] = SubChannel::bcd(p[4]);
162
p[5] = SubChannel::bcd(p[5]);
163
p[6] = SubChannel::bcd(p[6]);
164
p[7] = SubChannel::bcd(p[7]);
165
p[8] = SubChannel::bcd(p[8]);
166
p[9] = SubChannel::bcd(p[9]);
169
((PQSubChannel16*)scannedSubChannels_[i])->init(p);
171
if (scannedSubChannels_[i]->type() != SubChannel::QMODE_ILLEGAL) {
172
// the CRC of the sub-channel data is usually invalid -> mark the
173
// sub-channel object that it should not try to verify the CRC
174
scannedSubChannels_[i]->crcInvalid();
178
((PWSubChannel96*)scannedSubChannels_[i])->init(p);
184
if (audioData != NULL) {
187
for (i = 0; i < len; i++) {
188
memcpy(audioData, p, AUDIO_BLOCK_LEN);
191
audioData += SAMPLES_PER_BLOCK;
195
*chans = scannedSubChannels_;
199
int PlextorReaderScan::readAudioRange(ReadDiskInfo *info, int fd, long start,
200
long end, int startTrack, int endTrack,
201
TrackInfo *trackInfo)
204
if ((options_ & OPT_PLEX_READ_ISRC) ||
205
((options_ & OPT_PLEX_USE_PQ) && !(options_ & OPT_PLEX_PQ_BCD))) {
208
log_message(1, "Analyzing...");
210
for (t = startTrack; t <= endTrack; t++) {
213
log_message(1, "Track %d...", t + 1);
215
totalProgress = t * 1000;
216
totalProgress /= info->tracks;
217
sendReadCdProgressMsg(RCD_ANALYZING, info->tracks, t + 1, 0,
220
trackInfo[t].isrcCode[0] = 0;
221
readIsrc(t + 1, trackInfo[t].isrcCode);
222
if (trackInfo[t].isrcCode[0] != 0)
223
log_message(2, "Found ISRC code.");
225
totalProgress = (t + 1) * 1000;
226
totalProgress /= info->tracks;
227
sendReadCdProgressMsg(RCD_ANALYZING, info->tracks, t + 1, 1000,
231
log_message(1, "Reading...");
235
return CdrDriver::readAudioRangeParanoia(info, fd, start, end, startTrack,
236
endTrack, trackInfo);