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

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: TrackManager.cc,v $
  21.  * Revision 1.2  1999/05/24 18:10:25  mueller
  22.  * Adapted to new reading interface of 'trackdb'.
  23.  *
  24.  * Revision 1.1  1998/11/20 18:56:46  mueller
  25.  * Initial revision
  26.  *
  27.  */
  28. #include <stdio.h>
  29. #include <assert.h>
  30. #include "TrackManager.h"
  31. #include "Toc.h"
  32. #include "util.h"
  33. TrackManager::TrackManager(gint trackMarkerWidth)
  34. {
  35.   trackMarkerWidth_ = trackMarkerWidth;
  36.   width_ = 0;
  37.   entries_ = NULL;
  38.   lastEntry_ = NULL;
  39.   iterator_ = NULL;
  40. }
  41. TrackManager::~TrackManager()
  42. {
  43.   clear();
  44. }
  45. void TrackManager::clear()
  46. {
  47.   EntryList *next;
  48.   while (entries_ != NULL) {
  49.     next = entries_->next;
  50.     delete entries_->ent;
  51.     delete entries_;
  52.     entries_ = next;
  53.   }
  54.   lastEntry_ = NULL;
  55.   iterator_ = NULL;
  56. }
  57. void TrackManager::append(Entry *ent)
  58. {
  59.   EntryList *entry = new EntryList;
  60.   entry->ent = ent;
  61.   entry->next = NULL;
  62.   if (entries_ == NULL)
  63.     entries_ = entry;
  64.   else
  65.     lastEntry_->next = entry;
  66.   lastEntry_ = entry;
  67. }
  68. const TrackManager::Entry *TrackManager::first()
  69. {
  70.   if ((iterator_ = entries_) != NULL)
  71.     return iterator_->ent;
  72.   else
  73.     return NULL;
  74. }
  75. const TrackManager::Entry *TrackManager::next()
  76. {
  77.   if (iterator_ == NULL ||
  78.       (iterator_ = iterator_->next) == NULL) 
  79.     return NULL;
  80.   else
  81.     return iterator_->ent;
  82. }
  83. void TrackManager::select(const Entry *ent)
  84. {
  85.   EntryList *run;
  86.   for (run = entries_; run != NULL; run = run->next) {
  87.     if (run->ent == ent)
  88.       run->ent->selected = 1;
  89.     else
  90.       run->ent->selected = 0;
  91.   }
  92. }
  93. void TrackManager::select(int trackNr, int indexNr)
  94. {
  95.   EntryList *run;
  96.   for (run = entries_; run != NULL; run = run->next) {
  97.     if (run->ent->trackNr == trackNr && run->ent->indexNr == indexNr)
  98.       run->ent->selected = 1;
  99.     else
  100.       run->ent->selected = 0;
  101.   }
  102. }
  103. const TrackManager::Entry *TrackManager::pick(gint x, gint *stopXMin,
  104.       gint *stopXMax)
  105. {
  106.   EntryList *run;
  107.   Entry *pred;
  108.   for (run = entries_, pred = NULL; run != NULL; 
  109.        pred = run->ent, run = run->next) {
  110.     if ((run->ent->indexNr == 1 || run->ent->selected)&& 
  111. run->ent->extend == 0 &&
  112. run->ent->drawn &&
  113. x >= run->ent->xpos && x < run->ent->xpos + trackMarkerWidth_) {
  114.       if (stopXMin != NULL)
  115. *stopXMin = pred != NULL ? pred->xpos + 1 : 0;
  116.       if (stopXMax != NULL)
  117. *stopXMax = run->next != NULL ? run->next->ent->xpos - 1 : width_ - 1;
  118.   
  119.       return run->ent;
  120.     }
  121.   }
  122.   for (run = entries_, pred = NULL; run != NULL;
  123.        pred = run->ent, run = run->next) {
  124.     if (run->ent->indexNr != 1 && run->ent->extend == 0 &&
  125. run->ent->drawn &&
  126. x >= run->ent->xpos && x < run->ent->xpos + trackMarkerWidth_) {
  127.       
  128.       if (stopXMin != NULL)
  129. *stopXMin = pred != NULL ? pred->xpos : 0;
  130.       if (stopXMax != NULL)
  131. *stopXMax = run->next != NULL ? run->next->ent->xpos : width_;
  132.       return run->ent;
  133.     }
  134.   }
  135.   return NULL;
  136. }
  137. void TrackManager::update(const Toc *toc, unsigned long start,
  138.   unsigned long end, gint width)
  139. {
  140.   Msf tstart, tend;
  141.   long startLba = start / SAMPLES_PER_BLOCK;
  142.   long startRest = start % SAMPLES_PER_BLOCK;
  143.   long endLba = end / SAMPLES_PER_BLOCK;
  144.   int trackNr;
  145.   const Track *t;
  146.   Entry *ent;
  147.   int nindex, index;
  148.   long markStart = -1;
  149.   int last = 0;
  150.   clear();
  151.   width_ = width;
  152.   TrackIterator itr(toc);
  153.   if (toc == NULL || start == end ||
  154.       (t = itr.find(start, tstart, tend, &trackNr)) == NULL)
  155.     return;
  156.   double samp2pix = double(width - 1) / double(end - start);
  157. #define lba2pixel(lba) 
  158. gint(double(((lba) * SAMPLES_PER_BLOCK) - start) * samp2pix + 0.5)
  159.   nindex = t->nofIndices();
  160.   if (startLba < tstart.lba()) {
  161.     // 'start' is in pre-gap of track
  162.     ent = new Entry(t, trackNr, 0, 0);
  163.     markStart = tstart.lba() - t->start().lba();
  164.     index = 0;
  165.   }
  166.   else {
  167.     if (nindex == 0 || startLba <= tstart.lba() + t->getIndex(0).lba()) {
  168.       markStart = tstart.lba();
  169.       index = 1;
  170.     }
  171.     else {
  172.       for (index = 3; index - 2 < nindex; index++) {
  173. if (startLba >= tstart.lba() + t->getIndex(index - 3).lba() &&
  174.     startLba < tstart.lba() + t->getIndex(index - 2).lba()) {
  175.   markStart = tstart.lba() + t->getIndex(index - 3).lba();
  176.   index--;
  177.   break;
  178. }
  179.       }
  180.       if (markStart == -1) {
  181. markStart = tstart.lba() + t->getIndex(nindex - 1).lba();
  182. index = nindex + 1;
  183.       }
  184.     }
  185.   }
  186.   ent = new Entry(t, trackNr, index, 0);
  187.   if (startLba != markStart || startRest > 0) 
  188.     ent->extend = 1;
  189.   append(ent);
  190.   if (index == 0 && tstart.lba() <= endLba)
  191.     append(new Entry(t, trackNr, 1, lba2pixel(tstart.lba())));
  192.   if (index == 0) 
  193.     index = 1;
  194.   index++;
  195.   for (; index - 2 < nindex; index++) {
  196.     if (tstart.lba() + t->getIndex(index - 2).lba() > endLba) 
  197.       break;
  198.     append(new Entry(t, trackNr, index,
  199.      lba2pixel(tstart.lba() + t->getIndex(index - 2).lba())));
  200.   }
  201.   while ((t = itr.next(tstart, tend)) != NULL) {
  202.     trackNr++;
  203.     if (t->start().lba() != 0) {
  204.       if (tstart.lba() - t->start().lba() > endLba)
  205. break;
  206.       append(new Entry(t, trackNr, 0,
  207.        lba2pixel(tstart.lba() - t->start().lba())));
  208.     }
  209.     if (tstart.lba() > endLba)
  210.       break;
  211.     append(new Entry(t, trackNr, 1, lba2pixel(tstart.lba())));
  212.     last = 0;
  213.     nindex = t->nofIndices();
  214.     for (index = 0; index < nindex; index++) {
  215.       if (tstart.lba() + t->getIndex(index).lba() > endLba) {
  216. last = 1;
  217. break;
  218.       }
  219.       append(new Entry(t, trackNr, index + 2,
  220.        lba2pixel(tstart.lba() + t->getIndex(index).lba())));
  221.     }
  222.     if (last)
  223.       break;
  224.   }
  225. }