web c++ + lv2 and vst3 fixes

This commit is contained in:
Stefano D'Angelo 2024-02-02 17:44:58 +01:00
parent 985f3f7cc3
commit 4fe02c89af
10 changed files with 224 additions and 129 deletions

View File

@ -5,6 +5,7 @@ ifeq ($(OS), Windows_NT)
LV2DIR = $(shell echo '${COMMONPROGRAMFILES}' | sed 's:\\:/:g')/LV2
LV2DIR_USER = $(shell echo '${APPDATA}' | sed 's:\\:/:g')/LV2
CC = gcc
CXX = g++
else
UNAME_S = $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
@ -12,12 +13,14 @@ else
LV2DIR = /Library/Audio/Plug-Ins/LV2
LV2DIR_USER = ${HOME}/Library/Audio/Plug-Ins/LV2
CC = clang
CXX = clang++
else
DLL_SUFFIX = .so
PREFIX = /usr/local
LV2DIR = ${PREFIX}/lib/lv2
LV2DIR_USER = ${HOME}/.lv2
CC = gcc
CXX = g++
endif
endif

View File

@ -6,6 +6,7 @@ ifeq ($(OS), Windows_NT)
VST3DIR = $(shell echo '${COMMONPROGRAMFILES}' | sed 's:\\:/:g')/VST3
VST3DIR_USER = $(shell echo '${LOCALAPPDATA}' | sed 's:\\:/:g')/Programs/Common/VST3
CC = gcc
CXX = g++
else
UNAME_S = $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
@ -14,12 +15,14 @@ else
VST3DIR = /Library/Audio/Plug-Ins/VST3
VST3DIR_USER = ${HOME}/Library/Audio/Plug-Ins/VST3
CC = clang
CXX = clang++
else
DLL_SUFFIX = .so
PLATFORM = $(shell uname -m)-linux
VST3DIR = /usr/local/lib/vst3
VST3DIR_USER = ${HOME}/.vst3
CC = gcc
CXX = g++
endif
endif

View File

@ -5,6 +5,7 @@ DATA_DIR := $(or $(DATA_DIR),.)
PLUGIN_DIR := $(or $(PLUGIN_DIR),src)
CC = clang
CXX = clang++
CFLAGS = -Ofast -Wall -Wpedantic -Wextra
CFLAGS_ALL = -I${COMMON_DIR}/src -I${DATA_DIR}/src -I${PLUGIN_DIR} --target=wasm32 -flto -fvisibility=hidden ${CFLAGS} ${CFLAGS_EXTRA}
@ -29,9 +30,20 @@ LDFLAGS_ALL += -Wl,--export=processor_midi_msg_in
endif
LDFLAGS_ALL += ${LDFLAGS} ${LDFLAGS_EXTRA}
C_SRCS = ${COMMON_DIR}/src/processor.c
CXXFLAGS = ${CFLAGS}
CXXFLAGS_ALL = -I${COMMON_DIR}/src -I${DATA_DIR}/src -I${PLUGIN_DIR} --target=wasm32 -flto -fvisibility=hidden ${CXXFLAGS} ${CXXFLAGS_EXTRA}
C_SRCS = ${COMMON_DIR}/src/processor.c ${COMMON_DIR}/src/walloc.c ${COMMON_DIR}/src/memset.c
C_OBJS = $(addprefix build/obj/, $(notdir $(C_SRCS:.c=.o)))
ifeq ($(CXX_SRCS_EXTRA),)
CXX_SRCS =
CXX_OBJS =
else
CXX_SRCS = ${COMMON_DIR}/src/new.cpp ${CXX_SRCS_EXTRA}
CXX_OBJS = $(addprefix build/obj/, $(notdir $(CXX_SRCS:.cpp=.o)))
endif
ALL = build/${BUNDLE_NAME}.wasm build/${BUNDLE_NAME}_processor.js build/${BUNDLE_NAME}.js
default: all
@ -40,14 +52,13 @@ default: all
all: ${ALL}
ifeq ($(CXX_OBJS),)
build/${BUNDLE_NAME}.wasm: ${C_OBJS} | build
${CC} $^ -o $@ ${CFLAGS_ALL} ${LDFLAGS_ALL}
.SECONDEXPANSION:
PERCENT := %
$(C_OBJS): build/obj/%.o: $$(filter $$(PERCENT)/$$(basename $$(notdir $$@)).c,$$(C_SRCS)) | build/obj
${CC} $^ -o $@ -c ${CFLAGS_ALL}
else
build/${BUNDLE_NAME}.wasm: ${C_OBJS} ${CXX_OBJS} | build
${CXX} $^ -o $@ ${CFLAGS_ALL} ${CXXFLAGS_ALL} ${LDFLAGS_ALL}
endif
build/${BUNDLE_NAME}_processor.js: ${DATA_DIR}/src/processor.js | build
cp $^ $@
@ -62,3 +73,13 @@ clean:
rm -fr build
.PHONY: all clean
.SECONDEXPANSION:
PERCENT := %
$(C_OBJS): build/obj/%.o: $$(filter $$(PERCENT)/$$(basename $$(notdir $$@)).c,$$(C_SRCS)) | build/obj
${CC} $^ -o $@ -c ${CFLAGS_ALL}
$(CXX_OBJS): build/obj/%.o: $$(filter $$(PERCENT)/$$(basename $$(notdir $$@)).cpp,$$(CXX_SRCS)) | build/obj
${CXX} $^ -o $@ -c ${CXXFLAGS_ALL}

