diff options
Diffstat (limited to 'pluginhost~/src/handlers_pd.c')
-rw-r--r-- | pluginhost~/src/handlers_pd.c | 1153 |
1 files changed, 0 insertions, 1153 deletions
diff --git a/pluginhost~/src/handlers_pd.c b/pluginhost~/src/handlers_pd.c deleted file mode 100644 index bf5fd45..0000000 --- a/pluginhost~/src/handlers_pd.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* %s - A plugin host for Pd - * - * Copyright (C) 2006 Jamie Bullock and others - * - * This file incorporates code from the following sources: - * - * jack-dssi-host (BSD-style license): Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton. - * - * Hexter (GPL license): Copyright (C) 2004 Sean Bolton and others. - * - * plugin~ (GPL license): Copyright (C) 2000 Jarno Seppänen, remIXed 2005 - * - * liblo (CPL license): Copyright (C) 2004 Steve Harris - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> /* for uint8_t */ - -#include "jutils.h" -#include "handlers_osc.h" -#include "ph_common.h" - -#define DX7_VOICE_SIZE_PACKED 128 /*From hexter_types.h by Sean Bolton */ -#define DX7_DUMP_SIZE_BULK 4096+8 -#define DX7_BANK_SIZE 32 -#define DX7_MAX_PATCH_SIZE 16384 -#define ASCII_t 116 -#define ASCII_p 112 -#define ASCII_n 110 -#define ASCII_c 99 -#define ASCII_b 98 -#define ASCII_a 97 -#define TYPE_STRING_SIZE 20 -#define OSC_ADDR_MAX 8192 - -#if DEBUG == 1 -#define CHECKSUM_PATCH_FILES_ON_LOAD 1 -#endif - -#define CLASS_NAME_STR "pluginhost~" - - -/*From dx7_voice.h by Sean Bolton */ -typedef struct _dx7_patch_t { - uint8_t data[128]; -} dx7_patch_t; - - -/*From dx7_voice_data.c by Sean Bolton */ -static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* - * dx7_bulk_dump_checksum - ** Taken from dx7_voice_data.c by Sean Bolton ** - */ -static int -dx7_bulk_dump_checksum(uint8_t *data, int length) -{ - int sum = 0; - int i; - - for (i = 0; i < length; sum -= data[i++]); - return sum & 0x7F; -} - -/* - * encode_7in6 - ** Taken from gui_data.c by Sean Bolton ** - * - * encode a block of 7-bit data, in base64-ish style - */ -char *encode_7in6(uint8_t *data, int length) -{ - char *buffer; - int in, reg, above, below, shift, out; - int outchars = (length * 7 + 5) / 6; - unsigned int sum = 0; - - if (!(buffer = (char *)malloc(25 + outchars))) - return NULL; - - out = snprintf(buffer, 12, "%d ", length); - - in = reg = above = below = 0; - while (outchars) { - if (above == 6) { - buffer[out] = base64[reg >> 7]; - reg &= 0x7f; - above = 0; - out++; - outchars--; - } - if (below == 0) { - if (in < length) { - reg |= data[in] & 0x7f; - sum += data[in]; - } - below = 7; - in++; - } - shift = 6 - above; - if (below < shift) shift = below; - reg <<= shift; - above += shift; - below -= shift; - } - - snprintf(buffer + out, 12, " %d", sum); - - return buffer; -} - - - -/* end hexter code */ - - -static void ph_ladspa_description(ph *x, t_atom *at, - DSSI_Descriptor *psDescriptor){ - at[0].a_w.w_symbol = - gensym ((char*)psDescriptor->LADSPA_Plugin->Name); - outlet_anything (x->message_out, gensym ("name"), 1, at); - at[0].a_w.w_symbol = - gensym ((char*)psDescriptor->LADSPA_Plugin->Label); - outlet_anything (x->message_out, gensym ("label"), 1, at); - at[0].a_type = A_FLOAT; - at[0].a_w.w_float = psDescriptor->LADSPA_Plugin->UniqueID; - outlet_anything (x->message_out, gensym ("id"), 1, at); - at[0].a_type = A_SYMBOL; - at[0].a_w.w_symbol = - gensym ((char*)psDescriptor->LADSPA_Plugin->Maker); - outlet_anything (x->message_out, gensym ("maker"), 1, at); -} - -static void ph_midibuf_add(ph *x, int type, unsigned int chan, int param, int val) -{ - - if(chan > x->n_instances - 1){ - pd_error(x, "note discarded: MIDI data is for a bogus channel"); - return; - } - - t_int time_ref = x->time_ref; - t_int mapped; - - //mapped = x->channel_map[chan + 1] - 1; - /* FIX: get rid of mapping functionality */ - mapped = chan; - - x->midi_event_buf[x->buf_write_index].time.time.tv_sec = - (t_int)(clock_gettimesince(time_ref) * .001); - x->midi_event_buf[x->buf_write_index].time.time.tv_nsec = - (t_int)(clock_gettimesince(time_ref) * 1000); /*actually usec - we can't store this in nsec! */ - - if ((type == SND_SEQ_EVENT_NOTEON && val != 0) || - type != SND_SEQ_EVENT_NOTEON) { - x->midi_event_buf[x->buf_write_index].type = type; - switch (type) { - case SND_SEQ_EVENT_NOTEON: - x->midi_event_buf[x->buf_write_index].data.note.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.note.note = param; - x->midi_event_buf[x->buf_write_index].data.note.velocity = val; - break; - case SND_SEQ_EVENT_NOTEOFF: - x->midi_event_buf[x->buf_write_index].data.note.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.note.note = param; - x->midi_event_buf[x->buf_write_index].data.note.velocity = val; - break; - case SND_SEQ_EVENT_CONTROLLER: - x->midi_event_buf[x->buf_write_index].data.control.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.control.param = param; - x->midi_event_buf[x->buf_write_index].data.control.value = val; - break; - case SND_SEQ_EVENT_PITCHBEND: - x->midi_event_buf[x->buf_write_index].data.control.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.control.param = 0; - x->midi_event_buf[x->buf_write_index].data.control.value = val; - break; - case SND_SEQ_EVENT_CHANPRESS: - x->midi_event_buf[x->buf_write_index].data.control.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.control.param = 0; - x->midi_event_buf[x->buf_write_index].data.control.value = val; - break; - case SND_SEQ_EVENT_KEYPRESS: - x->midi_event_buf[x->buf_write_index].data.note.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.note.note = param; - x->midi_event_buf[x->buf_write_index].data.note.velocity = val; - break; - case SND_SEQ_EVENT_PGMCHANGE: - x->instances[mapped].pending_bank_msb = (param - 1) / 128; - x->instances[mapped].pending_bank_lsb = (param - 1) % 128; - x->instances[mapped].pending_pgm_change = val; - x->instances[mapped].ui_needs_pgm_update = 1; - ph_debug_post("pgm chabge received in buffer: MSB: %d, LSB %d, prog: %d", - x->instances[mapped].pending_bank_msb, x->instances[mapped].pending_bank_lsb, val); - - ph_program_change(x, mapped); - break; - } - } - else if (type == SND_SEQ_EVENT_NOTEON && val == 0) { - x->midi_event_buf[x->buf_write_index].type = SND_SEQ_EVENT_NOTEOFF; - x->midi_event_buf[x->buf_write_index].data.note.channel = mapped; - x->midi_event_buf[x->buf_write_index].data.note.note = param; - x->midi_event_buf[x->buf_write_index].data.note.velocity = val; - } - - ph_debug_post("MIDI received in buffer: chan %d, param %d, val %d, mapped to %d", - chan, param, val, mapped); - - x->buf_write_index = (x->buf_write_index + 1) % EVENT_BUFSIZE; -} - -static void ph_set_control_input_by_index (ph *x, - unsigned int ctrl_input_index, float value, unsigned int i) -{ - long port, portno; - t_int argc = 3; - t_atom argv[argc]; - ph_instance *instance; - - if (ctrl_input_index >= x->plugin_control_ins) { - pd_error(x, "control port number %d is out of range [1, %d]", - ctrl_input_index + 1, x->plugin_control_ins); - return; - } - - ph_debug_post("ctrl input number = %d", ctrl_input_index); - - port = x->plugin_ctlin_port_numbers[ctrl_input_index]; - - instance = &x->instances[i]; - - /* TODO - temporary hack */ - if(x->is_dssi) { - portno = instance->plugin_port_ctlin_numbers[ctrl_input_index + 1]; - } else { - portno = instance->plugin_port_ctlin_numbers[ctrl_input_index]; - } - - ph_debug_post("Global ctrl input number = %d", ctrl_input_index); - ph_debug_post("Global ctrl input value = %.2f", value); - - /* set the appropriate control port value */ - x->plugin_control_input[portno] = value; - - /* Update the UI if there is one */ - if(!x->is_dssi){ - return; - } - - if(instance->ui_osc_control_path == NULL){ - pd_error(x, "unable to send to NULL control path"); - return; - } - - SETSYMBOL(argv, gensym(instance->ui_osc_control_path)); - SETFLOAT(argv+1, port); - SETFLOAT(argv+2, value); - ph_instance_send_osc(x->message_out, instance, argc, argv); - -} - -static unsigned ph_get_param_num (ph *x, const char *str) -/* find out if str points to a parameter number or not and return the - number or zero. The number string has to begin with a '#' character */ -{ - long num = 0; - char* strend = NULL; - - if (str == NULL) { - return 0; - } - if (str[0] != '#') { - return 0; - } - num = strtol (&str[1], &strend, 10); - if (str[1] == 0 || *strend != 0) { - /* invalid string */ - return 0; - } - else if (num >= 1 && num <= (long)x->plugin_control_ins) { - /* string ok and within range */ - return (unsigned)num; - } - else { - /* number out of range */ - return 0; - } -} - -static void ph_set_control_input_by_name (ph *x, - const char* name, - float value, - unsigned int i) -{ - unsigned port_index = 0; - unsigned ctrl_input_index = 0; - int found_port = 0; /* boolean */ - - if (name == NULL || strlen (name) == 0) { - pd_error(x, "no control port name specified"); - return; - } - - /* compare control name to LADSPA control input ports' names - case-insensitively */ - found_port = 0; - ctrl_input_index = 0; - for (port_index = 0; port_index < x->descriptor->LADSPA_Plugin->PortCount; - port_index++) - { - LADSPA_PortDescriptor port_type; - port_type = x->descriptor->LADSPA_Plugin->PortDescriptors[port_index]; - if (LADSPA_IS_PORT_CONTROL (port_type) - && LADSPA_IS_PORT_INPUT (port_type)) - { - const char* port_name = NULL; - unsigned cmp_length = 0; - port_name = x->descriptor->LADSPA_Plugin->PortNames[port_index]; - cmp_length = MIN (strlen(name), strlen(port_name)); - if (cmp_length != 0 - && strncasecmp (name, port_name, cmp_length) == 0) - { - /* found the first port to match */ - found_port = 1; - break; - } - ctrl_input_index++; - } - } - - if (!found_port) { - pd_error(x, "plugin doesn't have a control input port named \"%s\"", - name); - return; - } - - ph_set_control_input_by_index (x, ctrl_input_index, value, i); - -} - -static void ph_ladspa_describe(const char * pcFullFilename, - void * pvPluginHandle, - DSSI_Descriptor_Function fDescriptorFunction, - void* user_data, - int is_dssi) -{ - - ph *x = (((void**)user_data)[0]); - t_atom at[1]; - DSSI_Descriptor *psDescriptor; - long lIndex; - - at[0].a_type = A_SYMBOL; - at[0].a_w.w_symbol = gensym ((char*)pcFullFilename); - outlet_anything (x->message_out, gensym ("library"), 1, at); - - if(is_dssi){ - ph_debug_post("DSSI plugin found by listinfo"); - - for (lIndex = 0; - (psDescriptor = (DSSI_Descriptor *) - fDescriptorFunction(lIndex)) != NULL; lIndex++) - ph_ladspa_description(x, &at[0], psDescriptor); - } - - else if(!is_dssi) - lIndex = 0; - do{ - psDescriptor = ladspa_to_dssi((LADSPA_Descriptor *)fDescriptorFunction(lIndex++)); - if(psDescriptor->LADSPA_Plugin != NULL){ - ph_ladspa_description(x, &at[0], psDescriptor); - free((DSSI_Descriptor *)psDescriptor); - } - else - break; - } while(1); -} - -static void ph_show(ph *x, unsigned int i, bool toggle) -{ - /* TODO:OSC */ -/* - if(instance->ui_target){ - if (instance->ui_hidden && toggle) { - lo_send(instance->ui_target, - instance->ui_osc_show_path, ""); - instance->ui_hidden = 0; - } - else if (!instance->ui_hidden && !toggle) { - instance->ui_osc_hide_path, ""); - instance->ui_hidden = 1; - } - } - else if(toggle){ - instance->ui_show = 1; - ph_load_gui(x, instance); - - } - */ -} - -static t_int ph_configure_buffer(ph *x, char *key, - char *value, unsigned int i) -{ - - ph_configure_pair *current; - ph_configure_pair *p; - ph_instance *instance; - - instance = &x->instances[i]; - current = x->configure_buffer_head; - - while(current){ - if(!strcmp(current->key, key) && current->instance == i) { - break; - } - current = current->next; - } - if(current) { - free(current->value); - } else { - current = malloc(sizeof(ph_configure_pair)); - current->next = x->configure_buffer_head; - current->key = strdup(key); - current->instance = i; - x->configure_buffer_head = current; - } - current->value = strdup(value); - p = x->configure_buffer_head; - - /*TODO: eventually give ability to query this buffer (to outlet?) */ - while(p){ - ph_debug_post("key: %s", p->key); - ph_debug_post("val: %s", p->value); - ph_debug_post("instance: %d", p->instance); - p = p->next; - } - - return 0; -} - -static t_int *ph_perform(t_int *w) -{ - unsigned int instance; - unsigned int i; - unsigned int N; - int timediff; - int framediff; - t_float **inputs; - t_float **outputs; - ph *x; - - x = (ph *)(w[1]); - N = (unsigned int)(w[2]); - inputs = (t_float **)(&w[3]); - outputs = (t_float **)(&w[3] + x->plugin_ins); - - if(x->dsp){ - x->dsp_loop = true; - - for(i = 0; i < x->plugin_ins; i++) - memcpy(x->plugin_input_buffers[i], inputs[i], N * - sizeof(LADSPA_Data)); - - for (i = 0; i < x->n_instances; i++) - x->instance_event_counts[i] = 0; - - for (;x->buf_read_index != x->buf_write_index; x->buf_read_index = - (x->buf_read_index + 1) % EVENT_BUFSIZE) { - - instance = x->midi_event_buf[x->buf_read_index].data.note.channel; - - if(instance > x->n_instances){ - pd_error(x, - "%s: %s: discarding spurious MIDI data, for instance %d", - CLASS_NAME_STR, - x->descriptor->LADSPA_Plugin->Label, - instance); - ph_debug_post("n_instances = %d", x->n_instances); - - continue; - } - - if (x->instance_event_counts[instance] == EVENT_BUFSIZE){ - pd_error(x, "MIDI overflow on channel %d", instance); - continue; - } - - timediff = (int)(clock_gettimesince(x->time_ref) * 1000) - - x->midi_event_buf[x->buf_read_index].time.time.tv_nsec; - framediff = (int)((t_float)timediff * .000001 / x->sr_inv); - - if (framediff >= (int)N || framediff < 0) - x->midi_event_buf[x->buf_read_index].time.tick = 0; - else - x->midi_event_buf[x->buf_read_index].time.tick = - N - framediff - 1; - - x->instance_event_buffers[instance] - [x->instance_event_counts[instance]] = - x->midi_event_buf[x->buf_read_index]; - ph_debug_post("%s, note received on channel %d", - x->descriptor->LADSPA_Plugin->Label, - x->instance_event_buffers[instance] - [x->instance_event_counts[instance]].data.note.channel); - - x->instance_event_counts[instance]++; - - ph_debug_post("Instance event count for instance %d of %d: %d\n", - instance + 1, x->n_instances, x->instance_event_counts[instance]); - - - } - - i = 0; - while(i < x->n_instances){ - if(x->instance_handles[i] && - x->descriptor->run_multiple_synths){ - x->descriptor->run_multiple_synths - (x->n_instances, x->instance_handles, - (unsigned long)N, x->instance_event_buffers, - &x->instance_event_counts[0]); - break; - } - else if (x->instance_handles[i] && - x->descriptor->run_synth){ - x->descriptor->run_synth(x->instance_handles[i], - (unsigned long)N, x->instance_event_buffers[i], - x->instance_event_counts[i]); - i++; - } - else if (x->instance_handles[i] && - x->descriptor->LADSPA_Plugin->run){ - x->descriptor->LADSPA_Plugin->run - (x->instance_handles[i], N); - i++; - } - } - - - for(i = 0; i < x->plugin_outs; i++) - memcpy(outputs[i], (t_float *)x->plugin_output_buffers[i], N * - sizeof(LADSPA_Data)); - - x->dsp_loop = false; - } - return w + (x->plugin_ins + x->plugin_outs + 3); -} - - -/* ======================================== */ - -void handle_pd_bang(ph *x) -{ - t_atom at[3]; - - at[0].a_type = A_FLOAT; - at[1].a_type = A_SYMBOL; - at[2].a_type = A_SYMBOL; - - if(x->plugin_label != NULL){ - at[0].a_w.w_float = x->n_instances; - at[1].a_w.w_symbol = gensym ((char *)x->plugin_label); - } - else{ - at[0].a_w.w_float = 0; - at[1].a_w.w_symbol = gensym ("plugin"); - } - at[2].a_w.w_symbol = gensym ("instances"); - outlet_anything (x->message_out, gensym ("running"), 3, at); -} - -void handle_pd_list(ph *x, t_symbol *s, int argc, t_atom *argv) -{ - char msg_type[TYPE_STRING_SIZE]; - int ev_type = 0; - atom_string(argv, msg_type, TYPE_STRING_SIZE); - int chan = (int)atom_getfloatarg(1, argc, argv) - 1; - int param = (int)atom_getfloatarg(2, argc, argv); - int val = (int)atom_getfloatarg(3, argc, argv); - int n_instances = x->n_instances; - - switch (msg_type[0]){ - case ASCII_n: ev_type = SND_SEQ_EVENT_NOTEON; - break; - case ASCII_c: ev_type = SND_SEQ_EVENT_CONTROLLER; - break; - case ASCII_p: ev_type = SND_SEQ_EVENT_PGMCHANGE; - break; - case ASCII_b: ev_type = SND_SEQ_EVENT_PITCHBEND; - break; - case ASCII_t: ev_type = SND_SEQ_EVENT_CHANPRESS; - break; - case ASCII_a: ev_type = SND_SEQ_EVENT_KEYPRESS; - break; - } - ph_debug_post("initial midi NOTE:, arg1 = %d, arg2 = %d, arg3 = %d, arg4 = %d",ev_type,chan,param,val); - - if(ev_type != 0) { - if(chan >= 0) { - ph_midibuf_add(x, ev_type, chan, param, val); - } else { - while(n_instances--) { - ph_midibuf_add(x, ev_type, n_instances, param, val); - } - } - } -} - -void handle_pd_dsp(ph *x, t_signal **sp) -{ - if(!x->n_instances){ - return; - } - - - t_int *dsp_vector, i, M; - - M = x->plugin_ins + x->plugin_outs + 2; - - dsp_vector = (t_int *) getbytes(M * sizeof(t_int)); - - dsp_vector[0] = (t_int)x; - dsp_vector[1] = (t_int)sp[0]->s_n; - - for(i = 2; i < M; i++) - dsp_vector[i] = (t_int)sp[i - 1]->s_vec; - - dsp_addv(ph_perform, M, dsp_vector); - -} - -void handle_pd_dssi(ph *x, t_symbol *s, int argc, t_atom *argv) -{ - if (!x->is_dssi) { - pd_error(x, "plugin is not a DSSI plugin, operation not supported"); - } - - char msg_type[TYPE_STRING_SIZE]; - char *debug; - char *filename; - char *filepath; - char *key; - char *value; - char *temp; - char mydir[MAXPDSTRING]; - int instance = -1; - int pathlen; - int toggle; - int fd; - int n_instances = x->n_instances; - int count; - int chan; - int maxpatches; - unsigned int i; - t_float val; - long filelength = 0; - unsigned char *raw_patch_data = NULL; - FILE *fp = NULL; - size_t filename_length, key_size, value_size; - dx7_patch_t patchbuf[DX7_BANK_SIZE]; - dx7_patch_t *firstpatch; - atom_string(argv, msg_type, TYPE_STRING_SIZE); - debug = NULL; - key = NULL; - value = NULL; - maxpatches = 128; - firstpatch = &patchbuf[0]; - val = 0; - - /*TODO: Temporary - at the moment we always load the first 32 patches to 0 */ - if(strcmp(msg_type, "configure")){ - instance = (int)atom_getfloatarg(2, argc, argv) - 1; - - if(!strcmp(msg_type, "load") && x->descriptor->configure){ - filename = argv[1].a_w.w_symbol->s_name; - pd_error(x, "loading patch: %s for instance %d", - filename, instance); - - if(!strcmp(x->descriptor->LADSPA_Plugin->Label, "hexter") || - !strcmp(x->descriptor->LADSPA_Plugin->Label, "hexter6")) { - - key = malloc(10 * sizeof(char)); /* holds "patchesN" */ - strcpy(key, "patches0"); - - /* TODO: duplicates code from load_plugin() */ - fd = canvas_open(x->x_canvas, filename, "", - mydir, &filename, MAXPDSTRING, 0); - - if(fd >= 0){ - filepath = mydir; - pathlen = strlen(mydir); - temp = &mydir[pathlen]; - sprintf(temp, "/%s", filename); - fp = fopen(filepath, "rb"); - } - else{ - pd_error(x, "unable to get file descriptor"); - } - - /*From dx7_voice_data by Sean Bolton */ - if(fp == NULL){ - pd_error(x, "unable to open patch file: %s", filename); - return; - } - if (fseek(fp, 0, SEEK_END) || - (filelength = ftell(fp)) == -1 || - fseek(fp, 0, SEEK_SET)) { - pd_error(x, "couldn't get length of patch file: %s", - filename); - fclose(fp); - return; - } - if (filelength == 0) { - pd_error(x, "patch file has zero length"); - fclose(fp); - return; - } else if (filelength > DX7_MAX_PATCH_SIZE) { - pd_error(x, "patch file is too large"); - fclose(fp); - return; - } - if (!(raw_patch_data = (unsigned char *)malloc(filelength))) { - pd_error(x, "couldn't allocate memory for raw patch file"); - fclose(fp); - return; - } - if (fread(raw_patch_data, 1, filelength, fp) - != (size_t)filelength) { - pd_error(x, "short read on patch file: %s", filename); - free(raw_patch_data); - fclose(fp); - return; - } - fclose(fp); - ph_debug_post("Patch file length is %ul", filelength); - - /* figure out what kind of file it is */ - filename_length = strlen(filename); - if (filename_length > 4 && - !strcmp(filename + filename_length - 4, ".dx7") && - filelength % DX7_VOICE_SIZE_PACKED == 0) { - /* It's a raw DX7 patch bank */ - ph_debug_post("Raw DX7 format patch bank passed"); - - count = filelength / DX7_VOICE_SIZE_PACKED; - count = count > maxpatches ? maxpatches : count; - - memcpy(firstpatch, raw_patch_data, count * - DX7_VOICE_SIZE_PACKED); - - } else if (filelength > 6 && - raw_patch_data[0] == 0xf0 && - raw_patch_data[1] == 0x43 && - /*This was used to fix some problem with Galaxy exports - possibly dump in worng format. It is not needed, but it did work, so in future, we may be able to support more formats not just DX7 */ - /* ((raw_patch_data[2] & 0xf0) == 0x00 || - raw_patch_data[2] == 0x7e) &&*/ - (raw_patch_data[2] & 0xf0) == 0x00 && - raw_patch_data[3] == 0x09 && - (raw_patch_data[4] == 0x10 || - raw_patch_data[4] == 0x20) && - /* 0x10 is actual, 0x20 matches typo in manual */ - raw_patch_data[5] == 0x00) { - /* It's a DX7 sys-ex 32 voice dump */ - - ph_debug_post("SYSEX header check passed"); - - - if (filelength != DX7_DUMP_SIZE_BULK || - raw_patch_data[DX7_DUMP_SIZE_BULK - 1] != 0xf7) { - pd_error(x, "badly formatted DX7 32 voice dump!"); - count = 0; - -#ifdef CHECKSUM_PATCH_FILES_ON_LOAD - } else if (dx7_bulk_dump_checksum(&raw_patch_data[6], - DX7_VOICE_SIZE_PACKED * 32) != - raw_patch_data[DX7_DUMP_SIZE_BULK - 2]) { - - pd_error(x, "DX7 32 voice dump with bad checksum!"); - count = 0; -#endif - - - } else { - - count = 32; - if (count > maxpatches) - count = maxpatches; - memcpy(firstpatch, raw_patch_data + 6, count * DX7_VOICE_SIZE_PACKED); - - } - } else { - - /* unsuccessful load */ - pd_error(x, "unknown patch bank file format!"); - count = 0; - - } - - free(raw_patch_data); - - if(count == 32) - value = encode_7in6((uint8_t *)&patchbuf[0].data[0], - count * DX7_VOICE_SIZE_PACKED); - - } - else if(!strcmp(x->descriptor->LADSPA_Plugin->Label, - "FluidSynth-DSSI")){ - key = malloc(6 * sizeof(char)); - strcpy(key, "load"); - value = filename; - } - else{ - pd_error(x, "%s patches are not supported", - x->descriptor->LADSPA_Plugin->Label); - } - } - - if(!strcmp(msg_type, "dir") && x->descriptor->configure){ - pathlen = strlen(argv[1].a_w.w_symbol->s_name) + 2; - x->project_dir = malloc((pathlen) * sizeof(char)); - atom_string(&argv[1], x->project_dir, pathlen); - pd_error(x, "project directory for instance %d has been set to: %s", instance, x->project_dir); - key = DSSI_PROJECT_DIRECTORY_KEY; - value = x->project_dir; - } else if (!strcmp(msg_type, "dir")) { - pd_error(x, "%s: %s %s: operation not supported", - CLASS_NAME_STR, - msg_type, - argv[1].a_w.w_symbol->s_name); - } - - if(!strcmp(msg_type, "show") || !strcmp(msg_type, "hide")){ - instance = (int)atom_getfloatarg(1, argc, argv) - 1; - if(!strcmp(msg_type, "show")) - toggle = 1; - else - toggle = 0; - - if(instance == -1){ - while(n_instances--) - ph_show(x, n_instances, toggle); - } - else - ph_show(x, instance, toggle); - } - - if(!strcmp(msg_type, "remap")) { - /* remap channel to instance */ - for(i = 0; i < x->n_instances && i < 128; i++){ - chan = (int)atom_getfloatarg(1 + i, argc, argv); - pd_error(x, "remapped MIDI channel %d to %d", 1+i, chan); - x->channel_map[i+1] = chan; - } - } - - } - - /*Use this to send arbitrary configure message to plugin */ - else if(!strcmp(msg_type, "configure")){ - key = - (char *)malloc(key_size = (strlen(argv[1].a_w.w_symbol->s_name) + 2) * sizeof(char)); - atom_string(&argv[1], key, key_size); - if(argc >= 3){ - if (argv[2].a_type == A_FLOAT){ - val = atom_getfloatarg(2, argc, argv); - value = (char *)malloc(TYPE_STRING_SIZE * - sizeof(char)); - sprintf(value, "%.2f", val); - } - else if(argv[2].a_type == A_SYMBOL){ - value = - (char *)malloc(value_size = - (strlen(argv[2].a_w.w_symbol->s_name) + 2) * - sizeof(char)); - atom_string(&argv[2], value, value_size); - } - - } - - if(argc == 4 && argv[3].a_type == A_FLOAT) - instance = atom_getfloatarg(3, argc, argv) - 1; - else if (n_instances) - instance = -1; - } - - if(key != NULL && value != NULL){ - - if(instance == -1){ - while(n_instances--){ - debug = ph_send_configure(x, key, value, n_instances); - ph_configure_buffer(x, key, value, n_instances); - } - } - /*TODO: Put some error checking in here to make sure instance is valid*/ - /* FIX: this is all a big hack (putting UI stuff in the host). Either - * hexter needs to expose these settings somehow (e.g. as configure - * key-value pairs), or we need a [hexter_ui] external/patch that - * mirrors the functionality of hexter_gtk */ - else{ - if(!strcmp(key, "pitch_bend_range")){ - x->instances[instance].perf_buffer[3] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "portamento_time")) { - x->instances[instance].perf_buffer[5] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "mod_wheel_sensitivity")) { - x->instances[instance].perf_buffer[9] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "mod_wheel_assign")) { - x->instances[instance].perf_buffer[10] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "foot_sensitivity")) { - x->instances[instance].perf_buffer[11] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "foot_assign")) { - x->instances[instance].perf_buffer[12] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "pressure_sensitivity")) { - x->instances[instance].perf_buffer[13] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "pressure_assign")) { - x->instances[instance].perf_buffer[14] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "breath_sensitivity")) { - x->instances[instance].perf_buffer[15] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else if (!strcmp(key, "breath_assign")) { - x->instances[instance].perf_buffer[16] = atoi(value); - char *p = encode_7in6(x->instances[instance].perf_buffer, - DX7_PERFORMANCE_SIZE); - debug = ph_send_configure(x, "performance", p, instance); - } else { - debug = ph_send_configure(x, key, value, instance); - } - ph_configure_buffer(x, key, value, instance); - } - } - ph_debug_post("The plugin returned %s", debug); - -} - -void handle_pd_control (ph *x, t_symbol* ctrl_name, t_float ctrl_value, - t_float instance) -/* Change the value of a named control port of the plug-in */ -{ - unsigned param = 0; - int i = instance - 1; - unsigned int n = x->n_instances; - - if (i > (int)x->n_instances || i < -1){ - pd_error(x, "control: invalid instance number %d", i); - return; - } - - ph_debug_post("Received LADSPA control data for instance %d", i); - - if (ctrl_name->s_name == NULL || strlen (ctrl_name->s_name) == 0) { - pd_error(x, "control messages must have a name and a value"); - return; - } - param = ph_get_param_num(x, ctrl_name->s_name); - if (param) { - if(i >= 0) { - ph_set_control_input_by_index (x, param - 1, ctrl_value, i); - } else if (i == -1) { - while(n--) { - ph_set_control_input_by_index (x, param - 1, ctrl_value, n); - } - } - } else if (i >= 0) { - ph_set_control_input_by_name (x, ctrl_name->s_name, - ctrl_value, i); - } else if (i == -1) { - while(n--) { - ph_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value, n); - } - } -} - -void handle_pd_info (ph *x) -{ - unsigned int i, - ctrl_portno, - audio_portno; - t_atom argv[7]; - - ctrl_portno = audio_portno = 0; - - if (x->descriptor == NULL) - return; - - for(i = 0; i < x->descriptor->LADSPA_Plugin->PortCount; i++){ - memcpy(&argv[0], &x->port_info[i].type, - sizeof(t_atom)); - memcpy(&argv[1], &x->port_info[i].data_type, - sizeof(t_atom)); - memcpy(&argv[3], &x->port_info[i].name, - sizeof(t_atom)); - memcpy(&argv[4], &x->port_info[i].lower_bound, - sizeof(t_atom)); - memcpy(&argv[5], &x->port_info[i].upper_bound, - sizeof(t_atom)); - memcpy(&argv[6], &x->port_info[i].p_default, - sizeof(t_atom)); - argv[2].a_type = A_FLOAT; - if(!strcmp(argv[1].a_w.w_symbol->s_name, "control")) - argv[2].a_w.w_float = (t_float)++ctrl_portno; - - else if(!strcmp(argv[1].a_w.w_symbol->s_name, "audio")) - argv[2].a_w.w_float = (t_float)++audio_portno; - - outlet_anything (x->message_out, gensym ("port"), 7, argv); - } -} - -void handle_pd_reset(ph *x, t_float i) -{ - unsigned int n; - const LADSPA_Descriptor *ladspa; - - ladspa = x->descriptor->LADSPA_Plugin; - - for(n = 0; n < x->n_instances; n++) { - if ((int)i == -1 || n == (int)i) { - if (ladspa->deactivate && ladspa->activate){ - ladspa->deactivate(x->instance_handles[n]); - ladspa->activate(x->instance_handles[n]); - } - } - } -} - -void handle_pd_listplugins (ph *x) -{ - void* user_data[1]; - user_data[0] = x; - LADSPAPluginSearch(ph_ladspa_describe,(void*)user_data); -} - -void handle_pd_osc(ph *x, t_symbol *s, int argc, t_atom *argv) -{ - - unsigned int i; - const char *method; - char path[OSC_ADDR_MAX]; - ph_instance *instance; - - instance = NULL; - - atom_string(argv, path, TYPE_STRING_SIZE); - - if (strncmp(path, "/dssi/", 6)){ - handle_osc_debug(path); - } - - for (i = 0; i < x->n_instances; i++) { - instance = &x->instances[i]; - if (!strncmp(path + 6, instance->osc_url_path, - strlen(instance->osc_url_path))) { - break; - } - } - - if(instance == NULL) { - pd_error(x, "instance not found"); - return; - } - - if (!instance->osc_url_path){ - handle_osc_debug(path); - } - - method = path + 6 + strlen(instance->osc_url_path); - - if (*method != '/' || *(method + 1) == 0){ - handle_osc_debug(path); - } - - method++; - - switch(argc) { - case 2: - - if (!strcmp(method, "configure") && - argv[1].a_type == A_SYMBOL && - argv[2].a_type == A_SYMBOL) { - handle_osc_configure(x, &argv[1], i); - } else if (!strcmp(method, "control") && - argv[1].a_type == A_FLOAT && - argv[2].a_type == A_FLOAT) { - handle_osc_control(x, argv, i); - } else if (!strcmp(method, "program") && - argv[1].a_type == A_FLOAT && - argv[2].a_type == A_FLOAT) { - handle_osc_program(x, argv, i); - } - break; - - case 1: - if (!strcmp(method, "midi")) { - handle_osc_midi(x, argv, i); - } else if (!strcmp(method, "update") && - argv[1].a_type == A_SYMBOL) { - handle_osc_update(x, argv, i); - } - break; - case 0: - if (!strcmp(method, "exiting")) { - handle_osc_exiting(x, argv, i); - } - break; - default: - handle_osc_debug(path); - break; - } -} |