Chris@175
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@175
|
2
|
Chris@175
|
3 /*
|
Chris@175
|
4 Sonic Visualiser
|
Chris@175
|
5 An audio file viewer and annotation editor.
|
Chris@175
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@202
|
7 This file copyright 2006 QMUL.
|
Chris@175
|
8
|
Chris@175
|
9 This program is free software; you can redistribute it and/or
|
Chris@175
|
10 modify it under the terms of the GNU General Public License as
|
Chris@175
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@175
|
12 License, or (at your option) any later version. See the file
|
Chris@175
|
13 COPYING included with this distribution for more information.
|
Chris@175
|
14 */
|
Chris@175
|
15
|
Chris@1122
|
16 #ifndef WRITABLE_WAVE_FILE_MODEL_H
|
Chris@1122
|
17 #define WRITABLE_WAVE_FILE_MODEL_H
|
Chris@175
|
18
|
Chris@175
|
19 #include "WaveFileModel.h"
|
Chris@1122
|
20 #include "ReadOnlyWaveFileModel.h"
|
Chris@1122
|
21 #include "PowerOfSqrtTwoZoomConstraint.h"
|
Chris@175
|
22
|
Chris@175
|
23 class WavFileWriter;
|
Chris@175
|
24 class WavFileReader;
|
Chris@175
|
25
|
Chris@1122
|
26 class WritableWaveFileModel : public WaveFileModel
|
Chris@175
|
27 {
|
Chris@175
|
28 Q_OBJECT
|
Chris@175
|
29
|
Chris@175
|
30 public:
|
Chris@1040
|
31 WritableWaveFileModel(sv_samplerate_t sampleRate, int channels, QString path = "");
|
Chris@175
|
32 ~WritableWaveFileModel();
|
Chris@175
|
33
|
Chris@188
|
34 /**
|
Chris@188
|
35 * Call addSamples to append a block of samples to the end of the
|
Chris@1337
|
36 * file.
|
Chris@1337
|
37 *
|
Chris@1337
|
38 * This function only appends the samples to the file being
|
Chris@1337
|
39 * written; it does not update the model's view of the samples in
|
Chris@1337
|
40 * that file. That is, it updates the file on disc but the model
|
Chris@1337
|
41 * itself does not change its content. This is because re-reading
|
Chris@1337
|
42 * the file to update the model may be more expensive than adding
|
Chris@1337
|
43 * the samples in the first place. If you are writing small
|
Chris@1337
|
44 * numbers of samples repeatedly, you probably only want the model
|
Chris@1337
|
45 * to update periodically rather than after every write.
|
Chris@1337
|
46 *
|
Chris@1337
|
47 * Call updateModel() periodically to tell the model to update its
|
Chris@1337
|
48 * own view of the samples in the file being written.
|
Chris@1337
|
49 *
|
Chris@1337
|
50 * Call setWriteProportion() periodically if the file being
|
Chris@1337
|
51 * written has known duration and you want the model to be able to
|
Chris@1337
|
52 * report the write progress as a percentage.
|
Chris@1337
|
53 *
|
Chris@1337
|
54 * Call writeComplete() when the file has been completely written.
|
Chris@188
|
55 */
|
Chris@1325
|
56 virtual bool addSamples(const float *const *samples, sv_frame_t count);
|
Chris@1133
|
57
|
Chris@1133
|
58 /**
|
Chris@1337
|
59 * Tell the model to update its own (read) view of the (written)
|
Chris@1337
|
60 * file. May cause modelChanged() and modelChangedWithin() to be
|
Chris@1337
|
61 * emitted. See the comment to addSamples above for rationale.
|
Chris@1337
|
62 */
|
Chris@1337
|
63 void updateModel();
|
Chris@1337
|
64
|
Chris@1337
|
65 /**
|
Chris@1133
|
66 * Set the proportion of the file which has been written so far,
|
Chris@1133
|
67 * as a percentage. This may be used to indicate progress.
|
Chris@1133
|
68 *
|
Chris@1133
|
69 * Note that this differs from the "completion" percentage
|
Chris@1133
|
70 * reported through isReady()/getCompletion(). That percentage is
|
Chris@1133
|
71 * updated when "internal processing has advanced... but the model
|
Chris@1133
|
72 * has not changed externally", i.e. it reports progress in
|
Chris@1133
|
73 * calculating the initial state of a model. In contrast, an
|
Chris@1133
|
74 * update to setWriteProportion corresponds to a change in the
|
Chris@1133
|
75 * externally visible state of the model (i.e. it contains more
|
Chris@1133
|
76 * data than before).
|
Chris@1133
|
77 */
|
Chris@1133
|
78 void setWriteProportion(int proportion);
|
Chris@1133
|
79
|
Chris@1133
|
80 /**
|
Chris@1133
|
81 * Indicate that writing is complete. You should call this even if
|
Chris@1337
|
82 * you have never called setWriteProportion() or updateModel().
|
Chris@1133
|
83 */
|
Chris@1133
|
84 void writeComplete();
|
Chris@1133
|
85
|
Chris@1133
|
86 static const int PROPORTION_UNKNOWN;
|
Chris@1133
|
87
|
Chris@1133
|
88 /**
|
Chris@1133
|
89 * Get the proportion of the file which has been written so far,
|
Chris@1133
|
90 * as a percentage. Return PROPORTION_UNKNOWN if unknown.
|
Chris@1133
|
91 */
|
Chris@1133
|
92 int getWriteProportion() const;
|
Chris@175
|
93
|
Chris@175
|
94 bool isOK() const;
|
Chris@175
|
95 bool isReady(int *) const;
|
Chris@1133
|
96
|
Chris@1133
|
97 /**
|
Chris@1133
|
98 * Return the generation completion percentage of this model. This
|
Chris@1133
|
99 * is always 100, because the model is always in a complete state
|
Chris@1133
|
100 * -- it just contains varying amounts of data depending on how
|
Chris@1133
|
101 * much has been written.
|
Chris@1133
|
102 */
|
Chris@1133
|
103 virtual int getCompletion() const { return 100; }
|
Chris@188
|
104
|
Chris@179
|
105 const ZoomConstraint *getZoomConstraint() const {
|
Chris@179
|
106 static PowerOfSqrtTwoZoomConstraint zc;
|
Chris@179
|
107 return &zc;
|
Chris@179
|
108 }
|
Chris@179
|
109
|
Chris@1038
|
110 sv_frame_t getFrameCount() const;
|
Chris@929
|
111 int getChannelCount() const { return m_channels; }
|
Chris@1040
|
112 sv_samplerate_t getSampleRate() const { return m_sampleRate; }
|
Chris@1122
|
113 sv_samplerate_t getNativeRate() const { return m_sampleRate; }
|
Chris@1122
|
114
|
Chris@1122
|
115 QString getTitle() const {
|
Chris@1122
|
116 if (m_model) return m_model->getTitle();
|
Chris@1122
|
117 else return "";
|
Chris@1122
|
118 }
|
Chris@1122
|
119 QString getMaker() const {
|
Chris@1122
|
120 if (m_model) return m_model->getMaker();
|
Chris@1122
|
121 else return "";
|
Chris@1122
|
122 }
|
Chris@1122
|
123 QString getLocation() const {
|
Chris@1122
|
124 if (m_model) return m_model->getLocation();
|
Chris@1122
|
125 else return "";
|
Chris@1122
|
126 }
|
Chris@175
|
127
|
Chris@175
|
128 float getValueMinimum() const { return -1.0f; }
|
Chris@175
|
129 float getValueMaximum() const { return 1.0f; }
|
Chris@175
|
130
|
Chris@1038
|
131 virtual sv_frame_t getStartFrame() const { return m_startFrame; }
|
Chris@1038
|
132 virtual sv_frame_t getEndFrame() const { return m_startFrame + getFrameCount(); }
|
Chris@175
|
133
|
Chris@1038
|
134 void setStartFrame(sv_frame_t startFrame);
|
Chris@175
|
135
|
Chris@1326
|
136 virtual floatvec_t getData(int channel, sv_frame_t start, sv_frame_t count) const;
|
Chris@175
|
137
|
Chris@1326
|
138 virtual std::vector<floatvec_t> getMultiChannelData(int fromchannel, int tochannel, sv_frame_t start, sv_frame_t count) const;
|
Chris@363
|
139
|
Chris@929
|
140 virtual int getSummaryBlockSize(int desired) const;
|
Chris@377
|
141
|
Chris@1038
|
142 virtual void getSummaries(int channel, sv_frame_t start, sv_frame_t count,
|
Chris@929
|
143 RangeBlock &ranges, int &blockSize) const;
|
Chris@300
|
144
|
Chris@1038
|
145 virtual Range getSummary(int channel, sv_frame_t start, sv_frame_t count) const;
|
Chris@175
|
146
|
Chris@345
|
147 QString getTypeName() const { return tr("Writable Wave File"); }
|
Chris@345
|
148
|
Chris@175
|
149 virtual void toXml(QTextStream &out,
|
Chris@175
|
150 QString indent = "",
|
Chris@175
|
151 QString extraAttributes = "") const;
|
Chris@175
|
152
|
Chris@175
|
153 protected:
|
Chris@1122
|
154 ReadOnlyWaveFileModel *m_model;
|
Chris@175
|
155 WavFileWriter *m_writer;
|
Chris@175
|
156 WavFileReader *m_reader;
|
Chris@1040
|
157 sv_samplerate_t m_sampleRate;
|
Chris@929
|
158 int m_channels;
|
Chris@1038
|
159 sv_frame_t m_frameCount;
|
Chris@1038
|
160 sv_frame_t m_startFrame;
|
Chris@1133
|
161 int m_proportion;
|
Chris@175
|
162 };
|
Chris@175
|
163
|
Chris@175
|
164 #endif
|
Chris@175
|
165
|