summaryrefslogtreecommitdiff
path: root/portmidi/pm_haiku/pmhaiku.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'portmidi/pm_haiku/pmhaiku.cpp')
-rw-r--r--portmidi/pm_haiku/pmhaiku.cpp473
1 files changed, 0 insertions, 473 deletions
diff --git a/portmidi/pm_haiku/pmhaiku.cpp b/portmidi/pm_haiku/pmhaiku.cpp
deleted file mode 100644
index 0c592f1..0000000
--- a/portmidi/pm_haiku/pmhaiku.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-/* pmhaiku.cpp -- PortMidi os-dependent code */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <vector>
-#include <MidiConsumer.h>
-#include <MidiEndpoint.h>
-#include <MidiProducer.h>
-#include <MidiRoster.h>
-#include <MidiSynth.h>
-#include "portmidi.h"
-#include "pmutil.h"
-#include "pminternal.h"
-
-namespace {
- struct PmInputConsumer : BMidiLocalConsumer {
- PmInputConsumer(PmInternal *midi) :
- BMidiLocalConsumer("PortMidi input consumer"),
- midi(midi)
- {
- }
-
-
- void Data(uchar *data, size_t length, bool atomic, bigtime_t time)
- {
- if (!atomic)
- return; // should these be also supported?
-
- if (data[0] == B_SYS_EX_START) {
- pm_read_bytes(midi, data, length, time / 1000);
- } else {
- PmEvent event;
- switch (length) {
- case 1:
- event.message = Pm_Message(data[0], 0, 0);
- break;
- case 2:
- event.message = Pm_Message(data[0], data[1], 0);
- break;
- case 3:
- event.message = Pm_Message(data[0], data[1], data[2]);
- break;
- default:
- printf("Unexpected message length for short message, got %" B_PRIuSIZE "\n", length);
- break;
- }
- event.timestamp = time / 1000;
- pm_read_short(midi, &event);
- }
- }
-
- private:
- PmInternal *midi;
- };
-
- struct PmOutputInfo {
- BMidiLocalProducer *producer;
- std::vector<unsigned char> sysexBuffer;
- };
-
- struct PmSynthOutputInfo {
- BMidiSynth midiSynth;
- std::vector<unsigned char> sysexBuffer;
- };
-
-
- PmTimestamp synchronize(PmInternal *midi)
- {
- return 0;
- }
-
-
- PmError in_open(PmInternal *midi, void *driverInfo)
- {
- int32 endpointID = (int32)(intptr_t)pm_descriptors[midi->device_id].descriptor;
- BMidiProducer *producer = BMidiRoster::FindProducer(endpointID);
- if (!producer)
- return pmInvalidDeviceId;
- PmInputConsumer *consumer = new PmInputConsumer(midi);
- status_t status = producer->Connect(consumer);
- if (status != B_OK) {
- consumer->Release();
- producer->Release();
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- midi->api_info = consumer;
- producer->Release();
- return pmNoError;
- }
-
-
- PmError in_abort(PmInternal *midi)
- {
- return pmNoError;
- }
-
-
- PmError in_close(PmInternal *midi)
- {
- int32 endpointID = (int32)(intptr_t)pm_descriptors[midi->device_id].descriptor;
- BMidiProducer *producer = BMidiRoster::FindProducer(endpointID);
- if (!producer)
- return pmInvalidDeviceId;
- PmInputConsumer *consumer = (PmInputConsumer*)midi->api_info;
- status_t status = producer->Disconnect(consumer);
- if (status != B_OK) {
- consumer->Release();
- producer->Release();
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- consumer->Release();
- midi->api_info = NULL;
- producer->Release();
- return pmNoError;
- }
-
-
- PmError out_open(PmInternal *midi, void *driverInfo)
- {
- int32 endpointID = (int32)(intptr_t)pm_descriptors[midi->device_id].descriptor;
- BMidiConsumer *consumer = BMidiRoster::FindConsumer(endpointID);
- if (!consumer)
- return pmInvalidDeviceId;
- BMidiLocalProducer *producer = new BMidiLocalProducer("PortMidi output producer");
- status_t status = producer->Connect(consumer);
- if (status != B_OK) {
- consumer->Release();
- producer->Release();
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- PmOutputInfo *info = new PmOutputInfo;
- info->producer = producer;
- midi->api_info = info;
- consumer->Release();
- return pmNoError;
- }
-
-
- PmError out_abort(PmInternal *midi)
- {
- return pmNoError;
- }
-
-
- PmError out_close(PmInternal *midi)
- {
- int32 endpointID = (int32)(intptr_t)pm_descriptors[midi->device_id].descriptor;
- BMidiConsumer *consumer = BMidiRoster::FindConsumer(endpointID);
- if (!consumer)
- return pmInvalidDeviceId;
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- status_t status = info->producer->Disconnect(consumer);
- if (status != B_OK) {
- consumer->Release();
- midi->api_info = NULL;
- info->producer->Release();
- delete info;
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- consumer->Release();
- midi->api_info = NULL;
- info->producer->Release();
- delete info;
- return pmNoError;
- }
-
-
- PmError write_short(PmInternal *midi, PmEvent *buffer)
- {
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- uchar data[3];
- data[0] = Pm_MessageStatus(buffer->message);
- data[1] = Pm_MessageData1(buffer->message);
- data[2] = Pm_MessageData2(buffer->message);
- size_t length = pm_midi_length(data[0]);
-
- info->producer->SprayData(data, length, true, buffer->timestamp * 1000);
-
- // TODO: handle latency != 0
- return pmNoError;
- }
-
-
- PmError begin_sysex(PmInternal *midi, PmTimestamp timestamp)
- {
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- info->sysexBuffer.clear();
- return pmNoError;
- }
-
-
- PmError end_sysex(PmInternal *midi, PmTimestamp timestamp)
- {
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- info->producer->SpraySystemExclusive(&info->sysexBuffer[0], info->sysexBuffer.size(), timestamp * 1000);
- info->sysexBuffer.clear();
- return pmNoError;
- }
-
-
- PmError write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp)
- {
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- info->sysexBuffer.push_back(byte);
- return pmNoError;
- }
-
-
- PmError write_realtime(PmInternal *midi, PmEvent *buffer)
- {
- PmOutputInfo *info = (PmOutputInfo*)midi->api_info;
- info->producer->SpraySystemRealTime(Pm_MessageStatus(buffer->message), buffer->timestamp * 1000);
- return pmNoError;
- }
-
-
- PmError synth_open(PmInternal *midi, void *driverInfo)
- {
- PmSynthOutputInfo *info = new PmSynthOutputInfo;
- info->midiSynth.EnableInput(true, true);
- midi->api_info = info;
- return pmNoError;
- }
-
-
- PmError synth_abort(PmInternal *midi)
- {
- return pmNoError;
- }
-
-
- PmError synth_close(PmInternal *midi)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- delete info;
- midi->api_info = NULL;
- return pmNoError;
- }
-
-
- PmError write_short_synth(PmInternal *midi, PmEvent *buffer)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- uchar data[3];
- data[0] = Pm_MessageStatus(buffer->message);
- data[1] = Pm_MessageData1(buffer->message);
- data[2] = Pm_MessageData2(buffer->message);
-
- switch(data[0] & 0xf0) {
- case B_NOTE_OFF:
- info->midiSynth.NoteOff((data[0] & 0x0f) + 1, data[1], data[2], buffer->timestamp);
- break;
- case B_NOTE_ON:
- info->midiSynth.NoteOn((data[0] & 0x0f) + 1, data[1], data[2], buffer->timestamp);
- break;
- case B_KEY_PRESSURE:
- info->midiSynth.KeyPressure((data[0] & 0x0f + 1), data[1], data[2], buffer->timestamp);
- break;
- case B_CONTROL_CHANGE:
- info->midiSynth.ControlChange((data[0] & 0x0f) + 1, data[1], data[2], buffer->timestamp);
- break;
- case B_PROGRAM_CHANGE:
- info->midiSynth.ProgramChange((data[0] & 0x0f) + 1, data[1], buffer->timestamp);
- break;
- case B_CHANNEL_PRESSURE:
- info->midiSynth.ChannelPressure((data[0] & 0x0f) + 1, data[1], buffer->timestamp);
- break;
- case B_PITCH_BEND:
- info->midiSynth.PitchBend((data[0] & 0x0f) + 1, data[1], data[2], buffer->timestamp);
- break;
- }
-
- // TODO: handle latency != 0
- return pmNoError;
- }
-
-
- PmError begin_sysex_synth(PmInternal *midi, PmTimestamp timestamp)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- info->sysexBuffer.clear();
- return pmNoError;
- }
-
-
- PmError end_sysex_synth(PmInternal *midi, PmTimestamp timestamp)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- info->midiSynth.SystemExclusive(&info->sysexBuffer[0], info->sysexBuffer.size(), timestamp);
- info->sysexBuffer.clear();
- return pmNoError;
- }
-
-
- PmError write_byte_synth(PmInternal *midi, unsigned char byte, PmTimestamp timestamp)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- info->sysexBuffer.push_back(byte);
- return pmNoError;
- }
-
-
- PmError write_realtime_synth(PmInternal *midi, PmEvent *buffer)
- {
- PmSynthOutputInfo *info = (PmSynthOutputInfo*)midi->api_info;
- info->midiSynth.SystemRealTime(Pm_MessageStatus(buffer->message), buffer->timestamp);
- return pmNoError;
- }
-
-
- PmError write_flush(PmInternal *midi, PmTimestamp timestamp)
- {
- return pmNoError;
- }
-
-
- unsigned int check_host_error(PmInternal *midi)
- {
- return 0;
- }
-
-
- pm_fns_node pm_in_dictionary = {
- none_write_short,
- none_sysex,
- none_sysex,
- none_write_byte,
- none_write_short,
- none_write_flush,
- synchronize,
- in_open,
- in_abort,
- in_close,
- success_poll,
- check_host_error
- };
-
- pm_fns_node pm_out_dictionary = {
- write_short,
- begin_sysex,
- end_sysex,
- write_byte,
- write_realtime,
- write_flush,
- synchronize,
- out_open,
- out_abort,
- out_close,
- none_poll,
- check_host_error
- };
-
-
- pm_fns_node pm_synth_dictionary = {
- write_short_synth,
- begin_sysex_synth,
- end_sysex_synth,
- write_byte_synth,
- write_realtime_synth,
- write_flush,
- synchronize,
- synth_open,
- synth_abort,
- synth_close,
- none_poll,
- check_host_error
- };
-
-
- PmError create_virtual(int is_input, const char *name, void *driverInfo)
- {
- BMidiEndpoint *endpoint = is_input ? (BMidiEndpoint*)new BMidiLocalProducer(name) : new BMidiLocalConsumer(name);
- if (!endpoint->IsValid()) {
- endpoint->Release();
- strcpy(pm_hosterror_text, "Endpoint could not be created");
- pm_hosterror = TRUE;
- return pmHostError;
- }
- status_t status = endpoint->Register();
- if (status != B_OK) {
- endpoint->Release();
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- return pm_add_device(const_cast<char*>("Haiku MIDI kit"), name, is_input, TRUE, (void*)(intptr_t)endpoint->ID(), is_input ? &pm_in_dictionary : &pm_out_dictionary);
- }
-
- PmError delete_virtual(PmDeviceID id)
- {
- int32 endpointID = (int32)(intptr_t)pm_descriptors[id].descriptor;
- BMidiEndpoint *endpoint = BMidiRoster::FindEndpoint(endpointID);
- //TODO: handle connected producers and consumers
- status_t status = endpoint->Unregister();
- // release twice to actually free the endpoint (FindEndpoint increases the ref-count)
- endpoint->Release();
- endpoint->Release();
- if (status != B_OK) {
- strcpy(pm_hosterror_text, strerror(status));
- pm_hosterror = TRUE;
- return pmHostError;
- }
- return pmNoError;
- }
-}
-
-extern "C" {
- void pm_init()
- {
- pm_add_interf(const_cast<char*>("Haiku MIDI kit"), create_virtual, delete_virtual);
-
- pm_add_device(const_cast<char*>("Haiku MIDI kit"), "Soft Synth", FALSE, FALSE, NULL, &pm_synth_dictionary);
-
- int32 id = 0;
- BMidiEndpoint *endpoint;
-
- while ((endpoint = BMidiRoster::NextEndpoint(&id)) != NULL) {
- bool isInput = endpoint->IsProducer();
- pm_add_device(const_cast<char*>("Haiku MIDI kit"), endpoint->Name(), isInput, FALSE, (void*)(intptr_t)id, isInput ? &pm_in_dictionary : &pm_out_dictionary);
- endpoint->Release();
- }
- }
-
-
- void pm_term()
- {
- int i;
- for (i = 0; i < pm_descriptor_len; i++) {
- PmInternal *midi = pm_descriptors[i].pm_internal;
- if (midi && midi->api_info) {
- // device is still open, close it
- (*midi->dictionary->close)(midi);
- }
- if (pm_descriptors[i].pub.is_virtual && !pm_descriptors[i].deleted) {
- delete_virtual(i);
- }
- }
- }
-
-
- PmDeviceID Pm_GetDefaultInputDeviceID()
- {
- Pm_Initialize();
- return pm_default_input_device_id;
- }
-
-
- PmDeviceID Pm_GetDefaultOutputDeviceID()
- {
- Pm_Initialize();
- return pm_default_output_device_id;
- }
-
-
- void *pm_alloc(size_t s)
- {
- return malloc(s);
- }
-
-
- void pm_free(void *ptr)
- {
- free(ptr);
- }
-}