You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiniDexed/src/net/udpmidi.cpp

89 lines
2.2 KiB

//
// udpmidi.cpp
//
// mt32-pi - A baremetal MIDI synthesizer for Raspberry Pi
// Copyright (C) 2020-2023 Dale Whinham <daleyo@gmail.com>
//
// 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 <http://www.gnu.org/licenses/>.
//
#include <circle/logger.h>
#include <circle/net/in.h>
#include <circle/net/netsubsystem.h>
#include <circle/sched/scheduler.h>
#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();
}
}