Skip to content

Commit

Permalink
implement AAPXS SysEx8 generator support, up to the new plugin manage…
Browse files Browse the repository at this point in the history
…r (WIP)

context: #169

Unlike service side, the client side needs to handle it at app level.

It is still not verified, as it turned out that we do not have any feature
that triggers preset setter in the current manager UI. We need to add it.
  • Loading branch information
atsushieno committed Sep 8, 2023
1 parent 43922f9 commit 1663b90
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 32 deletions.
31 changes: 27 additions & 4 deletions androidaudioplugin-manager/src/main/cpp/AAPMidiEventTranslator.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#include "aap/core/aap_midi2_helper.h"
#include "AAPMidiEventTranslator.h"

aap::AAPMidiEventTranslator::AAPMidiEventTranslator(RemotePluginInstance* instance, int32_t midiBufferSize, int32_t initialMidiProtocol) :
instance(instance),
midi_buffer_size(midiBufferSize),
conversion_helper_buffer_size(AAP_MAX_EXTENSION_URI_SIZE + AAP_MAX_EXTENSION_DATA_SIZE + 16),
receiver_midi_protocol(initialMidiProtocol) {
translation_buffer = (uint8_t*) calloc(1, midi_buffer_size);
conversion_helper_buffer = (uint8_t*) calloc(1, conversion_helper_buffer_size);
}

aap::AAPMidiEventTranslator::~AAPMidiEventTranslator() {
if (translation_buffer)
free(translation_buffer);
if (conversion_helper_buffer)
free(conversion_helper_buffer);
}

