SonyCDU948.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:5k
- /* cdrdao - write audio CD-Rs in disc-at-once mode
- *
- * Copyright (C) 1999 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: SonyCDU948.cc,v $
- * Revision 1.3 1999/05/24 17:32:59 mueller
- * Added CD-TEXT writing.
- *
- * Revision 1.2 1999/05/20 19:47:15 mueller
- * Updated implementation.
- *
- * Revision 1.1 1999/05/15 20:11:56 mueller
- * Initial revision
- *
- */
- static char rcsid[] = "$Id: SonyCDU948.cc,v 1.3 1999/05/24 17:32:59 mueller Exp mueller $";
- #include <config.h>
- #include <string.h>
- #include <assert.h>
- #include "SonyCDU948.h"
- #include "PWSubChannel96.h"
- #include "util.h"
- #include "Toc.h"
- #include "CdTextEncoder.h"
- SonyCDU948::SonyCDU948(ScsiIf *scsiIf, unsigned long options)
- : SonyCDU920(scsiIf, options)
- {
- driverName_ = "Sony CDU948 - Version 0.1 (data) (alpha)";
- speed_ = 4;
- cdTextEncoder_ = NULL;
- }
- SonyCDU948::~SonyCDU948()
- {
- delete cdTextEncoder_;
- cdTextEncoder_ = NULL;
- }
- // static constructor
- CdrDriver *SonyCDU948::instance(ScsiIf *scsiIf, unsigned long options)
- {
- return new SonyCDU948(scsiIf, options);
- }
- int SonyCDU948::checkToc(const Toc *toc)
- {
- int err = SonyCDU920::checkToc(toc);
- int e;
- if ((e = toc->checkCdTextData()) > err)
- err = e;
- return err;
- }
- int SonyCDU948::multiSession(int m)
- {
- multiSession_ = m != 0 ? 1 : 0;
- return 0;
- }
- // sets speed
- // return: 0: OK
- // 1: illegal speed
- int SonyCDU948::speed(int s)
- {
- if (s == 0 || s == 1 || s == 2 || s == 4)
- speed_ = s;
- else if (s == 3)
- speed_ = 2;
- else if (s > 4)
- speed_ = 4;
- else
- return 1;
- return 0;
- }
- // sets read/write speed and simulation mode
- // return: 0: OK
- // 1: scsi command failed
- int SonyCDU948::selectSpeed()
- {
- unsigned char mp[4];
-
- mp[0] = 0x31;
- mp[1] = 2;
- mp[2] = 0;
- mp[3] = 0;
- switch (speed_) {
- case 0:
- mp[2] = 0xff;
- case 1:
- mp[2] = 0;
- break;
- case 2:
- mp[2] = 1;
- break;
- case 4:
- mp[2] = 3;
- break;
- }
- if (setModePage6(mp, NULL, NULL, 1) != 0) {
- message(-2, "Cannot set speed mode page.");
- return 1;
- }
- return 0;
- }
- // Sets write parameters.
- // return: 0: OK
- // 1: scsi command failed
- int SonyCDU948::setWriteParameters()
- {
- unsigned char cmd[10];
- unsigned char data[52];
- if (SonyCDU920::setWriteParameters() != 0)
- return 1;
- memset(cmd, 0, 10);
- memset(data, 0, 52);
- cmd[0] = 0xf8; // SET WRITE PARAMETERS
- cmd[7] = 0;
- cmd[8] = 52;
- data[1] = 50;
- data[3] = (multiSession_ != 0 ? (3 << 6) : 0);
-
- if (sendCmd(cmd, 10, data, 52, NULL, 0, 1) != 0) {
- message(-1, "Cannot set write parameters.");
- return 1;
- }
- return 0;
- }
- int SonyCDU948::initDao(const Toc *toc)
- {
- long n;
- delete cdTextEncoder_;
- cdTextEncoder_ = new CdTextEncoder(toc);
- if (cdTextEncoder_->encode() != 0) {
- message(-2, "CD-TEXT encoding failed.");
- return 1;
- }
- if (cdTextEncoder_->getSubChannels(&n) == NULL || n == 0) {
- // there is no CD-TEXT data to write
- delete cdTextEncoder_;
- cdTextEncoder_ = NULL;
- }
- return SonyCDU920::initDao(toc);
- }
- int SonyCDU948::startDao()
- {
- unsigned char leadInDataForm = 0x00; // CD-DA, generate data by device
- scsiTimeout_ = scsiIf_->timeout(3 * 60);
- if (cdTextEncoder_ != NULL)
- leadInDataForm = 0xc0; // CD-DA with P-W sub-channel data
- if (setWriteParameters() != 0 ||
- sendCueSheet(leadInDataForm) != 0)
- return 1;
- if (writeCdTextLeadIn() != 0) {
- return 1;
- }
- long lba = -150;
- // write mandatory pre-gap after lead-in
- if (writeZeros(toc_->leadInMode(), lba, 0, 150) != 0) {
- return 1;
- }
-
- return 0;
- }
- int SonyCDU948::writeCdTextLeadIn()
- {
- unsigned char cmd[10];
- const PWSubChannel96 **cdTextSubChannels;
- long cdTextSubChannelCount;
- long channelsPerCmd = scsiIf_->maxDataLen() / 96;
- long scp = 0;
- long byteLen;
- long len = leadInLen_;
- long n;
- long i;
- unsigned char *p;
- if (cdTextEncoder_ == NULL)
- return 0;
- if (leadInLen_ == 0) {
- message(-2, "Cannot write CD-TEXT lead-in because lead-in length is not known.");
- return 1;
- }
- cdTextSubChannels = cdTextEncoder_->getSubChannels(&cdTextSubChannelCount);
- assert(channelsPerCmd > 0);
- assert(cdTextSubChannels != NULL);
- assert(cdTextSubChannelCount > 0);
- message(1, "Writing CD-TEXT lead-in...");
- memset(cmd, 0, 10);
- cmd[0] = 0xe1; // WRITE CONTINUE
- while (len > 0) {
- n = (len > channelsPerCmd) ? channelsPerCmd : len;
- byteLen = n * 96;
- cmd[1] = (byteLen >> 16) & 0x1f;
- cmd[2] = byteLen >> 8;
- cmd[3] = byteLen;
- p = transferBuffer_;
-
- for (i = 0; i < n; i++) {
- memcpy(p, cdTextSubChannels[scp]->data(), 96);
- p += 96;
- scp++;
- if (scp >= cdTextSubChannelCount)
- scp = 0;
- }
- if (sendCmd(cmd, 10, transferBuffer_, byteLen, NULL, 0) != 0) {
- message(-2, "Writing of CD-TEXT data failed.");
- return 1;
- }
- len -= n;
- }
-
- return 0;
- }