Mercurial > hg > svcore
comparison data/model/AggregateWaveModel.cpp @ 297:c022976d18e8
* Merge from sv-match-alignment branch (excluding alignment-specific document).
- add aggregate wave model (not yet complete enough to be added as a true
model in a layer, but there's potential)
- add play solo mode
- add alignment model -- unused in plain SV
- fix two plugin leaks
- add m3u playlist support (opens all files at once, potentially hazardous)
- fix retrieval of pre-encoded URLs
- add ability to resample audio files on import, so as to match rates with
other files previously loaded; add preference for same
- add preliminary support in transform code for range and rate of transform
input
- reorganise preferences dialog, move dark-background option to preferences,
add option for temporary directory location
author | Chris Cannam |
---|---|
date | Fri, 28 Sep 2007 13:56:38 +0000 |
parents | |
children | 5877d68815c7 |
comparison
equal
deleted
inserted
replaced
296:2b6c99b607f1 | 297:c022976d18e8 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2007 QMUL. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #include "AggregateWaveModel.h" | |
17 | |
18 #include <iostream> | |
19 | |
20 PowerOfSqrtTwoZoomConstraint | |
21 AggregateWaveModel::m_zoomConstraint; | |
22 | |
23 AggregateWaveModel::AggregateWaveModel(ChannelSpecList channelSpecs) : | |
24 m_components(channelSpecs) | |
25 { | |
26 for (ChannelSpecList::const_iterator i = channelSpecs.begin(); | |
27 i != channelSpecs.end(); ++i) { | |
28 if (i->model->getSampleRate() != | |
29 channelSpecs.begin()->model->getSampleRate()) { | |
30 std::cerr << "AggregateWaveModel::AggregateWaveModel: WARNING: Component models do not all have the same sample rate" << std::endl; | |
31 break; | |
32 } | |
33 } | |
34 } | |
35 | |
36 AggregateWaveModel::~AggregateWaveModel() | |
37 { | |
38 } | |
39 | |
40 bool | |
41 AggregateWaveModel::isOK() const | |
42 { | |
43 for (ChannelSpecList::const_iterator i = m_components.begin(); | |
44 i != m_components.end(); ++i) { | |
45 if (!i->model->isOK()) return false; | |
46 } | |
47 return true; | |
48 } | |
49 | |
50 bool | |
51 AggregateWaveModel::isReady(int *completion) const | |
52 { | |
53 if (completion) *completion = 100; | |
54 bool ready = true; | |
55 for (ChannelSpecList::const_iterator i = m_components.begin(); | |
56 i != m_components.end(); ++i) { | |
57 int completionHere = 100; | |
58 if (!i->model->isReady(&completionHere)) ready = false; | |
59 if (completion && completionHere < *completion) { | |
60 *completion = completionHere; | |
61 } | |
62 } | |
63 return ready; | |
64 } | |
65 | |
66 size_t | |
67 AggregateWaveModel::getFrameCount() const | |
68 { | |
69 size_t count = 0; | |
70 | |
71 for (ChannelSpecList::const_iterator i = m_components.begin(); | |
72 i != m_components.end(); ++i) { | |
73 size_t thisCount = i->model->getEndFrame() - i->model->getStartFrame(); | |
74 if (thisCount > count) count = thisCount; | |
75 } | |
76 | |
77 return count; | |
78 } | |
79 | |
80 size_t | |
81 AggregateWaveModel::getChannelCount() const | |
82 { | |
83 return m_components.size(); | |
84 } | |
85 | |
86 size_t | |
87 AggregateWaveModel::getSampleRate() const | |
88 { | |
89 if (m_components.empty()) return 0; | |
90 return m_components.begin()->model->getSampleRate(); | |
91 } | |
92 | |
93 Model * | |
94 AggregateWaveModel::clone() const | |
95 { | |
96 return new AggregateWaveModel(m_components); | |
97 } | |
98 | |
99 size_t | |
100 AggregateWaveModel::getValues(int channel, size_t start, size_t end, | |
101 float *buffer) const | |
102 { | |
103 int ch0 = channel, ch1 = channel; | |
104 bool mixing = false; | |
105 if (channel == -1) { | |
106 ch0 = 0; | |
107 ch1 = getChannelCount()-1; | |
108 mixing = true; | |
109 } | |
110 | |
111 float *readbuf = buffer; | |
112 if (mixing) { | |
113 readbuf = new float[end - start]; | |
114 for (size_t i = 0; i < end - start; ++i) { | |
115 buffer[i] = 0.f; | |
116 } | |
117 } | |
118 | |
119 size_t sz = end - start; | |
120 | |
121 for (int c = ch0; c <= ch1; ++c) { | |
122 size_t szHere = | |
123 m_components[c].model->getValues(m_components[c].channel, | |
124 start, end, | |
125 readbuf); | |
126 if (szHere < sz) sz = szHere; | |
127 if (mixing) { | |
128 for (size_t i = 0; i < end - start; ++i) { | |
129 buffer[i] += readbuf[i]; | |
130 } | |
131 } | |
132 } | |
133 | |
134 if (mixing) delete[] readbuf; | |
135 return sz; | |
136 } | |
137 | |
138 size_t | |
139 AggregateWaveModel::getValues(int channel, size_t start, size_t end, | |
140 double *buffer) const | |
141 { | |
142 int ch0 = channel, ch1 = channel; | |
143 bool mixing = false; | |
144 if (channel == -1) { | |
145 ch0 = 0; | |
146 ch1 = getChannelCount()-1; | |
147 mixing = true; | |
148 } | |
149 | |
150 double *readbuf = buffer; | |
151 if (mixing) { | |
152 readbuf = new double[end - start]; | |
153 for (size_t i = 0; i < end - start; ++i) { | |
154 buffer[i] = 0.f; | |
155 } | |
156 } | |
157 | |
158 size_t sz = end - start; | |
159 | |
160 for (int c = ch0; c <= ch1; ++c) { | |
161 size_t szHere = | |
162 m_components[c].model->getValues(m_components[c].channel, | |
163 start, end, | |
164 readbuf); | |
165 if (szHere < sz) sz = szHere; | |
166 if (mixing) { | |
167 for (size_t i = 0; i < end - start; ++i) { | |
168 buffer[i] += readbuf[i]; | |
169 } | |
170 } | |
171 } | |
172 | |
173 if (mixing) delete[] readbuf; | |
174 return sz; | |
175 } | |
176 | |
177 void | |
178 AggregateWaveModel::getRanges(size_t channel, size_t start, size_t end, | |
179 RangeBlock &ranges, size_t &blockSize) const | |
180 { | |
181 //!!! complete | |
182 } | |
183 | |
184 AggregateWaveModel::Range | |
185 AggregateWaveModel::getRange(size_t channel, size_t start, size_t end) const | |
186 { | |
187 //!!! complete | |
188 return Range(); | |
189 } | |
190 | |
191 size_t | |
192 AggregateWaveModel::getComponentCount() const | |
193 { | |
194 return m_components.size(); | |
195 } | |
196 | |
197 AggregateWaveModel::ModelChannelSpec | |
198 AggregateWaveModel::getComponent(size_t c) const | |
199 { | |
200 return m_components[c]; | |
201 } | |
202 | |
203 void | |
204 AggregateWaveModel::componentModelChanged() | |
205 { | |
206 emit modelChanged(); | |
207 } | |
208 | |
209 void | |
210 AggregateWaveModel::componentModelChanged(size_t start, size_t end) | |
211 { | |
212 emit modelChanged(start, end); | |
213 } | |
214 | |
215 void | |
216 AggregateWaveModel::componentModelCompletionChanged() | |
217 { | |
218 emit completionChanged(); | |
219 } | |
220 | |
221 void | |
222 AggregateWaveModel::toXml(QTextStream &out, | |
223 QString indent, | |
224 QString extraAttributes) const | |
225 { | |
226 //!!! complete | |
227 } | |
228 |