1 /*
2  * @(#)TSE3MDL.h 3.00 20 August 2000
3  *
4  * Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
5  *
6  * This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
7  *
8  * This library is modifiable/redistributable under the terms of the GNU
9  * General Public License.
10  *
11  * You should have received a copy of the GNU General Public License along
12  * with this program; see the file COPYING. If not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14  *
15  */
16 
17 #ifndef TSE3_TSE3MDL_H
18 #define TSE3_TSE3MDL_H
19 
20 #include "tse3/Serializable.h"
21 
22 #include <string>
23 #include <cstddef>
24 #include <iostream>
25 
26 namespace TSE3
27 {
28     class Song;
29 
30     /**
31      * The TSE3MDL object provides file operations for the @ref TSE3 library,
32      * being the main entry point for saving/loading in the TSE3MDL file
33      * format.
34      *
35      * It uses the @ref Serializable interface implemented by the various TSE3
36      * classes.
37      *
38      * @short   Object used to load/save TSE3MDL song files
39      * @author  Pete Goodliffe
40      * @version 1.00
41      * @see     Serializable
42      */
43     class TSE3MDL
44     {
45         public:
46             /**
47              * Create a TSE3MDL file operations object.
48              *
49              * @param appname Name of the application using TSE3.
50              *                This is saved into the TSE3MDL file header
51              * @param verbose Diagnostic level, normally you want to ignore
52              *                this and accept the default value
53              * @param diag    Where to send any diagnostic output
54              */
55             TSE3MDL(const std::string &appname = "",
56                     int                verbose = 0,
57                     std::ostream      &diag    = std::cout);
58 
59             /**
60              * Save the given @ref Song to the file specified. If the file
61              * already exists it will be overwritten.
62              *
63              * This will save the appropriate fill header and then call the
64              * @ref Song class's save method.
65              *
66              * @param  filename Filename to save to
67              * @param  song     Song object to save
68              * @throws SerializableError
69              */
70             void save(const std::string &filename, const Song *song);
71 
72             /**
73              * As @ref save above, but you specify the ostream.
74              */
75             void save(std::ostream &out, const Song *song);
76 
77             /**
78              * Load a @ref Song from the file specified. The returned @ref Song
79              * will have been newed from the free store, and so when you have
80              * finished with it it is your responsibility to delete it.
81              *
82              * @param  filename Filename to save to
83              * @param  progress The progress callback to keep informed of
84              *                  progress, or zero for no callback
85              * @return The loaded @ref Song - you must delete it
86              * @throws SerializableError
87              */
88             Song *load(const std::string &filename, Progress *progress = 0);
89 
90             static const int MajorVersion = 100;
91             static const int MinorVersion = 100;
92 
93         private:
94 
95             /**
96              * An internal class for saving and loading the TSE3MDL file
97              * header.
98              *
99              * The notable feature of this class is that it is the only one
100              * that actually writes into most of the @ref SerializableLoadInfo
101              * structure.
102              */
103             class Header : public Serializable
104             {
105                 public:
106                     Header(const std::string &originator);
107                     virtual ~Header();
108                     virtual void save(std::ostream &out, int indentLevel);
109                     virtual void load(std::istream &in,
110                                       SerializableLoadInfo &info);
111                 private:
112                     std::string originator;
113                     Header &operator=(const Header &);
114                     Header(const Header &);
115             } header;
116 
117             int           verbose;
118             std::ostream &diag;
119     };
120 
121     /**
122      * The FileRegoniser class will return information about a given file.
123      *
124      * It can recognise three file types - the three types that TSE3 provides
125      * support for. These are:
126      * @li Native TSE3MDL files
127      * @li TSE2MDL (the file format of TSE2)
128      * @li Standard MIDI files
129      *
130      * @short   Object used to work out a file's type
131      * @author  Pete Goodliffe
132      * @version 1.00
133      */
134     class FileRecogniser
135     {
136         public:
137 
138             /**
139              * Creates a FileRecogniser for a particular file.
140              *
141              * @param filename The name of the file to query
142              */
143             FileRecogniser(const std::string &filename);
144 
145             enum
146             {
147                 Type_Error,   // file could not be read (does it exist?)
148                 Type_Unknown, // file type not recognised
149                 Type_TSE3MDL, // TSE3MDL file
150                 Type_TSE2MDL, // TSEMDL (TSE2) file
151                 Type_Midi     // MIDI file
152             };
153 
154             /**
155              * Returns the type of the file. The value will be one of the
156              * below:
157              * @li Type_Unknown - No recognised music file type
158              * @li Type_TSE3MDL - A TSE3MDL file
159              * @li Type_TSE2MDL - A TSEMDL file (from TSE2)
160              * @li Type_Midi    - A standard MIDI file
161              *
162              * @return The type of the specified file
163              */
type()164             int type() const { return _type; }
165 
166             /**
167              * Returns the size of the file.
168              *
169              * @return The size of the file in bytes.
170              */
size()171             size_t size() const { return _size; }
172 
173             /**
174              * Loads the file in the appropriate way.
175              *
176              * This will use either the @ref TSE3MDL, @ref MidiImport or
177              * @ref TSE2MDL classes to create a @ref Song from the data in
178              * the file.
179              *
180              * If the file is of an unknown type, this will return zero.
181              *
182              * Any exception that may be thrown by the three file loading
183              * classes may pass from this method.
184              *
185              * The loaded @ref Song will have been created with new, it is
186              * now your responsibility to delete it.
187              *
188              * @param  progress A callback progress interface, or zero for none
189              * @return A newly loaded @ref Song, or zero for faliure
190              */
191             Song *load(Progress *progress);
192 
193         private:
194 
195             std::string filename;
196             int         _type;
197             size_t      _size;
198     };
199 }
200 
201 #endif
202