Mercurial > hg > svapp
comparison audioio/AudioGenerator.cpp @ 4:5865094175ea
* Fix update and play limits for play-selection mode when not looping
* Fix playback in loop mode when no selection -- but the GUI update for
this is still wrong on the flyback
* Various fixes and improvements to making selections, particularly during
playback
* Draw selection under non-opaque non-scrollable layers, so as to improve
cacheing
* Show selection limits as text when drawing selection
* Allow user to find missing audio files when loading session
* Cross-fade selections when in play-selection mode -- mostly. We don't
cross-fade on a processing block boundary, and unfortunately with short
selections the selection boundary is quite likely to coincide with a block
boundary.
author | Chris Cannam |
---|---|
date | Wed, 25 Jan 2006 17:46:28 +0000 |
parents | df5923e33d01 |
children | 2edc0757ca75 |
comparison
equal
deleted
inserted
replaced
3:75c3ea1c3a32 | 4:5865094175ea |
---|---|
148 return m_pluginBlockSize; | 148 return m_pluginBlockSize; |
149 } | 149 } |
150 | 150 |
151 size_t | 151 size_t |
152 AudioGenerator::mixModel(Model *model, size_t startFrame, size_t frameCount, | 152 AudioGenerator::mixModel(Model *model, size_t startFrame, size_t frameCount, |
153 float **buffer) | 153 float **buffer, size_t fadeIn, size_t fadeOut) |
154 { | 154 { |
155 if (m_sourceSampleRate == 0) { | 155 if (m_sourceSampleRate == 0) { |
156 std::cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << std::endl; | 156 std::cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << std::endl; |
157 return frameCount; | 157 return frameCount; |
158 } | 158 } |
167 float pan = parameters->getPlayPan(); | 167 float pan = parameters->getPlayPan(); |
168 | 168 |
169 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); | 169 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); |
170 if (dtvm) { | 170 if (dtvm) { |
171 return mixDenseTimeValueModel(dtvm, startFrame, frameCount, | 171 return mixDenseTimeValueModel(dtvm, startFrame, frameCount, |
172 buffer, gain, pan); | 172 buffer, gain, pan, fadeIn, fadeOut); |
173 } | 173 } |
174 | 174 |
175 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> | 175 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> |
176 (model); | 176 (model); |
177 if (sodm) { | 177 if (sodm) { |
178 return mixSparseOneDimensionalModel(sodm, startFrame, frameCount, | 178 return mixSparseOneDimensionalModel(sodm, startFrame, frameCount, |
179 buffer, gain, pan); | 179 buffer, gain, pan, fadeIn, fadeOut); |
180 } | 180 } |
181 | 181 |
182 return frameCount; | 182 return frameCount; |
183 } | 183 } |
184 | 184 |
185 size_t | 185 size_t |
186 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm, | 186 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm, |
187 size_t startFrame, size_t frames, | 187 size_t startFrame, size_t frames, |
188 float **buffer, float gain, float pan) | 188 float **buffer, float gain, float pan, |
189 size_t fadeIn, size_t fadeOut) | |
189 { | 190 { |
190 static float *channelBuffer = 0; | 191 static float *channelBuffer = 0; |
191 static size_t channelBufSiz = 0; | 192 static size_t channelBufSiz = 0; |
192 | 193 |
193 if (channelBufSiz < frames) { | 194 size_t totalFrames = frames + fadeIn/2 + fadeOut/2; |
195 | |
196 if (channelBufSiz < totalFrames) { | |
194 delete[] channelBuffer; | 197 delete[] channelBuffer; |
195 channelBuffer = new float[frames]; | 198 channelBuffer = new float[totalFrames]; |
196 channelBufSiz = frames; | 199 channelBufSiz = totalFrames; |
197 } | 200 } |
198 | 201 |
199 size_t got = 0; | 202 size_t got = 0; |
200 | 203 |
201 for (size_t c = 0; c < m_targetChannelCount && c < dtvm->getChannelCount(); ++c) { | 204 for (size_t c = 0; c < m_targetChannelCount && c < dtvm->getChannelCount(); ++c) { |
202 got = dtvm->getValues(c, startFrame, startFrame + frames, channelBuffer); | 205 |
203 for (size_t i = 0; i < frames; ++i) { | 206 got = dtvm->getValues |
204 buffer[c][i] += gain * channelBuffer[i]; | 207 (c, startFrame - fadeIn/2, startFrame + frames + fadeOut/2, |
208 channelBuffer); | |
209 | |
210 for (size_t i = 0; i < fadeIn/2; ++i) { | |
211 float *back = buffer[c]; | |
212 back -= fadeIn/2; | |
213 back[i] += (gain * channelBuffer[i] * i) / fadeIn; | |
214 } | |
215 | |
216 for (size_t i = 0; i < frames + fadeOut/2; ++i) { | |
217 float mult = gain; | |
218 if (i < fadeIn/2) { | |
219 mult = (mult * i) / fadeIn; | |
220 } | |
221 if (i > frames - fadeOut/2) { | |
222 mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut; | |
223 } | |
224 buffer[c][i] += mult * channelBuffer[i]; | |
205 } | 225 } |
206 } | 226 } |
207 | 227 |
208 return got; | 228 return got; |
209 } | 229 } |
210 | 230 |
211 size_t | 231 size_t |
212 AudioGenerator::mixSparseOneDimensionalModel(SparseOneDimensionalModel *sodm, | 232 AudioGenerator::mixSparseOneDimensionalModel(SparseOneDimensionalModel *sodm, |
213 size_t startFrame, size_t frames, | 233 size_t startFrame, size_t frames, |
214 float **buffer, float gain, float pan) | 234 float **buffer, float gain, float pan, |
235 size_t /* fadeIn */, | |
236 size_t /* fadeOut */) | |
215 { | 237 { |
216 RealTimePluginInstance *plugin = m_synthMap[sodm]; | 238 RealTimePluginInstance *plugin = m_synthMap[sodm]; |
217 if (!plugin) return 0; | 239 if (!plugin) return 0; |
218 | 240 |
219 size_t latency = plugin->getLatency(); | 241 size_t latency = plugin->getLatency(); |