// // udpmidi.cpp // // mt32-pi - A baremetal MIDI synthesizer for Raspberry Pi // Copyright (C) 2020-2023 Dale Whinham // // This file is part of mt32-pi. // // mt32-pi is free software: you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the Free Software // Foundation, either version 3 of the License, or (at your option) any later // version. // // mt32-pi is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // mt32-pi. If not, see . // #include #include #include #include #include "udpmidi.h" LOGMODULE("udpmidi"); constexpr u16 MIDIPort = 1999; CUDPMIDIReceiver::CUDPMIDIReceiver(CUDPMIDIHandler* pHandler) : CTask(TASK_STACK_SIZE, true), m_pMIDISocket(nullptr), m_MIDIBuffer{0}, m_pHandler(pHandler) { } CUDPMIDIReceiver::~CUDPMIDIReceiver() { if (m_pMIDISocket) delete m_pMIDISocket; } bool CUDPMIDIReceiver::Initialize() { assert(m_pMIDISocket == nullptr); CNetSubSystem* const pNet = CNetSubSystem::Get(); if ((m_pMIDISocket = new CSocket(pNet, IPPROTO_UDP)) == nullptr) return false; if (m_pMIDISocket->Bind(MIDIPort) != 0) { LOGERR("Couldn't bind to port %d", MIDIPort); return false; } // We started as a suspended task; run now that initialization is successful Start(); return true; } void CUDPMIDIReceiver::Run() { assert(m_pHandler != nullptr); assert(m_pMIDISocket != nullptr); CScheduler* const pScheduler = CScheduler::Get(); while (true) { // Blocking call const int nMIDIResult = m_pMIDISocket->Receive(m_MIDIBuffer, sizeof(m_MIDIBuffer), 0); if (nMIDIResult < 0) LOGERR("MIDI socket receive error: %d", nMIDIResult); else if (nMIDIResult > 0) m_pHandler->OnUDPMIDIDataReceived(m_MIDIBuffer, nMIDIResult); // Allow other tasks to run pScheduler->Yield(); } }