1 /*  cdrdao - write audio CD-Rs in disc-at-once mode
2  *
3  *  Copyright (C) 1998-2001 Andreas Mueller <andreas@daneb.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 #ifndef __TRACK_H__
21 #define __TRACK_H__
22 
23 #include <iostream>
24 
25 #include "SubTrack.h"
26 #include "Msf.h"
27 #include "CdTextContainer.h"
28 #include "CdTextItem.h"
29 
30 class TrackDataList;
31 
32 class Track {
33 public:
34   Track(TrackData::Mode, TrackData::SubChannelMode);
35   Track(const Track &);
36   ~Track();
37 
type()38   TrackData::Mode type() const { return type_; }
subChannelType()39   TrackData::SubChannelMode subChannelType() const { return subChannelType_; }
40 
audioCutMode()41   int audioCutMode() const { return audioCutMode_; }
42 
length()43   Msf length() const { return length_; }
44 
start()45   Msf start() const { return start_; }
46   int start(Msf);
47 
end()48   Msf end() const { return end_; }
49   int end(Msf);
50 
51   int isPadded() const;
52 
nofSubTracks()53   int nofSubTracks() const { return nofSubTracks_; }
54 
55   // return first/last sub-track
56   const SubTrack *firstSubTrack() const;
57   const SubTrack *lastSubTrack() const;
58 
59   int append(const SubTrack &);
60 
nofIndices()61   int nofIndices() const { return nofIndices_; }
62 
63   int appendIndex(const Msf &);
64   int addIndex(const Msf &index);
65   int removeIndex(int);
66   Msf getIndex(int) const;
67 
68   int moveIndex(int index, long lba);
69   TrackDataList *removeToEnd(unsigned long samplePos);
70   TrackDataList *removeFromStart(unsigned long sample);
71 
72   void prependTrackData(const TrackDataList *);
73   void appendTrackData(const TrackDataList *);
74   void appendTrackData(const Track *);
75 
76   TrackDataList *removeTrackData(unsigned long start, unsigned long end);
77   void insertTrackData(unsigned long pos, const TrackDataList *list);
78 
79   // fills provided buffer with an audio block that contains zero data
80   // encoded with given mode
81   static void encodeZeroData(int encMode, TrackData::Mode,
82 			     TrackData::SubChannelMode, long lba,
83 			     unsigned char *);
84 
85   int check(int trackNr) const;
86 
isrcValid()87   int isrcValid() const { return isrcValid_; }
88 
89   // set ISRC code from given string
90   int isrc(const char *); // sets ISRC code
91   const char *isrc() const;
92 
isrcCountry(int i)93   char isrcCountry(int i) const { return isrcCountry_[i]; } // ASCII
isrcOwner(int i)94   char isrcOwner(int i) const { return isrcOwner_[i]; }     // ASCII
isrcYear(int i)95   char isrcYear(int i) const { return isrcYear_[i]; }       // BCD
isrcSerial(int i)96   char isrcSerial(int i) const { return isrcSerial_[i]; }   // BCD
97 
98   // return/set COPY flag (1: copy permitted, 0: copy not permitted)
copyPermitted()99   int  copyPermitted() const { return flags_.copy; }
copyPermitted(int c)100   void copyPermitted(int c) { flags_.copy = c != 0 ? 1 : 0; }
101 
102   // return/set PRE-EMPHASIS flag (1: audio with pre-emphasis,
103   // 0: audio without pre-emphasis
preEmphasis()104   int  preEmphasis() const { return flags_.preEmphasis; }
preEmphasis(int p)105   void preEmphasis(int p) { flags_.preEmphasis = p != 0 ? 1 : 0; }
106 
107   // return/set audio type (0: two channel audio, 1: four channel audio)
audioType()108   int  audioType() const { return flags_.audioType; }
audioType(int t)109   void audioType(int t) { flags_.audioType = t != 0 ? 1 : 0; }
110 
111   void addCdTextItem(CdTextItem *);
112   void removeCdTextItem(CdTextItem::PackType, int blockNr);
existCdTextBlock(int n)113   int  existCdTextBlock(int n) const { return cdtext_.existBlock(n); }
getCdTextItem(int blockNr,CdTextItem::PackType t)114   const CdTextItem *getCdTextItem(int blockNr, CdTextItem::PackType t) const {
115     return cdtext_.getPack(blockNr, t);
116   }
117 
118   void print(std::ostream &, bool conversions = false) const;
119 
120   void collectFiles(std::set<std::string>& set);
121   void markFileConversion(const char* src, const char* dst);
122   bool resolveFilename(const char* path);
123   bool recomputeLength();
124 
125 private:
126   friend class TocParserGram;
127   friend class Toc;
128   friend class TrackReader;
129   friend class SubTrackIterator;
130 
131   TrackData::Mode type_; // track type
132   TrackData::SubChannelMode subChannelType_; // sub-channel mode
133   int audioCutMode_; /* -1: undefined
134 			 1: lengths of all sub-tracks are in units of samples
135 			 0: lengths of all sub-tracks are in byte units
136 		     */
137 
138   Msf length_; // total length of track
139   Msf start_;  // logical start of track data, end of pre-gap
140                // (where index switches from 0 to 1)
141   Msf end_;    // end of track data, start of post-gap
142 
143   int nofSubTracks_;    // number of sub tracks
144   SubTrack *subTracks_; // list of subtracks
145   SubTrack *lastSubTrack_; // points to last sub-track in list
146 
147   int nofIndices_;      // number of index increments
148   Msf *index_;          // index increment times
149 
150 
151   int  isrcValid_;
152   char isrcCountry_[2];
153   char isrcOwner_[3];
154   char isrcYear_[2];
155   char isrcSerial_[5];
156 
157   struct {
158     unsigned int copy : 1;
159     unsigned int preEmphasis : 1;
160     unsigned int audioType : 1;
161   } flags_;
162 
163   CdTextContainer cdtext_;
164 
165   void update();
166 
167   void insertSubTrackAfter(SubTrack *, SubTrack *newSubtrack);
168   SubTrack *removeSubTrack(SubTrack *);
169 
170   void countSubTracks();
171   void mergeSubTracks();
172 
173   SubTrack *findSubTrack(unsigned long sample) const;
174   void checkConsistency();
175 };
176 
177 class TrackReader {
178 public:
179   TrackReader(const Track * = 0);
180   ~TrackReader();
181 
182   void init(const Track *);
183 
184   int openData();
185   long readData(int raw, int subChanEncodingMode, long lba, char *buf,
186 		long len);
187   int seekSample(unsigned long sample);
188   long readSamples(Sample *buf, long len);
189   void closeData();
190 
191   const char* curFilename();
192 
193 private:
194   const Track *track_;
195 
196   TrackDataReader reader;
197 
198   long readPos_; // current read position (blocks)
199   long readPosSample_; // current read position (samples)
200   const SubTrack *readSubTrack_; // actual read sub-track
201   int open_; // 1 indicates the 'openData()' was called
202 
203   unsigned long subChanDelayLineIndex_;
204   unsigned char subChanDelayLine_[8][24];
205 
206 
207   long readTrackData(Sample *buf, long len);
208   int readBlock(int raw, int subChanEncodingMode, long lba, Sample *buf);
209 };
210 
211 class SubTrackIterator {
212 public:
213   SubTrackIterator(const Track *);
214   ~SubTrackIterator();
215 
216   const SubTrack *first();
217   const SubTrack *next();
218 
219 private:
220   const Track *track_;
221   SubTrack *iterator_;
222 };
223 
224 #endif
225