View File

@ -1,7 +1,14 @@
BUNDLE_NAME := {{=it.product.bundleName}}
CFLAGS_EXTRA := {{=it.make && it.make.cflags ? it.make.cflags : ""}} {{=it.web_make && it.web_make.cflags ? it.web_make.cflags : ""}}
LDFLAGS_EXTRA := {{=it.make && it.make.ldflags ? it.make.ldflags : ""}} {{=it.web_make && it.web_make.ldflags ? it.web_make.ldflags : ""}}
CXXFLAGS_EXTRA := {{=it.make && it.make.cxxflags ? it.make.cxxflags : ""}} {{=it.web_make && it.web_make.cxxflags ? it.web_make.cxxflags : ""}}
C_SRCS_EXTRA := {{=it.make && it.make.cSrcs ? it.make.cSrcs : ""}} {{=it.web_make.cSrcs ? it.web_make.cSrcs : ""}}
CXX_SRCS_EXTRA := {{=it.make && it.make.cxxSrcs ? it.make.cxxSrcs : ""}} {{=it.web_make.cxxSrcs ? it.web_make.cxxSrcs : ""}}
COMMON_DIR := {{=it.web_make && it.web_make.commonDir ? it.web_make.commonDir : (it.make && it.make.commonDir ? it.make.commonDir : "")}}
DATA_DIR := {{=it.web_make && it.web_make.dataDir ? it.web_make.dataDir : (it.make && it.make.dataDir ? it.make.dataDir : "")}}
PLUGIN_DIR := {{=it.web_make && it.web_make.pluginDir ? it.web_make.pluginDir : (it.make && it.make.pluginDir ? it.make.pluginDir : "")}}
HAS_MIDI_IN := {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "input").length > 0 ? "yes" : "no"}}

View File

