@@ -256,6 +256,97 @@ void registerYupAudioBasicsBindings (py::module_& m)
256256 return Decibels::toString (decibels, decimalPlaces, minusInfinityDb, shouldIncludeSuffix, customMinusInfinityString);
257257 }, " decibels" _a, " decimalPlaces" _a = 2 , " minusInfinityDb" _a = -100 .0f , " shouldIncludeSuffix" _a = true , " customMinusInfinityString" _a = StringRef ());
258258
259+ // ============================================================================================ yup::MidiMessage
260+
261+ py::class_<MidiMessage> classMidiMessage (m, " MidiMessage" );
262+
263+ classMidiMessage
264+ .def (py::init<>())
265+ .def (py::init<const MidiMessage&>())
266+ .def (py::init<const MidiMessage&, double >(), " other" _a, " newTimeStamp" _a)
267+ .def (" getRawData" , [] (const MidiMessage& self) -> py::bytes
268+ {
269+ return py::bytes (reinterpret_cast <const char *> (self.getRawData ()), self.getRawDataSize ());
270+ })
271+ .def (" getRawDataSize" , &MidiMessage::getRawDataSize)
272+ .def (" getDescription" , &MidiMessage::getDescription)
273+ .def (" getTimeStamp" , &MidiMessage::getTimeStamp)
274+ .def (" setTimeStamp" , &MidiMessage::setTimeStamp)
275+ .def (" addToTimeStamp" , &MidiMessage::addToTimeStamp)
276+ .def (" withTimeStamp" , &MidiMessage::withTimeStamp)
277+ .def (" getChannel" , &MidiMessage::getChannel)
278+ .def (" isForChannel" , &MidiMessage::isForChannel)
279+ .def (" setChannel" , &MidiMessage::setChannel)
280+ .def (" isSysEx" , &MidiMessage::isSysEx)
281+ .def (" getSysExDataSize" , &MidiMessage::getSysExDataSize)
282+ .def (" isNoteOn" , &MidiMessage::isNoteOn, " returnTrueForVelocity0" _a = false )
283+ .def (" isNoteOff" , &MidiMessage::isNoteOff, " returnTrueForNoteOnVelocity0" _a = true )
284+ .def (" isNoteOnOrOff" , &MidiMessage::isNoteOnOrOff)
285+ .def (" getNoteNumber" , &MidiMessage::getNoteNumber)
286+ .def (" setNoteNumber" , &MidiMessage::setNoteNumber)
287+ .def (" getVelocity" , &MidiMessage::getVelocity)
288+ .def (" getFloatVelocity" , &MidiMessage::getFloatVelocity)
289+ .def (" setVelocity" , &MidiMessage::setVelocity)
290+ .def (" multiplyVelocity" , &MidiMessage::multiplyVelocity)
291+ .def (" isAftertouch" , &MidiMessage::isAftertouch)
292+ .def (" getAfterTouchValue" , &MidiMessage::getAfterTouchValue)
293+ .def (" isProgramChange" , &MidiMessage::isProgramChange)
294+ .def (" getProgramChangeNumber" , &MidiMessage::getProgramChangeNumber)
295+ .def (" isPitchWheel" , &MidiMessage::isPitchWheel)
296+ .def (" getPitchWheelValue" , &MidiMessage::getPitchWheelValue)
297+ .def (" isController" , &MidiMessage::isController)
298+ .def (" getControllerNumber" , &MidiMessage::getControllerNumber)
299+ .def (" getControllerValue" , &MidiMessage::getControllerValue)
300+ .def (" isControllerOfType" , &MidiMessage::isControllerOfType)
301+ .def (" isAllNotesOff" , &MidiMessage::isAllNotesOff)
302+ .def (" isAllSoundOff" , &MidiMessage::isAllSoundOff)
303+ .def (" isResetAllControllers" , &MidiMessage::isResetAllControllers)
304+ .def_static (" noteOn" , static_cast <MidiMessage (*)(int , int , float )> (&MidiMessage::noteOn), " channel" _a, " noteNumber" _a, " velocity" _a)
305+ .def_static (" noteOff" , static_cast <MidiMessage (*)(int , int , float )> (&MidiMessage::noteOff), " channel" _a, " noteNumber" _a, " velocity" _a)
306+ .def_static (" noteOff" , static_cast <MidiMessage (*)(int , int )> (&MidiMessage::noteOff), " channel" _a, " noteNumber" _a)
307+ .def_static (" programChange" , &MidiMessage::programChange, " channel" _a, " programNumber" _a)
308+ .def_static (" pitchWheel" , &MidiMessage::pitchWheel, " channel" _a, " position" _a)
309+ .def_static (" aftertouchChange" , &MidiMessage::aftertouchChange, " channel" _a, " noteNumber" _a, " aftertouchValue" _a)
310+ .def_static (" channelPressureChange" , &MidiMessage::channelPressureChange, " channel" _a, " pressure" _a)
311+ .def_static (" controllerEvent" , &MidiMessage::controllerEvent, " channel" _a, " controllerType" _a, " value" _a)
312+ .def_static (" allNotesOff" , &MidiMessage::allNotesOff, " channel" _a)
313+ .def_static (" allSoundOff" , &MidiMessage::allSoundOff, " channel" _a)
314+ .def_static (" allControllersOff" , &MidiMessage::allControllersOff, " channel" _a);
315+
316+ // ============================================================================================ yup::MidiMessageMetadata
317+
318+ py::class_<MidiMessageMetadata> classMidiMessageMetadata (m, " MidiMessageMetadata" );
319+
320+ classMidiMessageMetadata
321+ .def (py::init<>())
322+ .def (py::init<const uint8*, int , int >())
323+ .def (" getMessage" , &MidiMessageMetadata::getMessage)
324+ .def_readonly (" numBytes" , &MidiMessageMetadata::numBytes)
325+ .def_readonly (" samplePosition" , &MidiMessageMetadata::samplePosition);
326+
327+ // ============================================================================================ yup::MidiBuffer
328+
329+ py::class_<MidiBuffer> classMidiBuffer (m, " MidiBuffer" );
330+
331+ classMidiBuffer
332+ .def (py::init<>())
333+ .def (py::init<const MidiMessage&>())
334+ .def (" clear" , py::overload_cast<> (&MidiBuffer::clear))
335+ .def (" clear" , py::overload_cast<int , int > (&MidiBuffer::clear))
336+ .def (" isEmpty" , &MidiBuffer::isEmpty)
337+ .def (" getNumEvents" , &MidiBuffer::getNumEvents)
338+ .def (" addEvent" , py::overload_cast<const MidiMessage&, int > (&MidiBuffer::addEvent))
339+ .def (" addEvents" , &MidiBuffer::addEvents)
340+ .def (" getFirstEventTime" , &MidiBuffer::getFirstEventTime)
341+ .def (" getLastEventTime" , &MidiBuffer::getLastEventTime)
342+ .def (" swapWith" , &MidiBuffer::swapWith)
343+ .def (" ensureSize" , &MidiBuffer::ensureSize)
344+ .def (" __iter__" , [] (const MidiBuffer& self)
345+ {
346+ return py::make_iterator (self.begin (), self.end ());
347+ }, py::keep_alive<0 , 1 >())
348+ .def (" __len__" , &MidiBuffer::getNumEvents);
349+
259350 // ============================================================================================ yup::ADSR
260351
261352 py::class_<ADSR> classADSR (m, " ADSR" );
@@ -382,7 +473,7 @@ void registerYupAudioBasicsBindings (py::module_& m)
382473
383474 // ============================================================================================ yup::PositionableAudioSource
384475
385- py::class_<PositionableAudioSource, PyPositionableAudioSource<>, AudioSource > classPositionableAudioSource (m, " PositionableAudioSource" );
476+ py::class_<PositionableAudioSource, PyPositionableAudioSource<>> classPositionableAudioSource (m, " PositionableAudioSource" );
386477
387478 classPositionableAudioSource
388479 .def (py::init<>())
@@ -422,7 +513,7 @@ void registerYupAudioBasicsBindings (py::module_& m)
422513
423514 // ============================================================================================ yup::SynthesiserVoice
424515
425- py::class_<SynthesiserVoice, PySynthesiserVoice> classSynthesiserVoice (m, " SynthesiserVoice" );
516+ py::class_<SynthesiserVoice, PySynthesiserVoice, ReferenceCountedObjectPtr<SynthesiserVoice> > classSynthesiserVoice (m, " SynthesiserVoice" );
426517
427518 classSynthesiserVoice
428519 .def (py::init<>())
@@ -443,11 +534,12 @@ void registerYupAudioBasicsBindings (py::module_& m)
443534
444535 // ============================================================================================ yup::Synthesiser
445536
446- py::class_<Synthesiser> classSynthesiser (m, " Synthesiser" );
537+ py::class_<Synthesiser, PySynthesiser > classSynthesiser (m, " Synthesiser" );
447538
448539 classSynthesiser
449540 .def (py::init<>())
450541 .def (" clearVoices" , &Synthesiser::clearVoices)
542+ .def (" getNumVoices" , &Synthesiser::getNumVoices)
451543 .def (" getVoice" , &Synthesiser::getVoice, py::return_value_policy::reference)
452544 .def (" addVoice" , &Synthesiser::addVoice)
453545 .def (" removeVoice" , &Synthesiser::removeVoice)
@@ -461,7 +553,17 @@ void registerYupAudioBasicsBindings (py::module_& m)
461553 .def (" setMinimumRenderingSubdivisionSize" , &Synthesiser::setMinimumRenderingSubdivisionSize)
462554 .def (" setCurrentPlaybackSampleRate" , &Synthesiser::setCurrentPlaybackSampleRate)
463555 .def (" renderNextBlock" , py::overload_cast<AudioBuffer<float >&, const MidiBuffer&, int , int > (&Synthesiser::renderNextBlock), " outputAudio" _a, " inputMidi" _a, " startSample" _a, " numSamples" _a)
464- .def (" allNotesOff" , &Synthesiser::allNotesOff);
556+ .def (" noteOn" , &Synthesiser::noteOn)
557+ .def (" noteOff" , &Synthesiser::noteOff)
558+ .def (" allNotesOff" , &Synthesiser::allNotesOff)
559+ .def (" handlePitchWheel" , &Synthesiser::handlePitchWheel)
560+ .def (" handleController" , &Synthesiser::handleController)
561+ .def (" handleAftertouch" , &Synthesiser::handleAftertouch)
562+ .def (" handleChannelPressure" , &Synthesiser::handleChannelPressure)
563+ .def (" handleSustainPedal" , &Synthesiser::handleSustainPedal)
564+ .def (" handleSostenutoPedal" , &Synthesiser::handleSostenutoPedal)
565+ .def (" handleSoftPedal" , &Synthesiser::handleSoftPedal)
566+ .def (" handleProgramChange" , &Synthesiser::handleProgramChange);
465567
466568 // ============================================================================================ yup::AudioPlayHead
467569
0 commit comments