summaryrefslogtreecommitdiffstats
path: root/src/sound/RIFFAudioFile.h
blob: a84630666af349db5552595a08e6fb9fc5bc9ceb (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
// -*- c-basic-offset: 4 -*-

/*
    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.
*/


// Resource Interchange File Formt - a chunk based audio 
// file format.  Type of chunk varies with specialisation
// of this class - WAV files are a specialisation with just
// a format chunk, BWF has more chunks.
//
//

#ifndef _RIFFAUDIOFILE_H_
#define _RIFFAUDIOFILE_H_

#include <string>
#include <vector>

#include "AudioFile.h"
#include "RealTime.h"

namespace Rosegarden
{

class RIFFAudioFile : public AudioFile
{
public:
    RIFFAudioFile(unsigned int id,
                  const std::string &name,
                  const std::string &fileName);

    RIFFAudioFile(const std::string &fileName,
                  unsigned int channels,
                  unsigned int sampleRate,
                  unsigned int bytesPerSecond,
                  unsigned int bytesPerFrame,
                  unsigned int bitsPerSample);

    ~RIFFAudioFile();

    typedef enum {
        PCM,
        FLOAT
    } SubFormat;

    // Our main control methods - again keeping abstract at this level
    //
    //virtual bool open() = 0;
    //virtual bool write() = 0;
    //virtual void close() = 0;

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

    // Slightly dodgy code here - we keep these functions here
    // because I don't want to duplicate them in PlayableRIFFAudioFile
    // and also don't want that class to inherit this one.
    //
    // Of course the file handle we use in might be pointing to
    // any file - for the most part we just assume it's an audio
    // file.
    //
    //
    // 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.
    // 
    virtual bool scanTo(const RealTime &time);
    virtual bool scanTo(std::ifstream *file, const RealTime &time);

    // Scan forward in a file by a certain amount of time
    //
    virtual bool scanForward(const RealTime &time);
    virtual bool scanForward(std::ifstream *file, const RealTime &time);

    // 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);
    virtual unsigned int getSampleFrames(std::ifstream *file,
                                         char *buf,
                                         unsigned int frames);
    virtual std::string getSampleFrames(unsigned int frames);

    // 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);
    virtual std::string getSampleFrameSlice(const RealTime &time);

    // Append a string of samples to an already open (for writing)
    // audio file.
    //
    virtual bool appendSamples(const std::string &buffer);
    virtual bool appendSamples(const char *buf, unsigned int frames);

    // Get the length of the sample in Seconds/Microseconds
    //
    virtual RealTime getLength();

    // Accessors
    //
    virtual unsigned int getBytesPerFrame() { return m_bytesPerFrame; }
    unsigned int getBytesPerSecond() { return m_bytesPerSecond; }

    // Allow easy identification of wav file type
    //
    static AudioFileType identifySubType(const std::string &filename);

    // Convert a single sample from byte format, given the right
    // number of bytes for the sample width
    float convertBytesToSample(const unsigned char *bytes);

    // 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:
    //virtual void parseHeader(const std::string &header);
    //virtual void parseBody();

    // Find and read in the format chunk of a RIFF file - without
    // this chunk we don't actually have a RIFF file.
    //
    void readFormatChunk();

    // Write out the Format chunk from the internal data we have
    //
    void writeFormatChunk();

    SubFormat m_subFormat;
    unsigned int   m_bytesPerSecond;
    unsigned int   m_bytesPerFrame;
};

}


#endif // _RIFFAUDIOFILE_H_