PWSubChannel96.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:11k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998  Andreas Mueller <mueller@daneb.ping.de>
  4.  *
  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.
  9.  *
  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.
  14.  *
  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.
  18.  */
  19. /*
  20.  * $Log: PWSubChannel96.cc,v $
  21.  * Revision 1.6  1999/04/05 11:04:48  mueller
  22.  * Added decoding of media catalog number and ISRC code.
  23.  *
  24.  * Revision 1.5  1999/03/27 20:58:55  mueller
  25.  * Added various access functions.
  26.  *
  27.  * Revision 1.4  1998/09/27 19:19:39  mueller
  28.  * Added retrieval of control nibbles for track with 'analyzeTrack()'.
  29.  *
  30.  * Revision 1.3  1998/09/06 13:34:22  mueller
  31.  * Use 'message()' for printing messages.
  32.  *
  33.  * Revision 1.2  1998/08/30 19:10:32  mueller
  34.  * Added handling of Catalog Number and ISRC codes.
  35.  *
  36.  * Revision 1.1  1998/08/29 21:32:27  mueller
  37.  * Initial revision
  38.  *
  39.  *
  40.  */
  41. #include "PWSubChannel96.h"
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <assert.h>
  45. #include "util.h"
  46. PWSubChannel96::PWSubChannel96()
  47. {
  48.   memset(data_, 0, 96);
  49.   type_ = QMODE1DATA;
  50. }
  51. PWSubChannel96::PWSubChannel96(unsigned char *buf)
  52. {
  53.   init(buf);
  54. }
  55. void PWSubChannel96::init(unsigned char *buf)
  56. {
  57.   memcpy(data_, buf, 96);
  58.   switch (getChannelByte(Q_CHAN, 0) & 0x0f) {
  59.   case 1:
  60.     type_ = QMODE1DATA;
  61.     break;
  62.   case 2:
  63.     type_ = QMODE2;
  64.     break;
  65.   case 3:
  66.     type_ = QMODE3;
  67.     break;
  68.   default:
  69.     type_ = QMODE_ILLEGAL;
  70.     break;
  71.   }
  72. }
  73. PWSubChannel96::~PWSubChannel96()
  74. {
  75. }
  76. SubChannel *PWSubChannel96::makeSubChannel(Type t)
  77. {
  78.   PWSubChannel96 *chan = new PWSubChannel96;
  79.   chan->type_ = t;
  80.   switch (t) {
  81.   case QMODE1TOC:
  82.   case QMODE1DATA:
  83.     chan->setChannelByte(Q_CHAN, 0, 0x01);
  84.     break;
  85.     
  86.   case QMODE2:
  87.     chan->setChannelByte(Q_CHAN, 0, 0x02);
  88.     break;
  89.   case QMODE3:
  90.     chan->setChannelByte(Q_CHAN, 0, 0x03);
  91.     break;
  92.   case QMODE_ILLEGAL:
  93.     chan->setChannelByte(Q_CHAN, 0, 0x00);
  94.     break;
  95.   }
  96.   return chan;
  97. }
  98. SubChannel *PWSubChannel96::makeSubChannel(unsigned char *buf)
  99. {
  100.   PWSubChannel96 *chan = new PWSubChannel96(buf);
  101.   return chan;
  102. }
  103. void PWSubChannel96::setChannelByte(Channel chan, int byteNr,
  104.     unsigned char value)
  105. {
  106.   assert(byteNr >= 0 && byteNr < 12);
  107.   register unsigned char setMask = 1 << chan;
  108.   register unsigned char clearMask = ~setMask;
  109.   register unsigned char *p = data_ + (byteNr * 8);
  110.   register int i;
  111.   for (i = 0; i < 8; i++) {
  112.     if (value & 0x80)
  113.       *p |= setMask;
  114.     else
  115.       *p &= clearMask;
  116.     p++;
  117.     value <<= 1;
  118.   }
  119. }
  120. unsigned char PWSubChannel96::getChannelByte(Channel chan, int byteNr) const
  121. {
  122.   assert(byteNr >= 0 && byteNr < 12);
  123.   register unsigned char testMask = 1 << chan;
  124.   register const unsigned char *p = data_ + (byteNr * 8);
  125.   register unsigned char val = 0;
  126.   register int i;
  127.   
  128.   for (i = 0; i < 8; i++) {
  129.     val <<= 1;
  130.     if ((*p) & testMask)
  131.       val |= 0x01;
  132.     p++;
  133.   }
  134.   return val;
  135. }
  136. const unsigned char *PWSubChannel96::data() const
  137. {
  138.   return data_;
  139. }
  140. long PWSubChannel96::dataLength() const
  141. {
  142.   return 96;
  143. }
  144. // calculate the crc over Q sub channel bytes 0-9 and stores it in byte 10,11
  145. void PWSubChannel96::calcCrc()
  146. {
  147.   register unsigned short crc = 0;
  148.   register int i;
  149.   for (i = 0; i < 10; i++) {
  150.     register unsigned char data = getChannelByte(Q_CHAN, i);
  151.     crc = crctab[(crc >> 8) ^ data] ^ (crc << 8);
  152.   }
  153.   crc = ~crc;
  154.   setChannelByte(Q_CHAN, 10, crc >> 8);
  155.   setChannelByte(Q_CHAN, 11, crc);
  156. }
  157. int PWSubChannel96::checkCrc() const
  158. {
  159.   register unsigned short crc = 0;
  160.   register int i;
  161.   if (!crcValid_) {
  162.     return 1;
  163.   }
  164.   for (i = 0; i < 10; i++) {
  165.     register unsigned char data = getChannelByte(Q_CHAN, i);
  166.     crc = crctab[(crc >> 8) ^ data] ^ (crc << 8);
  167.   }
  168.   crc = ~crc;
  169.   if (getChannelByte(Q_CHAN, 10) == (crc >> 8) &&
  170.       getChannelByte(Q_CHAN, 11) == (crc & 0xff))
  171.     return 1;
  172.   else
  173.     return 0;
  174. }
  175. // sets P channel bit
  176. void PWSubChannel96::pChannel(int f)
  177. {
  178.   register int i;
  179.   if (f != 0) {
  180.     for (i = 0; i < 96; i++)
  181.       data_[i] |= 0x80;
  182.   }
  183.   else {
  184.     for (i = 0; i < 96; i++)
  185.       data_[i] &= 0x7f;
  186.   }    
  187. }
  188. // returns Q type
  189. SubChannel::Type PWSubChannel96::type() const
  190. {
  191.   return type_;
  192. }
  193. // set Q type
  194. void PWSubChannel96::type(unsigned char type)
  195. {
  196.   switch (type & 0x0f) {
  197.   case 1:
  198.     type_ = QMODE1DATA;
  199.     break;
  200.   case 2:
  201.     type_ = QMODE2;
  202.     break;
  203.   case 3:
  204.     type_ = QMODE3;
  205.     break;
  206.   default:
  207.     type_ = QMODE_ILLEGAL;
  208.     break;
  209.   }
  210.   register unsigned char val = getChannelByte(Q_CHAN, 0);
  211.   val &= 0xf0;
  212.   val |= type & 0x0f;
  213.   setChannelByte(Q_CHAN, 0, val);
  214. }
  215. // function for setting various Q sub channel fields
  216. void PWSubChannel96::ctl(int c)
  217. {
  218.   assert((c & 0x0f) == 0);
  219.   register unsigned char val = getChannelByte(Q_CHAN, 0);
  220.   val &= 0x0f;
  221.   val |= c & 0xf0;
  222.   setChannelByte(Q_CHAN, 0, val);
  223. }
  224. unsigned char PWSubChannel96::ctl() const
  225. {
  226.   register unsigned char val = getChannelByte(Q_CHAN, 0);
  227.   return val >> 4;
  228. }
  229. void PWSubChannel96::trackNr(int t)
  230. {
  231.   assert(type_ == QMODE1DATA);
  232.   setChannelByte(Q_CHAN, 1, bcd(t));
  233. }
  234. int PWSubChannel96::trackNr() const
  235. {
  236.   assert(type_ == QMODE1DATA);
  237.   return bcd2int(getChannelByte(Q_CHAN, 1));
  238. }
  239. void PWSubChannel96::indexNr(int i)
  240. {
  241.   assert(type_ == QMODE1DATA);
  242.   setChannelByte(Q_CHAN, 2, bcd(i));
  243. }
  244. int PWSubChannel96::indexNr() const
  245. {
  246.   assert(type_ == QMODE1DATA);
  247.   return bcd2int(getChannelByte(Q_CHAN, 2));
  248. }
  249. void PWSubChannel96::point(int p)
  250. {
  251.   assert(type_ == QMODE1TOC);
  252.   setChannelByte(Q_CHAN, 2, bcd(p));
  253. }
  254. void PWSubChannel96::min(int m)
  255. {
  256.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  257.   setChannelByte(Q_CHAN, 3, bcd(m));
  258. }
  259. int PWSubChannel96::min() const
  260. {
  261.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  262.   return bcd2int(getChannelByte(Q_CHAN, 3));
  263. }
  264. void PWSubChannel96::sec(int s)
  265. {
  266.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  267.   setChannelByte(Q_CHAN, 4, bcd(s));
  268. }
  269. int PWSubChannel96::sec() const
  270. {
  271.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  272.   return bcd2int(getChannelByte(Q_CHAN, 4));
  273. }
  274. void PWSubChannel96::frame(int f)
  275. {
  276.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  277.   setChannelByte(Q_CHAN, 5, bcd(f));
  278. }
  279. int PWSubChannel96::frame() const
  280. {
  281.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  282.   return bcd2int(getChannelByte(Q_CHAN, 5));
  283. }
  284. void PWSubChannel96::amin(int am)
  285. {
  286.   assert(type_ == QMODE1DATA);
  287.   setChannelByte(Q_CHAN, 7, bcd(am));
  288. }
  289. int PWSubChannel96::amin() const
  290. {
  291.   assert(type_ == QMODE1DATA);
  292.   return bcd2int(getChannelByte(Q_CHAN, 7));
  293. }
  294. void PWSubChannel96::asec(int as)
  295. {
  296.   assert(type_ == QMODE1DATA);
  297.   setChannelByte(Q_CHAN, 8, bcd(as));
  298. }
  299. int PWSubChannel96::asec() const
  300. {
  301.   assert(type_ == QMODE1DATA);
  302.   return bcd2int(getChannelByte(Q_CHAN, 8));
  303. }
  304. void PWSubChannel96::aframe(int af)
  305. {
  306.   assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
  307.   setChannelByte(Q_CHAN, 9, bcd(af));
  308. }
  309. int PWSubChannel96::aframe() const
  310. {
  311.   assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
  312.   return bcd2int(getChannelByte(Q_CHAN, 9));
  313. }
  314. void PWSubChannel96::pmin(int pm)
  315. {
  316.   assert(type_ == QMODE1TOC);
  317.   setChannelByte(Q_CHAN, 7, bcd(pm));
  318. }
  319. void PWSubChannel96::psec(int ps)
  320. {
  321.   assert(type_ == QMODE1TOC);
  322.   setChannelByte(Q_CHAN, 8, bcd(ps));
  323. }
  324. void PWSubChannel96::pframe(int pf)
  325. {
  326.   assert(type_ == QMODE1TOC);
  327.   setChannelByte(Q_CHAN, 9, bcd(pf));
  328. }
  329. void PWSubChannel96::catalog(char n1, char n2, char n3, char n4, char n5,
  330.      char n6, char n7, char n8, char n9, char n10,
  331.      char n11, char n12, char n13)
  332. {
  333.   assert(type_ == QMODE2);
  334.   unsigned char buf[8];
  335.   int i;
  336.   
  337.   encodeCatalogNumber(buf, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12,
  338.       n13);
  339.   buf[7] = 0;
  340.   for (i = 0; i < 8; i++)
  341.     setChannelByte(Q_CHAN, i + 1, buf[i]);
  342. }
  343. const char *PWSubChannel96::catalog() const
  344. {
  345.   static char buf[14];
  346.   unsigned char in[7];
  347.   int i;
  348.   for (i = 0; i < 7; i++)
  349.     in[i] = getChannelByte(Q_CHAN, i + 1);
  350.   decodeCatalogNumber(in, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
  351.       &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10],
  352.       &buf[11], &buf[12]);
  353.   buf[13] = 0;
  354.   return buf;
  355. }
  356. void PWSubChannel96::isrc(char c1, char c2, char o1, char o2, char o3,
  357.   char y1, char y2, char s1, char s2, char s3,
  358.   char s4, char s5)
  359. {
  360.   assert(type_ == QMODE3);
  361.   unsigned char buf[8];
  362.   int i;
  363.   encodeIsrcCode(buf, c1, c2, o1, o2, o3, y1, y2, s1, s2, s3, s4, s5);
  364.   for (i = 0; i < 8; i++)
  365.     setChannelByte(Q_CHAN, i + 1, buf[i]);
  366. }
  367. const char *PWSubChannel96::isrc() const
  368. {
  369.   static char buf[13];
  370.   unsigned char in[8];
  371.   int i;
  372.   assert(type_ == QMODE3);
  373.   for (i = 0; i < 8; i++)
  374.     in[i] = getChannelByte(Q_CHAN, i + 1);
  375.   decodeIsrcCode(in, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
  376.  &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10], 
  377.  &buf[11]);
  378.   buf[12] = 0;
  379.   return buf;
  380. }
  381. void PWSubChannel96::print() const
  382. {
  383.   if (type_ != QMODE_ILLEGAL) 
  384.     message(0, "P:%02x ", getChannelByte(P_CHAN, 0));
  385.   switch (type_) {
  386.   case QMODE1TOC:
  387.   case QMODE1DATA:
  388.     message(0, "Q: (%02x) %02x,%02x %02x:%02x:%02x %02x %02x:%02x:%02x ", 
  389.    getChannelByte(Q_CHAN, 0), getChannelByte(Q_CHAN, 1),
  390.    getChannelByte(Q_CHAN, 2), getChannelByte(Q_CHAN, 3),
  391.    getChannelByte(Q_CHAN, 4), getChannelByte(Q_CHAN, 5),
  392.    getChannelByte(Q_CHAN, 6), getChannelByte(Q_CHAN, 7),
  393.    getChannelByte(Q_CHAN, 8), getChannelByte(Q_CHAN, 9));
  394.     break;
  395.   case QMODE2:
  396.     message(0, "Q: (%02x) MCN: %s      %02x ", getChannelByte(Q_CHAN, 0),
  397.     catalog(), getChannelByte(Q_CHAN, 9));
  398.     break;
  399.   case QMODE3:
  400.     message(0, "Q: (%02x) ISRC: %s      %02x ", getChannelByte(Q_CHAN, 0),
  401.     isrc(), getChannelByte(Q_CHAN, 9));
  402.     break;
  403.   case QMODE_ILLEGAL:
  404.     message(0, "INVALID QMODE: %02x", getChannelByte(Q_CHAN, 0));
  405.     break;
  406.   }
  407.   if (type_ != QMODE_ILLEGAL) 
  408.     message(0, "%04x %d", 
  409.     (getChannelByte(Q_CHAN, 10) << 8) | getChannelByte(Q_CHAN, 11),
  410.     checkCrc());
  411. }
  412. // sets R-W channel bits from 72 byte data buffer, used for CD-TEXT
  413. void PWSubChannel96::setRawRWdata(const unsigned char *data)
  414. {
  415.   int i;
  416.   for (i = 0; i < 96; i += 4) {
  417.     data_[i]     |= (data[0] >> 2) & 0x3f;
  418.     data_[i + 1] |= ((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0x0f);
  419.     data_[i + 2] |= ((data[1] << 2) & 0x3c) | ((data[2] >> 6) & 0x03);
  420.     data_[i + 3] |= data[2] & 0x3f;
  421.     
  422.     data += 3;
  423.   }
  424. }
  425. // concatenates the R-W channel bits and writes them to provided 72 byte buffer
  426. void PWSubChannel96::getRawRWdata(unsigned char *data) const
  427. {
  428.   int i;
  429.   for (i = 0; i < 96; i += 4) {
  430.     data[0] = ((data_[i] << 2) & 0xfc)     | ((data_[i + 1] >> 4) & 0x03);
  431.     data[1] = ((data_[i + 1] << 4) & 0xf0) | ((data_[i + 2] >> 2) & 0x0f);
  432.     data[2] = ((data_[i + 2] << 6) & 0xc0) | (data_[i + 3] & 0x3f);
  433.     
  434.     data += 3;
  435.   }
  436. }