#include "genlib.h"
#include "genlib_exportfunctions.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "genlib_ops.h"
#ifdef JSON
#include "json.h"
#include "json_builder.h"
#endif
#define DATA_MAXIMUM_ELEMENTS (33554432)
void my_memset(void *p, int c, long size);
void my_memcpy(void *dst, const void *src, long size);
t_ptr sysmem_newptr(t_ptr_size size)
{
return (t_ptr)malloc(size);
}
t_ptr sysmem_newptrclear(t_ptr_size size)
{
t_ptr p = (t_ptr)malloc(size);
if (p)
my_memset(p, 0, size);
return p;
}
t_ptr sysmem_resizeptr(void *ptr, t_ptr_size newsize)
{
return (t_ptr)realloc(ptr, newsize);
}
t_ptr sysmem_resizeptrclear(void *ptr, t_ptr_size newsize)
{
size_t oldsize = malloc_size(ptr);
t_ptr p = (t_ptr)realloc(ptr, newsize);
if (p) {
if (newsize > oldsize)
my_memset((char *)p + oldsize, 0, newsize - oldsize);
}
return p;
}
t_ptr_size sysmem_ptrsize(void *ptr)
{
return malloc_size(ptr);
}
void sysmem_freeptr(void *ptr)
{
free(ptr);
}
void sysmem_copyptr(const void *src, void *dst, t_ptr_size bytes)
{
my_memcpy(dst, src, bytes);
}
void my_memset(void *p, int c, long size)
{
char *p2 = (char *)p;
int i;
for (i = 0; i < size; i++, p2++)
*p2 = c;
}
void my_memcpy(void *dst, const void *src, long size)
{
char *s2 = (char *)src;
char *d2 = (char *)dst;
int i;
for (i = 0; i < size; i++, s2++, d2++)
*d2 = *s2;
}
void set_zero64(t_sample *memory, long size)
{
long i;
for (i = 0; i < size; i++, memory++) {
*memory = 0.;
}
}
void genlib_report_error(const char *s)
{
}
void genlib_report_message(const char *s)
{
}
unsigned long systime_ticks(void)
{
return 0; }
void * genlib_obtain_reference_from_string(const char * name) {
return 0; }
t_genlib_buffer * genlib_obtain_buffer_from_reference(void *ref)
{
return 0; }
t_genlib_err genlib_buffer_edit_begin(t_genlib_buffer *b)
{
return 0; }
t_genlib_err genlib_buffer_edit_end(t_genlib_buffer *b, long valid)
{
return 0; }
t_genlib_err genlib_buffer_getinfo(t_genlib_buffer *b, t_genlib_buffer_info *info)
{
return 0; }
char *genlib_reference_getname(void *ref)
{
return 0; }
void genlib_buffer_dirty(t_genlib_buffer *b)
{
}
t_genlib_err genlib_buffer_perform_begin(t_genlib_buffer *b)
{
return 0; }
void genlib_buffer_perform_end(t_genlib_buffer *b)
{
}
t_sample gen_msp_pow(t_sample value, t_sample power)
{
return pow(value, power);
}
void genlib_data_setbuffer(t_genlib_data *b, void *ref) {
genlib_report_error("not supported for export targets\n");
}
typedef struct {
t_genlib_data_info info;
t_sample cursor; } t_dsp_gen_data;
t_genlib_data * genlib_obtain_data_from_reference(void *ref)
{
t_dsp_gen_data * self = (t_dsp_gen_data *)malloc(sizeof(t_dsp_gen_data));
self->info.dim = 0;
self->info.channels = 0;
self->info.data = 0;
self->cursor = 0;
return (t_genlib_data *)self;
}
t_genlib_err genlib_data_getinfo(t_genlib_data *b, t_genlib_data_info *info) {
t_dsp_gen_data * self = (t_dsp_gen_data *)b;
info->dim = self->info.dim;
info->channels = self->info.channels;
info->data = self->info.data;
return GENLIB_ERR_NONE;
}
void genlib_data_release(t_genlib_data *b) {
t_dsp_gen_data * self = (t_dsp_gen_data *)b;
if (self->info.data) {
genlib_sysmem_freeptr(self->info.data);
self->info.data = 0;
}
}
long genlib_data_getcursor(t_genlib_data *b) {
t_dsp_gen_data * self = (t_dsp_gen_data *)b;
return self->cursor;
}
void genlib_data_setcursor(t_genlib_data *b, long cursor) {
t_dsp_gen_data * self = (t_dsp_gen_data *)b;
self->cursor = cursor;
}
void genlib_data_resize(t_genlib_data *b, long s, long c) {
t_dsp_gen_data * self = (t_dsp_gen_data *)b;
size_t sz, oldsz, copysz;
t_sample * old = 0;
t_sample * replaced = 0;
int i, j, copydim, copychannels, olddim, oldchannels;
old = self->info.data;
olddim = self->info.dim;
oldchannels = self->info.channels;
if (s * c > DATA_MAXIMUM_ELEMENTS) {
s = DATA_MAXIMUM_ELEMENTS/c;
genlib_report_message("warning: constraining [data] to < 256MB");
}
sz = sizeof(t_sample) * s * c;
oldsz = sizeof(t_sample) * olddim * oldchannels;
if (old && sz == oldsz) {
if (s > olddim) {
self->info.channels = c;
self->info.dim = s;
} else {
self->info.dim = s;
self->info.channels = c;
}
set_zero64(self->info.data, s * c);
return;
} else {
replaced = (t_sample *)sysmem_newptr(sz);
if (replaced == 0) {
genlib_report_error("allocating [data]: out of memory");
if (s > 512 || c > 1) {
genlib_data_resize((t_genlib_data *)self, 512, 1);
} else {
genlib_data_resize((t_genlib_data *)self, 4, 1);
}
return;
}
set_zero64(replaced, s * c);
if (old) {
copydim = olddim > s ? s : olddim;
if (c == oldchannels) {
copysz = sizeof(t_sample) * copydim * c;
memcpy(replaced, old, copysz);
} else {
copychannels = oldchannels > c ? c : oldchannels;
for (i = 0; i<copydim; i++) {
for (j = 0; j<copychannels; j++) {
replaced[j + i*c] = old[j + i*oldchannels];
}
}
}
}
if (old == 0) {
self->info.data = replaced;
self->info.dim = s;
self->info.channels = c;
} else {
if (oldsz > sz) {
if (s > olddim) {
self->info.channels = c;
self->info.dim = s;
} else {
self->info.dim = s;
self->info.channels = c;
}
self->info.data = replaced;
} else {
self->info.data = replaced;
if (s > olddim) {
self->info.channels = c;
self->info.dim = s;
} else {
self->info.dim = s;
self->info.channels = c;
}
}
sysmem_freeptr(old);
}
}
}
void genlib_reset_complete(void *data) {}
#ifdef JSON
void genlib_build_json(CommonState *cself, json_value **jsonvalue, getparameter_method getmethod)
{
int i;
*jsonvalue = json_object_new(0);
for (i = 0; i < cself->numparams; i++) {
t_param val;
(getmethod)(cself, i, &val);
json_object_push(*jsonvalue, cself->params[i].name, json_double_new(val));
}
}
size_t genlib_getstatesize(CommonState *cself, getparameter_method getmethod)
{
size_t size;
json_value *jsonvalue;
genlib_build_json(cself, &jsonvalue, getmethod);
size = json_measure(jsonvalue);
json_builder_free(jsonvalue);
return size;
}
short genlib_getstate(CommonState *cself, char *state, getparameter_method getmethod)
{
json_value *jsonvalue;
genlib_build_json(cself, &jsonvalue, getmethod);
json_serialize(state, jsonvalue);
json_builder_free(jsonvalue);
return 0;
}
static void * json_custom_alloc (size_t size, int zero, void * user_data)
{
return zero ? genlib_sysmem_newptrclear(size) : genlib_sysmem_newptr(size);
}
static void json_custom_free (void * ptr, void * user_data)
{
genlib_sysmem_freeptr(ptr);
}
short genlib_setstate(CommonState *cself, const char *state, setparameter_method setmethod)
{
json_settings settings;
char error[256];
memset(&settings, 0, sizeof (json_settings));
settings.mem_alloc = &json_custom_alloc;
settings.mem_free = &json_custom_free;
json_value *value = json_parse_ex(&settings, state, strlen(state), error);
if (value == NULL)
return 1;
if (value->type == json_object) {
unsigned int i;
for (i = 0; i < value->u.object.length; i++) {
char *name = NULL;
t_param val;
int j;
if (value->u.object.values[i].value->type == json_double) {
name = value->u.object.values[i].name;
val = value->u.object.values[i].value->u.dbl;
} else if (value->u.object.values[i].value->type == json_integer) {
name = value->u.object.values[i].name;
val = value->u.object.values[i].value->u.integer;
}
if (name) {
for (j = 0; j < cself->numparams; j++) {
if (!strcmp(cself->params[j].name, name)) {
(setmethod)(cself, j, val, NULL);
}
}
}
}
}
json_value_free_ex(&settings, value);
return 0;
}
#else
short genlib_setstate(CommonState *cself, const char *state, setparameter_method setmethod)
{
return 0;
}
short genlib_getstate(CommonState *cself, char *state, getparameter_method getmethod)
{
return 0;
}
size_t genlib_getstatesize(CommonState *cself, getparameter_method getmethod)
{
return 0;
}
#endif