Mercurial > hg > svcore
comparison plugin/DSSIPluginInstance.cpp @ 1040:a1cd5abcb38b cxx11
Introduce and use a samplerate type
author | Chris Cannam |
---|---|
date | Wed, 04 Mar 2015 12:01:04 +0000 |
parents | b14064bd1f97 |
children | 48e9f538e6e9 |
comparison
equal
deleted
inserted
replaced
1039:b14064bd1f97 | 1040:a1cd5abcb38b |
---|---|
55 | 55 |
56 DSSIPluginInstance::DSSIPluginInstance(RealTimePluginFactory *factory, | 56 DSSIPluginInstance::DSSIPluginInstance(RealTimePluginFactory *factory, |
57 int clientId, | 57 int clientId, |
58 QString identifier, | 58 QString identifier, |
59 int position, | 59 int position, |
60 int sampleRate, | 60 sv_samplerate_t sampleRate, |
61 size_t blockSize, | 61 int blockSize, |
62 int idealChannelCount, | 62 int idealChannelCount, |
63 const DSSI_Descriptor* descriptor) : | 63 const DSSI_Descriptor* descriptor) : |
64 RealTimePluginInstance(factory, identifier), | 64 RealTimePluginInstance(factory, identifier), |
65 m_client(clientId), | 65 m_client(clientId), |
66 m_position(position), | 66 m_position(position), |
88 m_outputBuffers = new sample_t*[m_outputBufferCount]; | 88 m_outputBuffers = new sample_t*[m_outputBufferCount]; |
89 | 89 |
90 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) { | 90 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) { |
91 m_inputBuffers[i] = new sample_t[blockSize]; | 91 m_inputBuffers[i] = new sample_t[blockSize]; |
92 } | 92 } |
93 for (size_t i = 0; i < m_outputBufferCount; ++i) { | 93 for (int i = 0; i < m_outputBufferCount; ++i) { |
94 m_outputBuffers[i] = new sample_t[blockSize]; | 94 m_outputBuffers[i] = new sample_t[blockSize]; |
95 } | 95 } |
96 | 96 |
97 m_ownBuffers = true; | 97 m_ownBuffers = true; |
98 | 98 |
263 SVDEBUG << "DSSIPluginInstance::DSSIPluginInstance - " | 263 SVDEBUG << "DSSIPluginInstance::DSSIPluginInstance - " |
264 << "unrecognised port type" << endl; | 264 << "unrecognised port type" << endl; |
265 #endif | 265 #endif |
266 } | 266 } |
267 | 267 |
268 m_outputBufferCount = std::max(m_idealChannelCount, m_audioPortsOut.size()); | 268 m_outputBufferCount = std::max(m_idealChannelCount, |
269 } | 269 (int)m_audioPortsOut.size()); |
270 | 270 } |
271 size_t | 271 |
272 sv_frame_t | |
272 DSSIPluginInstance::getLatency() | 273 DSSIPluginInstance::getLatency() |
273 { | 274 { |
274 size_t latency = 0; | 275 sv_frame_t latency = 0; |
275 | 276 |
276 #ifdef DEBUG_DSSI_PROCESS | 277 #ifdef DEBUG_DSSI_PROCESS |
277 SVDEBUG << "DSSIPluginInstance::getLatency(): m_latencyPort " << m_latencyPort << ", m_run " << m_run << endl; | 278 SVDEBUG << "DSSIPluginInstance::getLatency(): m_latencyPort " << m_latencyPort << ", m_run " << m_run << endl; |
278 #endif | 279 #endif |
279 | 280 |
280 if (m_latencyPort) { | 281 if (m_latencyPort) { |
281 if (!m_run) { | 282 if (!m_run) { |
282 for (size_t i = 0; i < getAudioInputCount(); ++i) { | 283 for (int i = 0; i < getAudioInputCount(); ++i) { |
283 for (size_t j = 0; j < m_blockSize; ++j) { | 284 for (int j = 0; j < m_blockSize; ++j) { |
284 m_inputBuffers[i][j] = 0.f; | 285 m_inputBuffers[i][j] = 0.f; |
285 } | 286 } |
286 } | 287 } |
287 run(Vamp::RealTime::zeroTime); | 288 run(Vamp::RealTime::zeroTime); |
288 } | 289 } |
289 latency = (size_t)(*m_latencyPort + 0.1); | 290 latency = (sv_frame_t)(*m_latencyPort + 0.1); |
290 } | 291 } |
291 | 292 |
292 #ifdef DEBUG_DSSI_PROCESS | 293 #ifdef DEBUG_DSSI_PROCESS |
293 SVDEBUG << "DSSIPluginInstance::getLatency(): latency is " << latency << endl; | 294 SVDEBUG << "DSSIPluginInstance::getLatency(): latency is " << latency << endl; |
294 #endif | 295 #endif |
310 { | 311 { |
311 m_eventBuffer.reset(); | 312 m_eventBuffer.reset(); |
312 } | 313 } |
313 | 314 |
314 void | 315 void |
315 DSSIPluginInstance::setIdealChannelCount(size_t channels) | 316 DSSIPluginInstance::setIdealChannelCount(int channels) |
316 { | 317 { |
317 #ifdef DEBUG_DSSI | 318 #ifdef DEBUG_DSSI |
318 SVDEBUG << "DSSIPluginInstance::setIdealChannelCount: channel count " | 319 SVDEBUG << "DSSIPluginInstance::setIdealChannelCount: channel count " |
319 << channels << " (was " << m_idealChannelCount << ")" << endl; | 320 << channels << " (was " << m_idealChannelCount << ")" << endl; |
320 #endif | 321 #endif |
330 | 331 |
331 m_idealChannelCount = channels; | 332 m_idealChannelCount = channels; |
332 | 333 |
333 if (channels > m_outputBufferCount) { | 334 if (channels > m_outputBufferCount) { |
334 | 335 |
335 for (size_t i = 0; i < m_outputBufferCount; ++i) { | 336 for (int i = 0; i < m_outputBufferCount; ++i) { |
336 delete[] m_outputBuffers[i]; | 337 delete[] m_outputBuffers[i]; |
337 } | 338 } |
338 | 339 |
339 delete[] m_outputBuffers; | 340 delete[] m_outputBuffers; |
340 | 341 |
341 m_outputBufferCount = channels; | 342 m_outputBufferCount = channels; |
342 | 343 |
343 m_outputBuffers = new sample_t*[m_outputBufferCount]; | 344 m_outputBuffers = new sample_t*[m_outputBufferCount]; |
344 | 345 |
345 for (size_t i = 0; i < m_outputBufferCount; ++i) { | 346 for (int i = 0; i < m_outputBufferCount; ++i) { |
346 m_outputBuffers[i] = new sample_t[m_blockSize]; | 347 m_outputBuffers[i] = new sample_t[m_blockSize]; |
347 } | 348 } |
348 | 349 |
349 connectPorts(); | 350 connectPorts(); |
350 } | 351 } |
436 | 437 |
437 m_controlPortsIn.clear(); | 438 m_controlPortsIn.clear(); |
438 m_controlPortsOut.clear(); | 439 m_controlPortsOut.clear(); |
439 | 440 |
440 if (m_ownBuffers) { | 441 if (m_ownBuffers) { |
441 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) { | 442 for (int i = 0; i < getAudioInputCount(); ++i) { |
442 delete[] m_inputBuffers[i]; | 443 delete[] m_inputBuffers[i]; |
443 } | 444 } |
444 for (size_t i = 0; i < m_outputBufferCount; ++i) { | 445 for (int i = 0; i < m_outputBufferCount; ++i) { |
445 delete[] m_outputBuffers[i]; | 446 delete[] m_outputBuffers[i]; |
446 } | 447 } |
447 | 448 |
448 delete[] m_inputBuffers; | 449 delete[] m_inputBuffers; |
449 delete[] m_outputBuffers; | 450 delete[] m_outputBuffers; |
453 m_audioPortsOut.clear(); | 454 m_audioPortsOut.clear(); |
454 } | 455 } |
455 | 456 |
456 | 457 |
457 void | 458 void |
458 DSSIPluginInstance::instantiate(int sampleRate) | 459 DSSIPluginInstance::instantiate(sv_samplerate_t sampleRate) |
459 { | 460 { |
460 if (!m_descriptor) return; | 461 if (!m_descriptor) return; |
461 | 462 |
462 #ifdef DEBUG_DSSI | 463 #ifdef DEBUG_DSSI |
463 cout << "DSSIPluginInstance::instantiate - plugin \"unique\" id = " | 464 cout << "DSSIPluginInstance::instantiate - plugin \"unique\" id = " |
470 << ":" << descriptor->Label | 471 << ":" << descriptor->Label |
471 << " has no instantiate method!" << endl; | 472 << " has no instantiate method!" << endl; |
472 return; | 473 return; |
473 } | 474 } |
474 | 475 |
475 m_instanceHandle = descriptor->instantiate(descriptor, sampleRate); | 476 unsigned long pluginRate = (unsigned long)(sampleRate); |
477 if (sampleRate != sv_samplerate_t(pluginRate)) { | |
478 cerr << "DSSIPluginInstance: WARNING: Non-integer sample rate " | |
479 << sampleRate << " presented, rounding to " << pluginRate | |
480 << endl; | |
481 } | |
482 m_instanceHandle = descriptor->instantiate(descriptor, pluginRate); | |
476 | 483 |
477 if (m_instanceHandle) { | 484 if (m_instanceHandle) { |
478 | 485 |
479 if (m_descriptor->get_midi_controller_for_port) { | 486 if (m_descriptor->get_midi_controller_for_port) { |
480 | 487 |
687 void | 694 void |
688 DSSIPluginInstance::connectPorts() | 695 DSSIPluginInstance::connectPorts() |
689 { | 696 { |
690 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->connect_port) return; | 697 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->connect_port) return; |
691 #ifdef DEBUG_DSSI | 698 #ifdef DEBUG_DSSI |
692 SVDEBUG << "DSSIPluginInstance::connectPorts: " << m_audioPortsIn.size() | 699 SVDEBUG << "DSSIPluginInstance::connectPorts: " << getAudioInputCount() |
693 << " audio ports in, " << m_audioPortsOut.size() << " out, " | 700 << " audio ports in, " << m_audioPortsOut.size() << " out, " |
694 << m_outputBufferCount << " output buffers" << endl; | 701 << m_outputBufferCount << " output buffers" << endl; |
695 #endif | 702 #endif |
696 | 703 |
697 assert(sizeof(LADSPA_Data) == sizeof(float)); | 704 assert(sizeof(LADSPA_Data) == sizeof(float)); |
698 assert(sizeof(sample_t) == sizeof(float)); | 705 assert(sizeof(sample_t) == sizeof(float)); |
699 | 706 |
700 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); | 707 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); |
701 int inbuf = 0, outbuf = 0; | 708 int inbuf = 0, outbuf = 0; |
702 | 709 |
703 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) { | 710 for (int i = 0; i < getAudioInputCount(); ++i) { |
704 m_descriptor->LADSPA_Plugin->connect_port | 711 m_descriptor->LADSPA_Plugin->connect_port |
705 (m_instanceHandle, | 712 (m_instanceHandle, |
706 m_audioPortsIn[i], | 713 m_audioPortsIn[i], |
707 (LADSPA_Data *)m_inputBuffers[inbuf]); | 714 (LADSPA_Data *)m_inputBuffers[inbuf]); |
708 ++inbuf; | 715 ++inbuf; |
809 } | 816 } |
810 } | 817 } |
811 } | 818 } |
812 | 819 |
813 float | 820 float |
814 DSSIPluginInstance::getControlOutputValue(size_t output) const | 821 DSSIPluginInstance::getControlOutputValue(int output) const |
815 { | 822 { |
816 if (!in_range_for(m_controlPortsOut, output)) return 0.0; | 823 if (!in_range_for(m_controlPortsOut, output)) return 0.0; |
817 return (*m_controlPortsOut[output].second); | 824 return (*m_controlPortsOut[output].second); |
818 } | 825 } |
819 | 826 |
904 | 911 |
905 return qm; | 912 return qm; |
906 } | 913 } |
907 | 914 |
908 void | 915 void |
909 DSSIPluginInstance::sendEvent(const Vamp::RealTime &eventTime, | 916 DSSIPluginInstance::sendEvent(const RealTime &eventTime, |
910 const void *e) | 917 const void *e) |
911 { | 918 { |
912 #ifdef DEBUG_DSSI_PROCESS | 919 #ifdef DEBUG_DSSI_PROCESS |
913 SVDEBUG << "DSSIPluginInstance::sendEvent: last was " << m_lastEventSendTime << " (valid " << m_haveLastEventSendTime << "), this is " << eventTime << endl; | 920 SVDEBUG << "DSSIPluginInstance::sendEvent: last was " << m_lastEventSendTime << " (valid " << m_haveLastEventSendTime << "), this is " << eventTime << endl; |
914 #endif | 921 #endif |
980 | 987 |
981 return false; | 988 return false; |
982 } | 989 } |
983 | 990 |
984 void | 991 void |
985 DSSIPluginInstance::run(const Vamp::RealTime &blockTime, size_t count) | 992 DSSIPluginInstance::run(const RealTime &blockTime, int count) |
986 { | 993 { |
987 static snd_seq_event_t localEventBuffer[EVENT_BUFFER_SIZE]; | 994 static snd_seq_event_t localEventBuffer[EVENT_BUFFER_SIZE]; |
988 int evCount = 0; | 995 int evCount = 0; |
989 | 996 |
990 if (count == 0) count = m_blockSize; | 997 if (count == 0) count = m_blockSize; |
1036 | 1043 |
1037 snd_seq_event_t *ev = localEventBuffer + evCount; | 1044 snd_seq_event_t *ev = localEventBuffer + evCount; |
1038 *ev = m_eventBuffer.peekOne(); | 1045 *ev = m_eventBuffer.peekOne(); |
1039 bool accept = true; | 1046 bool accept = true; |
1040 | 1047 |
1041 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); | 1048 RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); |
1042 | 1049 |
1043 long frameOffset = 0; | 1050 sv_frame_t frameOffset = 0; |
1044 if (evTime > blockTime) { | 1051 if (evTime > blockTime) { |
1045 frameOffset = Vamp::RealTime::realTime2Frame | 1052 frameOffset = RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); |
1046 (evTime - blockTime, | |
1047 (unsigned int)m_sampleRate); | |
1048 } | 1053 } |
1049 | 1054 |
1050 #ifdef DEBUG_DSSI_PROCESS | 1055 #ifdef DEBUG_DSSI_PROCESS |
1051 SVDEBUG << "DSSIPluginInstance::run: evTime " << evTime << ", blockTime " << blockTime << ", frameOffset " << frameOffset | 1056 SVDEBUG << "DSSIPluginInstance::run: evTime " << evTime << ", blockTime " << blockTime << ", frameOffset " << frameOffset |
1052 << ", blockSize " << m_blockSize << endl; | 1057 << ", blockSize " << m_blockSize << endl; |
1110 #endif | 1115 #endif |
1111 | 1116 |
1112 done: | 1117 done: |
1113 if (needLock) m_processLock.unlock(); | 1118 if (needLock) m_processLock.unlock(); |
1114 | 1119 |
1115 if (m_audioPortsOut.size() == 0) { | 1120 int numAudioOuts = int(m_audioPortsOut.size()); |
1121 | |
1122 if (numAudioOuts == 0) { | |
1116 // copy inputs to outputs | 1123 // copy inputs to outputs |
1117 for (size_t ch = 0; ch < m_idealChannelCount; ++ch) { | 1124 for (int ch = 0; ch < m_idealChannelCount; ++ch) { |
1118 size_t sch = ch % m_audioPortsIn.size(); | 1125 int sch = ch % getAudioInputCount(); |
1119 for (size_t i = 0; i < m_blockSize; ++i) { | 1126 for (int i = 0; i < m_blockSize; ++i) { |
1120 m_outputBuffers[ch][i] = m_inputBuffers[sch][i]; | 1127 m_outputBuffers[ch][i] = m_inputBuffers[sch][i]; |
1121 } | 1128 } |
1122 } | 1129 } |
1123 } else if (m_idealChannelCount < m_audioPortsOut.size()) { | 1130 } else if (m_idealChannelCount < numAudioOuts) { |
1124 if (m_idealChannelCount == 1) { | 1131 if (m_idealChannelCount == 1) { |
1125 // mix down to mono | 1132 // mix down to mono |
1126 for (size_t ch = 1; ch < m_audioPortsOut.size(); ++ch) { | 1133 for (int ch = 1; ch < numAudioOuts; ++ch) { |
1127 for (size_t i = 0; i < m_blockSize; ++i) { | 1134 for (int i = 0; i < m_blockSize; ++i) { |
1128 m_outputBuffers[0][i] += m_outputBuffers[ch][i]; | 1135 m_outputBuffers[0][i] += m_outputBuffers[ch][i]; |
1129 } | 1136 } |
1130 } | 1137 } |
1131 } | 1138 } |
1132 } else if (m_idealChannelCount > m_audioPortsOut.size()) { | 1139 } else if (m_idealChannelCount > numAudioOuts) { |
1133 // duplicate | 1140 // duplicate |
1134 for (size_t ch = m_audioPortsOut.size(); ch < m_idealChannelCount; ++ch) { | 1141 for (int ch = numAudioOuts; ch < m_idealChannelCount; ++ch) { |
1135 size_t sch = (ch - m_audioPortsOut.size()) % m_audioPortsOut.size(); | 1142 int sch = (ch - numAudioOuts) % numAudioOuts; |
1136 for (size_t i = 0; i < m_blockSize; ++i) { | 1143 for (int i = 0; i < m_blockSize; ++i) { |
1137 m_outputBuffers[ch][i] = m_outputBuffers[sch][i]; | 1144 m_outputBuffers[ch][i] = m_outputBuffers[sch][i]; |
1138 } | 1145 } |
1139 } | 1146 } |
1140 } | 1147 } |
1141 | 1148 |
1142 m_lastRunTime = blockTime; | 1149 m_lastRunTime = blockTime; |
1143 m_run = true; | 1150 m_run = true; |
1144 } | 1151 } |
1145 | 1152 |
1146 void | 1153 void |
1147 DSSIPluginInstance::runGrouped(const Vamp::RealTime &blockTime) | 1154 DSSIPluginInstance::runGrouped(const RealTime &blockTime) |
1148 { | 1155 { |
1149 // If something else in our group has just been called for this | 1156 // If something else in our group has just been called for this |
1150 // block time (but we haven't) then we should just write out the | 1157 // block time (but we haven't) then we should just write out the |
1151 // results and return; if we have just been called for this block | 1158 // results and return; if we have just been called for this block |
1152 // time or nothing else in the group has been, we should run the | 1159 // time or nothing else in the group has been, we should run the |
1214 | 1221 |
1215 snd_seq_event_t *ev = m_groupLocalEventBuffers[index] + counts[index]; | 1222 snd_seq_event_t *ev = m_groupLocalEventBuffers[index] + counts[index]; |
1216 *ev = instance->m_eventBuffer.peekOne(); | 1223 *ev = instance->m_eventBuffer.peekOne(); |
1217 bool accept = true; | 1224 bool accept = true; |
1218 | 1225 |
1219 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); | 1226 RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec); |
1220 | 1227 |
1221 int frameOffset = 0; | 1228 sv_frame_t frameOffset = 0; |
1222 if (evTime > blockTime) { | 1229 if (evTime > blockTime) { |
1223 frameOffset = (int) | 1230 frameOffset = RealTime::realTime2Frame(evTime - blockTime, m_sampleRate); |
1224 Vamp::RealTime::realTime2Frame(evTime - blockTime, | |
1225 (unsigned)m_sampleRate); | |
1226 } | 1231 } |
1227 | 1232 |
1228 #ifdef DEBUG_DSSI_PROCESS | 1233 #ifdef DEBUG_DSSI_PROCESS |
1229 SVDEBUG << "DSSIPluginInstance::runGrouped: evTime " << evTime << ", frameOffset " << frameOffset | 1234 SVDEBUG << "DSSIPluginInstance::runGrouped: evTime " << evTime << ", frameOffset " << frameOffset |
1230 << ", block size " << m_blockSize << endl; | 1235 << ", block size " << m_blockSize << endl; |
1231 #endif | 1236 #endif |
1232 | 1237 |
1233 if (frameOffset >= int(m_blockSize)) break; | 1238 if (frameOffset >= int(m_blockSize)) break; |
1234 if (frameOffset < 0) frameOffset = 0; | 1239 if (frameOffset < 0) frameOffset = 0; |
1235 | 1240 |
1236 ev->time.tick = frameOffset; | 1241 ev->time.tick = snd_seq_tick_time_t(frameOffset); |
1237 instance->m_eventBuffer.skip(1); | 1242 instance->m_eventBuffer.skip(1); |
1238 | 1243 |
1239 if (ev->type == SND_SEQ_EVENT_CONTROLLER) { | 1244 if (ev->type == SND_SEQ_EVENT_CONTROLLER) { |
1240 accept = instance->handleController(ev); | 1245 accept = instance->handleController(ev); |
1241 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) { | 1246 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) { |