Skip to content

Commit

Permalink
add remote midi
Browse files Browse the repository at this point in the history
  • Loading branch information
CrSjimo committed Jul 11, 2024
1 parent d3e04fe commit ef8f816
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ find_package(rpclib REQUIRED)

talcs_add_library(${PROJECT_NAME} AUTOGEN
SOURCES ${_src}
LINKS talcs::Device rpclib::rpc
LINKS talcs::Device talcs::Midi rpclib::rpc
LINKS_PRIVATE Boost::boost
QT_INCLUDE_PRIVATE Core
)
6 changes: 3 additions & 3 deletions src/remote/RemoteAudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ namespace talcs {
}
bufferPrepareStatus = reinterpret_cast<char *>(ptr);
ptr += sizeof(bool);
processInfo = reinterpret_cast<RemoteAudioDevice::ProcessInfo *>(ptr);
processInfo = reinterpret_cast<RemoteProcessInfo *>(ptr);
buffer.reset(new AudioDataWrapper(sharedAudioData.data(), maxChannelCount, bufferSize));

q->setAvailableBufferSizes({bufferSize});
Expand Down Expand Up @@ -259,15 +259,15 @@ namespace talcs {
/**
* Adds a ProcessInfoCallback.
*/
void RemoteAudioDevice::addProcessInfoCallback(RemoteAudioDevice::ProcessInfoCallback *callback) {
void RemoteAudioDevice::addProcessInfoCallback(RemoteProcessInfoCallback *callback) {
Q_D(RemoteAudioDevice);
d->processInfoCallbackList.append(callback);
}

/**
* Removes a ProcessInfoCallback.
*/
void RemoteAudioDevice::removeProcessInfoCallback(RemoteAudioDevice::ProcessInfoCallback *callback) {
void RemoteAudioDevice::removeProcessInfoCallback(RemoteProcessInfoCallback *callback) {
Q_D(RemoteAudioDevice);
d->processInfoCallbackList.removeOne(callback);
}
Expand Down
29 changes: 3 additions & 26 deletions src/remote/RemoteAudioDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define TALCS_REMOTEAUDIODEVICE_H

#include <TalcsDevice/AudioDevice.h>
#include <TalcsRemote/TalcsRemoteGlobal.h>
#include <TalcsRemote/RemoteProcessInfo.h>

namespace talcs {

Expand All @@ -32,29 +32,6 @@ namespace talcs {
Q_OBJECT
Q_DECLARE_PRIVATE(RemoteAudioDevice)
public:
struct ProcessInfo {
int containsInfo;

//== Playback Status Info ==//
enum PlaybackStatus {
NotPlaying,
Playing,
RealtimePlaying,
};
PlaybackStatus status;

//== Timeline Info ==//
int timeSignatureNumerator;
int timeSignatureDenominator;
double tempo;

int64_t position;
};

class ProcessInfoCallback {
public:
virtual void onThisBlockProcessInfo(const ProcessInfo &processInfo) = 0;
};

public:
explicit RemoteAudioDevice(RemoteSocket *socket, const QString &name, QObject *parent = nullptr);
Expand All @@ -63,8 +40,8 @@ namespace talcs {
bool open(qint64 bufferSize, double sampleRate) override;
void close() override;

void addProcessInfoCallback(ProcessInfoCallback *callback);
void removeProcessInfoCallback(ProcessInfoCallback *callback);
void addProcessInfoCallback(RemoteProcessInfoCallback *callback);
void removeProcessInfoCallback(RemoteProcessInfoCallback *callback);

bool start(AudioDeviceCallback *audioDeviceCallback) override;
void stop() override;
Expand Down
4 changes: 2 additions & 2 deletions src/remote/RemoteAudioDevice_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ namespace talcs {
};
char *bufferPrepareStatus;
QVector<float *> sharedAudioData;
RemoteAudioDevice::ProcessInfo *processInfo = nullptr;
RemoteProcessInfo *processInfo = nullptr;
QScopedPointer<AudioDataWrapper> buffer;

QScopedPointer<QThread> prepareBufferProducerThread;

AudioDeviceCallback *audioDeviceCallback = nullptr;

QList<RemoteAudioDevice::ProcessInfoCallback *> processInfoCallbackList;
QList<RemoteProcessInfoCallback *> processInfoCallbackList;

void remoteOpenRequired(qint64 bufferSize, double sampleRate, const QString &ipcKey, int maxChannelCount);
void remoteCloseRequired();
Expand Down
76 changes: 76 additions & 0 deletions src/remote/RemoteMidiMessageIntegrator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/******************************************************************************
* Copyright (c) 2024 CrSjimo *
* *
* This file is part of TALCS. *
* *
* TALCS is free software: you can redistribute it and/or modify it under the *
* terms of the GNU Lesser General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* TALCS 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 Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with TALCS. If not, see <https://www.gnu.org/licenses/>. *
******************************************************************************/

#include "RemoteMidiMessageIntegrator.h"
#include "RemoteMidiMessageIntegrator_p.h"

namespace talcs {
RemoteMidiMessageIntegrator::RemoteMidiMessageIntegrator() : RemoteMidiMessageIntegrator(*new RemoteMidiMessageIntegratorPrivate) {

}

RemoteMidiMessageIntegrator::~RemoteMidiMessageIntegrator() {

}

bool RemoteMidiMessageIntegrator::open(qint64 bufferSize, double sampleRate) {
Q_D(RemoteMidiMessageIntegrator);
QMutexLocker locker(&d->mutex);
d->midiMessages.clear();
return AbstractMidiMessageIntegrator::open(bufferSize, sampleRate);
}

void RemoteMidiMessageIntegrator::close() {
Q_D(RemoteMidiMessageIntegrator);
QMutexLocker locker(&d->mutex);
d->midiMessages.clear();
AbstractMidiMessageIntegrator::close();
}

QList<IntegratedMidiMessage> RemoteMidiMessageIntegrator::fetch(qint64 length) {
Q_D(RemoteMidiMessageIntegrator);
QMutexLocker locker(&d->mutex);
auto ret = d->midiMessages;
d->midiMessages.clear();
return ret;
}

void RemoteMidiMessageIntegrator::onThisBlockProcessInfo(const RemoteProcessInfo &processInfo) {
Q_D(RemoteMidiMessageIntegrator);
QMutexLocker locker(&d->mutex);
d->midiMessages.clear();
if (processInfo.containsInfo) {
auto midiMessagesRawData = &processInfo.midiMessages;
d->midiMessages.reserve(static_cast<int>(midiMessagesRawData->size));
auto midiMessagesRawDataPointer = reinterpret_cast<const char *>(midiMessagesRawData->messages);
for (int i = 0; i < midiMessagesRawData->size; i++) {
auto midiMessageRawData = reinterpret_cast<const RemoteMidiMessage *>(midiMessagesRawDataPointer);
d->midiMessages.append({
midiMessageRawData->position,
MidiMessage(midiMessageRawData->data, static_cast<int>(midiMessageRawData->size),
static_cast<double>(midiMessageRawData->position))
});
midiMessagesRawDataPointer+= sizeof(RemoteMidiMessage) + midiMessageRawData->size - 1;
}
}
}

RemoteMidiMessageIntegrator::RemoteMidiMessageIntegrator(RemoteMidiMessageIntegratorPrivate &d) : AbstractMidiMessageIntegrator(d) {
}
} // talcs
49 changes: 49 additions & 0 deletions src/remote/RemoteMidiMessageIntegrator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/******************************************************************************
* Copyright (c) 2024 CrSjimo *
* *
* This file is part of TALCS. *
* *
* TALCS is free software: you can redistribute it and/or modify it under the *
* terms of the GNU Lesser General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* TALCS 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 Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with TALCS. If not, see <https://www.gnu.org/licenses/>. *
******************************************************************************/

#ifndef TALCS_REMOTEMIDIMESSAGEINTEGRATOR_H
#define TALCS_REMOTEMIDIMESSAGEINTEGRATOR_H

#include <TalcsMidi/AbstractMidiMessageIntegrator.h>
#include <TalcsRemote/RemoteAudioDevice.h>

namespace talcs {

class RemoteMidiMessageIntegratorPrivate;

class TALCSREMOTE_EXPORT RemoteMidiMessageIntegrator : public AbstractMidiMessageIntegrator, public RemoteProcessInfoCallback {
Q_DECLARE_PRIVATE(RemoteMidiMessageIntegrator)
public:
explicit RemoteMidiMessageIntegrator();
~RemoteMidiMessageIntegrator() override;

bool open(qint64 bufferSize, double sampleRate) override;
void close() override;

protected:
QList<IntegratedMidiMessage> fetch(qint64 length) override;
void onThisBlockProcessInfo(const RemoteProcessInfo &processInfo) override;

explicit RemoteMidiMessageIntegrator(RemoteMidiMessageIntegratorPrivate &d);

};

} // talcs

#endif //TALCS_REMOTEMIDIMESSAGEINTEGRATOR_H
36 changes: 36 additions & 0 deletions src/remote/RemoteMidiMessageIntegrator_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/******************************************************************************
* Copyright (c) 2024 CrSjimo *
* *
* This file is part of TALCS. *
* *
* TALCS is free software: you can redistribute it and/or modify it under the *
* terms of the GNU Lesser General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* TALCS 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 Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with TALCS. If not, see <https://www.gnu.org/licenses/>. *
******************************************************************************/

#ifndef TALCS_REMOTEMIDIMESSAGEINTEGRATOR_P_H
#define TALCS_REMOTEMIDIMESSAGEINTEGRATOR_P_H

#include <TalcsRemote/RemoteMidiMessageIntegrator.h>

#include <TalcsMidi/private/AbstractMidiMessageIntegrator_p.h>

namespace talcs {
class RemoteMidiMessageIntegratorPrivate : public AbstractMidiMessageIntegratorPrivate {
Q_DECLARE_PUBLIC(RemoteMidiMessageIntegrator)
public:
QList<IntegratedMidiMessage> midiMessages;
QMutex mutex;
};
}

#endif //TALCS_REMOTEMIDIMESSAGEINTEGRATOR_P_H
67 changes: 67 additions & 0 deletions src/remote/RemoteProcessInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/******************************************************************************
* Copyright (c) 2024 CrSjimo *
* *
* This file is part of TALCS. *
* *
* TALCS is free software: you can redistribute it and/or modify it under the *
* terms of the GNU Lesser General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* TALCS 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 Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with TALCS. If not, see <https://www.gnu.org/licenses/>. *
******************************************************************************/

#ifndef TALCS_REMOTEPROCESSINFO_H
#define TALCS_REMOTEPROCESSINFO_H

#include <TalcsRemote/TalcsRemoteGlobal.h>

namespace talcs {

struct RemoteMidiMessage {
int64_t size;
int64_t position;
char data[1];
};

struct RemoteMidiMessageList {
int64_t size;
RemoteMidiMessage messages[1];
};

struct RemoteProcessInfo {
int containsInfo;

//== Playback Status Info ==//
enum PlaybackStatus {
NotPlaying,
Playing,
RealtimePlaying,
};
PlaybackStatus status;

//== Timeline Info ==//
int timeSignatureNumerator;
int timeSignatureDenominator;
double tempo;

int64_t position;

//== MIDI ==//
RemoteMidiMessageList midiMessages;
};

class RemoteProcessInfoCallback {
public:
virtual void onThisBlockProcessInfo(const RemoteProcessInfo &processInfo) = 0;
};

}

#endif //TALCS_REMOTEPROCESSINFO_H
4 changes: 2 additions & 2 deletions src/remote/TransportAudioSourceProcessInfoCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ namespace talcs {
* - If the remote audio context is playing, the source will be played and the position will be synchronized with
* the remote audio context.
*/
void TransportAudioSourceProcessInfoCallback::onThisBlockProcessInfo(const RemoteAudioDevice::ProcessInfo &processInfo) {
if (processInfo.status == RemoteAudioDevice::ProcessInfo::NotPlaying) {
void TransportAudioSourceProcessInfoCallback::onThisBlockProcessInfo(const RemoteProcessInfo &processInfo) {
if (processInfo.status == RemoteProcessInfo::NotPlaying) {
if (m_tpSrc->isPlaying() && !m_isPaused)
m_tpSrc->pause();
m_isPaused = true;
Expand Down
4 changes: 2 additions & 2 deletions src/remote/TransportAudioSourceProcessInfoCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ namespace talcs {

class TransportAudioSource;

class TALCSREMOTE_EXPORT TransportAudioSourceProcessInfoCallback : public RemoteAudioDevice::ProcessInfoCallback {
class TALCSREMOTE_EXPORT TransportAudioSourceProcessInfoCallback : public RemoteProcessInfoCallback {
public:
explicit TransportAudioSourceProcessInfoCallback(TransportAudioSource *tpSrc);
void onThisBlockProcessInfo(const RemoteAudioDevice::ProcessInfo &processInfo) override;
void onThisBlockProcessInfo(const RemoteProcessInfo &processInfo) override;

private:
TransportAudioSource *m_tpSrc;
Expand Down

0 comments on commit ef8f816

Please sign in to comment.