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

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: TocEdit.cc,v $
  21.  * Revision 1.1  1999/08/19 20:27:39  mueller
  22.  * Initial revision
  23.  *
  24.  */
  25. static char rcsid[] = "$Id: TocEdit.cc,v 1.1 1999/08/19 20:27:39 mueller Exp mueller $";
  26. #include "TocEdit.h"
  27. #include <stddef.h>
  28. #include "util.h"
  29. #include "Toc.h"
  30. #include "TrackData.h"
  31. #include "TrackDataList.h"
  32. #include "TrackDataScrap.h"
  33. #include "guiUpdate.h"
  34. #include "SampleManager.h"
  35. TocEdit::TocEdit(Toc *t, const char *filename)
  36. {
  37.   toc_ = NULL;
  38.   sampleManager_ = NULL;
  39.   filename_ = NULL;
  40.   trackDataScrap_ = NULL;
  41.   updateLevel_ = 0;
  42.   editBlocked_ = 0;
  43.   if (filename == NULL)
  44.     toc(t, "unnamed.toc");
  45.   else
  46.     toc(t, filename);
  47. }
  48. TocEdit::~TocEdit()
  49. {
  50.   delete toc_;
  51.   toc_ = NULL;
  52.   delete sampleManager_;
  53.   sampleManager_ = NULL;
  54.   delete[] filename_;
  55.   filename_ = NULL;
  56.   delete trackDataScrap_;
  57.   trackDataScrap_ = NULL;
  58. }
  59. void TocEdit::toc(Toc *t, const char *filename)
  60. {
  61.   delete toc_;
  62.   if (t == NULL)
  63.     toc_ = new Toc;
  64.   else
  65.     toc_ = t;
  66.   if (filename != NULL) {
  67.     delete[] filename_;
  68.     filename_ = strdupCC(filename);
  69.   }
  70.   tocDirty_ = 0;
  71.   editBlocked_ = 0;
  72.   delete sampleManager_;
  73.   sampleManager_ = new SampleManager(588);
  74.   sampleManager_->setTocEdit(this);
  75.   if (toc_->length().samples() > 0) {
  76.     unsigned long maxSample = toc_->length().samples() - 1;
  77.     sampleManager_->scanToc(0, maxSample);
  78.   }
  79.   sampleMarkerValid_ = 0;
  80.   sampleSelectionValid_ = 0;
  81.   trackSelectionValid_ = 0;
  82.   indexSelectionValid_ = 0;
  83.   updateLevel_ = UPD_ALL;
  84. }
  85. Toc *TocEdit::toc() const
  86. {
  87.   return toc_;
  88. }
  89. SampleManager *TocEdit::sampleManager()
  90. {
  91.   return sampleManager_;
  92. }
  93. void TocEdit::tocDirty(int f)
  94. {
  95.   int old = tocDirty_;
  96.   tocDirty_ = (f != 0) ? 1 : 0;
  97.   if (old != tocDirty_)
  98.     updateLevel_ |= UPD_TOC_DIRTY;
  99. }
  100. int TocEdit::tocDirty() const
  101. {
  102.   return tocDirty_;
  103. }
  104. void TocEdit::blockEdit()
  105. {
  106.   if (editBlocked_ == 0)
  107.     updateLevel_ |= UPD_EDITABLE_STATE;
  108.   editBlocked_ += 1;
  109. }
  110. void TocEdit::unblockEdit()
  111. {
  112.   if (editBlocked_ > 0) {
  113.     editBlocked_ -= 1;
  114.     if (editBlocked_ == 0)
  115.       updateLevel_ |= UPD_EDITABLE_STATE;
  116.   }
  117. }
  118. int TocEdit::editable() const
  119. {
  120.   return (editBlocked_ == 0) ? 1 : 0;
  121. }
  122. int TocEdit::modifyAllowed() const
  123. {
  124.   return (editBlocked_ == 0) ? 1 : 0;
  125. }
  126. unsigned long TocEdit::updateLevel()
  127. {
  128.   unsigned long level = updateLevel_;
  129.   updateLevel_ = 0;
  130.   return level;
  131. }
  132. unsigned long TocEdit::lengthSample() const
  133. {
  134.   return toc_->length().samples();
  135. }
  136. void TocEdit::filename(const char *fname)
  137. {
  138.   if (fname != NULL && *fname != 0) {
  139.     char *s = strdupCC(fname);
  140.     delete[] filename_;
  141.     filename_ = s;
  142.     updateLevel_ |= UPD_TOC_DATA;
  143.   }
  144. }
  145. const char *TocEdit::filename() const
  146. {
  147.   return filename_;
  148. }
  149. void TocEdit::sampleMarker(unsigned long sample)
  150. {
  151.   if (sample < toc_->length().samples()) {
  152.     sampleMarker_ = sample;
  153.     sampleMarkerValid_ = 1;
  154.   }
  155.   else {
  156.     sampleMarkerValid_ = 0;
  157.   }
  158.   updateLevel_ |= UPD_SAMPLE_MARKER;
  159. }
  160. int TocEdit::sampleMarker(unsigned long *sample) const
  161. {
  162.   if (sampleMarkerValid_)
  163.     *sample = sampleMarker_;
  164.   return sampleMarkerValid_;
  165. }
  166. void TocEdit::sampleSelection(unsigned long smin, unsigned long smax)
  167. {
  168.   unsigned long tmp;
  169.   if (smin > smax) {
  170.     tmp = smin;
  171.     smin = smax;
  172.     smax = tmp;
  173.   }
  174.   if (smax < toc_->length().samples()) {
  175.     sampleSelectionMin_ = smin;
  176.     sampleSelectionMax_ = smax;
  177.     sampleSelectionValid_ = 1;
  178.   }
  179.   else {
  180.     sampleSelectionValid_ = 0;
  181.   }
  182.   
  183.   updateLevel_ |= UPD_SAMPLE_SEL;
  184. }
  185. int TocEdit::sampleSelection(unsigned long *smin, unsigned long *smax) const
  186. {
  187.   if (sampleSelectionValid_) {
  188.     *smin = sampleSelectionMin_;
  189.     *smax = sampleSelectionMax_;
  190.   }
  191.   return sampleSelectionValid_;
  192. }
  193.   
  194. void TocEdit::trackSelection(int tnum)
  195. {
  196.   if (tnum > 0) {
  197.     trackSelection_ = tnum;
  198.     trackSelectionValid_ = 1;
  199.   }
  200.   else {
  201.     trackSelectionValid_ = 0;
  202.   }
  203.   updateLevel_ |= UPD_TRACK_MARK_SEL;
  204. }
  205. int TocEdit::trackSelection(int *tnum) const
  206. {
  207.   if (trackSelectionValid_)
  208.     *tnum = trackSelection_;
  209.   return trackSelectionValid_;
  210. }
  211. void TocEdit::indexSelection(int inum)
  212. {
  213.   if (inum >= 0) {
  214.     indexSelection_ = inum;
  215.     indexSelectionValid_ = 1;
  216.   }
  217.   else {
  218.     indexSelectionValid_ = 0;
  219.   }
  220.   updateLevel_ |= UPD_TRACK_MARK_SEL;
  221. }
  222. int TocEdit::indexSelection(int *inum) const
  223. {
  224.   if (indexSelectionValid_)
  225.     *inum = indexSelection_;
  226.   return indexSelectionValid_;
  227. }
  228. int TocEdit::readToc(const char *fname)
  229. {
  230.   if (!modifyAllowed())
  231.     return 0;
  232.   if (fname == NULL || *fname == 0)
  233.     return 1;
  234.   Toc *t = Toc::read(fname);
  235.   if (t != NULL) {
  236.     toc(t, fname);
  237.     return 0;
  238.   }
  239.   return 1;
  240. }
  241. int TocEdit::saveToc()
  242. {
  243.   int ret = toc_->write(filename_);
  244.   if (ret == 0)
  245.     tocDirty(0);
  246.   return ret;
  247. }
  248. int TocEdit::saveAsToc(const char *fname)
  249. {
  250.   int ret;
  251.   if (fname != NULL && *fname != 0) {
  252.     ret = toc_->write(fname);
  253.     if (ret == 0) {
  254.       filename(fname);
  255.       tocDirty(0);
  256.       updateLevel_ |= UPD_TOC_DATA;
  257.     }
  258.     return ret;
  259.   }
  260.   return 1;
  261. }
  262. int TocEdit::moveTrackMarker(int trackNr, int indexNr, long lba)
  263. {
  264.   if (!modifyAllowed())
  265.     return 0;
  266.   int ret = toc_->moveTrackMarker(trackNr, indexNr, lba);
  267.   if (ret == 0) {
  268.     tocDirty(1);
  269.     updateLevel_ |= UPD_TRACK_DATA;
  270.   }
  271.   return ret;
  272. }
  273. int TocEdit::addTrackMarker(long lba)
  274. {
  275.   if (!modifyAllowed())
  276.     return 0;
  277.   int ret = toc_->addTrackMarker(lba);
  278.   if (ret == 0) {
  279.     tocDirty(1);
  280.     updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA;
  281.   }
  282.   return ret;
  283. }
  284. int TocEdit::addIndexMarker(long lba)
  285. {
  286.   if (!modifyAllowed())
  287.     return 0;
  288.   int ret = toc_->addIndexMarker(lba);
  289.   if (ret == 0) {
  290.     tocDirty(1);
  291.     updateLevel_ |= UPD_TRACK_DATA;
  292.   }
  293.   return ret;
  294. }
  295. int TocEdit::addPregap(long lba)
  296. {
  297.   if (!modifyAllowed())
  298.     return 0;
  299.   int ret = toc_->addPregap(lba);
  300.   if (ret == 0) {
  301.     tocDirty(1);
  302.     updateLevel_ |= UPD_TRACK_DATA;
  303.   }
  304.   return ret;
  305. }
  306. int TocEdit::removeTrackMarker(int trackNr, int indexNr)
  307. {
  308.   if (!modifyAllowed())
  309.     return 0;
  310.   int ret = toc_->removeTrackMarker(trackNr, indexNr);
  311.   if (ret == 0) {
  312.     tocDirty(1);
  313.     updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA;
  314.   }
  315.   return ret;
  316. }
  317. // Creates an audio data object for given filename. Errors are send to
  318. // status line.
  319. // data: filled with newly allocated TrackData object on success
  320. // return: 0: OK
  321. //         1: cannot open file
  322. //         2: file has wrong format
  323. int TocEdit::createAudioData(const char *filename, TrackData **data)
  324. {
  325.   unsigned long len;
  326.   switch (TrackData::checkAudioFile(filename, &len)) {
  327.   case 1:
  328.     return 1; // Cannot open file
  329.   case 2:
  330.     return 2; // File format error
  331.   }
  332.   *data = new TrackData(filename, 0, len);
  333.   return 0;
  334. }
  335. int TocEdit::appendTrack(const char *fname)
  336. {
  337.   long start, end;
  338.   TrackData *data;
  339.   int ret;
  340.   if (!modifyAllowed())
  341.     return 0;
  342.   if ((ret = createAudioData(fname, &data)) == 0) {
  343.     TrackDataList list;
  344.     list.append(data);
  345.     toc_->appendTrack(&list, &start, &end);
  346.     sampleManager_->scanToc(Msf(start).samples(), Msf(end).samples() - 1);
  347.     tocDirty(1);
  348.     updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA;
  349.   }
  350.   return ret;
  351. }
  352. int TocEdit::appendFile(const char *fname)
  353. {
  354.   long start, end;
  355.   int ret;
  356.   TrackData *data;
  357.   if (!modifyAllowed())
  358.     return 0;
  359.   if ((ret = createAudioData(fname, &data)) == 0) {
  360.     TrackDataList list;
  361.     list.append(data);
  362.     if (toc_->appendTrackData(&list, &start, &end) == 0) {
  363.       sampleManager_->scanToc(Msf(start).samples(), Msf(end).samples() - 1);
  364.       
  365.       tocDirty(1);
  366.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA;
  367.     }
  368.   }
  369.   return ret;
  370. }
  371. // Inserts contents of specified file at given position.
  372. // Return: 0: OK
  373. //         1: cannot open file
  374. //         2: file has invalid format
  375. int TocEdit::insertFile(const char *fname, unsigned long pos)
  376. {
  377.   int ret;
  378.   TrackData *data;
  379.   if (!modifyAllowed())
  380.     return 0;
  381.   if ((ret = createAudioData(fname, &data)) == 0) {
  382.     TrackDataList list;
  383.     list.append(data);
  384.     if (toc_->insertTrackData(pos, &list) == 0) {
  385.       unsigned long len = list.length();
  386.       sampleManager_->insertSamples(pos, len, NULL);
  387.       sampleManager_->scanToc(pos, pos + len);
  388.       sampleSelection(pos, pos + len - 1);
  389.       
  390.       tocDirty(1);
  391.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA | UPD_SAMPLE_SEL;
  392.     }
  393.   }
  394.   return ret;
  395. }
  396. int TocEdit::appendSilence(unsigned long length)
  397. {
  398.   if (!modifyAllowed())
  399.     return 0;
  400.   if (length > 0) {
  401.     long start, end;
  402.     TrackData *data = new TrackData(TrackData::AUDIO, length);
  403.     TrackDataList list;
  404.     list.append(data);
  405.     if (toc_->appendTrackData(&list, &start, &end) == 0) {
  406.       sampleManager_->scanToc(Msf(start).samples(), Msf(end).samples() - 1);
  407.       
  408.       tocDirty(1);
  409.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA;
  410.     }
  411.   }
  412.   return 0;
  413. }
  414. int TocEdit::insertSilence(unsigned long length, unsigned long pos)
  415. {
  416.   if (!modifyAllowed())
  417.     return 0;
  418.   if (length > 0) {
  419.     TrackData *data = new TrackData(TrackData::AUDIO, length);
  420.     TrackDataList list;
  421.     list.append(data);
  422.     if (toc_->insertTrackData(pos, &list) == 0) {
  423.       sampleManager_->insertSamples(pos, length, NULL);
  424.       sampleManager_->scanToc(pos, pos + length);
  425.       
  426.       sampleSelection(pos, pos + length - 1);
  427.       
  428.       tocDirty(1);
  429.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA | UPD_SAMPLE_SEL;
  430.     }
  431.   }
  432.   return 0;
  433. }
  434. void TocEdit::setTrackCopyFlag(int trackNr, int flag)
  435. {
  436.   if (!modifyAllowed())
  437.     return;
  438.   Track *t = toc_->getTrack(trackNr);
  439.   
  440.   if (t != NULL) {
  441.     t->copyPermitted(flag);
  442.     tocDirty(1);
  443.     updateLevel_ |= UPD_TRACK_DATA;
  444.   }
  445. }
  446. void TocEdit::setTrackPreEmphasisFlag(int trackNr, int flag)
  447. {
  448.   if (!modifyAllowed())
  449.     return;
  450.   Track *t = toc_->getTrack(trackNr);
  451.   if (t != NULL) {
  452.     t->preEmphasis(flag);
  453.     tocDirty(1);
  454.     updateLevel_ |= UPD_TRACK_DATA;
  455.   }
  456. }
  457. void TocEdit::setTrackAudioType(int trackNr, int flag)
  458. {
  459.   if (!modifyAllowed())
  460.     return;
  461.   Track *t = toc_->getTrack(trackNr);
  462.   if (t != NULL) {
  463.     t->audioType(flag);
  464.     tocDirty(1);
  465.     updateLevel_ |= UPD_TRACK_DATA;
  466.   }
  467.   
  468. }
  469. void TocEdit::setTrackIsrcCode(int trackNr, const char *s)
  470. {
  471.   if (!modifyAllowed())
  472.     return;
  473.   Track *t = toc_->getTrack(trackNr);
  474.   if (t != NULL) {
  475.     if (t->isrc(s) == 0) {
  476.       tocDirty(1);
  477.       updateLevel_ |= UPD_TRACK_DATA;
  478.     }
  479.   }
  480. }
  481. void TocEdit::setCdTextItem(int trackNr, CdTextItem::PackType type,
  482.     int blockNr, const char *s)
  483. {
  484.   if (!modifyAllowed())
  485.     return;
  486.   if (s != NULL) {
  487.     CdTextItem *item = new CdTextItem(type, blockNr, s);
  488.     toc_->addCdTextItem(trackNr, item);
  489.   }
  490.   else {
  491.     toc_->removeCdTextItem(trackNr, type, blockNr);
  492.   }
  493.   tocDirty(1);
  494.   updateLevel_ |= (trackNr == 0) ? UPD_TOC_DATA : UPD_TRACK_DATA;
  495. }
  496. void TocEdit::setCdTextGenreItem(int blockNr, int code1, int code2,
  497.  const char *description)
  498. {
  499.   if (code1 > 255 || code2 > 255)
  500.     return;
  501.   if (!modifyAllowed())
  502.     return;
  503.   if (code1 < 0 || code2 < 0) {
  504.     toc_->removeCdTextItem(0, CdTextItem::CDTEXT_GENRE, blockNr);
  505.   }
  506.   else {
  507.     CdTextItem *item = new CdTextItem(blockNr, (unsigned char)code1,
  508.       (unsigned char)code2, description);
  509.     toc_->addCdTextItem(0, item);
  510.   }
  511.   tocDirty(1);
  512.   updateLevel_ |= UPD_TOC_DATA;
  513. }
  514. void TocEdit::setCdTextLanguage(int blockNr, int langCode)
  515. {
  516.   if (!modifyAllowed())
  517.     return;
  518.   toc_->cdTextLanguage(blockNr, langCode);
  519.   tocDirty(1);
  520.   updateLevel_ |= UPD_TOC_DATA;
  521. }
  522. void TocEdit::setCatalogNumber(const char *s)
  523. {
  524.   if (!modifyAllowed())
  525.     return;
  526.   if (toc_->catalog(s) == 0) {
  527.     tocDirty(1);
  528.     updateLevel_ |= UPD_TOC_DATA;
  529.   }
  530. }
  531. void TocEdit::setTocType(Toc::TocType type)
  532. {
  533.   if (!modifyAllowed())
  534.     return;
  535.   toc_->tocType(type);
  536.   tocDirty(1);
  537.   updateLevel_ |= UPD_TOC_DATA;
  538. }
  539. // Removes selected track data
  540. // Return: 0: OK
  541. //         1: no selection
  542. //         2: selection crosses track boundaries
  543. //         3: cannot modify data track
  544. int TocEdit::removeTrackData()
  545. {
  546.   TrackDataList *list;
  547.   if (!modifyAllowed())
  548.     return 0;
  549.   if (!sampleSelectionValid_)
  550.     return 1;
  551.   switch (toc_->removeTrackData(sampleSelectionMin_, sampleSelectionMax_,
  552. &list)) {
  553.   case 0:
  554.     if (list != NULL) {
  555.       if (list->length() > 0) {
  556. delete trackDataScrap_;
  557. trackDataScrap_ = new TrackDataScrap(list);
  558.       }
  559.       else {
  560. delete list;
  561.       }
  562.       sampleManager_->removeSamples(sampleSelectionMin_, sampleSelectionMax_,
  563.     trackDataScrap_);
  564.       sampleSelectionValid_ = 0;
  565.       sampleMarker(sampleSelectionMin_);
  566.     
  567.       tocDirty(1);
  568.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA | UPD_SAMPLE_SEL | UPD_SAMPLES;
  569.     }
  570.     break;
  571.   case 1:
  572.     return 2;
  573.     break;
  574.   case 2:
  575.     return 3;
  576.     break;
  577.   }
  578.   return 0;
  579. }
  580. // Inserts track data from scrap
  581. // Return: 0: OK
  582. //         1: no scrap data to paste
  583. int TocEdit::insertTrackData()
  584. {
  585.   if (!modifyAllowed())
  586.     return 0;
  587.   if (trackDataScrap_ == NULL)
  588.     return 1;
  589.   unsigned long len = trackDataScrap_->trackDataList()->length();
  590.   if (sampleMarkerValid_ && sampleMarker_ < toc_->length().samples()) {
  591.     if (toc_->insertTrackData(sampleMarker_, trackDataScrap_->trackDataList())
  592. == 0) {
  593.       sampleManager_->insertSamples(sampleMarker_, len, trackDataScrap_);
  594.       sampleManager_->scanToc(sampleMarker_, sampleMarker_);
  595.       sampleManager_->scanToc(sampleMarker_ + len - 1,
  596.       sampleMarker_ + len - 1);
  597.       
  598.       sampleSelection(sampleMarker_, sampleMarker_ + len - 1);
  599.     
  600.       tocDirty(1);
  601.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA | UPD_SAMPLE_SEL;
  602.     }
  603.   }
  604.   else {
  605.     long start, end;
  606.     if (toc_->appendTrackData(trackDataScrap_->trackDataList(), &start, &end)
  607. == 0) {
  608.       sampleManager_->insertSamples(Msf(start).samples(), 
  609.     Msf(end - start).samples(), trackDataScrap_);
  610.       sampleManager_->scanToc(Msf(start).samples(), Msf(start).samples());
  611.       if (end > 0) 
  612. sampleManager_->scanToc(Msf(start).samples() + len, Msf(end).samples() - 1);
  613.       sampleSelection(Msf(start).samples(), Msf(end).samples() - 1);
  614.       
  615.       tocDirty(1);
  616.       updateLevel_ |= UPD_TOC_DATA | UPD_TRACK_DATA | UPD_SAMPLE_SEL;
  617.     }
  618.   }
  619.   return 0;
  620. }