int32_t aap::AAPMidiEventTranslator::translateMidiEvent(uint8_t * bytes, int32_t length) {
Expand Down Expand Up @@ -63,10 +73,23 @@ size_t aap::AAPMidiEventTranslator::runThroughMidi2UmpForMidiMapping(uint8_t* by
break;
}
if (presetIndex >= 0) {
// FIXME: this should not trigger non-RT extension event, but rather, generate an
// extension SysEx8 (TBD as per issue #73) and send it so that it can be processed
// in RT-safe manner as well as in sample accurate manner.
instance->getStandardExtensions().setCurrentPresetIndex(presetIndex);
if (instance->getInstanceState() == aap::PluginInstantiationState::PLUGIN_INSTANTIATION_STATE_ACTIVE) {
auto aapxsInstance = instance->getAAPXSManager()->getInstanceFor(
AAP_PRESETS_EXTENSION_URI);
auto size = aap_midi2_generate_aapxs_sysex8(
(uint32_t *) (translation_buffer + translatedIndex),
(midi_buffer_size - translatedIndex) / 4,
conversion_helper_buffer,
conversion_helper_buffer_size,
0,
AAP_PRESETS_EXTENSION_URI,
(const uint8_t *) aapxsInstance->data,
aapxsInstance->data_size);
translatedIndex += size;
}
else
// Trigger non-RT extension event at inactive state.
instance->getStandardExtensions().setCurrentPresetIndex(presetIndex);
}
// If a translated AAP parameter change message is detected, then output sysex8.
if (parameterIndex < 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ namespace aap {
// used when we need MIDI1<->UMP translation.
uint8_t* translation_buffer{nullptr};
int32_t midi_buffer_size;

uint8_t* conversion_helper_buffer{nullptr};
int32_t conversion_helper_buffer_size;

// MIDI protocol type of the messages it receives via JNI
int32_t receiver_midi_protocol;
int32_t current_mapping_policy{AAP_PARAMETERS_MAPPING_POLICY_NONE};
Expand All @@ -20,6 +24,7 @@ namespace aap {

public:
AAPMidiEventTranslator(RemotePluginInstance* instance, int32_t midiBufferSize = AAP_MANAGER_MIDI_BUFFER_SIZE, int32_t initialMidiProtocol = CMIDI2_PROTOCOL_TYPE_MIDI2);
~AAPMidiEventTranslator();

int32_t translateMidiEvent(uint8_t *data, int32_t length);

Expand Down
1 change: 0 additions & 1 deletion androidaudioplugin-manager/src/main/cpp/LocalDefinitions.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef AAP_CORE_LOCALDEFINITIONS_H
#define AAP_CORE_LOCALDEFINITIONS_H

#define AAP_PUBLIC_API __attribute__((__visibility__("default")))
#define AAP_OPEN_CLASS

#define AAP_MANAGER_MIDI_BUFFER_SIZE 65536
Expand Down
27 changes: 17 additions & 10 deletions androidaudioplugin/src/main/cpp/core/hosting/aap_midi2_helper.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#include "aap/core/aap_midi2_helper.h"
#include "aap/core/host/plugin-instance.h"

#ifdef __cplusplus
extern "C" {
#endif

static uint32_t aapMidi2ExtensionHelperGetUInt32(uint8_t* dst) {
if (cmidi2_util_is_platform_little_endian())
return dst[0] + (dst[1] << 8) + (dst[2] << 16) + (dst[1] << 24);
Expand All @@ -27,17 +31,17 @@ static void* aapMidi2ExtensionInvokeHelperSysEx8Forge(uint64_t data1, uint64_t d
return (void*) true;
}

bool aapMidi2GenerateAAPXSSysEx8(uint32_t* dst,
size_t dstSizeInInt,
uint8_t* conversionHelperBuffer,
size_t conversionHelperBufferSize,
uint8_t group,
const char* uri,
const uint8_t* data,
size_t dataSize) {
size_t aap_midi2_generate_aapxs_sysex8(uint32_t* dst,
size_t dstSizeInInt,
uint8_t* conversionHelperBuffer,
size_t conversionHelperBufferSize,
uint8_t group,
const char* uri,
const uint8_t* data,
size_t dataSize) {
size_t required = 16 + strlen(uri) + 4 + dataSize * sizeof(uint32_t);
if (dstSizeInInt < required || conversionHelperBufferSize < required)
return false;
return 0;

uint8_t* sysex = conversionHelperBuffer;
uint8_t* ptr = sysex;
Expand Down Expand Up @@ -69,7 +73,7 @@ bool aapMidi2GenerateAAPXSSysEx8(uint32_t* dst,
cmidi2_ump_sysex8_process(group, sysex, ptr - sysex, 0,
aapMidi2ExtensionInvokeHelperSysEx8Forge, &forge);

return true;
return forge.offset;
}

cmidi2_ump_binary_read_state* sysex8_binary_reader_helper_select_stream(uint8_t targetStreamId, void* context) {
Expand Down Expand Up @@ -124,3 +128,6 @@ bool aap_midi2_parse_aapxs_sysex8(aap_midi2_aapxs_parse_context* context,
return true;
}

#ifdef __cplusplus
} // extern "C"
#endif
8 changes: 8 additions & 0 deletions include/aap/android-audio-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <stddef.h>
#include <string.h>

/* it *may* be used on some public API. Not comprehensive. */
#define AAP_PUBLIC_API __attribute__((__visibility__("default")))

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -49,6 +52,11 @@ typedef struct aap_buffer_t {
/* The length of any plugin is limited to this number. */
const int32_t AAP_MAX_PLUGIN_ID_SIZE = 1024;
const int32_t AAP_MAX_EXTENSION_URI_SIZE = 1024;
/*
* Maximum transferable AAPXS data size (either as Binder Parcelable or as MIDI2 SysEx8).
* Anything that goes beyond this size in total should be passed via shared memory.
*/
const int32_t AAP_MAX_EXTENSION_DATA_SIZE = 1024;

/* forward declarations */
struct AndroidAudioPluginFactory;
Expand Down
43 changes: 26 additions & 17 deletions include/aap/core/aap_midi2_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include "aap/android-audio-plugin.h"

// C header, not C++. No namespace.
#ifdef __cplusplus
extern "C" {
#endif

#define AAP_MIDI2_AAPXS_DATA_MAX_SIZE 1024

Expand All @@ -27,31 +30,33 @@
* @param uri the extension URI (must be null terminated)
* @param data the extension invocation data
* @param dataSize the size of `data`
* @return `true` if success, `false` for failure (so far insufficient memory only).
* @return size of generated bytes (0 if failed)
*/
[[maybe_unused]] // FIXME: test!
static bool aapMidi2GenerateAAPXSSysEx8(uint32_t* dst,
size_t dstSizeInInt,
uint8_t* conversionHelperBuffer,
size_t conversionHelperBufferSize,
uint8_t group,
const char* uri,
const uint8_t* data,
size_t dataSize);
[[maybe_unused]] // it is used in androidaudioplugin-manager
AAP_PUBLIC_API
size_t aap_midi2_generate_aapxs_sysex8(uint32_t *dst,
size_t dstSizeInInt,
uint8_t *conversionHelperBuffer,
size_t conversionHelperBufferSize,
uint8_t group,
const char *uri,
const uint8_t *data,
size_t dataSize);

struct aap_midi2_aapxs_parse_context {
uint8_t group;
char uri[AAP_MAX_EXTENSION_URI_SIZE]; // must be null-terminated
uint8_t *data; // buffer must be allocated by the parsing host
uint32_t dataSize; // parsed result
uint8_t* conversionHelperBuffer;
uint8_t *conversionHelperBuffer;
size_t conversionHelperBufferSize;
};

AAP_PUBLIC_API
static inline void aap_midi2_aapxs_parse_context_prepare(
aap_midi2_aapxs_parse_context* context,
uint8_t* dataBuffer,
uint8_t* conversionHelperBuffer,
aap_midi2_aapxs_parse_context *context,
uint8_t *dataBuffer,
uint8_t *conversionHelperBuffer,
size_t conversionHelperBufferSize) {
context->data = dataBuffer;
context->dataSize = 0;
Expand All @@ -62,8 +67,12 @@ static inline void aap_midi2_aapxs_parse_context_prepare(
// Reads AAPXS SysEx8 UMP into `aap_midi2_aapxs_parse_context`.
// Returns true if it is successfully parsed and it turned out to be AAPXS SysEx8.
// In any other case, return false.
bool aap_midi2_parse_aapxs_sysex8(aap_midi2_aapxs_parse_context* context,
uint8_t* umpData,
size_t umpSize);
AAP_PUBLIC_API
bool aap_midi2_parse_aapxs_sysex8(aap_midi2_aapxs_parse_context *context,
uint8_t *umpData,
size_t umpSize);

#ifdef __cplusplus
} // extern "C"
#endif
#endif //AAP_CORE_AAP_MIDI2_HELPER_H

0 comments on commit 1663b90

Please sign in to comment.