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) {