Skip to content
This repository has been archived by the owner on May 4, 2021. It is now read-only.

Commit

Permalink
implemented port buffer and shared memory preparation part.
Browse files Browse the repository at this point in the history
There was a lot of cumbersome androidaudioplugin API that needs to be
addressed and cleaned up... logged as atsushieno/aap-core#79
  • Loading branch information
atsushieno committed Apr 20, 2021
1 parent 8f2f1a5 commit c98b7e9
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
64 changes: 62 additions & 2 deletions aap-midi-device-service/src/main/cpp/AAPMidiProcessor.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <sys/mman.h>
#include <android/sharedmem.h>
#include <aap/logging.h>
#include <aap/audio-plugin-host-android.h>
#include "AAPMidiProcessor.h"
Expand All @@ -23,10 +25,11 @@ namespace aapmidideviceservice {
return oboe::DataCallbackResult::Continue;
}

void AAPMidiProcessor::initialize(int32_t sampleRate) {
void AAPMidiProcessor::initialize(int32_t sampleRate, int32_t pluginFrameSize) {
// AAP settings
host = std::make_unique<aap::PluginHost>(&host_manager);
sample_rate = sampleRate;
plugin_frame_size = pluginFrameSize;

// Oboe configuration
builder.setDirection(oboe::Direction::Output);
Expand All @@ -39,6 +42,20 @@ namespace aapmidideviceservice {
}

void AAPMidiProcessor::terminate() {

// free shared memory buffers and close FDs for the instances.
// FIXME: shouldn't androidaudioplugin implement this functionality so that we don't have
// to manage it everywhere? It is also super error prone.
for (auto& data : instance_data_list) {
int numBuffers = data->plugin_buffer->num_buffers;
for (int n = 0; n < numBuffers; n++) {
munmap(data->buffer_pointers[n], data->plugin_buffer->num_frames * sizeof(float));
int fd = data->portSharedMemoryFDs[n];
if (fd != 0)
close(fd);
}
}

host.reset();
}

Expand Down Expand Up @@ -71,11 +88,44 @@ namespace aapmidideviceservice {
return;
}

auto pluginInfo = host_manager.getPluginInformation(pluginId);
int32_t numPorts = pluginInfo->getNumPorts();

auto instanceId = host->createInstance(pluginId, sample_rate);
instance_ids.emplace_back(instanceId);
auto instance = host->getInstance(instanceId);

auto data = std::make_unique<PluginInstanceData>(instanceId, numPorts);

instance->completeInstantiation();

auto sharedMemoryExtension = (aap::SharedMemoryExtension*) instance->getExtension(aap::SharedMemoryExtension::URI);

auto buffer = std::make_unique<AndroidAudioPluginBuffer>();
buffer->num_buffers = numPorts;
buffer->num_frames = plugin_frame_size;

size_t memSize = buffer->num_frames * sizeof(float);

data->instance_id = instanceId;
data->plugin_buffer = std::move(buffer);
data->plugin_buffer->buffers = data->buffer_pointers.get();


for (int i = 0; i < numPorts; i++) {
int fd = ASharedMemory_create(nullptr, memSize);
data->portSharedMemoryFDs.emplace_back(fd);
sharedMemoryExtension->getPortBufferFDs().emplace_back(fd);
data->plugin_buffer->buffers[i] = mmap(nullptr, memSize,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
}

instance->prepare(plugin_frame_size, data->plugin_buffer.get());

instance_data_list.emplace_back(std::move(data));
}

void AAPMidiProcessor::activate() {
// start Oboe stream.
if (state != AAP_MIDI_PROCESSOR_STATE_CREATED) {
aap::aprintf("Unexpected call to start() at %s state.",
convertStateToText(state).c_str());
Expand All @@ -92,10 +142,20 @@ namespace aapmidideviceservice {

stream->requestStart();

// activate instances
for (int i = 0; i < host->getInstanceCount(); i++)
host->getInstance(i)->activate();

state = AAP_MIDI_PROCESSOR_STATE_STARTED;
}

void AAPMidiProcessor::deactivate() {

// deactivate instances
for (int i = 0; i < host->getInstanceCount(); i++)
host->getInstance(i)->deactivate();

// close Oboe stream.
stream->stop();
stream->close();
stream.reset();
Expand Down
16 changes: 14 additions & 2 deletions aap-midi-device-service/src/main/cpp/AAPMidiProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,26 @@ namespace aapmidideviceservice {
AAP_MIDI_PROCESSOR_STATE_ERROR
};

struct PluginInstanceData {
PluginInstanceData(int instanceId, size_t numPorts) : instance_id(instanceId) {
buffer_pointers.reset((void**) calloc(sizeof(void*), numPorts));
}

int instance_id;
std::vector<int> portSharedMemoryFDs{};
std::unique_ptr<AndroidAudioPluginBuffer> plugin_buffer;
std::unique_ptr<void*> buffer_pointers{nullptr};
};

class AAPMidiProcessor {
static std::string convertStateToText(AAPMidiProcessorState state);

// AAP
aap::PluginHostManager host_manager{};
std::unique_ptr<aap::PluginHost> host{nullptr};
int sample_rate{0};
std::vector<int32_t> instance_ids{};
int plugin_frame_size{1024};
std::vector<std::unique_ptr<PluginInstanceData>> instance_data_list{};

// Oboe
oboe::AudioStreamBuilder builder;
Expand All @@ -37,7 +49,7 @@ namespace aapmidideviceservice {
public:
static AAPMidiProcessor* getInstance();

void initialize(int32_t sampleRate);
void initialize(int32_t sampleRate, int32_t frameSize);

static void registerPluginService(const aap::AudioPluginServiceConnection service);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ extern "C" {
#define AAPMIDIDEVICE_INSTANCE aapmidideviceservice::AAPMidiProcessor::getInstance()

JNIEXPORT void JNICALL Java_org_androidaudioplugin_midideviceservice_AudioPluginMidiReceiver_initializeReceiverNative(
JNIEnv *env, jobject midiReceiver, jobject applicationContext, jint sampleRate) {
AAPMIDIDEVICE_INSTANCE->initialize(sampleRate);
JNIEnv *env, jobject midiReceiver, jobject applicationContext, jint sampleRate, jint frameSize) {
AAPMIDIDEVICE_INSTANCE->initialize(sampleRate, frameSize);
}

JNIEXPORT void JNICALL Java_org_androidaudioplugin_midideviceservice_AudioPluginMidiReceiver_registerPluginService(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class AudioPluginMidiReceiver(private val service: AudioPluginMidiDeviceService)
// time as it must be instantiated at MidiDeviceService instantiation time when ApplicationContext
// is not assigned yet (as onCreate() was not invoked yet!).
private var sampleRate: Int? = null
private var frameSize: Int = 4096

fun initialize() {
val audioManager = service.getSystemService(Context.AUDIO_SERVICE) as AudioManager
Expand All @@ -62,7 +63,7 @@ class AudioPluginMidiReceiver(private val service: AudioPluginMidiDeviceService)

activate()
}
initializeReceiverNative(service.applicationContext, sampleRate!!)
initializeReceiverNative(service.applicationContext, sampleRate!!, frameSize)

setupDefaultPlugins()
}
Expand Down Expand Up @@ -95,7 +96,7 @@ class AudioPluginMidiReceiver(private val service: AudioPluginMidiDeviceService)
processMessage(msg, offset, count, timestamp)

// Initialize basic native parts, without any plugin information.
private external fun initializeReceiverNative(applicationContext: Context, sampleRate: Int)
private external fun initializeReceiverNative(applicationContext: Context, sampleRate: Int, frameSize: Int)
private external fun terminateReceiverNative()
// register Binder instance to native host
private external fun registerPluginService(binder: IBinder, packageName: String, className: String)
Expand Down

0 comments on commit c98b7e9

Please sign in to comment.