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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998, 1999  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: Track.cc,v $
  21.  * Revision 1.9  1999/04/05 11:03:01  mueller
  22.  * Added CD-TEXT support.
  23.  *
  24.  * Revision 1.8  1999/04/02 20:36:21  mueller
  25.  * Created implementation class that contains all mutual member data.
  26.  *
  27.  * Revision 1.7  1999/03/27 19:52:26  mueller
  28.  * Added data track support.
  29.  *
  30.  * Revision 1.6  1999/01/10 15:09:47  mueller
  31.  * Fixed bug in sub-track list.
  32.  *
  33.  * Revision 1.5  1998/11/15 12:19:13  mueller
  34.  * Added several functions for manipulating track/index marks.
  35.  *
  36.  * Revision 1.4  1998/09/22 19:17:19  mueller
  37.  * Added seeking to and reading of samples for GUI.
  38.  *
  39.  * Revision 1.3  1998/08/15 17:58:13  mueller
  40.  * Added missing printing of index increment data in 'print()'.
  41.  *
  42.  */
  43. static char rcsid[] = "$Id: Track.cc,v 1.9 1999/04/05 11:03:01 mueller Exp mueller $";
  44. #include <config.h>
  45. #include <stddef.h>
  46. #include <assert.h>
  47. #include <ctype.h>
  48. #include <string.h>
  49. #include "Track.h"
  50. #include "util.h"
  51. #include "TrackDataList.h"
  52. #include "CdTextItem.h"
  53. #include "edc_ecc/ecc.h"
  54. Track::Track(TrackData::Mode t) : length_(0), start_(0), end_(0)
  55. {
  56.   type_ = t;
  57.   nofSubTracks_ = 0;
  58.   subTracks_ = lastSubTrack_ = NULL;
  59.   nofIndices_ = 0;
  60.   index_ = new Msf[98](0);
  61.   isrcValid_ = 0;
  62.   flags_.copy = 0;         // digital copy not permitted
  63.   flags_.preEmphasis = 0;  // no pre-emphasis
  64.   flags_.audioType = 0;    // two channel audio
  65. }
  66. Track::Track(const Track &obj)
  67.   : length_(obj.length_), start_(obj.start_), end_(obj.end_),
  68.     cdtext_(obj.cdtext_)
  69. {
  70.   int i;
  71.   SubTrack *run;
  72.   type_ = obj.type_;
  73.   nofSubTracks_ = obj.nofSubTracks_;
  74.   subTracks_ = lastSubTrack_ = NULL;
  75.   for (run = obj.subTracks_; run != NULL; run = run->next_) {
  76.     if (subTracks_ == NULL) {
  77.       subTracks_ = lastSubTrack_ = new SubTrack(*run);
  78.     }
  79.     else {
  80.       lastSubTrack_->next_ = new SubTrack(*run);
  81.       lastSubTrack_->next_->pred_ = lastSubTrack_;
  82.       lastSubTrack_ = lastSubTrack_->next_;
  83.     }
  84.   }
  85.   nofIndices_ = obj.nofIndices_;
  86.   index_ = new Msf[98](0);
  87.   for (i = 0; i < nofIndices_; i++) {
  88.     index_[i] = obj.index_[i];
  89.   }
  90.   
  91.   isrcValid_ = obj.isrcValid_;
  92.   memcpy(isrcCountry_, obj.isrcCountry_, 2);
  93.   memcpy(isrcOwner_, obj.isrcOwner_, 3);
  94.   memcpy(isrcYear_, obj.isrcYear_, 2);
  95.   memcpy(isrcSerial_, obj.isrcSerial_, 5);
  96.   flags_ = obj.flags_;
  97. }
  98. Track::~Track()
  99. {
  100.   SubTrack *run = subTracks_;
  101.   SubTrack *next = NULL;
  102.   while (run != NULL) {
  103.     next = run->next_;
  104.     delete run;
  105.     run = next;
  106.   }
  107.   delete[] index_;
  108. }
  109. // Returns first sub-track or 'NULL' if no sub-tracks are defined
  110. const SubTrack *Track::firstSubTrack() const
  111. {
  112.   return subTracks_ != NULL ? subTracks_ : NULL;
  113. }
  114. // Returns last sub-track or 'NULL' if no sub-tracks are defined
  115. const SubTrack *Track::lastSubTrack() const
  116. {
  117.   return lastSubTrack_ != NULL ? lastSubTrack_ : NULL;
  118. }
  119. // Appends given sub-track to list of sub-tracks.
  120. // return: 0: OK
  121. //         1: tried to append PAD sub-track
  122. int Track::append(const SubTrack &strack)
  123. {
  124.   if (strack.type() == SubTrack::PAD) {
  125.     return 1;
  126.   }
  127.   if (lastSubTrack_ != NULL && lastSubTrack_->type() == SubTrack::PAD &&
  128.       lastSubTrack_->mode() == strack.mode()) {
  129.     // remove padding sub track
  130.     delete removeSubTrack(lastSubTrack_);
  131.   }
  132.   // append sub track
  133.   insertSubTrackAfter(lastSubTrack_, new SubTrack(strack));
  134.   update();
  135.   return 0;
  136. }
  137. // Traverses all sub-tracks to update summary data of track.
  138. void Track::update()
  139. {
  140.   long lenLba = 0;           // accumulates total length of track in blocks
  141.   unsigned long slength;     // length of track in samples
  142.   unsigned long padLen;      // padding length
  143.   unsigned long blen;        // block length for current data mode
  144.   SubTrack *run, *next;
  145.   SubTrack *pad;
  146.   TrackData::Mode dataMode;
  147.   // remove all padding sub-tracks
  148.   run = subTracks_;
  149.   while (run != NULL) {
  150.     next = run->next_;
  151.     if (run->type() == SubTrack::PAD) {
  152.       delete removeSubTrack(run);
  153.     }
  154.     run = next;
  155.   }
  156.   if ((run = subTracks_) != NULL) {
  157.     do {
  158.       dataMode = run->mode();
  159.       if (run->mode() == TrackData::AUDIO) {
  160. blen = SAMPLES_PER_BLOCK;
  161.       }
  162.       else {
  163. blen = TrackData::dataBlockSize(run->mode());
  164.       }
  165.       slength = 0;
  166.       // find continues range of sub tracks with same data mode
  167.       do {
  168. slength += run->length();
  169. run = run->next_;
  170.       } while (run != NULL && run->mode() == dataMode);
  171.       
  172.       if ((padLen = slength % blen) != 0) {
  173. padLen = blen - padLen;
  174. pad = new SubTrack(SubTrack::PAD, 0, TrackData(dataMode, padLen));
  175. if (run != NULL) {
  176.   insertSubTrackAfter(run->pred_, pad);
  177. }
  178. else {
  179.   insertSubTrackAfter(lastSubTrack_, pad);
  180. }
  181. slength += padLen;
  182.       }
  183.       // at this point 'slength' should be a multiple of 'blen'
  184.       assert(slength % blen == 0);
  185.       lenLba += slength / blen;
  186.     
  187.     } while (run != NULL);
  188.   }
  189.   length_ = Msf(lenLba);
  190.   slength = 0;
  191.   for (run = subTracks_; run != NULL; run = run->next_) {
  192.     run->start(slength); // set start position of sub-track
  193.     slength += run->length();
  194.   }
  195.   // reset 'start_' if necessary
  196.   if (start_.lba() >= length_.lba()) {
  197.     start_ = Msf(0);
  198.   }
  199. }
  200. // Sets logical start of track, everthing before start (if != 0) is taken
  201. // as pre-gap. FIXME: Already set index marks are not updated.
  202. // return: 0: OK
  203. //         1: given start behind track end
  204. int Track::start(Msf s)
  205. {
  206.   if (s.lba() >= length_.lba()) {
  207.     return 1;
  208.   }
  209.   start_ = s;
  210.   return 0;
  211. }
  212. // Sets end of user area of track which is the start of the post-gap. 
  213. // An index entry is created at this point. The pre-gap length must be
  214. // set with 'start()' before this function can be called.
  215. // return: 0: OK
  216. //         1: start of post-gap is behind or at track end
  217. //         2: post-gap within pre-gap
  218. //         3: cannot create index mark, 98 index marks are already defined
  219. int Track::end(Msf e)
  220. {
  221.   if (e.lba() >= length_.lba()) {
  222.     return 1;
  223.   }
  224.   if (e.lba() != 0 && e.lba() <= start_.lba()) {
  225.     return 2;
  226.   }
  227.   if (e.lba() != 0) {
  228.     // add index mark for post-gap
  229.     if (addIndex(Msf(e.lba() - start_.lba())) == 1) {
  230.       // already 98 index increments defined
  231.       return 3;
  232.     }
  233.   }
  234.   end_ = e;
  235.   return 0;
  236. }
  237. // Appends given index to index increment list.
  238. // return: 0: OK
  239. //         1: > 98 index increments 
  240. //         2: index at or beyond track end
  241. //         3: index at start
  242. int Track::appendIndex(const Msf &index)
  243. {
  244.   if (nofIndices_ == 98) {
  245.     return 1;
  246.   }
  247.   if (index.lba() >= (length_ - start_).lba()) {
  248.     return 2;
  249.   }
  250.   if (index.lba() == 0) {
  251.     return 3;
  252.   }
  253.   index_[nofIndices_] = index;
  254.   nofIndices_ += 1;
  255.   return 0;
  256. }
  257. // Adds index at given position
  258. // return: 0: OK
  259. //         1: > 98 index increments 
  260. //         2: cannot add index at specified position
  261. int Track::addIndex(const Msf &index)
  262. {
  263.   int i;
  264.   if (nofIndices_ == 98) {
  265.     return 1;
  266.   }
  267.   if (index.lba() >= (length_ - start_).lba()) {
  268.     return 2;
  269.   }
  270.   if (index.lba() == 0) {
  271.     return 2;
  272.   }
  273.   for (i = 0; i < nofIndices_; i++) {
  274.     if (index.lba() == index_[i].lba())
  275.       return 2;
  276.     if (index.lba() < index_[i].lba())
  277.       break;
  278.   }
  279.   if (i == nofIndices_) {
  280.     // append index
  281.     index_[nofIndices_] = index;
  282.     nofIndices_ += 1; 
  283.   }
  284.   else {
  285.     int pos = i;
  286.     for (i = nofIndices_; i > pos; i--)
  287.       index_[i] = index_[i - 1];
  288.     index_[pos] = index;
  289.     nofIndices_ += 1; 
  290.   }
  291.   
  292.   return 0;
  293. }
  294. // Removes specified index.
  295. // return 0: OK
  296. //        1: index not found
  297. int Track::removeIndex(int index)
  298. {
  299.   int i;
  300.   if (index < 0 || index >= nofIndices_)
  301.     return 1;
  302.   
  303.   for (i = index; i < nofIndices_ - 1; i++)
  304.     index_[i] = index_[i + 1];
  305.   nofIndices_ -= 1;
  306.   return 0;
  307. }
  308. // returns index increment
  309. Msf Track::getIndex(int i) const
  310. {
  311.   if (i >= nofIndices_ || i < 0) {
  312.     return Msf(0);
  313.   }
  314.   else {
  315.     return index_[i];
  316.   }
  317. }
  318. int Track::check() const
  319. {
  320.   SubTrack *st;
  321.   int ret;
  322.   for (st = subTracks_; st != NULL; st = st->next_) {
  323.     if ((ret = st->check()) != 0) {
  324.       return ret;
  325.     }
  326.   }
  327.   return 0;
  328. }
  329. // Sets ISRC code. Expected string: "CCOOOYYSSSSS"
  330. //                 C: country code (ASCII)
  331. //                 O: owner code (ASCII)
  332. //                 Y: year ('0'-'9')
  333. //                 S: serial number ('0'-'9')
  334. // return: 0: OK
  335. //         1: ilegal ISRC string
  336. int Track::isrc(const char *isrc)
  337. {
  338.   int i;
  339.   if (isrc == NULL) {
  340.     isrcValid_ = 0;
  341.     return 0;
  342.   }
  343.   if (strlen(isrc) != 12) {
  344.     return 1;
  345.   }
  346.   for (i=0; i < 5; i++) {
  347.     if (!(isdigit(isrc[i]) || isupper(isrc[i]))) {
  348.       return 1;
  349.     }
  350.   }
  351.   for (i = 5; i < 12; i++) {
  352.     if (!isdigit(isrc[i])) {
  353.       return 1;
  354.     }
  355.   }
  356.   isrcCountry_[0] = isrc[0];
  357.   isrcCountry_[1] = isrc[1];
  358.   isrcOwner_[0] = isrc[2];
  359.   isrcOwner_[1] = isrc[3];
  360.   isrcOwner_[2] = isrc[4];
  361.   // store BCD
  362.   isrcYear_[0] = isrc[5] - '0';
  363.   isrcYear_[1] = isrc[6] - '0';
  364.   
  365.   isrcSerial_[0] = isrc[7] - '0';
  366.   isrcSerial_[1] = isrc[8] - '0';
  367.   isrcSerial_[2] = isrc[9] - '0';
  368.   isrcSerial_[3] = isrc[10] - '0';
  369.   isrcSerial_[4] = isrc[11] - '0';
  370.   
  371.   isrcValid_ = 1;
  372.   return 0;
  373. }
  374. const char *Track::isrc() const
  375. {
  376.   static char buf[13];
  377.   
  378.   if (!isrcValid_)
  379.     return NULL;
  380.   buf[0] = isrcCountry_[0];
  381.   buf[1] = isrcCountry_[1];
  382.   buf[2] = isrcOwner_[0];
  383.   buf[3] = isrcOwner_[1];
  384.   buf[4] = isrcOwner_[2];
  385.   buf[5] = isrcYear_[0] + '0';
  386.   buf[6] = isrcYear_[1] + '0';
  387.   buf[7] = isrcSerial_[0] + '0';
  388.   buf[8] = isrcSerial_[1] + '0';
  389.   buf[9] = isrcSerial_[2] + '0';
  390.   buf[10] = isrcSerial_[3] + '0';
  391.   buf[11] = isrcSerial_[4] + '0';
  392.   buf[12] = 0;
  393.   return buf;
  394. }
  395. int Track::isPadded() const
  396. {
  397.   SubTrack *run;
  398.   for (run = subTracks_; run != NULL; run = run->next_) {
  399.     if (run->type() == SubTrack::PAD)
  400.       return 1;
  401.   }
  402.   return 0;
  403. }
  404. // writes out track data in TOC file syntax
  405. void Track::print(ostream &out) const
  406. {
  407.   SubTrack *st;
  408.   int i;
  409.   out << "TRACK " << TrackData::mode2String(type());
  410.   out << endl;
  411.   if (!copyPermitted())
  412.     out << "NO ";
  413.   out << "COPY" << endl;
  414.   if (type() == TrackData::AUDIO) {
  415.     if (!preEmphasis())
  416.       out << "NO ";
  417.     out << "PRE_EMPHASIS" << endl;
  418.     if (audioType() == 0)
  419.       out << "TWO_CHANNEL_AUDIO" << endl;
  420.     else
  421.       out << "FOUR_CHANNEL_AUDIO" << endl;
  422.   
  423.     if (isrcValid()) {
  424.       out << "ISRC "" << isrcCountry(0) << isrcCountry(1)
  425.   << isrcOwner(0) << isrcOwner(1) << isrcOwner(2)
  426.   << (char)(isrcYear(0) + '0') << (char)(isrcYear(1) + '0')
  427.   << (char)(isrcSerial(0) + '0') << (char)(isrcSerial(1) + '0')
  428.   << (char)(isrcSerial(2) + '0') << (char)(isrcSerial(3) + '0')
  429.   << (char)(isrcSerial(4) + '0') << """ << endl;
  430.     }
  431.     cdtext_.print(1, out);
  432.   }
  433.   for (st = subTracks_; st != NULL; st = st->next_) {
  434.     st->print(out);
  435.   }
  436.   if (start_.lba() != 0) {
  437.     out << "START " << start_.str() << endl;
  438.   }
  439.   for (i = 0; i < nofIndices_; i++) {
  440.     out << "INDEX " << index_[i].str() << endl;
  441.   }
  442. }
  443. // Locates 'SubTrack' that contains specified sample.
  444. // return: found 'SubTrack' or 'NULL' if given sample is out of range
  445. SubTrack *Track::findSubTrack(unsigned long sample) const
  446. {
  447.   SubTrack *run;
  448.   if (sample >= length_.samples()) 
  449.     return NULL;
  450.   for (run = subTracks_;
  451.        run != NULL && run->next_ != NULL;
  452.        run = run->next_) {
  453.     if (sample < run->next_->start())
  454.       return run;
  455.   }
  456.   return run;
  457. }
  458. void Track::countSubTracks()
  459. {
  460.   SubTrack *run;
  461.   nofSubTracks_ = 0;
  462.   for (run = subTracks_; run != NULL; run = run->next_)
  463.     nofSubTracks_++;
  464. }
  465. // move track start or index increment within track range
  466. // return: 0: OK
  467. //         1: track length would be shorter than 4 seconds
  468. //         2: cannot cross index boundary
  469. int Track::moveIndex(int index, long lba)
  470. {
  471.   int i;
  472.   long rangeMin;
  473.   long rangeMax;
  474.   assert(index > 0 && index - 2 < nofIndices_);
  475.   assert(lba >= 0 && index < length_.lba());
  476.   if (index == 1) {
  477.     if (nofIndices_ > 0 && lba >= start_.lba() + getIndex(0).lba())
  478.       return 2;
  479.     if (lba > length_.lba() - 4 * 75)
  480.       return 1;
  481.     // adjust index increments to new track start
  482.     for (i = 0; i < nofIndices_; i++) {
  483.       index_[i] = Msf(index_[i].lba() + start_.lba() - lba);
  484.     }
  485.     start_ = Msf(lba);
  486.     return 0;
  487.   }
  488.   // adjust 'index' for index array access
  489.   index -= 2;
  490.   if (lba <= start_.lba())
  491.     return 2;
  492.   lba -= start_.lba();
  493.   rangeMin = (index == 0 ? 0 : index_[index - 1].lba());
  494.   rangeMax =
  495.     (index == nofIndices_ - 1 ? length_.lba() - start_.lba() :
  496.                                 index_[index + 1].lba());
  497.   if (lba > rangeMin && lba < rangeMax) {
  498.     index_[index] = Msf(lba);
  499.     return 0;
  500.   }
  501.   return 2;
  502. }
  503. TrackDataList *Track::removeToEnd(unsigned long sample)
  504. {
  505.   SubTrack *strun;
  506.   SubTrack *store;
  507.   int i;
  508.   assert(sample > 0 && sample < length_.samples());
  509.   strun = findSubTrack(sample);
  510.   assert(strun != NULL);
  511.   TrackDataList *list = new TrackDataList;
  512.   if (sample == strun->start()) {
  513.     // we don't have to split the TrackData object
  514.     list->append(new TrackData(*strun));
  515.     // cannot be the first SubTrack because 'sample' > 0
  516.     strun->pred_->next_ = NULL;
  517.     lastSubTrack_ = strun->pred_;
  518.     
  519.     store = strun;
  520.     strun = strun->next_;
  521.     delete store;
  522.   }
  523.   else {
  524.     // split audio data object
  525.     TrackData *part1, *part2;
  526.     strun->split(sample - strun->start(), &part1, &part2);
  527.     list->append(part2);
  528.     store = new SubTrack(strun->type(), *part1);
  529.     delete part1;
  530.     if (strun->pred_ == NULL) {
  531.       subTracks_ = store;
  532.     }
  533.     else {
  534.       strun->pred_->next_ = store;
  535.       store->pred_ = strun->pred_;
  536.     }
  537.     lastSubTrack_ = store;
  538.     
  539.     store = strun;
  540.     strun = strun->next_;
  541.     delete store;
  542.   }
  543.   
  544.   while (strun != NULL) {
  545.     list->append(new TrackData(*strun));
  546.     store = strun;
  547.     strun = strun->next_;
  548.     delete store;
  549.   }
  550.   countSubTracks();
  551.   update();
  552.   checkConsistency();
  553.   // adjust index increments
  554.   for (i = 0; i < nofIndices_; i++) {
  555.     if (index_[i].lba() + start_.lba() >= length_.lba()) {
  556.       nofIndices_ = i;
  557.       break;
  558.     }
  559.   }
  560.   return list;
  561. }
  562. TrackDataList *Track::removeFromStart(unsigned long sample)
  563. {
  564.   SubTrack *strun;
  565.   SubTrack *store, *start;
  566.   int i;
  567.   assert(sample > 0 && sample < length_.samples());
  568.   TrackDataList *list = new TrackDataList;
  569.   for (strun = subTracks_;
  570.        strun != NULL && strun->next_ != NULL;
  571.        strun = strun->next_) {
  572.     if (sample < strun->next_->start())
  573.       break;
  574.     else
  575.       list->append(new TrackData(*strun));
  576.   }
  577.   assert(strun != NULL);
  578.   start = subTracks_;
  579.   if (sample == strun->start()) {
  580.     // we don't have to split the TrackData object
  581.     // cannot be the first SubTrack because 'sample' > 0
  582.     strun->pred_->next_ = NULL;
  583.     subTracks_ = strun;
  584.     subTracks_->pred_ = NULL;
  585.   }
  586.   else {
  587.     // split actual sub track
  588.     TrackData *part1, *part2;
  589.     strun->split(sample - strun->start(), &part1, &part2);
  590.     
  591.     list->append(part1);
  592.     store = new SubTrack(strun->type(), *part2);
  593.     delete part2;
  594.     store->next_ = strun->next_;
  595.     if (store->next_ != NULL)
  596.       store->next_->pred_ = store;
  597.     strun->next_ = NULL;
  598.     subTracks_ = store;
  599.     if (strun == lastSubTrack_)
  600.       lastSubTrack_ = store;
  601.   }
  602.   // remove unlinked sub tracks
  603.   while (start != NULL) {
  604.     store = start;
  605.     start = start->next_;
  606.     delete store;
  607.   }
  608.   
  609.   countSubTracks();
  610.   update();
  611.   checkConsistency();
  612.   // adjust index increments
  613.   for (i = 0; i < nofIndices_; i++) {
  614.     if (index_[i].lba() + start_.lba() >= length_.lba()) {
  615.       nofIndices_ = i;
  616.       break;
  617.     }
  618.   }
  619.   return list;
  620. }
  621.   
  622. void Track::prependTrackData(const TrackDataList *list)
  623. {
  624.   SubTrack *start = NULL;
  625.   SubTrack *last = NULL;
  626.   SubTrack *ent;
  627.   const TrackData *run;
  628.   if (list->count() == 0)
  629.     return;
  630.   for (run = list->first(); run != NULL; run = list->next()) {
  631.     ent = new SubTrack(SubTrack::DATA, *run);
  632.     if (last == NULL) {
  633.       start = ent;
  634.     }
  635.     else {
  636.       last->next_ = ent;
  637.       ent->pred_ = last;
  638.     }
  639.     last = ent;
  640.   }
  641.   if (subTracks_ == NULL) {
  642.     subTracks_ = start;
  643.     lastSubTrack_ = last;
  644.   }
  645.   else {
  646.     last->next_ = subTracks_;
  647.     subTracks_->pred_ = last;
  648.     subTracks_ = start;
  649.   }
  650.   mergeSubTracks(); // this will also update the sub track counter
  651.   update();
  652.   checkConsistency();
  653. }
  654. void Track::appendTrackData(const TrackDataList *list)
  655. {
  656.   SubTrack *start = NULL;
  657.   SubTrack *last = NULL;
  658.   SubTrack *ent;
  659.   const TrackData *run;
  660.   if (list->count() == 0)
  661.     return;
  662.   for (run = list->first(); run != NULL; run = list->next()) {
  663.     ent = new SubTrack(SubTrack::DATA, *run);
  664.     if (last == NULL) {
  665.       start = ent;
  666.     }
  667.     else {
  668.       last->next_ = ent;
  669.       ent->pred_ = last;
  670.     }
  671.     last = ent;
  672.   }
  673.   if (lastSubTrack_ != NULL) {
  674.     if (lastSubTrack_->type() == SubTrack::PAD)
  675.       lastSubTrack_->type_ = SubTrack::DATA;
  676.     lastSubTrack_->next_ = start;
  677.     start->pred_ = lastSubTrack_;
  678.     lastSubTrack_ = last;
  679.   }
  680.   else {
  681.     subTracks_ = start;
  682.     lastSubTrack_ = last;
  683.   }
  684.   mergeSubTracks(); // this will also update the sub track counter
  685.   update();
  686.   checkConsistency();
  687. }  
  688. void Track::appendTrackData(const Track *track)
  689. {
  690.   SubTrack *run, *ent;
  691.   for (run = track->subTracks_; run != NULL; run = run->next_) {
  692.     ent = new SubTrack(*run);
  693.     if (lastSubTrack_ == NULL) {
  694.       subTracks_ = ent;
  695.     }
  696.     else {
  697.       lastSubTrack_->next_ = ent;
  698.       ent->pred_ = lastSubTrack_;
  699.     }
  700.     lastSubTrack_ = ent;
  701.   }
  702.   mergeSubTracks(); // this will also update the sub track counter
  703.   update();
  704.   checkConsistency();
  705. }
  706. TrackDataList *Track::removeTrackData(unsigned long start, unsigned long end)
  707. {
  708.   SubTrack *run;
  709.   TrackData *part1, *part2, *part3;
  710.   unsigned long plen;
  711.   if (start > end || end >= length_.samples())
  712.     return NULL;
  713.   SubTrack *startSt = findSubTrack(start);
  714.   SubTrack *endSt = findSubTrack(end);
  715.   assert(startSt != NULL);
  716.   assert(endSt != NULL);
  717.   TrackDataList *list = new TrackDataList;
  718.   if (startSt == endSt) {
  719.     if (start == startSt->start() &&
  720. end == startSt->start() + startSt->length() - 1) {
  721.       // remove complete sub track
  722.       list->append(new TrackData(*startSt));
  723.     }
  724.     else if (start == startSt->start()) {
  725.       // remove first part of sub track
  726.       startSt->split(end + 1 - startSt->start(), &part1, &part2);
  727.       list->append(part1);
  728.       insertSubTrackAfter(startSt, new SubTrack(startSt->type(), *part2));
  729.       delete part2;
  730.     }
  731.     else if (end == startSt->start() + startSt->length() - 1) {
  732.       // remove last part of sub track
  733.       startSt->split(start - startSt->start(), &part1, &part2);
  734.       list->append(part2);
  735.       insertSubTrackAfter(startSt, new SubTrack(startSt->type(), *part1));
  736.       delete part1;
  737.     }
  738.     else {
  739.       // remove middle part of sub track
  740.       startSt->split(start - startSt->start(), &part1, &part2);
  741.       insertSubTrackAfter(startSt->pred_,
  742.   new SubTrack(startSt->type(), *part1));
  743.       plen = part1->length();
  744.       delete part1;
  745.       part2->split(end + 1 - startSt->start() - plen, &part1, &part3);
  746.       list->append(part1);
  747.       insertSubTrackAfter(startSt, new SubTrack(startSt->type(), *part3));
  748.       delete part3;
  749.       delete part2;
  750.     }
  751.     delete removeSubTrack(startSt);
  752.   }
  753.   else {
  754.     if (start == startSt->start()) {
  755.       // remove complete sub track
  756.       list->append(new TrackData(*startSt));
  757.     }
  758.     else {
  759.       startSt->split(start - startSt->start(), &part1, &part2);
  760.       list->append(part2);
  761.       insertSubTrackAfter(startSt->pred_,
  762.   new SubTrack(startSt->type(), *part1));
  763.       delete part1;
  764.     }
  765.     for (run = startSt->next_; run != endSt; run = run->next_)
  766.       list->append(new TrackData(*(startSt->next_)));
  767.     if (end == endSt->start() + endSt->length() - 1) {
  768.       // remove complete sub track
  769.       list->append(new TrackData(*endSt));
  770.     }
  771.     else {
  772.       endSt->split(end + 1 - endSt->start(), &part1, &part2);
  773.       list->append(part1);
  774.       insertSubTrackAfter(endSt, new SubTrack(endSt->type(), *part2));
  775.       delete part2;
  776.     }
  777.     while (startSt->next_ != endSt)
  778.       delete removeSubTrack(startSt->next_);
  779.     delete removeSubTrack(startSt);
  780.     delete removeSubTrack(endSt);
  781.   }
  782.   // adjust index marks
  783.   unsigned long len;
  784.   long preGapAdj = 0;
  785.   long slba = 0;
  786.   long elba = 0;
  787.   long indexMove = 0;
  788.   long indexAdj = 0;
  789.   int i;
  790.   if (start < start_.samples()) {
  791.     if (end < start_.samples()) {
  792.       len = end - start + 1;
  793.       slba = -1;
  794.       elba = -1;
  795.     }
  796.     else {
  797.       len = start_.samples() - start;
  798.       elba = (end - start_.samples()) / SAMPLES_PER_BLOCK;
  799.       slba = 0;
  800.       indexMove = (end - start_.samples() + 1) / SAMPLES_PER_BLOCK;
  801.       if (((end - start_.samples() + 1) % SAMPLES_PER_BLOCK) != 0) 
  802. indexMove += 1;
  803.     }
  804.     preGapAdj = len / SAMPLES_PER_BLOCK;
  805.     if ((len % SAMPLES_PER_BLOCK) != 0)
  806.       indexAdj = 1;
  807.   }
  808.   else {
  809.     slba = (start - start_.samples()) / SAMPLES_PER_BLOCK;
  810.     if (((start - start_.samples()) % SAMPLES_PER_BLOCK) != 0)
  811.       slba += 1;
  812.     elba = (end - start_.samples()) / SAMPLES_PER_BLOCK;
  813.     indexMove = (end - start + 1) / SAMPLES_PER_BLOCK;
  814.     if (((end - start + 1) % SAMPLES_PER_BLOCK) != 0)
  815.       indexMove += 1;
  816.   }
  817.   
  818.   i = 0;
  819.   while (i < nofIndices_) {
  820.     if (index_[i].lba() >= slba && index_[i].lba() <= elba) {
  821.       removeIndex(i);
  822.       continue;
  823.     }
  824.     else if (index_[i].lba() > elba) {
  825.       if (index_[i].lba() - indexMove <= 0) {
  826. removeIndex(i);
  827. continue;
  828.       }
  829.       else {
  830. index_[i] = Msf(index_[i].lba() - indexMove);
  831.       }
  832.       if (i > 0 && index_[i - 1].lba() == index_[i].lba()) {
  833. removeIndex(i);
  834. continue;
  835.       }
  836.     }
  837.     if (index_[i].lba() - indexAdj <= 0) {
  838.       removeIndex(i);
  839.       continue;
  840.     }
  841.     else {
  842.       index_[i] = Msf(index_[i].lba() - indexAdj);
  843.     }
  844.     i++;
  845.   }
  846.   // adjust pre-gap length
  847.   start_ = Msf(start_.lba() - preGapAdj);
  848.   
  849.   mergeSubTracks(); // this will also update the sub track counter
  850.   update();
  851.   checkConsistency();
  852.   return list;
  853. }
  854. void Track::insertTrackData(unsigned long pos, const TrackDataList *list)
  855. {
  856.   const TrackData *run;
  857.   TrackData *part1, *part2;
  858.   SubTrack *st;
  859.   unsigned long len;
  860.   long blen;
  861.   int i;
  862.   if (list == NULL || list->first() == NULL || list->length() == 0)
  863.     return;
  864.   if (pos >= length_.samples()) {
  865.     // append data
  866.     for (run = list->first(); run != NULL; run = list->next()) {
  867.       insertSubTrackAfter(lastSubTrack_, new SubTrack(SubTrack::DATA, *run));
  868.     }
  869.   }
  870.   else {
  871.     st = findSubTrack(pos);
  872.     assert(st != NULL);
  873.     len = list->length();
  874.     if (pos == st->start()) {
  875.       for (run = list->first(); run != NULL; run = list->next()) {
  876. insertSubTrackAfter(st->pred_, new SubTrack(SubTrack::DATA, *run));
  877.       }
  878.     }
  879.     else {
  880.       st->split(pos - st->start(), &part1, &part2);
  881.       
  882.       insertSubTrackAfter(st->pred_, new SubTrack(SubTrack::DATA, *part1));
  883.       insertSubTrackAfter(st, new SubTrack(st->type(), *part2));
  884.       delete part1;
  885.       delete part2;
  886.       
  887.       for (run = list->first(); run != NULL; run = list->next()) {
  888. insertSubTrackAfter(st->pred_, new SubTrack(SubTrack::DATA, *run));
  889.       }
  890.       
  891.       delete removeSubTrack(st);
  892.     }
  893.     blen = len / SAMPLES_PER_BLOCK;
  894.     if (pos <= start_.samples()) {
  895.       start_ = Msf(start_.lba() + blen);
  896.     }
  897.     else {
  898.       for (i = 0; i < nofIndices_; i++) {
  899. if (index_[i].samples() >= pos)
  900.   index_[i] = Msf(index_[i].lba() + blen);
  901.       }
  902.     }
  903.   }
  904.   mergeSubTracks(); // this will also update the sub track counter
  905.   update();
  906.   checkConsistency();
  907.   return;
  908. }
  909.     
  910. void Track::mergeSubTracks()
  911. {
  912.   SubTrack *run = subTracks_;
  913.   SubTrack *newSubTrack;
  914.   TrackData *mergedData;
  915.   while (run != NULL && run->next_ != NULL) {
  916.     if (run->type() == run->next_->type() &&
  917. (mergedData = run->merge(run->next_)) != NULL) {
  918.       newSubTrack = new SubTrack(run->type(), *mergedData);
  919.       delete mergedData;
  920.       newSubTrack->next_ =  run->next_->next_;
  921.       if (newSubTrack->next_ != NULL)
  922. newSubTrack->next_->pred_ = newSubTrack;
  923.       if (run->pred_ == NULL) {
  924. subTracks_ = newSubTrack;
  925.       }
  926.       else {
  927. run->pred_->next_ = newSubTrack;
  928. newSubTrack->pred_ = run->pred_;
  929.       }
  930.       if (run->next_ == lastSubTrack_)
  931. lastSubTrack_ = newSubTrack;
  932.       delete run->next_;
  933.       delete run;
  934.       run = newSubTrack;
  935.     }
  936.     else {
  937.       run = run->next_;
  938.     }
  939.   }
  940.   countSubTracks();
  941. }
  942. void Track::checkConsistency()
  943. {
  944.   SubTrack *run, *last = NULL;
  945.   long cnt = 0;
  946.   for (run = subTracks_; run != NULL; last = run, run = run->next_) {
  947.     cnt++;
  948.     if (run->pred_ != last) 
  949.       message(-3, "Track::checkConsistency: wrong pred pointer.");
  950.   }
  951.   if (last != lastSubTrack_)
  952.     message(-3, "Track::checkConsistency: wrong last pointer.");
  953.   if (cnt != nofSubTracks_)
  954.     message(-3, "Track::checkConsistency: wrong sub track counter.");
  955. }
  956. // Inserts 'newSubTrack' after existing sub track 'subTrack'. If 'subTrack'
  957. // is NULL it will be prepended.
  958. void Track::insertSubTrackAfter(SubTrack *subTrack, SubTrack *newSubTrack)
  959. {
  960.   if (subTrack == NULL) {
  961.     if (subTracks_ == NULL) {
  962.       subTracks_ = lastSubTrack_ = newSubTrack;
  963.       newSubTrack->next_ = newSubTrack->pred_ = NULL;
  964.     }
  965.     else {
  966.       newSubTrack->next_ = subTracks_;
  967.       subTracks_->pred_ = newSubTrack;
  968.       newSubTrack->pred_ = NULL;
  969.       subTracks_ = newSubTrack;
  970.     }
  971.   }
  972.   else {
  973.     newSubTrack->next_ = subTrack->next_;
  974.     if (newSubTrack->next_ != NULL) {
  975.       newSubTrack->next_->pred_ = newSubTrack;
  976.     }
  977.     else {
  978.       lastSubTrack_ = newSubTrack;
  979.     }
  980.     subTrack->next_ = newSubTrack;
  981.     newSubTrack->pred_ = subTrack;
  982.   }
  983.   nofSubTracks_ += 1;
  984.   checkConsistency();
  985. }
  986. // Removes given sub track from list. Returns the removed sub track.
  987. SubTrack *Track::removeSubTrack(SubTrack *subTrack)
  988. {
  989.   if (subTrack->pred_ == NULL) {
  990.     assert(subTrack == subTracks_);
  991.     subTracks_ = subTrack->next_;
  992.     if (subTracks_ != NULL) {
  993.       subTracks_->pred_ = NULL;
  994.     }
  995.     else {
  996.       lastSubTrack_ = NULL;
  997.     }
  998.   }
  999.   else {
  1000.     subTrack->pred_->next_ = subTrack->next_;
  1001.     if (subTrack->next_ != NULL) {
  1002.       subTrack->next_->pred_ = subTrack->pred_;
  1003.     }
  1004.     else {
  1005.       lastSubTrack_ = subTrack->pred_;
  1006.     }
  1007.   }
  1008.   nofSubTracks_ -= 1;
  1009.   subTrack->next_ = subTrack->pred_ = NULL;
  1010.   checkConsistency();
  1011.   return subTrack;
  1012. }
  1013. // Fills provided buffer with an audio block that contains zero data
  1014. // encoded with given mode.
  1015. // encMode: encoding mode, see 'Track::readBlock()'
  1016. // mode: sector mode
  1017. // lba : absolute address of sector
  1018. // buf : caller provided buffer that is filled with 2352 bytes
  1019. void Track::encodeZeroData(int encMode, TrackData::Mode mode, long lba,
  1020.    char *buf)
  1021. {
  1022.   if (encMode == 0) {
  1023.     memset(buf, 0, AUDIO_BLOCK_LEN);
  1024.     switch (mode) {
  1025.     case TrackData::AUDIO:
  1026.       break;
  1027.     case TrackData::MODE0:
  1028.       do_encode_L2((unsigned char *)buf, MODE_0, lba);
  1029.       scramble_L2((unsigned char *)buf);
  1030.       break;
  1031.     case TrackData::MODE1:
  1032.     case TrackData::MODE1_RAW:
  1033.       do_encode_L2((unsigned char *)buf, MODE_1, lba);
  1034.       scramble_L2((unsigned char *)buf);
  1035.       break;
  1036.     case TrackData::MODE2:
  1037.     case TrackData::MODE2_RAW:
  1038.       do_encode_L2((unsigned char *)buf, MODE_2, lba);
  1039.       scramble_L2((unsigned char *)buf);
  1040.       break;
  1041.     case TrackData::MODE2_FORM1:
  1042.     case TrackData::MODE2_FORM_MIX: // encode as form 1
  1043.       do_encode_L2((unsigned char *)buf, MODE_2_FORM_1, lba);
  1044.       scramble_L2((unsigned char *)buf);
  1045.       break;
  1046.     case TrackData::MODE2_FORM2:
  1047.       // setup sub header
  1048.       buf[16+2] = 0x20;
  1049.       buf[16+6] = 0x20;
  1050.       do_encode_L2((unsigned char *)buf, MODE_2_FORM_2, lba);
  1051.       scramble_L2((unsigned char *)buf);
  1052.       break;
  1053.     }
  1054.   }
  1055.   else if (encMode == 1) {
  1056.     switch (mode) {
  1057.     case TrackData::AUDIO:
  1058.       memset(buf, 0, AUDIO_BLOCK_LEN);
  1059.       break;
  1060.     case TrackData::MODE0:
  1061.       memset(buf, 0, MODE0_BLOCK_LEN);
  1062.       break;
  1063.     case TrackData::MODE1:
  1064.     case TrackData::MODE1_RAW:
  1065.       memset(buf, 0, MODE1_BLOCK_LEN);
  1066.       break;
  1067.     case TrackData::MODE2:
  1068.     case TrackData::MODE2_RAW:
  1069.     case TrackData::MODE2_FORM_MIX:
  1070.       memset(buf, 0, MODE2_BLOCK_LEN);
  1071.       break;
  1072.     case TrackData::MODE2_FORM1:
  1073.       memset(buf, 0, MODE2_BLOCK_LEN);
  1074.       break;
  1075.     case TrackData::MODE2_FORM2:
  1076.       memset(buf, 0, MODE2_BLOCK_LEN);
  1077.       // setup sub header
  1078.       buf[2] = 0x20;
  1079.       buf[6] = 0x20;
  1080.       break;
  1081.     }
  1082.   }
  1083.   else {
  1084.     message(-3, "Illegal encoding mode in 'Track::encodeZeroData()'.");
  1085.   }
  1086. }
  1087. void Track::addCdTextItem(CdTextItem *item)
  1088. {
  1089.   assert(CdTextItem::isTrackPack(item->packType()));
  1090.   cdtext_.add(item);
  1091. }
  1092. void Track::removeCdTextItem(CdTextItem::PackType type, int blockNr)
  1093. {
  1094.   cdtext_.remove(type, blockNr);
  1095. }
  1096. TrackReader::TrackReader(const Track *t) : reader(NULL)
  1097. {
  1098.   track_ = t;
  1099.   readPos_ = 0;
  1100.   readPosSample_ = 0;
  1101.   readSubTrack_ = NULL;
  1102.   open_ = 0;
  1103. }
  1104. TrackReader::~TrackReader()
  1105. {
  1106.   if (open_) {
  1107.     closeData();
  1108.   }
  1109.   track_ = NULL;
  1110.   readSubTrack_ = NULL;
  1111. }
  1112. void TrackReader::init(const Track *t)
  1113. {
  1114.   if (open_) {
  1115.     closeData();
  1116.   }
  1117.   track_ = t;
  1118.   readSubTrack_ = NULL;
  1119. }  
  1120. // initiates reading track
  1121. // return: 0: OK
  1122. //         1: data file could not be opened
  1123. //         2: could not seek to start position
  1124. int TrackReader::openData()
  1125. {
  1126.   assert(open_ == 0);
  1127.   assert(track_ != NULL);
  1128.   int ret = 0;
  1129.   open_ = 1;
  1130.   readPos_ = 0;
  1131.   readPosSample_ = 0;
  1132.   readSubTrack_ = track_->subTracks_;
  1133.   reader.init(readSubTrack_);
  1134.   if (readSubTrack_ != NULL) {
  1135.     ret = reader.openData();
  1136.   }
  1137.   return ret;
  1138. }
  1139. void TrackReader::closeData()
  1140. {
  1141.   if (open_) {
  1142.     open_ = 0;
  1143.     readPos_ = 0;
  1144.     readPosSample_ = 0;
  1145.     readSubTrack_ = NULL;
  1146.   
  1147.     reader.closeData();
  1148.   }
  1149. }
  1150. long TrackReader::readData(int encodingMode, long lba, char *buf, long len)
  1151. {
  1152.   long err = 0;
  1153.   long b;
  1154.   long offset; 
  1155.   assert(open_ != 0);
  1156.   if (readPos_ + len > track_->length_.lba()) {
  1157.     if ((len = track_->length_.lba() - readPos_) <= 0) {
  1158.       return 0;
  1159.     }
  1160.   }
  1161.   for (b = 0; b < len; b++) {
  1162.     if ((offset = readBlock(encodingMode, lba, (Sample*)buf)) == 0) {
  1163.       err = 1;
  1164.       break;
  1165.     }
  1166.     buf += offset;
  1167.     lba++;
  1168.   }
  1169.   readPos_ += b;
  1170.   return err == 0 ? b : -1;
  1171. }
  1172. // Reads one block from sub-tracks and performs the data encoding for the
  1173. // block.
  1174. // encodingMode: conrols how the data is encoded
  1175. //               0: returned data is always an audio block (2352 bytes),
  1176. //                  data blocks are completely encoded
  1177. //               1: data is returned mostly unencoded, the block size
  1178. //                  depends on the actual sub-track mode, MODE2_FORM1 and
  1179. //                  MODE2_FORM2 blocks are extended by the sub header and
  1180. //                  filled with 0 bytes to match the MODE2 block size
  1181. //                  (2336 bytes).
  1182. // lba: Logical block address that must be encoded into header of data blocks
  1183. // Return: 0 if error occured, else length of block that has been filled
  1184. //         
  1185. int TrackReader::readBlock(int encodingMode, long lba, Sample *buf)
  1186. {
  1187.   TrackData::Mode dataMode; // actual data mode of sub-track
  1188.   long actLen;
  1189.   long count; // amount of data the must be read from sub track
  1190.   long nread = 0;
  1191.   long offset = 0; // block length of returned data
  1192.   while (reader.readLeft() == 0) {
  1193.     // skip to next sub track with available data
  1194.     readSubTrack_ = readSubTrack_->next_;
  1195.     // next sub-track must exist since requested length matches available data
  1196.     assert(readSubTrack_ != NULL); 
  1197.     reader.init(readSubTrack_);
  1198.     if (reader.openData() != 0) {
  1199.       return 0;
  1200.     }
  1201.   }
  1202.   dataMode = readSubTrack_->mode(); // actual data mode
  1203.   if (dataMode == TrackData::AUDIO)
  1204.     count = SAMPLES_PER_BLOCK;
  1205.   else
  1206.     count = TrackData::dataBlockSize(dataMode);
  1207.   char *dataBuf = (char *)buf;
  1208.   if (encodingMode == 0) {
  1209.     offset = AUDIO_BLOCK_LEN;
  1210.     switch (dataMode) {
  1211.     case TrackData::AUDIO:
  1212.     case TrackData::MODE1_RAW:
  1213.     case TrackData::MODE2_RAW:
  1214.       break;
  1215.     case TrackData::MODE0:
  1216.     case TrackData::MODE1:
  1217.     case TrackData::MODE2:
  1218.     case TrackData::MODE2_FORM_MIX:
  1219.       dataBuf += 16;
  1220.       break;
  1221.     case TrackData::MODE2_FORM1:
  1222.       memset(dataBuf + 16, 0, 8); // clear sub-header
  1223.       dataBuf += 24;
  1224.       break;
  1225.     case TrackData::MODE2_FORM2:
  1226.       memset(dataBuf + 16, 0, 8); // clear sub-header
  1227.       dataBuf[16+2] = 0x20;
  1228.       dataBuf[16+6] = 0x20;
  1229.       dataBuf += 24;
  1230.       break;
  1231.     }
  1232.   }
  1233.   else if (encodingMode == 1) {
  1234.     switch (dataMode) {
  1235.     case TrackData::AUDIO:
  1236.       offset = AUDIO_BLOCK_LEN;
  1237.       break;
  1238.     case TrackData::MODE0:
  1239.       offset = MODE0_BLOCK_LEN;
  1240.       break;
  1241.     case TrackData::MODE1:
  1242.       offset = MODE1_BLOCK_LEN;
  1243.       break;
  1244.     case TrackData::MODE1_RAW:
  1245.       offset = MODE1_BLOCK_LEN;
  1246.       break;
  1247.     case TrackData::MODE2:
  1248.     case TrackData::MODE2_FORM_MIX:
  1249.       offset = MODE2_BLOCK_LEN;
  1250.       break;
  1251.     case TrackData::MODE2_FORM1:
  1252.     case TrackData::MODE2_FORM2:
  1253.       offset = MODE2_BLOCK_LEN;
  1254.       memset(dataBuf, 0, MODE2_BLOCK_LEN);
  1255.       dataBuf += 8; // reserve space for sub-header
  1256.       break;
  1257.     case TrackData::MODE2_RAW:
  1258.       offset = MODE2_BLOCK_LEN;
  1259.       break;
  1260.     }
  1261.   }
  1262.   // gather one block of data, block length depends on 'dataMode'
  1263.   while (count > 0) {
  1264.     if (dataMode == TrackData::AUDIO)
  1265.       actLen = reader.readData(buf + nread, count);
  1266.     else 
  1267.       actLen = reader.readData((Sample *)(dataBuf + nread), count);
  1268.     if (actLen < 0) // indicates read error
  1269.       return 0;
  1270.     if (actLen != count) {
  1271.       // end of data in sub-track reached, skip to next sub-track
  1272.       readSubTrack_ = readSubTrack_->next_;
  1273.       // next sub-track must exist since requested length match available data
  1274.       assert(readSubTrack_ != NULL); 
  1275.       // mode of next sub-track must match 'dataMode', this is ensured
  1276.       // in 'update()'.
  1277.       assert(readSubTrack_->mode() == dataMode);
  1278.       reader.init(readSubTrack_);
  1279.       if (reader.openData() != 0) {
  1280. return 0;
  1281.       }
  1282.     }
  1283.     count -= actLen;
  1284.     nread += actLen;
  1285.   }
  1286.   unsigned char *encBuf = (unsigned char *)buf;
  1287.   if (encodingMode == 0) {
  1288.     // encode data block according to 'dataMode'
  1289.     switch (dataMode) {
  1290.     case TrackData::AUDIO:
  1291.       break;
  1292.     case TrackData::MODE0:
  1293.       do_encode_L2(encBuf, MODE_0, lba);
  1294.       scramble_L2(encBuf);
  1295.       break;
  1296.     case TrackData::MODE1:
  1297.       do_encode_L2(encBuf, MODE_1, lba);
  1298.       scramble_L2(encBuf);
  1299.       break;
  1300.     case TrackData::MODE1_RAW:
  1301.       {
  1302. Msf m(lba);
  1303. if (int2bcd(m.min()) != encBuf[12] ||
  1304.     int2bcd(m.sec()) != encBuf[13] ||
  1305.     int2bcd(m.frac()) != encBuf[14]) {
  1306.   // sector address mismatch -> rebuild L-EC since it covers the header
  1307.   do_encode_L2(encBuf, MODE_1, lba);
  1308. }
  1309. scramble_L2(encBuf);
  1310.       }
  1311.       break;
  1312.     case TrackData::MODE2:
  1313.       do_encode_L2(encBuf, MODE_2, lba);
  1314.       scramble_L2(encBuf);
  1315.       break;
  1316.     case TrackData::MODE2_FORM1:
  1317.       do_encode_L2(encBuf, MODE_2_FORM_1, lba);
  1318.       scramble_L2(encBuf);
  1319.       break;
  1320.     case TrackData::MODE2_FORM2:
  1321.       do_encode_L2(encBuf, MODE_2_FORM_2, lba);
  1322.       scramble_L2(encBuf);
  1323.       break;
  1324.     case TrackData::MODE2_FORM_MIX:
  1325.       if ((encBuf[16+2] & 0x20) != 0)
  1326. do_encode_L2(encBuf, MODE_2_FORM_2, lba);
  1327.       else
  1328. do_encode_L2(encBuf, MODE_2_FORM_1, lba);
  1329.       scramble_L2(encBuf);
  1330.       break;
  1331.     case TrackData::MODE2_RAW:
  1332.       {
  1333. Msf m(lba);
  1334. // L-EC does not cover sector header so it is relocatable
  1335. // just update the sector address in the header
  1336. encBuf[12] = int2bcd(m.min());
  1337. encBuf[13] = int2bcd(m.sec());
  1338. encBuf[14] = int2bcd(m.frac());
  1339. scramble_L2(encBuf);
  1340.       }
  1341.       break;
  1342.     }
  1343.   }
  1344.   else if (encodingMode == 1) {
  1345.     switch (dataMode) {
  1346.     case TrackData::MODE2_FORM2:
  1347.       // add sub header for data form 2 sectors
  1348.       encBuf[2] = 0x20;
  1349.       encBuf[6] = 0x20;
  1350.       break;
  1351.     case TrackData::MODE1_RAW:
  1352.       // strip off sync and header
  1353.       memmove(encBuf, encBuf + 16, MODE1_BLOCK_LEN);
  1354.       break;
  1355.     case TrackData::MODE2_RAW:
  1356.       // strip off sync and header
  1357.       memmove(encBuf, encBuf + 16, MODE2_BLOCK_LEN);
  1358.       break;
  1359.     default:
  1360.       break;
  1361.     }
  1362.   }
  1363.  
  1364.   return offset;
  1365. }
  1366. long TrackReader::readTrackData(Sample *buf, long len)
  1367. {
  1368.   long actLen;
  1369.   long count = len;
  1370.   long nread = 0;
  1371.   while (count > 0) {
  1372.     actLen = reader.readData(buf + nread, count);
  1373.     if (actLen < 0) {
  1374.       return -1;
  1375.     }
  1376.     if (actLen != count) {
  1377.       // end of audio data in sub-track reached, skip to next sub-track
  1378.       readSubTrack_ = readSubTrack_->next_;
  1379.       // next sub-track must exists since requested length match available data
  1380.       assert(readSubTrack_ != NULL); 
  1381.       reader.init(readSubTrack_);
  1382.       if (reader.openData() != 0) {
  1383. return -1;
  1384.       }
  1385.     }
  1386.     count -= actLen;
  1387.     nread += actLen;
  1388.   }
  1389.   return len;
  1390. }
  1391. // Seeks to specified sample.
  1392. // return: 0: OK
  1393. //        10: sample out of range
  1394. //        return code of 'TrackData::openData()'
  1395. int TrackReader::seekSample(unsigned long sample)
  1396. {
  1397.   int ret;
  1398.   assert(open_ != 0);
  1399.   // find sub track containing 'sample'
  1400.   SubTrack *st = track_->findSubTrack(sample);
  1401.   if (st == NULL) 
  1402.     return 10;
  1403.   // open sub track if necessary
  1404.   if (readSubTrack_ != st) {
  1405.     readSubTrack_ = st;
  1406.     reader.init(readSubTrack_);
  1407.     if ((ret = reader.openData()) != 0) 
  1408.       return ret;
  1409.   }
  1410.   assert(sample >= readSubTrack_->start());
  1411.   unsigned long offset = sample - readSubTrack_->start();
  1412.   // seek in sub track
  1413.   if ((ret = reader.seekSample(offset)) != 0)
  1414.     return ret;
  1415.   readPosSample_ = sample;
  1416.   return 0;
  1417. }
  1418. long TrackReader::readSamples(Sample *buf, long len)
  1419. {
  1420.   long ret;
  1421.   long i;
  1422.   assert(open_ != 0);
  1423.   if (readPosSample_ + (unsigned long)len > track_->length_.samples()) {
  1424.     if ((len = track_->length_.samples() - readPosSample_) <= 0) {
  1425.       return 0;
  1426.     }
  1427.   }
  1428.   if (track_->type_ == TrackData::AUDIO) {
  1429.     if ((ret = readTrackData(buf, len)) > 0)
  1430.       readPosSample_ += ret;
  1431.   }
  1432.   else {
  1433.     for (i = 0; i < len; i++) {
  1434.       buf[i].left(16000);
  1435.       buf[i].right(16000);
  1436.     }
  1437.     readPosSample_ += len;
  1438.     ret = len;
  1439.   }
  1440.   
  1441.   return ret;
  1442. }