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

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: PQSubChannel16.cc,v $
  21.  * Revision 1.5  1999/04/05 11:04:48  mueller
  22.  * Added decoding of media catalog number and ISRC code.
  23.  *
  24.  * Revision 1.4  1999/03/27 20:58:55  mueller
  25.  * Added various access functions.
  26.  *
  27.  * Revision 1.3  1998/09/06 13:34:22  mueller
  28.  * Use 'message()' for printing messages.
  29.  *
  30.  * Revision 1.2  1998/08/30 19:10:32  mueller
  31.  * Added handling of Catalog Number and ISRC codes.
  32.  *
  33.  * Revision 1.1  1998/08/29 21:31:36  mueller
  34.  * Initial revision
  35.  *
  36.  *
  37.  */
  38. #include "PQSubChannel16.h"
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <assert.h>
  42. #include "util.h"
  43. PQSubChannel16::PQSubChannel16()
  44. {
  45.   memset(data_, 0, 16);
  46.   type_ = QMODE1DATA;
  47. }
  48. PQSubChannel16::~PQSubChannel16()
  49. {
  50. }
  51. SubChannel *PQSubChannel16::makeSubChannel(Type t)
  52. {
  53.   PQSubChannel16 *chan = new PQSubChannel16;
  54.   chan->type_ = t;
  55.   switch (t) {
  56.   case QMODE1TOC:
  57.   case QMODE1DATA:
  58.     chan->data_[0] = 0x01;
  59.     break;
  60.     
  61.   case QMODE2:
  62.     chan->data_[0] = 0x02;
  63.     break;
  64.   case QMODE3:
  65.     chan->data_[0] = 0x03;
  66.     break;
  67.   case QMODE_ILLEGAL:
  68.     chan->data_[0] = 0x00;
  69.     break;
  70.   }
  71.   return chan;
  72. }
  73. void PQSubChannel16::init(unsigned char *buf)
  74. {
  75.   memcpy(data_, buf, 16);
  76.   switch (data_[0] & 0x0f) {
  77.   case 1:
  78.     type_ = QMODE1DATA;
  79.     break;
  80.     
  81.   case 2:
  82.     type_ = QMODE2;
  83.     break;
  84.     
  85.   case 3:
  86.     type_ = QMODE3;
  87.     break;
  88.   default:
  89.     type_ = QMODE_ILLEGAL;
  90.     break;
  91.   }
  92. }
  93. SubChannel *PQSubChannel16::makeSubChannel(unsigned char *buf)
  94. {
  95.   PQSubChannel16 *chan = new PQSubChannel16;
  96.   chan->init(buf);
  97.   return chan;
  98. }
  99. const unsigned char *PQSubChannel16::data() const
  100. {
  101.   return data_;
  102. }
  103. long PQSubChannel16::dataLength() const
  104. {
  105.   return 16;
  106. }
  107. // calculate the crc over Q sub channel bytes 0-9 and stores it in byte 10,11
  108. void PQSubChannel16::calcCrc()
  109. {
  110.   register unsigned short crc = 0;
  111.   register int i;
  112.   for (i = 0; i < 10; i++) {
  113.     crc = crctab[(crc >> 8) ^ data_[i]] ^ (crc << 8);
  114.   }
  115.   data_[10] = crc >> 8;
  116.   data_[11] = crc;
  117. }
  118. int PQSubChannel16::checkCrc() const
  119. {
  120.   register unsigned short crc = 0;
  121.   register int i;
  122.   if (!crcValid_) {
  123.     return 1;
  124.   }
  125.   for (i = 0; i < 10; i++) {
  126.     crc = crctab[(crc >> 8) ^ data_[i]] ^ (crc << 8);
  127.   }
  128.   if (data_[10] == (crc >> 8) && data_[11] == (crc & 0xff))
  129.     return 1;
  130.   else
  131.     return 0;
  132. }
  133. // set Q type
  134. void PQSubChannel16::type(unsigned char type)
  135. {
  136.   switch (type & 0x0f) {
  137.   case 1:
  138.     type_ = QMODE1DATA;
  139.     break;
  140.     
  141.   case 2:
  142.     type_ = QMODE2;
  143.     break;
  144.     
  145.   case 3:
  146.     type_ = QMODE3;
  147.     break;
  148.   default:
  149.     type_ = QMODE_ILLEGAL;
  150.     break;
  151.   }
  152.   
  153.   data_[0] &= 0xf0;
  154.   data_[0] |= type & 0x0f;
  155. }
  156. // sets P channel bit
  157. void PQSubChannel16::pChannel(int f)
  158. {
  159.   data_[15] = f != 0 ? 0x80 : 0;
  160. }
  161. // function for setting various Q sub channel fields
  162. void PQSubChannel16::ctl(int c)
  163. {
  164.   assert((c & 0x0f) == 0);
  165.   data_[0] &= 0x0f;
  166.   data_[0] |= c & 0xf0;
  167. }
  168. unsigned char PQSubChannel16::ctl() const
  169. {
  170.   return data_[0] >> 4;
  171. }
  172. void PQSubChannel16::trackNr(int t)
  173. {
  174.   assert(type_ == QMODE1DATA);
  175.   data_[1] = bcd(t);
  176. }
  177. int PQSubChannel16::trackNr() const
  178. {
  179.   assert(type_ == QMODE1DATA);
  180.   return bcd2int(data_[1]);
  181. }
  182. void PQSubChannel16::indexNr(int i)
  183. {
  184.   assert(type_ == QMODE1DATA);
  185.   data_[2] = bcd(i);
  186. }
  187. int PQSubChannel16::indexNr() const
  188. {
  189.   assert(type_ == QMODE1DATA);
  190.   return bcd2int(data_[2]);
  191. }
  192. void PQSubChannel16::point(int p)
  193. {
  194.   assert(type_ == QMODE1TOC);
  195.   data_[2] = bcd(p);
  196. }
  197. void PQSubChannel16::min(int m)
  198. {
  199.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  200.   data_[3] = bcd(m);
  201. }
  202. int PQSubChannel16::min() const
  203. {
  204.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  205.   return bcd2int(data_[3]);
  206. }
  207. void PQSubChannel16::sec(int s)
  208. {
  209.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  210.   data_[4] = bcd(s);
  211. }
  212. int PQSubChannel16::sec() const
  213. {
  214.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  215.   return bcd2int(data_[4]);
  216. }
  217. void PQSubChannel16::frame(int f)
  218. {
  219.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  220.   data_[5] = bcd(f);
  221. }
  222. int PQSubChannel16::frame() const
  223. {
  224.   assert(type_ == QMODE1TOC || type_ == QMODE1DATA);
  225.   return bcd2int(data_[5]);
  226. }
  227. void PQSubChannel16::amin(int am)
  228. {
  229.   assert(type_ == QMODE1DATA);
  230.   data_[7] = bcd(am);
  231. }
  232. int PQSubChannel16::amin() const
  233. {
  234.   assert(type_ == QMODE1DATA);
  235.   return bcd2int(data_[7]);
  236. }
  237. void PQSubChannel16::asec(int as)
  238. {
  239.   assert(type_ == QMODE1DATA);
  240.   data_[8] = bcd(as);
  241. }
  242. int PQSubChannel16::asec() const
  243. {
  244.   assert(type_ == QMODE1DATA);
  245.   return bcd2int(data_[8]);
  246. }
  247. void PQSubChannel16::aframe(int af)
  248. {
  249.   assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
  250.   data_[9] = bcd(af);
  251. }
  252. int PQSubChannel16::aframe() const
  253. {
  254.   assert(type_ == QMODE1DATA || type_ == QMODE2 || type_ == QMODE3);
  255.   return bcd2int(data_[9]);
  256. }
  257. void PQSubChannel16::pmin(int pm)
  258. {
  259.   assert(type_ == QMODE1TOC);
  260.   data_[7] = bcd(pm);
  261. }
  262. void PQSubChannel16::psec(int ps)
  263. {
  264.   assert(type_ == QMODE1TOC);
  265.   data_[8] = bcd(ps);
  266. }
  267. void PQSubChannel16::pframe(int pf)
  268. {
  269.   assert(type_ == QMODE1TOC);
  270.   data_[9] = bcd(pf);
  271. }
  272. void PQSubChannel16::catalog(char n1, char n2, char n3, char n4, char n5,
  273.      char n6, char n7, char n8, char n9, char n10,
  274.      char n11, char n12, char n13)
  275. {
  276.   assert(type_ == QMODE2);
  277.   encodeCatalogNumber(data_ + 1, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10,
  278.       n11, n12, n13);
  279.   data_[8] = 0;
  280. }
  281. const char *PQSubChannel16::catalog() const
  282. {
  283.   static char buf[14];
  284.   assert(type_ == QMODE2);
  285.   decodeCatalogNumber(data_ + 1, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
  286.       &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10],
  287.       &buf[11], &buf[12]);
  288.   buf[13] = 0;
  289.   return buf;
  290. }
  291. void PQSubChannel16::isrc(char c1, char c2, char o1, char o2, char o3,
  292.   char y1, char y2, char s1, char s2, char s3,
  293.   char s4, char s5)
  294. {
  295.   assert(type_ == QMODE3);
  296.   encodeIsrcCode(data_ + 1, c1, c2, o1, o2, o3, y1, y2, s1, s2, s3, s4, s5);
  297. }
  298. const char *PQSubChannel16::isrc() const
  299. {
  300.   static char buf[13];
  301.   assert(type_ == QMODE3);
  302.   decodeIsrcCode(data_ + 1, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4],
  303.  &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10], 
  304.  &buf[11]);
  305.   buf[12] = 0;
  306.   return buf;
  307. }
  308. void PQSubChannel16::print() const
  309. {
  310.   if (type_ != QMODE_ILLEGAL) 
  311.     message(0, "P:%02x ", data_[15]);
  312.   switch (type_) {
  313.   case QMODE1TOC:
  314.   case QMODE1DATA:
  315.     message(0, "Q: (%02x) %02x,%02x %02x:%02x:%02x %02x %02x:%02x:%02x ", 
  316.    data_[0], data_[1], data_[2], data_[3], data_[4], data_[5], 
  317.    data_[6], data_[7], data_[8], data_[9]);
  318.     break;
  319.   case QMODE2:
  320.     message(0, "Q: (%02x) MCN: %s      %02x ", data_[0], catalog(), data_[9]);
  321.     break;
  322.   case QMODE3:
  323.     message(0, "Q: (%02x) ISRC: %s      %02x ", data_[0], isrc(), data_[9]);
  324.     break;
  325.   case QMODE_ILLEGAL:
  326.     message(0, "INVALID QMODE: %02x", data_[0]);
  327.     break;
  328.   }
  329.   if (type_ != QMODE_ILLEGAL) 
  330.     message(0, "%04x %d", (data_[10] << 8) | data_[11], checkCrc());
  331. }
  332. int PQSubChannel16::checkConsistency()
  333. {
  334.   switch (type_) {
  335.   case QMODE1DATA:
  336.     if (!isBcd(data_[3]) || !isBcd(data_[4]) || !isBcd(data_[5]) ||
  337. !isBcd(data_[7]) || !isBcd(data_[8]) || !isBcd(data_[9]))
  338.       return 0;
  339.     break;
  340.   }
  341.   return SubChannel::checkConsistency();
  342. }