TrackManager.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:6k
- /* 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: TrackManager.cc,v $
- * Revision 1.2 1999/05/24 18:10:25 mueller
- * Adapted to new reading interface of 'trackdb'.
- *
- * Revision 1.1 1998/11/20 18:56:46 mueller
- * Initial revision
- *
- */
- #include <stdio.h>
- #include <assert.h>
- #include "TrackManager.h"
- #include "Toc.h"
- #include "util.h"
- TrackManager::TrackManager(gint trackMarkerWidth)
- {
- trackMarkerWidth_ = trackMarkerWidth;
- width_ = 0;
- entries_ = NULL;
- lastEntry_ = NULL;
- iterator_ = NULL;
- }
- TrackManager::~TrackManager()
- {
- clear();
- }
- void TrackManager::clear()
- {
- EntryList *next;
- while (entries_ != NULL) {
- next = entries_->next;
- delete entries_->ent;
- delete entries_;
- entries_ = next;
- }
- lastEntry_ = NULL;
- iterator_ = NULL;
- }
- void TrackManager::append(Entry *ent)
- {
- EntryList *entry = new EntryList;
- entry->ent = ent;
- entry->next = NULL;
- if (entries_ == NULL)
- entries_ = entry;
- else
- lastEntry_->next = entry;
- lastEntry_ = entry;
- }
- const TrackManager::Entry *TrackManager::first()
- {
- if ((iterator_ = entries_) != NULL)
- return iterator_->ent;
- else
- return NULL;
- }
- const TrackManager::Entry *TrackManager::next()
- {
- if (iterator_ == NULL ||
- (iterator_ = iterator_->next) == NULL)
- return NULL;
- else
- return iterator_->ent;
- }
- void TrackManager::select(const Entry *ent)
- {
- EntryList *run;
- for (run = entries_; run != NULL; run = run->next) {
- if (run->ent == ent)
- run->ent->selected = 1;
- else
- run->ent->selected = 0;
- }
- }
- void TrackManager::select(int trackNr, int indexNr)
- {
- EntryList *run;
- for (run = entries_; run != NULL; run = run->next) {
- if (run->ent->trackNr == trackNr && run->ent->indexNr == indexNr)
- run->ent->selected = 1;
- else
- run->ent->selected = 0;
- }
- }
- const TrackManager::Entry *TrackManager::pick(gint x, gint *stopXMin,
- gint *stopXMax)
- {
- EntryList *run;
- Entry *pred;
- for (run = entries_, pred = NULL; run != NULL;
- pred = run->ent, run = run->next) {
- if ((run->ent->indexNr == 1 || run->ent->selected)&&
- run->ent->extend == 0 &&
- run->ent->drawn &&
- x >= run->ent->xpos && x < run->ent->xpos + trackMarkerWidth_) {
- if (stopXMin != NULL)
- *stopXMin = pred != NULL ? pred->xpos + 1 : 0;
- if (stopXMax != NULL)
- *stopXMax = run->next != NULL ? run->next->ent->xpos - 1 : width_ - 1;
-
- return run->ent;
- }
- }
- for (run = entries_, pred = NULL; run != NULL;
- pred = run->ent, run = run->next) {
- if (run->ent->indexNr != 1 && run->ent->extend == 0 &&
- run->ent->drawn &&
- x >= run->ent->xpos && x < run->ent->xpos + trackMarkerWidth_) {
-
- if (stopXMin != NULL)
- *stopXMin = pred != NULL ? pred->xpos : 0;
- if (stopXMax != NULL)
- *stopXMax = run->next != NULL ? run->next->ent->xpos : width_;
- return run->ent;
- }
- }
- return NULL;
- }
- void TrackManager::update(const Toc *toc, unsigned long start,
- unsigned long end, gint width)
- {
- Msf tstart, tend;
- long startLba = start / SAMPLES_PER_BLOCK;
- long startRest = start % SAMPLES_PER_BLOCK;
- long endLba = end / SAMPLES_PER_BLOCK;
- int trackNr;
- const Track *t;
- Entry *ent;
- int nindex, index;
- long markStart = -1;
- int last = 0;
- clear();
- width_ = width;
- TrackIterator itr(toc);
- if (toc == NULL || start == end ||
- (t = itr.find(start, tstart, tend, &trackNr)) == NULL)
- return;
- double samp2pix = double(width - 1) / double(end - start);
- #define lba2pixel(lba)
- gint(double(((lba) * SAMPLES_PER_BLOCK) - start) * samp2pix + 0.5)
- nindex = t->nofIndices();
- if (startLba < tstart.lba()) {
- // 'start' is in pre-gap of track
- ent = new Entry(t, trackNr, 0, 0);
- markStart = tstart.lba() - t->start().lba();
- index = 0;
- }
- else {
- if (nindex == 0 || startLba <= tstart.lba() + t->getIndex(0).lba()) {
- markStart = tstart.lba();
- index = 1;
- }
- else {
- for (index = 3; index - 2 < nindex; index++) {
- if (startLba >= tstart.lba() + t->getIndex(index - 3).lba() &&
- startLba < tstart.lba() + t->getIndex(index - 2).lba()) {
- markStart = tstart.lba() + t->getIndex(index - 3).lba();
- index--;
- break;
- }
- }
- if (markStart == -1) {
- markStart = tstart.lba() + t->getIndex(nindex - 1).lba();
- index = nindex + 1;
- }
- }
- }
- ent = new Entry(t, trackNr, index, 0);
- if (startLba != markStart || startRest > 0)
- ent->extend = 1;
- append(ent);
- if (index == 0 && tstart.lba() <= endLba)
- append(new Entry(t, trackNr, 1, lba2pixel(tstart.lba())));
- if (index == 0)
- index = 1;
- index++;
- for (; index - 2 < nindex; index++) {
- if (tstart.lba() + t->getIndex(index - 2).lba() > endLba)
- break;
- append(new Entry(t, trackNr, index,
- lba2pixel(tstart.lba() + t->getIndex(index - 2).lba())));
- }
- while ((t = itr.next(tstart, tend)) != NULL) {
- trackNr++;
- if (t->start().lba() != 0) {
- if (tstart.lba() - t->start().lba() > endLba)
- break;
- append(new Entry(t, trackNr, 0,
- lba2pixel(tstart.lba() - t->start().lba())));
- }
- if (tstart.lba() > endLba)
- break;
- append(new Entry(t, trackNr, 1, lba2pixel(tstart.lba())));
- last = 0;
- nindex = t->nofIndices();
- for (index = 0; index < nindex; index++) {
- if (tstart.lba() + t->getIndex(index).lba() > endLba) {
- last = 1;
- break;
- }
- append(new Entry(t, trackNr, index + 2,
- lba2pixel(tstart.lba() + t->getIndex(index).lba())));
- }
- if (last)
- break;
- }
- }