@ -0,0 +1,12 @@
/*
* Copyright (C) 2023 Orastron Srl unipersonale
*/
#include "memset.h"
void *memset(void *ptr, int value, size_t num) {
unsigned char *p = (unsigned char *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = (unsigned char)value;
return ptr;
}

View File

@ -2,9 +2,19 @@
* Copyright (C) 2023 Orastron Srl unipersonale
*/
void *memset(void *ptr, int value, size_t num) {
unsigned char *p = (unsigned char *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = (unsigned char)value;
return ptr;
#ifndef MEMSET_H
#define MEMSET_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void *memset(void *ptr, int value, size_t num);
#ifdef __cplusplus
}
#endif
#endif

14
templates/web/src/new.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "walloc.h"
void * operator new(size_t size) {
return malloc(size);
}
void * operator new[](size_t size) {
return malloc(size);
}
void operator delete (void *ptr) noexcept {
free(ptr);
}
void operator delete[] (void *ptr) noexcept {
free(ptr);
}

127
templates/web/src/walloc.c Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2021, 2022, 2024 Orastron Srl unipersonale
*/
#include "walloc.h"
#include <stdint.h>
extern unsigned char __heap_base;
typedef struct _header {
struct _header *next;
struct _header *prev;
char free;
} header;
static char inited = 0;
static size_t get_size(header *h) {
char *n = (char *)h->next;
return (n ? n : (char *)(__builtin_wasm_memory_size(0) << 16)) - (char *)h - sizeof(header);
}
static void split_if_possible(header *h, size_t s, size_t size) {
if (s <= size + sizeof(header) + sizeof(header))
return;
header *hn = (header *)((char *)h + sizeof(header) + size);
hn->prev = h;
hn->next = h->next;
hn->free = 1;
h->next = hn;
if (hn->next)
hn->next->prev = hn;
}
void *malloc(size_t size) {
if (size == 0)
return NULL;
header *h = (header *)&__heap_base;
if (!inited) {
h->next = NULL;
h->prev = NULL;
h->free = 1;
inited = 1;
}
header *p;
for (; h; p = h, h = h->next) {
if (!h->free)
continue;
size_t s = get_size(h);
if (s < size)
continue;
split_if_possible(h, s, size);
h->free = 0;
return (char *)h + sizeof(header);
}
int32_t n = __builtin_wasm_memory_grow(0, ((size + sizeof(header) - 1) >> 16) + 1);
if (n < 0)
return NULL;
if (p->free)
h = p;
else {
h = (header *)(n << 16);
p->next = h;
h->prev = p;
h->next = NULL;
}
split_if_possible(h, get_size(h), size);
h->free = 0;
return (char *)h + sizeof(header);
}
void *realloc(void *ptr, size_t size) {
if (ptr == NULL)
return malloc(size);
if (size == 0) {
free(ptr);
return NULL;
}
header *h = (header *)((char *)ptr - sizeof(header));
size_t s = get_size(h);
if (s >= size)
return ptr;
void *p = malloc(size);
if (p == NULL)
return NULL;
char *src = (char *)ptr;
char *dest = (char *)p;
for (size_t i = 0; i < s; i++)
dest[i] = src[i];
free(ptr);
return p;
}
void free(void *ptr) {
header *h = (header *)((char *)ptr - sizeof(header));
h->free = 1;
if (h->next && h->next->free) {
h->next = h->next->next;
if (h->next)
h->next->prev = h;
}
if (h->prev && h->prev->free) {
h->prev->next = h->next;
if (h->next)
h->next->prev = h->prev;
}
}

View File

@ -2,126 +2,21 @@
* Copyright (C) 2021, 2022, 2024 Orastron Srl unipersonale
*/
#ifndef WALLOC_H
#define WALLOC_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
extern unsigned char __heap_base;
typedef struct _header {
struct _header *next;
struct _header *prev;
char free;
} header;
static char inited = 0;
static size_t get_size(header *h) {
char *n = (char *)h->next;
return (n ? n : (char *)(__builtin_wasm_memory_size(0) << 16)) - (char *)h - sizeof(header);
#ifdef __cplusplus
}
#endif
static void split_if_possible(header *h, size_t s, size_t size) {
if (s <= size + sizeof(header) + sizeof(header))
return;
header *hn = (header *)((char *)h + sizeof(header) + size);
hn->prev = h;
hn->next = h->next;
hn->free = 1;
h->next = hn;
if (hn->next)
hn->next->prev = hn;
}
void *malloc(size_t size) {
if (size == 0)
return NULL;
header *h = (header *)&__heap_base;
if (!inited) {
h->next = NULL;
h->prev = NULL;
h->free = 1;
inited = 1;
}
header *p;
for (; h; p = h, h = h->next) {
if (!h->free)
continue;
size_t s = get_size(h);
if (s < size)
continue;
split_if_possible(h, s, size);
h->free = 0;
return (char *)h + sizeof(header);
}
int32_t n = __builtin_wasm_memory_grow(0, ((size + sizeof(header) - 1) >> 16) + 1);
if (n < 0)
return NULL;
if (p->free)
h = p;
else {
h = (header *)(n << 16);
p->next = h;
h->prev = p;
h->next = NULL;
}
split_if_possible(h, get_size(h), size);
h->free = 0;
return (char *)h + sizeof(header);
}
void *realloc(void *ptr, size_t size) {
if (ptr == NULL)
return malloc(size);
if (size == 0) {
free(ptr);
return NULL;
}
header *h = (header *)((char *)ptr - sizeof(header));
size_t s = get_size(h);
if (s >= size)
return ptr;
void *p = malloc(size);
if (p == NULL)
return NULL;
char *src = (char *)ptr;
char *dest = (char *)p;
for (size_t i = 0; i < s; i++)
dest[i] = src[i];
free(ptr);
return p;
}
void free(void *ptr) {
header *h = (header *)((char *)ptr - sizeof(header));
h->free = 1;
if (h->next && h->next->free) {
h->next = h->next->next;
if (h->next)
h->next->prev = h;
}
if (h->prev && h->prev->free) {
h->prev->next = h->next;
if (h->next)
h->next->prev = h->prev;
}
}
#endif

View File

@ -3,7 +3,10 @@ var sep = path.sep;
module.exports = function (data, api) {
api.copyFile(`src${sep}memset.h`, `src${sep}memset.h`);
api.copyFile(`src${sep}memset.c`, `src${sep}memset.c`);
api.copyFile(`src${sep}walloc.h`, `src${sep}walloc.h`);
api.copyFile(`src${sep}walloc.c`, `src${sep}walloc.c`);
api.copyFile(`src${sep}new.cpp`, `src${sep}new.cpp`);
api.copyFile(`src${sep}processor.c`, `src${sep}processor.c`);
api.generateFileFromTemplateFile(`src${sep}data.h`, `src${sep}data.h`, data);
api.generateFileFromTemplateFile(`src${sep}processor.js`, `src${sep}processor.js`, data);