summaryrefslogtreecommitdiffstats
path: root/src/sound/AudioFile.h
blob: 95e907579d1e5e8eb1ec46a7db6961fcadf17fb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
    Rosegarden
    A sequencer and musical notation editor.

    This program is Copyright 2000-2008
        Guillaume Laurent   <[email protected]>,
        Chris Cannam        <[email protected]>,
        Richard Bown        <[email protected]>

    The moral right of the authors to claim authorship of this work
    has been asserted.

    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.  See the file
    COPYING included with this distribution for more information.
*/


#ifndef _AUDIOFILE_H_
#define _AUDIOFILE_H_

#include <string>
#include <vector>
#include <cmath>

#include <tqfileinfo.h>

#include "SoundFile.h"
#include "RealTime.h"

// An AudioFile maintains information pertaining to an audio sample.
// This is an abstract base class from which we derive our actual
// AudioFile types - WAV, BWF, AIFF etc.
//
//

namespace Rosegarden
{

typedef unsigned int AudioFileId;

// The different types of audio file we support.
//
typedef enum
{

    UNKNOWN, // not yet known
    WAV,     // RIFF (Resource Interchange File Format) wav file 
    BWF,     // RIFF Broadcast Wave File
    AIFF,    // Audio Interchange File Format
    MP3

} AudioFileType;

class AudioFile : public SoundFile
{
public:
    // The "read" constructor - open a file
    // an assign a name and id to it.
    //
    AudioFile(AudioFileId id,
              const std::string &name,
              const std::string &fileName);

    // The "write" constructor - we only need to
    // specify a filename and some parameters and
    // then write it out.
    //
    AudioFile(const std::string &fileName,
              unsigned int channels,
              unsigned int sampleRate,
              unsigned int bitsPerSample);

    ~AudioFile();

    // Id of this audio file (used by AudioFileManager)
    //
    void setId(AudioFileId id) { m_id = id; }
    AudioFileId getId() const { return m_id; }

    // Name of this sample - in addition to a filename
    //
    void setName(const std::string &name) { m_name = name; }
    std::string getName() const { return m_name; }

    // Used for waveform interpolation at a point
    //
    float sinc(float value) { return sin(M_PI * value)/ M_PI * value; }

    // Audio file identifier - set in constructor of file type
    //
    AudioFileType getType() const { return m_type; }

    unsigned int getBitsPerSample() const { return m_bitsPerSample; }
    unsigned int getSampleRate() const { return m_sampleRate; }
    unsigned int getChannels() const { return m_channels; }
    
    // We must continue our main control abstract methods from SoundFile
    // and add our own close() method that will add any relevant header
    // information to an audio file that has been written and is now
    // being closed.
    //
    virtual bool open() = 0;
    virtual bool write() = 0;
    virtual void close() = 0;

    // Show the information we have on this file
    //
    virtual void printStats() = 0;

    // Move file pointer to relative time in data chunk - shouldn't be
    // less than zero.  Returns true if the scan time was valid and
    // successful.  Need two interfaces because when playing we use an
    // external file handle (one per playback instance - PlayableAudioFile)
    // 
    virtual bool scanTo(const RealTime &time) = 0;
    virtual bool scanTo(std::ifstream *file, const RealTime &time) = 0;

    // Scan forward in a file by a certain amount of time - same
    // double interface (simple one for peak file generation, other
    // for playback).
    //
    virtual bool scanForward(const RealTime &time) = 0;
    virtual bool scanForward(std::ifstream *file, const RealTime &time) = 0;

    // Return a number of samples - caller will have to
    // de-interleave n-channel samples themselves.
    //
    virtual std::string getSampleFrames(std::ifstream *file,
                                        unsigned int frames) = 0;

    // Return a number of samples - caller will have to
    // de-interleave n-channel samples themselves.  Place
    // results in buf, return actual number of frames read.
    //
    virtual unsigned int getSampleFrames(std::ifstream *file,
                                         char *buf,
                                         unsigned int frames) = 0;

    // Return a number of (possibly) interleaved samples
    // over a time slice from current file pointer position.
    //
    virtual std::string getSampleFrameSlice(std::ifstream *file,
                                            const RealTime &time) = 0;

    // Append a string of samples to an already open (for writing)
    // audio file.  Caller must have interleaved samples etc.
    //
    virtual bool appendSamples(const std::string &buffer) = 0;

    // Append a string of samples to an already open (for writing)
    // audio file.  Caller must have interleaved samples etc.
    //
    virtual bool appendSamples(const char *buffer, unsigned int frames) = 0;

    // Get the length of the sample file in RealTime
    //
    virtual RealTime getLength() = 0;

    // Offset to start of sample data
    //
    virtual std::streampos getDataOffset() = 0;

    // Return the peak file name
    //
    virtual std::string getPeakFilename() = 0;

    // Return the modification timestamp
    //
    TQDateTime getModificationDateTime();

    // Implement in actual file type
    //
    virtual unsigned int getBytesPerFrame() = 0;

    // Decode and de-interleave the given samples that were retrieved
    // from this file or another with the same format as it.  Place
    // the results in the given float buffer.  Return true for
    // success.  This function does crappy resampling if necessary.
    // 
    virtual bool decode(const unsigned char *sourceData,
                        size_t sourceBytes,
                        size_t targetSampleRate,
                        size_t targetChannels,
                        size_t targetFrames,
                        std::vector<float *> &targetData,
                        bool addToResultBuffers = false) = 0;

protected:

    AudioFileType  m_type;   // AudioFile type
    AudioFileId    m_id;     // AudioFile ID
    std::string    m_name;   // AudioFile name (not filename)

    unsigned int   m_bitsPerSample;
    unsigned int   m_sampleRate;
    unsigned int   m_channels;

    // How many bytes do we read before we get to the data?
    // Could be huge so we make it a long long. -1 means it
    // hasn't been set yet.
    //
    long long      m_dataChunkIndex;

    TQFileInfo     *m_fileInfo;

};

}


#endif // _AUDIOFILE_H_