PWSubChannel96.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:11k
源码类别:
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: PWSubChannel96.cc,v $
- * Revision 1.6 1999/04/05 11:04:48 mueller
- * Added decoding of media catalog number and ISRC code.
- *
- * Revision 1.5 1999/03/27 20:58:55 mueller
- * Added various access functions.
- *
- * Revision 1.4 1998/09/27 19:19:39 mueller
- * Added retrieval of control nibbles for track with 'analyzeTrack()'.
- *
- * Revision 1.3 1998/09/06 13:34:22 mueller
- * Use 'message()' for printing messages.
- *
- * Revision 1.2 1998/08/30 19:10:32 mueller
- * Added handling of Catalog Number and ISRC codes.
- *
- * Revision 1.1 1998/08/29 21:32:27 mueller
- * Initial revision
- *
- *
- */
- #include "PWSubChannel96.h"
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include "util.h"
- PWSubChannel96::PWSubChannel96()
- {
- memset(data_, 0, 96);
- type_ = QMODE1DATA;
- }
- PWSubChannel96::PWSubChannel96(unsigned char *buf)
- {
- init(buf);
- }
- void PWSubChannel96::init(unsigned char *buf)
- {
- memcpy(data_, buf, 96);
- switch (getChannelByte(Q_CHAN, 0) & 0x0f) {
- case 1:
- type_ = QMODE1DATA;
- break;
- case 2:
- type_ = QMODE2;
- break;
- case 3:
- type_ = QMODE3;
- break;
- default:
- type_ = QMODE_ILLEGAL;
- break;
- }
- }
- PWSubChannel96::~PWSubChannel96()
- {
- }
- SubChannel *PWSubChannel96::makeSubChannel(Type t)
- {
- PWSubChannel96 *chan = new PWSubChannel96;
- chan->type_ = t;
- switch (t) {
- case QMODE1TOC:
- case QMODE1DATA:
- chan->setChannelByte(Q_CHAN, 0, 0x01);
- break;
- case QMODE2:
- chan->setChannelByte(Q_CHAN, 0, 0x02);
- break;
- case QMODE3:
- chan->setChannelByte(Q_CHAN, 0, 0x03);
- break;
- case QMODE_ILLEGAL:
- chan->setChannelByte(Q_CHAN, 0, 0x00);
- break;
- }
- return chan;
- }
- SubChannel *PWSubChannel96::makeSubChannel(unsigned char *buf)
- {
- PWSubChannel96 *chan = new PWSubChannel96(buf);
- return chan;
- }
- void PWSubChannel96::setChannelByte(Channel chan, int byteNr,
- unsigned char value)
- {
- assert(byteNr >= 0 && byteNr < 12);
- register unsigned char setMask = 1 << chan;
- register unsigned char clearMask = ~setMask;
- register unsigned char *p = data_ + (byteNr * 8);
- register int i;
- for (i = 0; i < 8; i++) {
- if (value & 0x80)
- *p |= setMask;
- else
- *p &= clearMask;
- p++;
- value <<= 1;
- }
- }
- unsigned char PWSubChannel96::getChannelByte(Channel chan, int byteNr) const
- {
- assert(byteNr >= 0 && byteNr < 12);
- register unsigned char testMask = 1 << chan;
- register const unsigned char *p = data_ + (byteNr * 8);
- register unsigned char val = 0;
- register int i;
- for (i = 0; i < 8; i++) {
- val <<= 1;
- if ((*p) & testMask)
- val |= 0x01;
- p++;
- }
- return val;
- }
- const unsigned char *PWSubChannel96::data() const
- {
- return data_;
- }
- long PWSubChannel96::dataLength() const
- {
- return 96;
- }
- // calculate the crc over Q sub channel bytes 0-9 and stores it in byte 10,11
- void PWSubChannel96::calcCrc()
- {
- register unsigned short crc = 0;
- register int i;
- for (i = 0; i < 10; i++) {
- register unsigned char data = getChannelByte(Q_CHAN, i);
- crc = crctab[(crc >> 8) ^ data] ^ (crc << 8);
- }
- crc = ~crc;
- setChannelByte(Q_CHAN, 10, crc >> 8);
- setChannelByte(Q_CHAN, 11, crc);
- }
- int PWSubChannel96::checkCrc() const
- {
- register unsigned short crc = 0;
- register int i;
- if (!crcValid_) {
- return 1;
- }
- for (i = 0; i < 10; i++) {
- register unsigned char data = getChannelByte(Q_CHAN, i);
- crc = crctab[(crc >> 8) ^ data] ^ (crc << 8);
- }
- crc = ~crc;
- if (getChannelByte(Q_CHAN, 10) == (crc >> 8) &&
- getChannelByte(Q_CHAN, 11) == (crc & 0xff))
- return 1;
- else
- return 0;
- }
- // sets P channel bit
- void PWSubChannel96::pChannel(int f)
- {
- register int i;
- if (f != 0) {
- for (i = 0; i < 96; i++)
- data_[i] |= 0x80;
- }
- else {
- for (i = 0; i < 96; i++)
- data_[i] &= 0x7f;
- }
- }
- // returns Q type
- SubChannel::Type PWSubChannel96::type() const
- {
- return type_;
- }
- // set Q type
- void PWSubChannel96::type(unsigned char type)
- {
- switch (type & 0x0f) {
- case 1:
- type_ = QMODE1DATA;
- break;
- case 2:
- type_ = QMODE2;
- break;
- case 3:
- type_ = QMODE3;
- break;
- default:
- type_ = QMODE_ILLEGAL;
- break;
- }
- register unsigned char val = getChannelByte(Q_CHAN, 0);
- val &= 0xf0;
- val |= type & 0x0f;
- setChannelByte(Q_CHAN, 0, val);
- }
- // function for setting various Q sub channel fields
- void PWSubChannel96::ctl(int c)
- {
- assert((c & 0x0f) == 0);
- register unsigned char val = getChannelByte(Q_CHAN, 0);
- val &= 0x0f;
- val |= c & 0xf0;
- setChannelByte(Q_CHAN, 0, val);
- }
- unsigned char PWSubChannel96::ctl() const
- {
- register unsigned char val = getChannelByte(Q_CHAN, 0);
- return val >> 4;
- }
- void PWSubChannel96::trackNr(int t)
- {
- assert(type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 1, bcd(t));
- }
- int PWSubChannel96::trackNr() const
- {
- assert(type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 1));
- }
- void PWSubChannel96::indexNr(int i)
- {
- assert(type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 2, bcd(i));
- }
- int PWSubChannel96::indexNr() const
- {
- assert(type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 2));
- }
- void PWSubChannel96::point(int p)
- {
- assert(type_ == QMODE1TOC);
- setChannelByte(Q_CHAN, 2, bcd(p));
- }
- void PWSubChannel96::min(int m)
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 3, bcd(m));
- }
- int PWSubChannel96::min() const
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 3));
- }
- void PWSubChannel96::sec(int s)
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 4, bcd(s));
- }
- int PWSubChannel96::sec() const
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 4));
- }
- void PWSubChannel96::frame(int f)
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 5, bcd(f));
- }
- int PWSubChannel96::frame() const
- {
- assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 5));
- }
- void PWSubChannel96::amin(int am)
- {
- assert(type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 7, bcd(am));
- }
- int PWSubChannel96::amin() const
- {
- assert(type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 7));
- }
- void PWSubChannel96::asec(int as)
- {
- assert(type_ == QMODE1DATA);
- setChannelByte(Q_CHAN, 8, bcd(as));
- }
- int PWSubChannel96::asec() const
- {
- assert(type_ == QMODE1DATA);
- return bcd2int(getChannelByte(Q_CHAN, 8));
- }
- void PWSubChannel96::aframe(int af)
- {
- assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
- setChannelByte(Q_CHAN, 9, bcd(af));
- }
- int PWSubChannel96::aframe() const
- {
- assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
- return bcd2int(getChannelByte(Q_CHAN, 9));
- }
- void PWSubChannel96::pmin(int pm)
- {
- assert(type_ == QMODE1TOC);
- setChannelByte(Q_CHAN, 7, bcd(pm));
- }
- void PWSubChannel96::psec(int ps)
- {
- assert(type_ == QMODE1TOC);
- setChannelByte(Q_CHAN, 8, bcd(ps));
- }
- void PWSubChannel96::pframe(int pf)
- {
- assert(type_ == QMODE1TOC);
- setChannelByte(Q_CHAN, 9, bcd(pf));
- }
- void PWSubChannel96::catalog(char n1, char n2, char n3, char n4, char n5,
- char n6, char n7, char n8, char n9, char n10,
- char n11, char n12, char n13)
- {
- assert(type_ == QMODE2);
- unsigned char buf[8];
- int i;
- encodeCatalogNumber(buf, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12,
- n13);
- buf[7] = 0;
- for (i = 0; i < 8; i++)
- setChannelByte(Q_CHAN, i + 1, buf[i]);
- }
- const char *PWSubChannel96::catalog() const
- {
- static char buf[14];
- unsigned char in[7];
- int i;
- for (i = 0; i < 7; i++)
- in[i] = getChannelByte(Q_CHAN, i + 1);
- decodeCatalogNumber(in, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
- &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10],
- &buf[11], &buf[12]);
- buf[13] = 0;
- return buf;
- }
- void PWSubChannel96::isrc(char c1, char c2, char o1, char o2, char o3,
- char y1, char y2, char s1, char s2, char s3,
- char s4, char s5)
- {
- assert(type_ == QMODE3);
- unsigned char buf[8];
- int i;
- encodeIsrcCode(buf, c1, c2, o1, o2, o3, y1, y2, s1, s2, s3, s4, s5);
- for (i = 0; i < 8; i++)
- setChannelByte(Q_CHAN, i + 1, buf[i]);
- }
- const char *PWSubChannel96::isrc() const
- {
- static char buf[13];
- unsigned char in[8];
- int i;
- assert(type_ == QMODE3);
- for (i = 0; i < 8; i++)
- in[i] = getChannelByte(Q_CHAN, i + 1);
- decodeIsrcCode(in, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
- &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10],
- &buf[11]);
- buf[12] = 0;
- return buf;
- }
- void PWSubChannel96::print() const
- {
- if (type_ != QMODE_ILLEGAL)
- message(0, "P:%02x ", getChannelByte(P_CHAN, 0));
- switch (type_) {
- case QMODE1TOC:
- case QMODE1DATA:
- message(0, "Q: (%02x) %02x,%02x %02x:%02x:%02x %02x %02x:%02x:%02x ",
- getChannelByte(Q_CHAN, 0), getChannelByte(Q_CHAN, 1),
- getChannelByte(Q_CHAN, 2), getChannelByte(Q_CHAN, 3),
- getChannelByte(Q_CHAN, 4), getChannelByte(Q_CHAN, 5),
- getChannelByte(Q_CHAN, 6), getChannelByte(Q_CHAN, 7),
- getChannelByte(Q_CHAN, 8), getChannelByte(Q_CHAN, 9));
- break;
- case QMODE2:
- message(0, "Q: (%02x) MCN: %s %02x ", getChannelByte(Q_CHAN, 0),
- catalog(), getChannelByte(Q_CHAN, 9));
- break;
- case QMODE3:
- message(0, "Q: (%02x) ISRC: %s %02x ", getChannelByte(Q_CHAN, 0),
- isrc(), getChannelByte(Q_CHAN, 9));
- break;
- case QMODE_ILLEGAL:
- message(0, "INVALID QMODE: %02x", getChannelByte(Q_CHAN, 0));
- break;
- }
- if (type_ != QMODE_ILLEGAL)
- message(0, "%04x %d",
- (getChannelByte(Q_CHAN, 10) << 8) | getChannelByte(Q_CHAN, 11),
- checkCrc());
- }
- // sets R-W channel bits from 72 byte data buffer, used for CD-TEXT
- void PWSubChannel96::setRawRWdata(const unsigned char *data)
- {
- int i;
- for (i = 0; i < 96; i += 4) {
- data_[i] |= (data[0] >> 2) & 0x3f;
- data_[i + 1] |= ((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0x0f);
- data_[i + 2] |= ((data[1] << 2) & 0x3c) | ((data[2] >> 6) & 0x03);
- data_[i + 3] |= data[2] & 0x3f;
- data += 3;
- }
- }
- // concatenates the R-W channel bits and writes them to provided 72 byte buffer
- void PWSubChannel96::getRawRWdata(unsigned char *data) const
- {
- int i;
- for (i = 0; i < 96; i += 4) {
- data[0] = ((data_[i] << 2) & 0xfc) | ((data_[i + 1] >> 4) & 0x03);
- data[1] = ((data_[i + 1] << 4) & 0xf0) | ((data_[i + 2] >> 2) & 0x0f);
- data[2] = ((data_[i + 2] << 6) & 0xc0) | (data_[i + 3] & 0x3f);
- data += 3;
- }
- }