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 
21 #ifndef __TRACKDATA_H__
22 #define __TRACKDATA_H__
23 
24 #include <iostream>
25 #include <string>
26 #include <set>
27 
28 #include "Sample.h"
29 
30 #define AUDIO_BLOCK_LEN 2352
31 #define MODE0_BLOCK_LEN 2336
32 #define MODE1_BLOCK_LEN 2048
33 #define MODE2_BLOCK_LEN 2336
34 
35 #define MODE2_FORM1_DATA_LEN 2048
36 #define MODE2_FORM2_DATA_LEN 2324
37 
38 #define PQ_SUBCHANNEL_LEN 16
39 #define PW_SUBCHANNEL_LEN 96
40 #define MAX_SUBCHANNEL_LEN 96
41 
42 #define SAMPLE_LEN 4
43 
44 class TrackData {
45 public:
46   enum Mode { AUDIO, MODE0, MODE1, MODE2, MODE2_FORM1, MODE2_FORM2,
47               MODE2_FORM_MIX, MODE1_RAW, MODE2_RAW };
48 
49   enum SubChannelMode { SUBCHAN_NONE, SUBCHAN_RW, SUBCHAN_RW_RAW };
50 
51   enum Type { DATAFILE, ZERODATA, STDIN, FIFO };
52 
53   enum FileType { RAW, WAVE, MP3, OGG };
54 
55   // creates an audio mode file entry
56   TrackData(const char *filename, long offset, unsigned long start,
57 	    unsigned long length);
58   TrackData(const char *filename, unsigned long start, unsigned long length);
59 
60   // creates a zero audio entry
61   TrackData(unsigned long length);
62 
63   // creates a zero data entry with given mode
64   TrackData(Mode, SubChannelMode, unsigned long length);
65 
66   // creates a file entry with given mode
67   TrackData(Mode, SubChannelMode, const char *filename, long offset,
68 	    unsigned long length);
69 
70   // create a fifo entry with given mode
71   TrackData(Mode, SubChannelMode, const char *filename, unsigned long length);
72 
73   // copy constructor
74   TrackData(const TrackData &);
75 
76   ~TrackData();
77 
type()78   Type type() const                        { return type_; }
mode()79   Mode mode() const                        { return mode_; }
subChannelMode()80   SubChannelMode subChannelMode() const    { return subChannelMode_; }
audioCutMode()81   int audioCutMode() const                 { return audioCutMode_; }
82 
filename()83   const char *filename() const             { return filename_; }
startPos()84   unsigned long startPos() const           { return startPos_; }
85   unsigned long length() const;
86 
87   // sets/returns flag for swapping expected byte order of audio samples
swapSamples(int f)88   void swapSamples(int f)                  { swapSamples_ = f != 0 ? 1 : 0; }
swapSamples()89   int swapSamples() const                  { return swapSamples_; }
90 
91   int determineLength();
92   int check(int trackNr) const;
93 
94   void effectiveFilename(const char*);
95 
96   void split(unsigned long, TrackData **part1, TrackData **part2);
97   TrackData *merge(const TrackData *) const;
98 
99   void print(std::ostream &, bool conversions = false) const;
100 
101   static int checkAudioFile(const char *fn, unsigned long *length);
102   static int waveLength(const char *filename, long offset, long *hdrlen,
103 			unsigned long *datalen = 0);
104   static int audioDataLength(const char *fname, long offset,
105 			     unsigned long *length);
106   static FileType audioFileType(const char *filename);
107   static int dataFileLength(const char *fname, long offset,
108 			    unsigned long *length);
109 
110   static unsigned long dataBlockSize(Mode, SubChannelMode);
111   static unsigned long subChannelSize(SubChannelMode);
112 
113   static const char *mode2String(Mode);
114   static const char *subChannelMode2String(SubChannelMode);
115 
116 private:
117   int audioCutMode_; /* defines if audio cut mode is requested, if yes
118 			all lengths are in sample units and sub-channel
119 			data is not allowed
120 		     */
121   Type type_; // type of data (file, stdin, zero)
122   Mode mode_; // data mode for recording (audio, mode0, mode1, ...)
123   SubChannelMode subChannelMode_; // sub-channel mode
124 
125   FileType fileType_; // only for audio mode data, type of file (raw, wave)
126 
127   char *filename_;    // used for object type 'FILE'
128   char *effFilename_; // effective filename (absolute path or converted file)
129 
130   long offset_; // byte offset into file
131 
132   unsigned long length_; // length of data in samples (for audio data) or bytes
133 
134   // only used for audio files:
135   unsigned long startPos_; // starting sample within file,
136                            // used for object type 'FILE', mode 'AUDIO'
137   int swapSamples_;        // 1 if expected byte order of audio samples should
138                            // be swapped
139 
140   friend class TrackDataReader;
141 
142   void init(const char *filename, long offset, unsigned long start,
143 	    unsigned long length);
144   void init(Mode, SubChannelMode, const char *filename, long offset,
145 	    unsigned long length);
146 
147 
148 };
149 
150 class TrackDataReader {
151 public:
152   TrackDataReader(const TrackData * = 0);
153   ~TrackDataReader();
154 
155   void init(const TrackData *);
156 
157   int openData();
158   void closeData();
159   long readData(Sample *buffer, long len);
160   int seekSample(unsigned long sample);
161 
trackData()162   const TrackData* trackData() const { return trackData_; }
163 
164   // returns number of bytes/samples that are left for reading
165   unsigned long readLeft() const;
166 
167 private:
168   const TrackData *trackData_;
169 
170   int open_;  // 1: data can be retrieved with 'readData()', 'fd_' is valid if
171               // object type is 'FILE'
172 
173   int fd_;         // used for object type 'FILE'
174   unsigned long readPos_; // actual read position (samples or bytes)
175                           // (0 .. length_-1)
176 
177   long headerLength_; // length of audio file header
178 
179   int readUnderRunMsgGiven_;
180 };
181 
182 #endif
183