summaryrefslogtreecommitdiffstats
path: root/src/sound/PeakFile.h
blob: ce1aeac73fd404e5dfd12b39fb4eb8e7972cc95d (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
// -*- c-indentation-style:"stroustrup" c-basic-offset: 4 -*- /*
/*
  Rosegarden
  A sequencer and musical notation editor.

  This program is Copyright 2000-2008
  Guillaume Laurent   <glaurent@telegraph-road.org>,
  Chris Cannam        <cannam@all-day-breakfast.com>,
  Richard Bown        <bownie@bownie.com>

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

#include <vector>

#include <tqobject.h>
#include <tqdatetime.h>

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

#ifndef _PEAKFILE_H_
#define _PEAKFILE_H_

// A PeakFile is generated to the BWF Supplement 3 Peak Envelope Chunk
// format as defined here:
//
// http://www.ebu.ch/pmc_bwf.html
//
// To comply with BWF format files this chunk can be embedded into
// the sample file itself (writeToHandle()) or used to generate an
// external peak file (write()).  At the moment the only type of file
// with an embedded peak chunk is the BWF file itself.
//
//



namespace Rosegarden
{

class AudioFile;


typedef std::pair<RealTime, RealTime> SplitPointPair;

class PeakFile : public TQObject, public SoundFile
{
    Q_OBJECT

public:
    PeakFile(AudioFile *audioFile);
    virtual ~PeakFile();

    // Copy constructor
    //
    PeakFile(const PeakFile &);

    // Standard file methods
    //
    virtual bool open();
    virtual void close();

    // Write to standard peak file
    //
    virtual bool write();

    // Write the file, emit progress signal and process app events
    //
    virtual bool write(unsigned short updatePercentage);

    // Write peak chunk to file handle (BWF)
    //
    bool writeToHandle(std::ofstream *file, unsigned short updatePercentage);

    // Is the peak file valid and up to date?
    //
    bool isValid();

    // Vital file stats
    //
    void printStats();

    // Get a preview of a section of the audio file where that section
    // is "width" pixels.
    //
    std::vector<float> getPreview(const RealTime &startTime,
                                  const RealTime &endTime,
                                  int width,
                                  bool showMinima);

    AudioFile* getAudioFile() { return m_audioFile; }
    const AudioFile* getAudioFile() const { return m_audioFile; }

    // Scan to a peak and scan forward a number of peaks
    //
    bool scanToPeak(int peak);
    bool scanForward(int numberOfPeaks);

    // Find threshold crossing points
    //
    std::vector<SplitPointPair> getSplitPoints(const RealTime &startTime,
                                               const RealTime &endTime,
                                               int threshold,
                                               const RealTime &minLength);
    // Accessors
    //
    int getVersion() const { return m_version; }
    int getFormat() const { return m_format; }
    int getPointsPerValue() const { return m_pointsPerValue; }
    int getBlockSize() const { return m_blockSize; }
    int getChannels() const { return m_channels; }
    int getNumberOfPeaks() const { return m_numberOfPeaks; }
    int getPositionPeakOfPeaks() const { return m_positionPeakOfPeaks; }
    int getOffsetToPeaks() const { return m_offsetToPeaks; }
    int getBodyBytes() const { return m_bodyBytes; }
    TQDateTime getModificationTime() const { return m_modificationTime; }
    std::streampos getChunkStartPosition() const
        { return m_chunkStartPosition; }

    bool isProcessingPeaks() const { return m_keepProcessing; }
    void setProcessingPeaks(bool value) { m_keepProcessing = value; }

signals:
    void setProgress(int);
    
protected:
    // Write the peak header and the peaks themselves
    //
    void writeHeader(std::ofstream *file);
    void writePeaks(unsigned short updatePercentage,
                    std::ofstream *file);

    // Get the position of a peak for a given time
    //
    int getPeak(const RealTime &time);

    // And the time of a peak
    //
    RealTime getTime(int peak);

    // Parse the header
    //
    void parseHeader();

    AudioFile *m_audioFile;

    // Some Peak Envelope Chunk parameters
    //
    int m_version;
    int m_format;  // bytes in peak value (1 or 2)
    int m_pointsPerValue;
    int m_blockSize;
    int m_channels;
    int m_numberOfPeaks;
    int m_positionPeakOfPeaks;
    int m_offsetToPeaks;
    int m_bodyBytes;

    // Peak timestamp
    //
    TQDateTime m_modificationTime;

    std::streampos m_chunkStartPosition;

    // For cacheing of peak information in memory we use the last query 
    // parameters as our key to the cached data.
    //
    RealTime           m_lastPreviewStartTime;
    RealTime           m_lastPreviewEndTime;
    int                m_lastPreviewWidth;
    bool               m_lastPreviewShowMinima;
    std::vector<float> m_lastPreviewCache;

    // Do we actually want to keep processing this peakfile?
    // In case we get a cancel.
    //
    bool               m_keepProcessing;

    std::string        m_peakCache;
    
};

}


#endif // _PEAKFILE_H_