Skip to content

Commit

Permalink
Add URID extension.
Browse files Browse the repository at this point in the history
context: #180
  • Loading branch information
atsushieno committed Nov 16, 2023
1 parent c572e57 commit fb806cd
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions androidaudioplugin/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set (androidaudioplugin_SOURCES
"core/aapxs/presets-aapxs.cpp"
"core/aapxs/state-aapxs.cpp"
"core/aapxs/standard-extensions.cpp"
"core/aapxs/urid-aapxs.cpp"
)

if (ANDROID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ aap::xs::AAPXSDefinition_Parameters parameters;
aap::xs::AAPXSDefinition_Presets presets;
aap::xs::AAPXSDefinition_State state;
aap::xs::AAPXSDefinition_Gui gui;
aap::xs::AAPXSDefinition_Urid urid;

aap::xs::AAPXSDefinitionRegistry::AAPXSDefinitionRegistry(
std::unique_ptr<UridMapping> mapping,
Expand All @@ -18,6 +19,7 @@ aap::xs::AAPXSDefinitionRegistry::AAPXSDefinitionRegistry(
}

aap::xs::AAPXSDefinitionRegistry standard_extensions{std::make_unique<aap::xs::UridMapping>(), std::vector<AAPXSDefinition>({
urid.asPublic(),
midi.asPublic(),
parameters.asPublic(),
presets.asPublic(),
Expand Down
62 changes: 62 additions & 0 deletions androidaudioplugin/src/main/cpp/core/aapxs/urid-aapxs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#include "aap/core/aapxs/urid-aapxs.h"
#include "../AAPJniFacade.h"

void aap::xs::AAPXSDefinition_Urid::aapxs_urid_process_incoming_plugin_aapxs_request(
struct AAPXSDefinition *feature, AAPXSRecipientInstance *aapxsInstance,
AndroidAudioPlugin *plugin, AAPXSRequestContext *request) {
auto ext = (aap_urid_extension_t*) plugin->get_extension(plugin, AAP_URID_EXTENSION_URI);
if (!ext)
return; // FIXME: should there be any global error handling?
switch (request->opcode) {
case OPCODE_MAP:
uint8_t urid = *(uint8_t*) request->serialization->data;
auto len = *(int32_t *) ((uint8_t*) request->serialization->data + 1);
assert(len < AAP_MAX_EXTENSION_URI_SIZE);
char uri[AAP_MAX_EXTENSION_URI_SIZE];
strncpy(uri, (const char *) (1 + (int32_t *) request->serialization->data), len);
ext->map(ext, plugin, urid, uri);
aapxsInstance->send_aapxs_reply(aapxsInstance, request);
break;
}
}

void aap::xs::AAPXSDefinition_Urid::aapxs_urid_process_incoming_host_aapxs_request(
struct AAPXSDefinition *feature, AAPXSRecipientInstance *aapxsInstance,
AndroidAudioPluginHost *host, AAPXSRequestContext *request) {
throw std::runtime_error("There is no URID host extension");
}

void aap::xs::AAPXSDefinition_Urid::aapxs_urid_process_incoming_plugin_aapxs_reply(
struct AAPXSDefinition *feature, AAPXSInitiatorInstance *aapxsInstance,
AndroidAudioPlugin *plugin, AAPXSRequestContext *request) {
if (request->callback != nullptr)
request->callback(request->callback_user_data, plugin, request->request_id);
}

void aap::xs::AAPXSDefinition_Urid::aapxs_urid_process_incoming_host_aapxs_reply(
struct AAPXSDefinition *feature, AAPXSInitiatorInstance *aapxsInstance,
AndroidAudioPluginHost *host, AAPXSRequestContext *request) {
if (request->callback != nullptr)
request->callback(request->callback_user_data, host, request->request_id);
}

AAPXSExtensionClientProxy
aap::xs::AAPXSDefinition_Urid::aapxs_urid_get_plugin_proxy(struct AAPXSDefinition *feature,
AAPXSInitiatorInstance *aapxsInstance,
AAPXSSerializationContext *serialization) {
auto client = (AAPXSDefinition_Urid*) feature->aapxs_context;
if (!client->typed_client)
client->typed_client = std::make_unique<UridClientAAPXS>(aapxsInstance, serialization);
*client->typed_client = UridClientAAPXS(aapxsInstance, serialization);
client->client_proxy = AAPXSExtensionClientProxy{client->typed_client.get(), aapxs_urid_as_plugin_extension};
return client->client_proxy;
}

void aap::xs::UridClientAAPXS::map(uint8_t urid, const char *uri) {
*(uint8_t*) serialization->data = urid;
size_t len = strlen(uri);
*(uint32_t*) ((uint8_t*) serialization->data + 1) = len;
memcpy((uint8_t*) serialization->data + 1 + sizeof(int32_t), uri, len);
callVoidFunctionSynchronously(OPCODE_MAP);
}
1 change: 1 addition & 0 deletions include/aap/core/aapxs/standard-extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "state-aapxs.h"
#include "midi-aapxs.h"
#include "gui-aapxs.h"
#include "urid-aapxs.h"

namespace aap::xs {
class StandardExtensions {
Expand Down
96 changes: 96 additions & 0 deletions include/aap/core/aapxs/urid-aapxs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@


#ifndef AAP_CORE_URID_AAPXS_H
#define AAP_CORE_URID_AAPXS_H

#include <functional>
#include <future>
#include "aap/aapxs.h"
#include "../../ext/urid.h"
#include "typed-aapxs.h"

// plugin extension opcodes
const int32_t OPCODE_MAP = 1;

// host extension opcodes
// ... nothing?

const int32_t URID_SHARED_MEMORY_SIZE = AAP_MAX_PLUGIN_ID_SIZE + sizeof(int32_t) * 2 + AAP_MAX_EXTENSION_URI_SIZE + 1;

namespace aap::xs {
class UridClientAAPXS : public TypedAAPXS {
static void staticMap(aap_urid_extension_t* ext, AndroidAudioPlugin*, uint8_t urid, const char* uri) {
return ((UridClientAAPXS*) ext->aapxs_context)->map(urid, uri);
}
aap_urid_extension_t as_public_extension{this, staticMap};
public:
UridClientAAPXS(AAPXSInitiatorInstance* initiatorInstance, AAPXSSerializationContext* serialization)
: TypedAAPXS(AAP_URID_EXTENSION_URI, initiatorInstance, serialization) {
}

void map(uint8_t urid, const char* uri);

aap_urid_extension_t* asPluginExtension() { return &as_public_extension; }
};

class UridServiceAAPXS : public TypedAAPXS {
public:
UridServiceAAPXS(AAPXSInitiatorInstance* initiatorInstance, AAPXSSerializationContext* serialization)
: TypedAAPXS(AAP_URID_EXTENSION_URI, initiatorInstance, serialization) {
}

// nothing?
};

class AAPXSDefinition_Urid : public AAPXSDefinitionWrapper {

static void aapxs_urid_process_incoming_plugin_aapxs_request(
struct AAPXSDefinition* feature,
AAPXSRecipientInstance* aapxsInstance,
AndroidAudioPlugin* plugin,
AAPXSRequestContext* request);
static void aapxs_urid_process_incoming_host_aapxs_request(
struct AAPXSDefinition* feature,
AAPXSRecipientInstance* aapxsInstance,
AndroidAudioPluginHost* host,
AAPXSRequestContext* request);
static void aapxs_urid_process_incoming_plugin_aapxs_reply(
struct AAPXSDefinition* feature,
AAPXSInitiatorInstance* aapxsInstance,
AndroidAudioPlugin* plugin,
AAPXSRequestContext* request);
static void aapxs_urid_process_incoming_host_aapxs_reply(
struct AAPXSDefinition* feature,
AAPXSInitiatorInstance* aapxsInstance,
AndroidAudioPluginHost* host,
AAPXSRequestContext* request);

// It is used in synchronous context such as `get_extension()` in `binder-client-as-plugin.cpp` etc.
static AAPXSExtensionClientProxy aapxs_urid_get_plugin_proxy(
struct AAPXSDefinition* feature,
AAPXSInitiatorInstance* aapxsInstance,
AAPXSSerializationContext* serialization);

static void* aapxs_urid_as_plugin_extension(AAPXSExtensionClientProxy* proxy) {
return ((UridClientAAPXS*) proxy->aapxs_context)->asPluginExtension();
}

AAPXSDefinition aapxs_urid{this,
AAP_URID_EXTENSION_URI,
URID_SHARED_MEMORY_SIZE,
aapxs_urid_process_incoming_plugin_aapxs_request,
aapxs_urid_process_incoming_host_aapxs_request,
aapxs_urid_process_incoming_plugin_aapxs_reply,
aapxs_urid_process_incoming_host_aapxs_reply,
aapxs_urid_get_plugin_proxy,
nullptr // no host extension
};

public:
AAPXSDefinition& asPublic() override {
return aapxs_urid;
}
};
}

#endif //AAP_CORE_URID_AAPXS_H
32 changes: 32 additions & 0 deletions include/aap/ext/urid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef AAP_URID_H_INCLUDED
#define AAP_URID_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

#include "../android-audio-plugin.h"
#include "stdint.h"

#define AAP_URID_EXTENSION_URI "urn://androidaudioplugin.org/extensions/urid/v3"

typedef struct aap_urid_extension_t {
/*
* `aapxs_context` is an opaque pointer assigned and used by AAPXS hosting implementation (libandroidaudioplugin).
* Neither of plugin developer (extension user) or extension developers is supposed to touch it.
* this struct is instantiated per extension in a plugin instance.
*/
void *aapxs_context;

/*
* Add a mapping from URI to URID.
* It is an error if this function is called once it started "beginPrepare()" call.
*/
void (*map) (aap_urid_extension_t* ext, AndroidAudioPlugin* plugin, uint8_t urid, const char* uri);
} aap_urid_extension_t;

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

#endif // AAP_URID_H_INCLUDED

0 comments on commit fb806cd

Please sign in to comment.