diff --git a/platform/drumlogue/Gator-delfx/Makefile b/platform/drumlogue/Gator-delfx/Makefile new file mode 100644 index 00000000..a6cc2345 --- /dev/null +++ b/platform/drumlogue/Gator-delfx/Makefile @@ -0,0 +1,435 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +# Target architecture +TARGET_ARCH := armv7a + +# Set to 'yes' if you want to see the full log while compiling. +VERBOSE_COMPILE := no + +############################################################################## +# Additional source related definitions +# + +DINCDIR := $(COMMON_INC_PATH) + +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +############################################################################## +# Compiler options +# + +# C compiler warnings +USE_CWARN ?= -W -Wall -Wextra + +# C++ compiler warnings +USE_CXXWARN ?= -W -Wall -Wextra -Wno-ignored-qualifiers + +# Generic compiler options +ifeq ($(USE_OPT),) + USE_COPT = -pipe + USE_COPT += -ffast-math + USE_COPT += -fsigned-char + USE_COPT += -fno-stack-protector + USE_COPT += -fstrict-aliasing + USE_COPT += -falign-functions=16 + USE_COPT += -fno-math-errno + # USE_COPT += -fpermissive + + USE_CXXOPT = -pipe + USE_CXXOPT += -ffast-math + USE_CXXOPT += -fsigned-char + USE_CXXOPT += -fno-stack-protector + USE_CXXOPT += -fstrict-aliasing + USE_CXXOPT += -falign-functions=16 + USE_CXXOPT += -fno-math-errno + USE_CXXOPT += -fconcepts + # USE_CXXOPT += -fpermissive + # USE_CXXOPT += -fmessage-length=0 +endif + +# C specific options here (added to USE_OPT). +USE_COPT ?= + +# C++ specific options here (added to USE_OPT). +USE_CXXOPT ?= + +# Debug/Release build dependent options +ifneq ($(DEBUG),) + USE_OPT += -ggdb3 + USE_LTO := no + UDEFS += -DDEBUG + ifeq ($(DEBUG_OPTIM),) + USE_OPT += -Og ## Debug friendly optimizatiions + else + USE_OPT += $(DEBUG_OPTIM) + endif + + USE_VECTORIZATION := no +else + # Non-debug + USE_COPT += -fomit-frame-pointer + USE_COPT += -finline-limit=9999999999 + USE_COPT += --param max-inline-insns-single=9999999999 + + USE_CXXOPT += -fomit-frame-pointer + USE_CXXOPT += -finline-limit=9999999999 + USE_CXXOPT += --param max-inline-insns-single=9999999999 + USE_CXXOPT += -fno-threadsafe-statics + + ifeq ($(OPTIM),) + USE_OPT += -Os + else + USE_OPT += $(OPTIM) + endif + + USE_VECTORIZATION := yes +endif + +ifneq ($(NO_INLINE),) + USE_COPT += -fno-inline + USE_CXXOPT += -fno-inline +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC := no +endif + +# Linker extra options here. +USE_LDOPT ?= + +# Enable this if you want link time optimizations (LTO) +USE_LTO ?= yes + +############################################################################## +# Compiler settings +# + +CC := $(CROSS_COMPILE)gcc +CXXC := $(CROSS_COMPILE)g++ +LD := $(CROSS_COMPILE)g++ +AS := $(CROSS_COMPILE)g++ +AR := $(CROSS_COMPILE)ar +CP := $(CROSS_COMPILE)objcopy +OD := $(CROSS_COMPILE)objdump +SZ := $(CROSS_COMPILE)size +STRIP := $(CROSS_COMPILE)strip +NM := $(CROSS_COMPILE)nm +RANLIB := $(CROSS_COMPILE)ranlib +CXXFILT := $(CROSS_COMPILE)c++filt +RM := rm -f +MV := mv -f +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +# Non-THUMB-specific options here +AOPT := + +# Define C warning options here +CWARN := $(USE_CWARN) + +# Define C++ warning options here +CXXWARN := $(USE_CXXWARN) + +# Compiler options +OPT := $(USE_OPT) +COPT := $(USE_COPT) +CXXOPT := $(USE_CXXOPT) + +# Garbage collection +ifeq ($(USE_LINK_GC),yes) + COPT += -ffunction-sections -fdata-sections -fno-common + CXXOPT += -ffunction-sections -fdata-sections -fno-common + LDOPT := --gc-sections +else + LDOPT := +endif + +# Linker extra options +ifneq ($(USE_LDOPT),) + LDOPT := $(LDOPT),$(USE_LDOPT) +endif + +# Link time optimizations +ifeq ($(USE_LTO),yes) + OPT += -flto +endif + +# CPU/Architecture + +ARCH_OPT := -march=armv7-a -mtune=cortex-a7 -marm +OPT += -mfloat-abi=hard -mfpu=neon-vfpv4 +ifeq ($(USE_VECTORIZATION),yes) + OPT += -mvectorize-with-neon-quad + # OPT += -ffast-math + OPT += -ftree-vectorize + OPT += -ftree-vectorizer-verbose=4 + OPT += -funsafe-math-optimizations ## denormals assumed 0, so breaks IEEE754 + DDEF += -D__NEON__ +endif +DDEFS += -D__arm__ -D__cortex_a7__ + +# C Standard +CSTD ?= -std=c11 +COPT += $(CSTD) + +# C++ Standard +CXXSTD ?= -std=gnu++14 +CXXOPT += $(CXXSTD) + +# Output directory and files +BUILDDIR ?= build + +ifeq ($(BUILDDIR),.) + BUILDDIR = build +endif + +OUTFILES := $(BUILDDIR)/$(PROJECT).drmlgunit \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +ifdef $(SREC) + OUTFILES += $(BUILDDIR)/$(PROJECT).srec +endif + +# Source files groups and paths +SRC := $(CSRC) $(CXXSRC) +SRCPATHS := $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(SRC))) + +# Various directories +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst +DEPDIR := .dep + +# Object files groups +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +# dependency files +DEPS := $(addprefix $(DEPDIR)/, $(notdir $(OBJS:%.o=%.o.d))) + +# Paths +IINCDIR := $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR)) +LLIBDIR := $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) + +# Macros +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +# Libs +LIBS := $(DLIBS) $(ULIBS) + +# Various settings +MCFLAGS := $(ARCH_OPT) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(OPT) $(CXXOPT) $(CXXWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(OPT) $(LLIBDIR) -shared -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref$(LDOPT) + +# Generate dependency information +ASFLAGS += -MMD -MP -MF .dep/$(@F).d +ASXFLAGS += -MMD -MP -MF .dep/$(@F).d +CFLAGS += -MMD -MP -MF .dep/$(@F).d +CXXFLAGS += -MMD -MP -MF .dep/$(@F).d + +# Paths where to search for sources +VPATH := $(SRCPATHS) + +############################################################################## +# Deduce File Ownership for Build Products +# + +USER_ID := $(strip $(shell stat -c %u .)) +GROUP_ID := $(strip $(shell stat -c %g .)) + +############################################################################## +# Rules +# + +all: PRE_MAKE_ALL_RULE_HOOK $(OBJS) $(OUTFILES) POST_MAKE_ALL_RULE_HOOK + + +PRE_MAKE_ALL_RULE_HOOK: + +POST_MAKE_ALL_RULE_HOOK: | $(OBJS) $(OUTFILES) + @chown -R $(USER_ID):$(GROUP_ID) $(BUILDDIR) + @chown -R $(USER_ID):$(GROUP_ID) .dep + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): +ifneq ($(VERBOSE_COMPILE),yes) + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.c -o $(OBJDIR)/xxxx.o + @echo $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.cc -o $(OBJDIR)/xxxx.o + @echo $(AS) -c $(ASFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(CC) -c $(ASXFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(LD) xxxx.o $(LDFLAGS) $(LIBS) -o $(BUILDDIR)/$(PROJECT).elf + @echo +endif + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(CXXOBJS) : $(OBJDIR)/%.o : %.cc Makefile +ifeq ($(VERBOSE_COMPILE),yes) + @echo + $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@ +else + @echo Compiling $( $@ + $(SZ) $< +else + @echo Creating $@ + @$(OD) $(ODFLAGS) $< > $@ + @echo + @$(SZ) $< +endif + +%.list: %.drmlgunit +ifeq ($(VERBOSE_COMPILE),yes) + $(OD) -S $< > $@ +else + @echo Creating $@ + @$(OD) -S $< > $@ + @echo + @echo Done + @echo +endif + +install: | $(OBJS) $(OUTFILES) + @echo Deploying to $(INSTALLDIR)/$(PROJECT).drmlgunit + @mv $(BUILDDIR)/$(PROJECT).drmlgunit $(INSTALLDIR)/ + @echo + @echo Done + @echo + +clean: CLEAN_RULE_HOOK + @echo + @echo Cleaning + -rm -fR .dep $(BUILDDIR) $(PROJECT_ROOT)/$(PROJECT).drmlgunit + @echo + @echo Done + @echo + +CLEAN_RULE_HOOK: + +# +# Include the dependency files, should be the last of the makefile +# +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) diff --git a/platform/drumlogue/Gator-delfx/config.mk b/platform/drumlogue/Gator-delfx/config.mk new file mode 100644 index 00000000..c6646bb6 --- /dev/null +++ b/platform/drumlogue/Gator-delfx/config.mk @@ -0,0 +1,9 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +CSRC = header.c +CXXSRC = unit.cc +UINCDIR = ../../inc ../../prologue/inc/utils +ULIBS = -lm +ULIBS += -lc +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=8 diff --git a/platform/drumlogue/Gator-delfx/header.c b/platform/drumlogue/Gator-delfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/drumlogue/Gator-delfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/drumlogue/Gator-delfx/unit.cc b/platform/drumlogue/Gator-delfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/drumlogue/Gator-delfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/drumlogue/Gator-masterfx/Makefile b/platform/drumlogue/Gator-masterfx/Makefile new file mode 100644 index 00000000..a6cc2345 --- /dev/null +++ b/platform/drumlogue/Gator-masterfx/Makefile @@ -0,0 +1,435 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +# Target architecture +TARGET_ARCH := armv7a + +# Set to 'yes' if you want to see the full log while compiling. +VERBOSE_COMPILE := no + +############################################################################## +# Additional source related definitions +# + +DINCDIR := $(COMMON_INC_PATH) + +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +############################################################################## +# Compiler options +# + +# C compiler warnings +USE_CWARN ?= -W -Wall -Wextra + +# C++ compiler warnings +USE_CXXWARN ?= -W -Wall -Wextra -Wno-ignored-qualifiers + +# Generic compiler options +ifeq ($(USE_OPT),) + USE_COPT = -pipe + USE_COPT += -ffast-math + USE_COPT += -fsigned-char + USE_COPT += -fno-stack-protector + USE_COPT += -fstrict-aliasing + USE_COPT += -falign-functions=16 + USE_COPT += -fno-math-errno + # USE_COPT += -fpermissive + + USE_CXXOPT = -pipe + USE_CXXOPT += -ffast-math + USE_CXXOPT += -fsigned-char + USE_CXXOPT += -fno-stack-protector + USE_CXXOPT += -fstrict-aliasing + USE_CXXOPT += -falign-functions=16 + USE_CXXOPT += -fno-math-errno + USE_CXXOPT += -fconcepts + # USE_CXXOPT += -fpermissive + # USE_CXXOPT += -fmessage-length=0 +endif + +# C specific options here (added to USE_OPT). +USE_COPT ?= + +# C++ specific options here (added to USE_OPT). +USE_CXXOPT ?= + +# Debug/Release build dependent options +ifneq ($(DEBUG),) + USE_OPT += -ggdb3 + USE_LTO := no + UDEFS += -DDEBUG + ifeq ($(DEBUG_OPTIM),) + USE_OPT += -Og ## Debug friendly optimizatiions + else + USE_OPT += $(DEBUG_OPTIM) + endif + + USE_VECTORIZATION := no +else + # Non-debug + USE_COPT += -fomit-frame-pointer + USE_COPT += -finline-limit=9999999999 + USE_COPT += --param max-inline-insns-single=9999999999 + + USE_CXXOPT += -fomit-frame-pointer + USE_CXXOPT += -finline-limit=9999999999 + USE_CXXOPT += --param max-inline-insns-single=9999999999 + USE_CXXOPT += -fno-threadsafe-statics + + ifeq ($(OPTIM),) + USE_OPT += -Os + else + USE_OPT += $(OPTIM) + endif + + USE_VECTORIZATION := yes +endif + +ifneq ($(NO_INLINE),) + USE_COPT += -fno-inline + USE_CXXOPT += -fno-inline +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC := no +endif + +# Linker extra options here. +USE_LDOPT ?= + +# Enable this if you want link time optimizations (LTO) +USE_LTO ?= yes + +############################################################################## +# Compiler settings +# + +CC := $(CROSS_COMPILE)gcc +CXXC := $(CROSS_COMPILE)g++ +LD := $(CROSS_COMPILE)g++ +AS := $(CROSS_COMPILE)g++ +AR := $(CROSS_COMPILE)ar +CP := $(CROSS_COMPILE)objcopy +OD := $(CROSS_COMPILE)objdump +SZ := $(CROSS_COMPILE)size +STRIP := $(CROSS_COMPILE)strip +NM := $(CROSS_COMPILE)nm +RANLIB := $(CROSS_COMPILE)ranlib +CXXFILT := $(CROSS_COMPILE)c++filt +RM := rm -f +MV := mv -f +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +# Non-THUMB-specific options here +AOPT := + +# Define C warning options here +CWARN := $(USE_CWARN) + +# Define C++ warning options here +CXXWARN := $(USE_CXXWARN) + +# Compiler options +OPT := $(USE_OPT) +COPT := $(USE_COPT) +CXXOPT := $(USE_CXXOPT) + +# Garbage collection +ifeq ($(USE_LINK_GC),yes) + COPT += -ffunction-sections -fdata-sections -fno-common + CXXOPT += -ffunction-sections -fdata-sections -fno-common + LDOPT := --gc-sections +else + LDOPT := +endif + +# Linker extra options +ifneq ($(USE_LDOPT),) + LDOPT := $(LDOPT),$(USE_LDOPT) +endif + +# Link time optimizations +ifeq ($(USE_LTO),yes) + OPT += -flto +endif + +# CPU/Architecture + +ARCH_OPT := -march=armv7-a -mtune=cortex-a7 -marm +OPT += -mfloat-abi=hard -mfpu=neon-vfpv4 +ifeq ($(USE_VECTORIZATION),yes) + OPT += -mvectorize-with-neon-quad + # OPT += -ffast-math + OPT += -ftree-vectorize + OPT += -ftree-vectorizer-verbose=4 + OPT += -funsafe-math-optimizations ## denormals assumed 0, so breaks IEEE754 + DDEF += -D__NEON__ +endif +DDEFS += -D__arm__ -D__cortex_a7__ + +# C Standard +CSTD ?= -std=c11 +COPT += $(CSTD) + +# C++ Standard +CXXSTD ?= -std=gnu++14 +CXXOPT += $(CXXSTD) + +# Output directory and files +BUILDDIR ?= build + +ifeq ($(BUILDDIR),.) + BUILDDIR = build +endif + +OUTFILES := $(BUILDDIR)/$(PROJECT).drmlgunit \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +ifdef $(SREC) + OUTFILES += $(BUILDDIR)/$(PROJECT).srec +endif + +# Source files groups and paths +SRC := $(CSRC) $(CXXSRC) +SRCPATHS := $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(SRC))) + +# Various directories +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst +DEPDIR := .dep + +# Object files groups +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +# dependency files +DEPS := $(addprefix $(DEPDIR)/, $(notdir $(OBJS:%.o=%.o.d))) + +# Paths +IINCDIR := $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR)) +LLIBDIR := $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) + +# Macros +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +# Libs +LIBS := $(DLIBS) $(ULIBS) + +# Various settings +MCFLAGS := $(ARCH_OPT) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(OPT) $(CXXOPT) $(CXXWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(OPT) $(LLIBDIR) -shared -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref$(LDOPT) + +# Generate dependency information +ASFLAGS += -MMD -MP -MF .dep/$(@F).d +ASXFLAGS += -MMD -MP -MF .dep/$(@F).d +CFLAGS += -MMD -MP -MF .dep/$(@F).d +CXXFLAGS += -MMD -MP -MF .dep/$(@F).d + +# Paths where to search for sources +VPATH := $(SRCPATHS) + +############################################################################## +# Deduce File Ownership for Build Products +# + +USER_ID := $(strip $(shell stat -c %u .)) +GROUP_ID := $(strip $(shell stat -c %g .)) + +############################################################################## +# Rules +# + +all: PRE_MAKE_ALL_RULE_HOOK $(OBJS) $(OUTFILES) POST_MAKE_ALL_RULE_HOOK + + +PRE_MAKE_ALL_RULE_HOOK: + +POST_MAKE_ALL_RULE_HOOK: | $(OBJS) $(OUTFILES) + @chown -R $(USER_ID):$(GROUP_ID) $(BUILDDIR) + @chown -R $(USER_ID):$(GROUP_ID) .dep + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): +ifneq ($(VERBOSE_COMPILE),yes) + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.c -o $(OBJDIR)/xxxx.o + @echo $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.cc -o $(OBJDIR)/xxxx.o + @echo $(AS) -c $(ASFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(CC) -c $(ASXFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(LD) xxxx.o $(LDFLAGS) $(LIBS) -o $(BUILDDIR)/$(PROJECT).elf + @echo +endif + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(CXXOBJS) : $(OBJDIR)/%.o : %.cc Makefile +ifeq ($(VERBOSE_COMPILE),yes) + @echo + $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@ +else + @echo Compiling $( $@ + $(SZ) $< +else + @echo Creating $@ + @$(OD) $(ODFLAGS) $< > $@ + @echo + @$(SZ) $< +endif + +%.list: %.drmlgunit +ifeq ($(VERBOSE_COMPILE),yes) + $(OD) -S $< > $@ +else + @echo Creating $@ + @$(OD) -S $< > $@ + @echo + @echo Done + @echo +endif + +install: | $(OBJS) $(OUTFILES) + @echo Deploying to $(INSTALLDIR)/$(PROJECT).drmlgunit + @mv $(BUILDDIR)/$(PROJECT).drmlgunit $(INSTALLDIR)/ + @echo + @echo Done + @echo + +clean: CLEAN_RULE_HOOK + @echo + @echo Cleaning + -rm -fR .dep $(BUILDDIR) $(PROJECT_ROOT)/$(PROJECT).drmlgunit + @echo + @echo Done + @echo + +CLEAN_RULE_HOOK: + +# +# Include the dependency files, should be the last of the makefile +# +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) diff --git a/platform/drumlogue/Gator-masterfx/config.mk b/platform/drumlogue/Gator-masterfx/config.mk new file mode 100644 index 00000000..8967ed9a --- /dev/null +++ b/platform/drumlogue/Gator-masterfx/config.mk @@ -0,0 +1,9 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +CSRC = header.c +CXXSRC = unit.cc +UINCDIR = ../../inc ../../prologue/inc/utils +ULIBS = -lm +ULIBS += -lc +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=11 diff --git a/platform/drumlogue/Gator-masterfx/header.c b/platform/drumlogue/Gator-masterfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/drumlogue/Gator-masterfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/drumlogue/Gator-masterfx/unit.cc b/platform/drumlogue/Gator-masterfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/drumlogue/Gator-masterfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/drumlogue/Gator-revfx/Makefile b/platform/drumlogue/Gator-revfx/Makefile new file mode 100644 index 00000000..a6cc2345 --- /dev/null +++ b/platform/drumlogue/Gator-revfx/Makefile @@ -0,0 +1,435 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +# Target architecture +TARGET_ARCH := armv7a + +# Set to 'yes' if you want to see the full log while compiling. +VERBOSE_COMPILE := no + +############################################################################## +# Additional source related definitions +# + +DINCDIR := $(COMMON_INC_PATH) + +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +############################################################################## +# Compiler options +# + +# C compiler warnings +USE_CWARN ?= -W -Wall -Wextra + +# C++ compiler warnings +USE_CXXWARN ?= -W -Wall -Wextra -Wno-ignored-qualifiers + +# Generic compiler options +ifeq ($(USE_OPT),) + USE_COPT = -pipe + USE_COPT += -ffast-math + USE_COPT += -fsigned-char + USE_COPT += -fno-stack-protector + USE_COPT += -fstrict-aliasing + USE_COPT += -falign-functions=16 + USE_COPT += -fno-math-errno + # USE_COPT += -fpermissive + + USE_CXXOPT = -pipe + USE_CXXOPT += -ffast-math + USE_CXXOPT += -fsigned-char + USE_CXXOPT += -fno-stack-protector + USE_CXXOPT += -fstrict-aliasing + USE_CXXOPT += -falign-functions=16 + USE_CXXOPT += -fno-math-errno + USE_CXXOPT += -fconcepts + # USE_CXXOPT += -fpermissive + # USE_CXXOPT += -fmessage-length=0 +endif + +# C specific options here (added to USE_OPT). +USE_COPT ?= + +# C++ specific options here (added to USE_OPT). +USE_CXXOPT ?= + +# Debug/Release build dependent options +ifneq ($(DEBUG),) + USE_OPT += -ggdb3 + USE_LTO := no + UDEFS += -DDEBUG + ifeq ($(DEBUG_OPTIM),) + USE_OPT += -Og ## Debug friendly optimizatiions + else + USE_OPT += $(DEBUG_OPTIM) + endif + + USE_VECTORIZATION := no +else + # Non-debug + USE_COPT += -fomit-frame-pointer + USE_COPT += -finline-limit=9999999999 + USE_COPT += --param max-inline-insns-single=9999999999 + + USE_CXXOPT += -fomit-frame-pointer + USE_CXXOPT += -finline-limit=9999999999 + USE_CXXOPT += --param max-inline-insns-single=9999999999 + USE_CXXOPT += -fno-threadsafe-statics + + ifeq ($(OPTIM),) + USE_OPT += -Os + else + USE_OPT += $(OPTIM) + endif + + USE_VECTORIZATION := yes +endif + +ifneq ($(NO_INLINE),) + USE_COPT += -fno-inline + USE_CXXOPT += -fno-inline +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC := no +endif + +# Linker extra options here. +USE_LDOPT ?= + +# Enable this if you want link time optimizations (LTO) +USE_LTO ?= yes + +############################################################################## +# Compiler settings +# + +CC := $(CROSS_COMPILE)gcc +CXXC := $(CROSS_COMPILE)g++ +LD := $(CROSS_COMPILE)g++ +AS := $(CROSS_COMPILE)g++ +AR := $(CROSS_COMPILE)ar +CP := $(CROSS_COMPILE)objcopy +OD := $(CROSS_COMPILE)objdump +SZ := $(CROSS_COMPILE)size +STRIP := $(CROSS_COMPILE)strip +NM := $(CROSS_COMPILE)nm +RANLIB := $(CROSS_COMPILE)ranlib +CXXFILT := $(CROSS_COMPILE)c++filt +RM := rm -f +MV := mv -f +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +# Non-THUMB-specific options here +AOPT := + +# Define C warning options here +CWARN := $(USE_CWARN) + +# Define C++ warning options here +CXXWARN := $(USE_CXXWARN) + +# Compiler options +OPT := $(USE_OPT) +COPT := $(USE_COPT) +CXXOPT := $(USE_CXXOPT) + +# Garbage collection +ifeq ($(USE_LINK_GC),yes) + COPT += -ffunction-sections -fdata-sections -fno-common + CXXOPT += -ffunction-sections -fdata-sections -fno-common + LDOPT := --gc-sections +else + LDOPT := +endif + +# Linker extra options +ifneq ($(USE_LDOPT),) + LDOPT := $(LDOPT),$(USE_LDOPT) +endif + +# Link time optimizations +ifeq ($(USE_LTO),yes) + OPT += -flto +endif + +# CPU/Architecture + +ARCH_OPT := -march=armv7-a -mtune=cortex-a7 -marm +OPT += -mfloat-abi=hard -mfpu=neon-vfpv4 +ifeq ($(USE_VECTORIZATION),yes) + OPT += -mvectorize-with-neon-quad + # OPT += -ffast-math + OPT += -ftree-vectorize + OPT += -ftree-vectorizer-verbose=4 + OPT += -funsafe-math-optimizations ## denormals assumed 0, so breaks IEEE754 + DDEF += -D__NEON__ +endif +DDEFS += -D__arm__ -D__cortex_a7__ + +# C Standard +CSTD ?= -std=c11 +COPT += $(CSTD) + +# C++ Standard +CXXSTD ?= -std=gnu++14 +CXXOPT += $(CXXSTD) + +# Output directory and files +BUILDDIR ?= build + +ifeq ($(BUILDDIR),.) + BUILDDIR = build +endif + +OUTFILES := $(BUILDDIR)/$(PROJECT).drmlgunit \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +ifdef $(SREC) + OUTFILES += $(BUILDDIR)/$(PROJECT).srec +endif + +# Source files groups and paths +SRC := $(CSRC) $(CXXSRC) +SRCPATHS := $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(SRC))) + +# Various directories +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst +DEPDIR := .dep + +# Object files groups +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +# dependency files +DEPS := $(addprefix $(DEPDIR)/, $(notdir $(OBJS:%.o=%.o.d))) + +# Paths +IINCDIR := $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR)) +LLIBDIR := $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) + +# Macros +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +# Libs +LIBS := $(DLIBS) $(ULIBS) + +# Various settings +MCFLAGS := $(ARCH_OPT) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -fPIC -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(OPT) $(CXXOPT) $(CXXWARN) -fPIC -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(OPT) $(LLIBDIR) -shared -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref$(LDOPT) + +# Generate dependency information +ASFLAGS += -MMD -MP -MF .dep/$(@F).d +ASXFLAGS += -MMD -MP -MF .dep/$(@F).d +CFLAGS += -MMD -MP -MF .dep/$(@F).d +CXXFLAGS += -MMD -MP -MF .dep/$(@F).d + +# Paths where to search for sources +VPATH := $(SRCPATHS) + +############################################################################## +# Deduce File Ownership for Build Products +# + +USER_ID := $(strip $(shell stat -c %u .)) +GROUP_ID := $(strip $(shell stat -c %g .)) + +############################################################################## +# Rules +# + +all: PRE_MAKE_ALL_RULE_HOOK $(OBJS) $(OUTFILES) POST_MAKE_ALL_RULE_HOOK + + +PRE_MAKE_ALL_RULE_HOOK: + +POST_MAKE_ALL_RULE_HOOK: | $(OBJS) $(OUTFILES) + @chown -R $(USER_ID):$(GROUP_ID) $(BUILDDIR) + @chown -R $(USER_ID):$(GROUP_ID) .dep + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): +ifneq ($(VERBOSE_COMPILE),yes) + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.c -o $(OBJDIR)/xxxx.o + @echo $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) xxxx.cc -o $(OBJDIR)/xxxx.o + @echo $(AS) -c $(ASFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(CC) -c $(ASXFLAGS) -I. $(IINCDIR) xxxx.s -o $(OBJDIR)/xxxx.o + @echo $(LD) xxxx.o $(LDFLAGS) $(LIBS) -o $(BUILDDIR)/$(PROJECT).elf + @echo +endif + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(CXXOBJS) : $(OBJDIR)/%.o : %.cc Makefile +ifeq ($(VERBOSE_COMPILE),yes) + @echo + $(CXXC) -c $(CXXFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@ +else + @echo Compiling $( $@ + $(SZ) $< +else + @echo Creating $@ + @$(OD) $(ODFLAGS) $< > $@ + @echo + @$(SZ) $< +endif + +%.list: %.drmlgunit +ifeq ($(VERBOSE_COMPILE),yes) + $(OD) -S $< > $@ +else + @echo Creating $@ + @$(OD) -S $< > $@ + @echo + @echo Done + @echo +endif + +install: | $(OBJS) $(OUTFILES) + @echo Deploying to $(INSTALLDIR)/$(PROJECT).drmlgunit + @mv $(BUILDDIR)/$(PROJECT).drmlgunit $(INSTALLDIR)/ + @echo + @echo Done + @echo + +clean: CLEAN_RULE_HOOK + @echo + @echo Cleaning + -rm -fR .dep $(BUILDDIR) $(PROJECT_ROOT)/$(PROJECT).drmlgunit + @echo + @echo Done + @echo + +CLEAN_RULE_HOOK: + +# +# Include the dependency files, should be the last of the makefile +# +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) diff --git a/platform/drumlogue/Gator-revfx/config.mk b/platform/drumlogue/Gator-revfx/config.mk new file mode 100644 index 00000000..c6646bb6 --- /dev/null +++ b/platform/drumlogue/Gator-revfx/config.mk @@ -0,0 +1,9 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +CSRC = header.c +CXXSRC = unit.cc +UINCDIR = ../../inc ../../prologue/inc/utils +ULIBS = -lm +ULIBS += -lc +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=8 diff --git a/platform/drumlogue/Gator-revfx/header.c b/platform/drumlogue/Gator-revfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/drumlogue/Gator-revfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/drumlogue/Gator-revfx/unit.cc b/platform/drumlogue/Gator-revfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/drumlogue/Gator-revfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/inc/envelopes.h b/platform/inc/envelopes.h new file mode 100644 index 00000000..78f0b642 --- /dev/null +++ b/platform/inc/envelopes.h @@ -0,0 +1,168 @@ +/* + * File: envelopes.h + * + * Envelope generators + * + * 2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#pragma once + +#include + +#include "float_math.h" + +#define STAGE_IDLE 0U +#define STAGE_ATTACK 1U +#define STAGE_DECAY 2U +#define STAGE_SUSTAIN 3U +#define STAGE_RELEASE 4U + +struct eg_adsr { + uint32_t stage; + float attack_min_level = 0.f; + float attack_max_level = 1.f; + float idle_treshold = -144.4944f; //24-bit dBFS is small enough to finish with decaying + float idle_level = 0.f; + float decay_rate_ref_level = -60.f; + float level; + float rate; + float attack_rate; + float decay_rate; + float sustain_level; + float release_rate; + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_stage_idle() { + level = idle_level; + stage = STAGE_IDLE; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_stage_release() { + if (release_rate == 0.f) { + set_stage_idle(); + } else { + rate = release_rate; + if (stage != STAGE_DECAY) + level = fasterampdbf(level); + stage = STAGE_RELEASE; + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_stage_sustain() { + level = fasterdbampf(sustain_level); + stage = STAGE_SUSTAIN; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_stage_decay() { + if (decay_rate == 0.f) { + set_stage_sustain(); + } else { + rate = decay_rate; + level = fasterampdbf(attack_max_level); + stage = STAGE_DECAY; + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_stage_attack() { + if (attack_rate == 0.f) { + set_stage_decay(); + } else { + if (stage == STAGE_DECAY || stage == STAGE_RELEASE) + level = fasterdbampf(level); + if (attack_min_level > level) + level = attack_min_level; + stage = STAGE_ATTACK; + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void start() { + set_stage_attack(); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void stop() { + if (stage != STAGE_IDLE) + set_stage_release(); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_attack(float attack_time_s) { + if (attack_time_s == 0.f) { + attack_rate = 0.f; + if (stage == STAGE_ATTACK) + set_stage_decay(); + } else { + attack_rate = .208333333e-4f * (attack_max_level - idle_level) / attack_time_s; //1/48000 + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_decay(float decay_time_s) { + if (decay_time_s == 0.f) { + decay_rate = 0.f; + if (stage == STAGE_DECAY) + set_stage_sustain(); + } else { + decay_rate = .208333333e-4f * decay_rate_ref_level / decay_time_s; //1/48000 + } + if (stage == STAGE_DECAY) + rate = decay_rate; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_sustain(float sustain_level_db) { + sustain_level = sustain_level_db; + if (stage == STAGE_SUSTAIN) + level = fasterdbampf(sustain_level); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_release(float release_time_s) { + if (release_time_s == 0.f) { + release_rate = 0.f; + if (stage == STAGE_RELEASE) + set_stage_idle(); + } else { + release_rate = .208333333e-4f * decay_rate_ref_level / release_time_s; //1/48000 + } + if (stage == STAGE_RELEASE) + rate = release_rate; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + float out() { + return stage == STAGE_DECAY || stage == STAGE_RELEASE ? fasterdbampf(level) : level; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void advance(uint32_t samples) { + if (stage == STAGE_ATTACK) { + level += attack_rate * samples; + if (level < attack_max_level) + return; + samples = attack_rate == 0.f ? 0 : (level - attack_max_level) / attack_rate; + set_stage_decay(); + } + if (stage == STAGE_DECAY || stage == STAGE_RELEASE) { + level += rate * samples; + if (level < idle_treshold) { + set_stage_idle(); + } else if (stage == STAGE_DECAY && level < sustain_level) { + set_stage_sustain(); + } + } + } +}; + +#undef STAGE_IDLE +#undef STAGE_ATTACK +#undef STAGE_DECAY +#undef STAGE_SUSTAIN +#undef STAGE_RELEASE diff --git a/platform/inc/gate_arp.h b/platform/inc/gate_arp.h new file mode 100644 index 00000000..4780cca0 --- /dev/null +++ b/platform/inc/gate_arp.h @@ -0,0 +1,132 @@ +/* + * File: gate_arp.h + * + * Gate arpeggiator + * + * 2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#pragma once + +#include + +#include "patterns.h" + +#define MASK_ARP_GATE_ON 1U +#define MASK_ARP_STARTED 2U + +struct gate_arp { + uint32_t sample_counter; + uint32_t tick_samples; + uint32_t tick_counter; + uint32_t state; + uint32_t unit_num; + uint32_t unit_samples = 60 * 48000 / 56 / PATTERN_QUANTIZE; //default 120BPM + uint32_t unit_counter; + uint32_t pattern_idx; + const uint8_t *pattern_ptr = patterns; + void (*gate_on_callback)(); + void (*gate_off_callback)(); + + gate_arp() {} + + gate_arp(void (*gate_on)(), void (*gate_off)()) : gate_on_callback{gate_on}, gate_off_callback{gate_off} {} + + inline __attribute__((optimize("Ofast"), always_inline)) + void start() { + if (state & MASK_ARP_STARTED) + return; + state |= MASK_ARP_GATE_ON | MASK_ARP_STARTED; + sample_counter = 0; + pattern_idx = 0; + unit_num = pattern_ptr[pattern_idx] >> 4; + unit_counter = unit_num * unit_samples; + if (gate_on_callback != nullptr) + gate_on_callback(); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void stop() { + if (!(state & MASK_ARP_STARTED)) + return; + state &= ~(MASK_ARP_GATE_ON | MASK_ARP_STARTED); + if (gate_off_callback != nullptr) + gate_off_callback(); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void advance(uint32_t samples) { + tick_samples += samples; + if (!(state & MASK_ARP_STARTED)) + return; + sample_counter += samples; + if (sample_counter >= unit_counter) { + if (state & MASK_ARP_GATE_ON && (unit_num = pattern_ptr[pattern_idx] & 0x0F) != 0) { + state &= ~MASK_ARP_GATE_ON; + if (gate_off_callback != nullptr) + gate_off_callback(); + } else { + pattern_idx++; + if (pattern_ptr[pattern_idx] == 0) + pattern_idx = 0; + unit_num = pattern_ptr[pattern_idx] >> 4; + if (!(state & MASK_ARP_GATE_ON)) { + state |= MASK_ARP_GATE_ON; + if (gate_on_callback != nullptr) + gate_on_callback(); + } + } + sample_counter -= unit_counter; + unit_counter = unit_num * unit_samples; + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_pattern(uint32_t pattern) { + static uint32_t current_pattern; + if (pattern >= PATTERN_COUNT) + pattern = PATTERN_COUNT - 1; + if (pattern != current_pattern) { + if (pattern == 0) { + current_pattern = 0; + pattern_ptr = patterns; + } else { + for (; pattern > current_pattern; current_pattern++) + while (*(pattern_ptr++)); + for (; pattern < current_pattern; current_pattern--) + while (*(--pattern_ptr - 1)); + } + pattern_idx = 0; + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_tempo(uint32_t tempo) { + unit_samples = ((uint32_t)60 * 48000 / PATTERN_QUANTIZE << 14) / tempo << 2; + unit_counter = unit_num * unit_samples; + } + inline __attribute__((optimize("Ofast"), always_inline)) + + void set_tempo_4ppqn_tick(uint32_t counter) { + if (tick_counter != 0) { + unit_samples = tick_samples * 4 / PATTERN_QUANTIZE; + unit_counter = unit_num * unit_samples; + } + tick_samples = 0; + tick_counter = counter; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + bool is_gate_on() { + return state & MASK_ARP_GATE_ON; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + float out() { + return state & MASK_ARP_GATE_ON ? 1.f : 0.f; + } +}; + +#undef MASK_ARP_GATE_ON +#undef MASK_ARP_STARTED diff --git a/platform/inc/logue_wrap.h b/platform/inc/logue_wrap.h new file mode 100644 index 00000000..b9ccd14f --- /dev/null +++ b/platform/inc/logue_wrap.h @@ -0,0 +1,188 @@ +/* + * File: logue_wrap.h + * + * logue SDK 1.0/2.0 wrapper + * + * 2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#pragma once + +#define UNBRACE(X) ESC(ESCE X) +#define ESCE(...) ESCE __VA_ARGS__ +#define ESC(...) ESC_(__VA_ARGS__) +#define ESC_(...) EVAN ## __VA_ARGS__ +#define EVANESCE + +#define VAL_(a) a##_val +#define VAL(a) VAL_(a) + +#ifdef ARM_MATH_CM4 + #pragma message "ARM Cortex M4 target detected" + #include "userprg.h" +#elif defined(__cortex_a7__) + #pragma message "ARM Cortex A7 target detected" + #include "runtime.h" +#elif defined(ARM_MATH_CM7) + #pragma message "ARM Cortex M7 target detected" + #include "runtime.h" +#endif + +#if defined(USER_API_VERSION) && defined(USER_TARGET_PLATFORM) + #pragma message "logue SDK 1.0 detected" + #define TARGET_PLATFORM VAL(UNBRACE(USER_TARGET_PLATFORM)) + #define TARGET_MODULE VAL(USER_TARGET_MODULE) +#elif defined(UNIT_API_VERSION) && defined(UNIT_TARGET_PLATFORM) + #pragma message "logue SDK 2.0 detected" + #define TARGET_PLATFORM VAL(UNBRACE(UNIT_TARGET_PLATFORM)) + #define TARGET_MODULE VAL(UNIT_TARGET_MODULE) +#else + #pragma GCC error "Unsupported platform" +#endif + +#define k_user_target_prologue_val 1 +#define k_user_target_miniloguexd_val 2 +#define k_user_target_nutektdigital_val 3 +#define k_unit_target_prologue_val 1 +#define k_unit_target_miniloguexd_val 2 +#define k_unit_target_nts1_val 3 +#define k_unit_target_nutektdigital_val 3 +#define k_unit_target_drumlogue_val 4 +#define k_unit_target_nts1_mkii_val 5 +#define k_unit_target_nts3_kaoss_val 6 + +#if TARGET_PLATFORM == k_unit_target_prologue_val + #pragma message "prologue target detected" + #define UNIT_TARGET_PLATFORM_PROLOGUE +#elif TARGET_PLATFORM == k_unit_target_miniloguexd_val + #pragma message "minilogue XD target detected" + #define UNIT_TARGET_PLATFORM_MINILOGUEXD +#elif TARGET_PLATFORM == k_unit_target_nts1_val + #pragma message "NTS-1 target detected" + #define UNIT_TARGET_PLATFORM_NTS1 +#elif TARGET_PLATFORM == k_unit_target_drumlogue_val + #pragma message "drumlogue target detected" + #define UNIT_TARGET_PLATFORM_DRUMLOGUE +#elif TARGET_PLATFORM == k_unit_target_nts1_mkii_val + #pragma message "NTS-1 mkII target detected" + #define UNIT_TARGET_PLATFORM_NTS1_MKII +#elif TARGET_PLATFORM == k_unit_target_nts3_kaoss_val + #pragma message "NTS-3 target detected" + #define UNIT_TARGET_PLATFORM_NTS3_KAOSS +#else + #pragma GCC error "Unsupported platform" +#endif + +#define k_user_module_modfx_val 11 +#define k_user_module_delfx_val 12 +#define k_user_module_revfx_val 13 +#define k_user_module_osc_val 14 +#define k_unit_module_modfx_val 21 +#define k_unit_module_delfx_val 22 +#define k_unit_module_revfx_val 23 +#define k_unit_module_osc_val 24 +#define k_unit_module_synth_val 25 +#define k_unit_module_masterfx_val 26 +#define k_unit_module_genericfx_val 27 + +#define UNIT_INPUT_CHANNELS 2 +#define UNIT_OUTPUT_CHANNELS 2 + +#ifdef UNIT_TARGET_MODULE + #if TARGET_MODULE == k_user_module_modfx_val + #pragma message "ModFX module detected" + #include "usermodfx.h" + #elif TARGET_MODULE == k_user_module_delfx_val + #pragma message "DelFX module detected" + #include "userdel.h" + #elif TARGET_MODULE == k_user_module_revfx_val + #pragma message "RevFX module detected" + #include "userrevfx.h" + #elif TARGET_MODULE == k_user_module_osc_val + #pragma message "OSC module detected" + #include "userosc.h" + #elif TARGET_MODULE == k_unit_module_modfx_val + #pragma message "ModFX module detected" + #ifdef UNIT_TARGET_PLATFORM_DRUMLOGUE + #include "unit.h" + #else + #include "unit_modfx.h" + #endif + #elif TARGET_MODULE == k_unit_module_delfx_val + #pragma message "DelFX module detected" + #ifdef UNIT_TARGET_PLATFORM_DRUMLOGUE + #include "unit.h" + #define UNIT_TARGET_MODULE_DELFX + #else + #include "unit_delfx.h" + #endif + #elif TARGET_MODULE == k_unit_module_revfx_val + #pragma message "RevFX module detected" + #ifdef UNIT_TARGET_PLATFORM_DRUMLOGUE + #include "unit.h" + #define UNIT_TARGET_MODULE_REVFX + #else + #include "unit_revfx.h" + #endif + #elif TARGET_MODULE == k_unit_module_osc_val + #pragma message "OSC module detected" + #include "unit_osc.h" + #undef UNIT_OUTPUT_CHANNELS + #define UNIT_OUTPUT_CHANNELS 1 + #elif TARGET_MODULE == k_unit_module_synth_val + #pragma message "Synth module detected" + #include "unit.h" + #define UNIT_TARGET_MODULE_SYNTH + #undef UNIT_INPUT_CHANNELS + #define UNIT_INPUT_CHANNELS 0 + #elif TARGET_MODULE == k_unit_module_masterfx_val + #pragma message "MasterFX module detected" + #include "unit.h" + #define UNIT_TARGET_MODULE_MASTERFX + #undef UNIT_INPUT_CHANNELS + #define UNIT_INPUT_CHANNELS 4 + #elif TARGET_MODULE == k_unit_module_genericfx_val + #pragma message "GenericFX module detected" + #include "unit_genericfx.h" + #else + #pragma GCC error "Unsupported unit module target" + #endif +#else + #pragma GCC error "Unsupported unit module target" +#endif + +#ifdef UNIT_GENERICFX_H_ + #define UNIT_HEADER_TYPE genericfx_unit_header_t + #define UNIT_HEADER_TARGET_FIELD unit_header.common.target +#else + #define UNIT_HEADER_TYPE unit_header_t + #define UNIT_HEADER_TARGET_FIELD unit_header.target +#endif + +#define UNIT_HEADER_TARGET_VALUE (UNIT_TARGET_PLATFORM | UNIT_TARGET_MODULE) + +#undef TARGET_PLATFORM +#undef k_user_target_prologue_val +#undef k_user_target_miniloguexd_val +#undef k_user_target_nutektdigital_val +#undef k_unit_target_prologue_val +#undef k_unit_target_miniloguexd_val +#undef k_unit_target_nts1_val +#undef k_unit_target_nutektdigital_val +#undef k_unit_target_drumlogue_val +#undef k_unit_target_nts1_mkii_val +#undef k_unit_target_nts3_kaoss_val + +#undef TARGET_MODULE +#undef k_user_module_modfx_val +#undef k_user_module_delfx_val +#undef k_user_module_revfx_val +#undef k_user_module_osc_val +#undef k_unit_module_modfx_val +#undef k_unit_module_delfx_val +#undef k_unit_module_revfx_val +#undef k_unit_module_osc_val +#undef k_unit_module_synth_val +#undef k_unit_module_masterfx_val +#undef k_unit_module_genericfx_val diff --git a/platform/inc/patterns.h b/platform/inc/patterns.h new file mode 100644 index 00000000..ad140eb1 --- /dev/null +++ b/platform/inc/patterns.h @@ -0,0 +1,72 @@ +/* + * File: patterns.h + * + * Kaossilator-style gate arpeggiator patterns + * + * 2020-2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#define PATTERN_QUANTIZE 16 //pattern beat quantization +#define PATTERN_SIZE 64 //pattern maximum size in quantization units +#define PATTERN_COUNT 51 //number of patterns + +//Patterns data - RLE endocded and zero-terminated +const uint8_t patterns[] = { +0x10, 0x00, + +0x31, 0x31, 0x31, 0x31, 0x00, +0x62, 0x62, 0x00, +0xA2, 0x00, +0xD3, 0x00, +0xF0, 0x54, 0x00, +0xF0, 0xD4, 0x00, +0xF0, 0xF0, 0xF0, 0xF4, 0x00, +0x31, 0x35, 0x00, +0x84, 0x00, +0x44, 0x31, 0x00, + +0x13, 0x53, 0x00, +0x71, 0x31, 0x31, 0x00, +0x31, 0x31, 0x71, 0x00, +0x31, 0x35, 0x31, 0x00, +0x13, 0x62, 0x13, 0x00, +0x17, 0x71, 0x00, +0x35, 0x31, 0x31, 0x00, +0x13, 0x13, 0x62, 0x00, +0x32, 0x12, 0x41, 0x12, 0x00, +0x35, 0x41, 0x12, 0x00, + +0x23, 0x12, 0x41, 0x21, 0x00, +0x71, 0x53, 0x13, 0x00, +0x84, 0x44, 0x00, +0x35, 0x35, 0x31, 0x00, +0x71, 0x31, 0x31, 0x31, 0x00, +0x31, 0x31, 0x71, 0x71, 0x00, +0x48, 0x84, 0x00, +0x41, 0x26, 0x21, 0x41, 0x21, 0x00, +0x31, 0x35, 0x31, 0x35, 0x31, 0x31, 0x00, +0x31, 0x31, 0x71, 0x13, 0x31, 0x31, 0x31, 0x00, + +0x71, 0x71, 0x13, 0x71, 0x31, 0x00, +0x48, 0xF0, 0x14, 0x00, +0x2A, 0x2A, 0x26, 0x00, +0x31, 0x31, 0x13, 0x53, 0x13, 0x53, 0x00, +0x71, 0x13, 0x71, 0x71, 0x13, 0x00, +0x13, 0x53, 0x53, 0x13, 0x53, 0x00, +0x17, 0x62, 0x13, 0x66, 0x00, +0x17, 0x13, 0x62, 0x13, 0x62, 0x00, +0xA2, 0x48, 0x31, 0x31, 0x00, +0x41, 0x21, 0x14, 0x44, 0x13, 0x62, 0x00, + +0x14, 0x12, 0x41, 0x71, 0x12, 0x44, 0x00, +0x85, 0x83, 0x53, 0x00, +0xC4, 0xC4, 0x84, 0x53, 0x53, 0x22, 0x00, +0x84, 0x84, 0x84, 0x84, 0x71, 0x62, 0x00, +0x97, 0x84, 0x84, 0x84, 0x84, 0x00, +0x26, 0x2A, 0x2A, 0x2A, 0x2A, 0x26, 0x00, +0x44, 0x84, 0x44, 0x44, 0x84, 0x44, 0x44, 0x00, +0x31, 0x22, 0x22, 0x22, 0x35, 0x31, 0x35, 0x31, 0x35, 0x31, 0x22, 0x35, 0x00, +0xC4, 0x13, 0x44, 0x44, 0x75, 0x44, 0x44, 0x00, +0xF0, 0x45, 0x22, 0x22, 0x22, 0x22, 0x22, 0x62, 0x22, 0x62, 0x00 +}; diff --git a/platform/inc/peak_detect.h b/platform/inc/peak_detect.h new file mode 100644 index 00000000..149bd34c --- /dev/null +++ b/platform/inc/peak_detect.h @@ -0,0 +1,83 @@ +/* + * File: peak_detect.h + * + * Peak detector + * + * 2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#pragma once + +#include + +#include "float_math.h" + +#define PEAK_LOW 0U +#define PEAK_HIGH 1U + +struct peak_detect { + uint32_t state; + uint32_t sample_counter; + uint32_t time_counter; + float threshold_level; + void (*peak_high_callback)(); + void (*peak_low_callback)(); + + peak_detect() {} + + peak_detect(void (*peak_high)(), void (*peak_low)()) : peak_high_callback{peak_high}, peak_low_callback{peak_low} {} + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_threshold(float threshold_level_db) { + threshold_level = fasterdbampf(threshold_level_db); + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void set_time(float time_s) { + time_counter = 48000 * time_s; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + void process(const float * in, uint32_t frames, uint32_t channels, uint32_t channel_mask) { + const float * __restrict in_p = in; + const float * in_e = in_p + frames * channels; + bool high_pending = false; + for (; in_p != in_e; in_p += channels) { + sample_counter++; + for (uint32_t i = 1 << channels; i >>= 1; i >>= 1) { + if (i & channel_mask && abs(*in_p) > threshold_level) { + high_pending = true; + sample_counter = 0; + break; + } + } + } + if (time_counter != 0 && sample_counter > time_counter) { + if (state == PEAK_HIGH) { + state = PEAK_LOW; + if (peak_low_callback != nullptr) + peak_low_callback(); + } + } else if (high_pending) { + if (state == PEAK_LOW) { + state = PEAK_HIGH; + if (peak_high_callback != nullptr) + peak_high_callback(); + } + } + } + + inline __attribute__((optimize("Ofast"), always_inline)) + bool is_high() { + return state == PEAK_HIGH; + } + + inline __attribute__((optimize("Ofast"), always_inline)) + float out() { + return state == PEAK_HIGH ? 1.f : 0.f; + } +}; + +#undef PEAK_LOW +#undef PEAK_HIGH diff --git a/platform/nts-1_mkii/Gator-delfx/Makefile b/platform/nts-1_mkii/Gator-delfx/Makefile new file mode 100644 index 00000000..280400ef --- /dev/null +++ b/platform/nts-1_mkii/Gator-delfx/Makefile @@ -0,0 +1,237 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +# Tools directory +TOOLSDIR ?= $(PROJECT_ROOT)/../../../tools + +# External library directory +EXTDIR ?= $(PROJECT_ROOT)/../../ext + +# CMSIS library location +CMSISDIR ?= $(EXTDIR)/CMSIS/CMSIS + +# Linker scripts location +LDDIR ?= $(PROJECT_ROOT)/../ld + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +############################################################################## +# Setup cross compilation +# + +MCU := cortex-m7 + +MCU_MODEL := STM32H725xE + +GCC_TARGET := arm-none-eabi- +GCC_BIN_PATH ?= $(TOOLSDIR)/gcc/gcc-arm-none-eabi-10.3-2021.10/bin + +CC := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +CXXC := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +LD := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +#LD := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +CP := $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy +AS := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp +AR := $(GCC_BIN_PATH)/$(GCC_TARGET)ar +OD := $(GCC_BIN_PATH)/$(GCC_TARGET)objdump +SZ := $(GCC_BIN_PATH)/$(GCC_TARGET)size +STRIP := $(GCC_BIN_PATH)/$(GCC_TARGET)strip + +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +RULESPATH := $(LDDIR) +LDSCRIPT := $(LDDIR)/unit.ld +DLIBS := -lc + +DADEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 +DDEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 -D__FPU_PRESENT + +COPT := -fPIC -std=c11 -fno-exceptions +CXXOPT := -fPIC -fno-use-cxa-atexit -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions -fno-threadsafe-statics + +LDOPT := -shared --entry=0 -specs=nano.specs -specs=nosys.specs + +CWARN := -W -Wall -Wextra +CXXWARN := -W -Wall -Wextra + +FPU_OPTS := -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant -fcheck-new + +OPT := -g -Os -mlittle-endian +OPT += $(FPU_OPTS) + +## TODO: there seems to be a bug or some yet unknown behavior that breaks PLT code for external calls when LTO is enabled alongside -nostartfiles +#OPT += -flto + +TOPT := -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT + +############################################################################## +# Set compilation targets and directories +# + +PRODUCT := $(PROJECT).nts1mkiiunit + +BUILDDIR := $(PROJECT_ROOT)/build +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst + +ASMSRC := $(UASMSRC) + +ASMXSRC := $(UASMXSRC) + +CSRC := $(UCSRC) +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +CXXSRC := $(UCXXSRC) + +vpath %.s $(sort $(dir $(ASMSRC))) +vpath %.S $(sort $(dir $(ASMXSRC))) +vpath %.c $(sort $(dir $(CSRC))) +vpath %.cc $(sort $(dir $(CXXSRC))) + +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) + +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +DINCDIR := $(COMMON_INC_PATH) \ + $(CMSISDIR)/Include + +INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) + +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +LIBS := $(DLIBS) $(ULIBS) + +LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) + +############################################################################## +# Compiler flags +# + +MCFLAGS := -mcpu=$(MCU) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-z,max-page-size=128,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) + +OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +############################################################################## +# Targets +# + +all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL + @echo Done + @echo + +PRE_ALL: + +POST_ALL: + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) + @echo + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile + @echo Assembling $( $@ + @echo + @$(SZ) $< + @echo + +%.list: %.elf + @echo Creating $@ + @$(OD) -S $< > $@ + +clean: + @echo Cleaning + -rm -fR $(PROJECT_ROOT)/.dep $(BUILDDIR) $(PROJECT_ROOT)/$(PRODUCT) + @echo Done + @echo + +$(BUILDDIR)/$(PRODUCT): | $(OBJS) $(OUTFILES) + @echo Making $(BUILDDIR)/$(PRODUCT) + @cp -a $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PRODUCT) + @$(STRIP) $(BUILDDIR)/$(PRODUCT) + +install: $(BUILDDIR)/$(PRODUCT) + @echo Deploying to $(INSTALLDIR)/$(PRODUCT) + @mv $(BUILDDIR)/$(PRODUCT) $(INSTALLDIR)/$(PRODUCT) + @echo Done + @echo + diff --git a/platform/nts-1_mkii/Gator-delfx/config.mk b/platform/nts-1_mkii/Gator-delfx/config.mk new file mode 100644 index 00000000..dfc2c77a --- /dev/null +++ b/platform/nts-1_mkii/Gator-delfx/config.mk @@ -0,0 +1,8 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +UCSRC = header.c +UCXXSRC = unit.cc +UINCDIR = ../../inc ../common/utils +ULIBS = -lm +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=11 diff --git a/platform/nts-1_mkii/Gator-delfx/header.c b/platform/nts-1_mkii/Gator-delfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/nts-1_mkii/Gator-delfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/nts-1_mkii/Gator-delfx/unit.cc b/platform/nts-1_mkii/Gator-delfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/nts-1_mkii/Gator-delfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/nts-1_mkii/Gator-modfx/Makefile b/platform/nts-1_mkii/Gator-modfx/Makefile new file mode 100644 index 00000000..280400ef --- /dev/null +++ b/platform/nts-1_mkii/Gator-modfx/Makefile @@ -0,0 +1,237 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +# Tools directory +TOOLSDIR ?= $(PROJECT_ROOT)/../../../tools + +# External library directory +EXTDIR ?= $(PROJECT_ROOT)/../../ext + +# CMSIS library location +CMSISDIR ?= $(EXTDIR)/CMSIS/CMSIS + +# Linker scripts location +LDDIR ?= $(PROJECT_ROOT)/../ld + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +############################################################################## +# Setup cross compilation +# + +MCU := cortex-m7 + +MCU_MODEL := STM32H725xE + +GCC_TARGET := arm-none-eabi- +GCC_BIN_PATH ?= $(TOOLSDIR)/gcc/gcc-arm-none-eabi-10.3-2021.10/bin + +CC := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +CXXC := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +LD := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +#LD := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +CP := $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy +AS := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp +AR := $(GCC_BIN_PATH)/$(GCC_TARGET)ar +OD := $(GCC_BIN_PATH)/$(GCC_TARGET)objdump +SZ := $(GCC_BIN_PATH)/$(GCC_TARGET)size +STRIP := $(GCC_BIN_PATH)/$(GCC_TARGET)strip + +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +RULESPATH := $(LDDIR) +LDSCRIPT := $(LDDIR)/unit.ld +DLIBS := -lc + +DADEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 +DDEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 -D__FPU_PRESENT + +COPT := -fPIC -std=c11 -fno-exceptions +CXXOPT := -fPIC -fno-use-cxa-atexit -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions -fno-threadsafe-statics + +LDOPT := -shared --entry=0 -specs=nano.specs -specs=nosys.specs + +CWARN := -W -Wall -Wextra +CXXWARN := -W -Wall -Wextra + +FPU_OPTS := -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant -fcheck-new + +OPT := -g -Os -mlittle-endian +OPT += $(FPU_OPTS) + +## TODO: there seems to be a bug or some yet unknown behavior that breaks PLT code for external calls when LTO is enabled alongside -nostartfiles +#OPT += -flto + +TOPT := -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT + +############################################################################## +# Set compilation targets and directories +# + +PRODUCT := $(PROJECT).nts1mkiiunit + +BUILDDIR := $(PROJECT_ROOT)/build +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst + +ASMSRC := $(UASMSRC) + +ASMXSRC := $(UASMXSRC) + +CSRC := $(UCSRC) +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +CXXSRC := $(UCXXSRC) + +vpath %.s $(sort $(dir $(ASMSRC))) +vpath %.S $(sort $(dir $(ASMXSRC))) +vpath %.c $(sort $(dir $(CSRC))) +vpath %.cc $(sort $(dir $(CXXSRC))) + +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) + +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +DINCDIR := $(COMMON_INC_PATH) \ + $(CMSISDIR)/Include + +INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) + +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +LIBS := $(DLIBS) $(ULIBS) + +LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) + +############################################################################## +# Compiler flags +# + +MCFLAGS := -mcpu=$(MCU) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-z,max-page-size=128,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) + +OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +############################################################################## +# Targets +# + +all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL + @echo Done + @echo + +PRE_ALL: + +POST_ALL: + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) + @echo + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile + @echo Assembling $( $@ + @echo + @$(SZ) $< + @echo + +%.list: %.elf + @echo Creating $@ + @$(OD) -S $< > $@ + +clean: + @echo Cleaning + -rm -fR $(PROJECT_ROOT)/.dep $(BUILDDIR) $(PROJECT_ROOT)/$(PRODUCT) + @echo Done + @echo + +$(BUILDDIR)/$(PRODUCT): | $(OBJS) $(OUTFILES) + @echo Making $(BUILDDIR)/$(PRODUCT) + @cp -a $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PRODUCT) + @$(STRIP) $(BUILDDIR)/$(PRODUCT) + +install: $(BUILDDIR)/$(PRODUCT) + @echo Deploying to $(INSTALLDIR)/$(PRODUCT) + @mv $(BUILDDIR)/$(PRODUCT) $(INSTALLDIR)/$(PRODUCT) + @echo Done + @echo + diff --git a/platform/nts-1_mkii/Gator-modfx/config.mk b/platform/nts-1_mkii/Gator-modfx/config.mk new file mode 100644 index 00000000..f26fea04 --- /dev/null +++ b/platform/nts-1_mkii/Gator-modfx/config.mk @@ -0,0 +1,8 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +UCSRC = header.c +UCXXSRC = unit.cc +UINCDIR = ../../inc ../common/utils +ULIBS = -lm +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=10 diff --git a/platform/nts-1_mkii/Gator-modfx/header.c b/platform/nts-1_mkii/Gator-modfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/nts-1_mkii/Gator-modfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/nts-1_mkii/Gator-modfx/unit.cc b/platform/nts-1_mkii/Gator-modfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/nts-1_mkii/Gator-modfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/nts-1_mkii/Gator-osc/Makefile b/platform/nts-1_mkii/Gator-osc/Makefile new file mode 100644 index 00000000..280400ef --- /dev/null +++ b/platform/nts-1_mkii/Gator-osc/Makefile @@ -0,0 +1,237 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +# Tools directory +TOOLSDIR ?= $(PROJECT_ROOT)/../../../tools + +# External library directory +EXTDIR ?= $(PROJECT_ROOT)/../../ext + +# CMSIS library location +CMSISDIR ?= $(EXTDIR)/CMSIS/CMSIS + +# Linker scripts location +LDDIR ?= $(PROJECT_ROOT)/../ld + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +############################################################################## +# Setup cross compilation +# + +MCU := cortex-m7 + +MCU_MODEL := STM32H725xE + +GCC_TARGET := arm-none-eabi- +GCC_BIN_PATH ?= $(TOOLSDIR)/gcc/gcc-arm-none-eabi-10.3-2021.10/bin + +CC := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +CXXC := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +LD := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +#LD := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +CP := $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy +AS := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp +AR := $(GCC_BIN_PATH)/$(GCC_TARGET)ar +OD := $(GCC_BIN_PATH)/$(GCC_TARGET)objdump +SZ := $(GCC_BIN_PATH)/$(GCC_TARGET)size +STRIP := $(GCC_BIN_PATH)/$(GCC_TARGET)strip + +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +RULESPATH := $(LDDIR) +LDSCRIPT := $(LDDIR)/unit.ld +DLIBS := -lc + +DADEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 +DDEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 -D__FPU_PRESENT + +COPT := -fPIC -std=c11 -fno-exceptions +CXXOPT := -fPIC -fno-use-cxa-atexit -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions -fno-threadsafe-statics + +LDOPT := -shared --entry=0 -specs=nano.specs -specs=nosys.specs + +CWARN := -W -Wall -Wextra +CXXWARN := -W -Wall -Wextra + +FPU_OPTS := -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant -fcheck-new + +OPT := -g -Os -mlittle-endian +OPT += $(FPU_OPTS) + +## TODO: there seems to be a bug or some yet unknown behavior that breaks PLT code for external calls when LTO is enabled alongside -nostartfiles +#OPT += -flto + +TOPT := -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT + +############################################################################## +# Set compilation targets and directories +# + +PRODUCT := $(PROJECT).nts1mkiiunit + +BUILDDIR := $(PROJECT_ROOT)/build +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst + +ASMSRC := $(UASMSRC) + +ASMXSRC := $(UASMXSRC) + +CSRC := $(UCSRC) +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +CXXSRC := $(UCXXSRC) + +vpath %.s $(sort $(dir $(ASMSRC))) +vpath %.S $(sort $(dir $(ASMXSRC))) +vpath %.c $(sort $(dir $(CSRC))) +vpath %.cc $(sort $(dir $(CXXSRC))) + +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) + +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +DINCDIR := $(COMMON_INC_PATH) \ + $(CMSISDIR)/Include + +INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) + +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +LIBS := $(DLIBS) $(ULIBS) + +LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) + +############################################################################## +# Compiler flags +# + +MCFLAGS := -mcpu=$(MCU) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-z,max-page-size=128,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) + +OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +############################################################################## +# Targets +# + +all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL + @echo Done + @echo + +PRE_ALL: + +POST_ALL: + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) + @echo + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile + @echo Assembling $( $@ + @echo + @$(SZ) $< + @echo + +%.list: %.elf + @echo Creating $@ + @$(OD) -S $< > $@ + +clean: + @echo Cleaning + -rm -fR $(PROJECT_ROOT)/.dep $(BUILDDIR) $(PROJECT_ROOT)/$(PRODUCT) + @echo Done + @echo + +$(BUILDDIR)/$(PRODUCT): | $(OBJS) $(OUTFILES) + @echo Making $(BUILDDIR)/$(PRODUCT) + @cp -a $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PRODUCT) + @$(STRIP) $(BUILDDIR)/$(PRODUCT) + +install: $(BUILDDIR)/$(PRODUCT) + @echo Deploying to $(INSTALLDIR)/$(PRODUCT) + @mv $(BUILDDIR)/$(PRODUCT) $(INSTALLDIR)/$(PRODUCT) + @echo Done + @echo + diff --git a/platform/nts-1_mkii/Gator-osc/config.mk b/platform/nts-1_mkii/Gator-osc/config.mk new file mode 100644 index 00000000..f26fea04 --- /dev/null +++ b/platform/nts-1_mkii/Gator-osc/config.mk @@ -0,0 +1,8 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +UCSRC = header.c +UCXXSRC = unit.cc +UINCDIR = ../../inc ../common/utils +ULIBS = -lm +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=10 diff --git a/platform/nts-1_mkii/Gator-osc/header.c b/platform/nts-1_mkii/Gator-osc/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/nts-1_mkii/Gator-osc/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/nts-1_mkii/Gator-osc/unit.cc b/platform/nts-1_mkii/Gator-osc/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/nts-1_mkii/Gator-osc/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/nts-1_mkii/Gator-revfx/Makefile b/platform/nts-1_mkii/Gator-revfx/Makefile new file mode 100644 index 00000000..280400ef --- /dev/null +++ b/platform/nts-1_mkii/Gator-revfx/Makefile @@ -0,0 +1,237 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +# Tools directory +TOOLSDIR ?= $(PROJECT_ROOT)/../../../tools + +# External library directory +EXTDIR ?= $(PROJECT_ROOT)/../../ext + +# CMSIS library location +CMSISDIR ?= $(EXTDIR)/CMSIS/CMSIS + +# Linker scripts location +LDDIR ?= $(PROJECT_ROOT)/../ld + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +############################################################################## +# Setup cross compilation +# + +MCU := cortex-m7 + +MCU_MODEL := STM32H725xE + +GCC_TARGET := arm-none-eabi- +GCC_BIN_PATH ?= $(TOOLSDIR)/gcc/gcc-arm-none-eabi-10.3-2021.10/bin + +CC := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +CXXC := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +LD := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +#LD := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +CP := $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy +AS := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp +AR := $(GCC_BIN_PATH)/$(GCC_TARGET)ar +OD := $(GCC_BIN_PATH)/$(GCC_TARGET)objdump +SZ := $(GCC_BIN_PATH)/$(GCC_TARGET)size +STRIP := $(GCC_BIN_PATH)/$(GCC_TARGET)strip + +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +RULESPATH := $(LDDIR) +LDSCRIPT := $(LDDIR)/unit.ld +DLIBS := -lc + +DADEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 +DDEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 -D__FPU_PRESENT + +COPT := -fPIC -std=c11 -fno-exceptions +CXXOPT := -fPIC -fno-use-cxa-atexit -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions -fno-threadsafe-statics + +LDOPT := -shared --entry=0 -specs=nano.specs -specs=nosys.specs + +CWARN := -W -Wall -Wextra +CXXWARN := -W -Wall -Wextra + +FPU_OPTS := -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant -fcheck-new + +OPT := -g -Os -mlittle-endian +OPT += $(FPU_OPTS) + +## TODO: there seems to be a bug or some yet unknown behavior that breaks PLT code for external calls when LTO is enabled alongside -nostartfiles +#OPT += -flto + +TOPT := -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT + +############################################################################## +# Set compilation targets and directories +# + +PRODUCT := $(PROJECT).nts1mkiiunit + +BUILDDIR := $(PROJECT_ROOT)/build +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst + +ASMSRC := $(UASMSRC) + +ASMXSRC := $(UASMXSRC) + +CSRC := $(UCSRC) +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +CXXSRC := $(UCXXSRC) + +vpath %.s $(sort $(dir $(ASMSRC))) +vpath %.S $(sort $(dir $(ASMXSRC))) +vpath %.c $(sort $(dir $(CSRC))) +vpath %.cc $(sort $(dir $(CXXSRC))) + +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) + +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +DINCDIR := $(COMMON_INC_PATH) \ + $(CMSISDIR)/Include + +INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) + +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +LIBS := $(DLIBS) $(ULIBS) + +LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) + +############################################################################## +# Compiler flags +# + +MCFLAGS := -mcpu=$(MCU) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-z,max-page-size=128,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) + +OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +############################################################################## +# Targets +# + +all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL + @echo Done + @echo + +PRE_ALL: + +POST_ALL: + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) + @echo + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile + @echo Assembling $( $@ + @echo + @$(SZ) $< + @echo + +%.list: %.elf + @echo Creating $@ + @$(OD) -S $< > $@ + +clean: + @echo Cleaning + -rm -fR $(PROJECT_ROOT)/.dep $(BUILDDIR) $(PROJECT_ROOT)/$(PRODUCT) + @echo Done + @echo + +$(BUILDDIR)/$(PRODUCT): | $(OBJS) $(OUTFILES) + @echo Making $(BUILDDIR)/$(PRODUCT) + @cp -a $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PRODUCT) + @$(STRIP) $(BUILDDIR)/$(PRODUCT) + +install: $(BUILDDIR)/$(PRODUCT) + @echo Deploying to $(INSTALLDIR)/$(PRODUCT) + @mv $(BUILDDIR)/$(PRODUCT) $(INSTALLDIR)/$(PRODUCT) + @echo Done + @echo + diff --git a/platform/nts-1_mkii/Gator-revfx/config.mk b/platform/nts-1_mkii/Gator-revfx/config.mk new file mode 100644 index 00000000..dfc2c77a --- /dev/null +++ b/platform/nts-1_mkii/Gator-revfx/config.mk @@ -0,0 +1,8 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +UCSRC = header.c +UCXXSRC = unit.cc +UINCDIR = ../../inc ../common/utils +ULIBS = -lm +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=11 diff --git a/platform/nts-1_mkii/Gator-revfx/header.c b/platform/nts-1_mkii/Gator-revfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/nts-1_mkii/Gator-revfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/nts-1_mkii/Gator-revfx/unit.cc b/platform/nts-1_mkii/Gator-revfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/nts-1_mkii/Gator-revfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/nts-3_kaoss/Gator-genericfx/Makefile b/platform/nts-3_kaoss/Gator-genericfx/Makefile new file mode 100644 index 00000000..66fddca5 --- /dev/null +++ b/platform/nts-3_kaoss/Gator-genericfx/Makefile @@ -0,0 +1,237 @@ +############################################################################## +# Common project definitions +# + +MKFILE_PATH := $(realpath $(lastword $(MAKEFILE_LIST))) + +# Project root +PROJECT_ROOT ?= $(dir $(MKFILE_PATH)) + +# Common includes +COMMON_INC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Common sources +COMMON_SRC_PATH ?= $(realpath $(PROJECT_ROOT)/../common/) + +# Installation directory +INSTALLDIR ?= $(PROJECT_ROOT) + +# Tools directory +TOOLSDIR ?= $(PROJECT_ROOT)/../../../tools + +# External library directory +EXTDIR ?= $(PROJECT_ROOT)/../../ext + +# CMSIS library location +CMSISDIR ?= $(EXTDIR)/CMSIS/CMSIS + +# Linker scripts location +LDDIR ?= $(PROJECT_ROOT)/../ld + +############################################################################## +# Include custom project configuration and sources +# + +include config.mk + +############################################################################## +# Common defaults +# + +# Define project name here +PROJECT ?= my_unit + +############################################################################## +# Setup cross compilation +# + +MCU := cortex-m7 + +MCU_MODEL := STM32H725xE + +GCC_TARGET := arm-none-eabi- +GCC_BIN_PATH ?= $(TOOLSDIR)/gcc/gcc-arm-none-eabi-10.3-2021.10/bin + +CC := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +CXXC := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +LD := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc +#LD := $(GCC_BIN_PATH)/$(GCC_TARGET)g++ +CP := $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy +AS := $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp +AR := $(GCC_BIN_PATH)/$(GCC_TARGET)ar +OD := $(GCC_BIN_PATH)/$(GCC_TARGET)objdump +SZ := $(GCC_BIN_PATH)/$(GCC_TARGET)size +STRIP := $(GCC_BIN_PATH)/$(GCC_TARGET)strip + +HEX := $(CP) -O ihex +BIN := $(CP) -O binary + +RULESPATH := $(LDDIR) +LDSCRIPT := $(LDDIR)/unit.ld +DLIBS := -lc + +DADEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 +DDEFS := -D$(MCU_MODEL) -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM7 -D__FPU_PRESENT + +COPT := -fPIC -std=c11 -fno-exceptions +CXXOPT := -fPIC -fno-use-cxa-atexit -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions -fno-threadsafe-statics + +LDOPT := -shared --entry=0 -specs=nano.specs -specs=nosys.specs + +CWARN := -W -Wall -Wextra +CXXWARN := -W -Wall -Wextra + +FPU_OPTS := -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant -fcheck-new + +OPT := -g -Os -mlittle-endian +OPT += $(FPU_OPTS) + +## TODO: there seems to be a bug or some yet unknown behavior that breaks PLT code for external calls when LTO is enabled alongside -nostartfiles +#OPT += -flto + +TOPT := -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT + +############################################################################## +# Set compilation targets and directories +# + +PRODUCT := $(PROJECT).nts3unit + +BUILDDIR := $(PROJECT_ROOT)/build +OBJDIR := $(BUILDDIR)/obj +LSTDIR := $(BUILDDIR)/lst + +ASMSRC := $(UASMSRC) + +ASMXSRC := $(UASMXSRC) + +CSRC := $(UCSRC) +CSRC += $(realpath $(COMMON_SRC_PATH)/_unit_base.c) + +CXXSRC := $(UCXXSRC) + +vpath %.s $(sort $(dir $(ASMSRC))) +vpath %.S $(sort $(dir $(ASMXSRC))) +vpath %.c $(sort $(dir $(CSRC))) +vpath %.cc $(sort $(dir $(CXXSRC))) + +ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) +ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) +COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) +CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cc=.o))) + +OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) + +DINCDIR := $(COMMON_INC_PATH) \ + $(CMSISDIR)/Include + +INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) + +DEFS := $(DDEFS) $(UDEFS) +ADEFS := $(DADEFS) $(UADEFS) + +LIBS := $(DLIBS) $(ULIBS) + +LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) + +############################################################################## +# Compiler flags +# + +MCFLAGS := -mcpu=$(MCU) +ODFLAGS := -x --syms +ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) +ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) +CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) +CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cc=.lst)) $(DEFS) +LDFLAGS := $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-z,max-page-size=128,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) + +OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ + $(BUILDDIR)/$(PROJECT).hex \ + $(BUILDDIR)/$(PROJECT).bin \ + $(BUILDDIR)/$(PROJECT).dmp \ + $(BUILDDIR)/$(PROJECT).list + +############################################################################## +# Targets +# + +all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL + @echo Done + @echo + +PRE_ALL: + +POST_ALL: + +$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) + +$(BUILDDIR): + @echo Compiler Options + @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) + @echo + @mkdir -p $(BUILDDIR) + +$(OBJDIR): + @mkdir -p $(OBJDIR) + +$(LSTDIR): + @mkdir -p $(LSTDIR) + +$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile + @echo Assembling $( $@ + @echo + @$(SZ) $< + @echo + +%.list: %.elf + @echo Creating $@ + @$(OD) -S $< > $@ + +clean: + @echo Cleaning + -rm -fR $(PROJECT_ROOT)/.dep $(BUILDDIR) $(PROJECT_ROOT)/$(PRODUCT) + @echo Done + @echo + +$(BUILDDIR)/$(PRODUCT): | $(OBJS) $(OUTFILES) + @echo Making $(BUILDDIR)/$(PRODUCT) + @cp -a $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PRODUCT) + @$(STRIP) $(BUILDDIR)/$(PRODUCT) + +install: $(BUILDDIR)/$(PRODUCT) + @echo Deploying to $(INSTALLDIR)/$(PRODUCT) + @mv $(BUILDDIR)/$(PRODUCT) $(INSTALLDIR)/$(PRODUCT) + @echo Done + @echo + diff --git a/platform/nts-3_kaoss/Gator-genericfx/config.mk b/platform/nts-3_kaoss/Gator-genericfx/config.mk new file mode 100644 index 00000000..3f06c74e --- /dev/null +++ b/platform/nts-3_kaoss/Gator-genericfx/config.mk @@ -0,0 +1,8 @@ +PROJECT := $(lastword $(subst /, , $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +PROJECT_TYPE := $(lastword $(subst -, , $(PROJECT))) +UNIT_NAME := \"$(firstword $(subst -, , $(PROJECT)))\" +UCSRC = header.c +UCXXSRC = unit.cc +UINCDIR = ../../inc ../common/utils +ULIBS = -lm +UDEFS = -DUNIT_NAME=$(UNIT_NAME) -DUNIT_TARGET_MODULE=k_unit_module_$(PROJECT_TYPE) -DPARAM_COUNT=8 diff --git a/platform/nts-3_kaoss/Gator-genericfx/header.c b/platform/nts-3_kaoss/Gator-genericfx/header.c new file mode 100644 index 00000000..2844ff51 --- /dev/null +++ b/platform/nts-3_kaoss/Gator-genericfx/header.c @@ -0,0 +1 @@ +#include "../../src/gator.c" diff --git a/platform/nts-3_kaoss/Gator-genericfx/unit.cc b/platform/nts-3_kaoss/Gator-genericfx/unit.cc new file mode 100644 index 00000000..faeeab4d --- /dev/null +++ b/platform/nts-3_kaoss/Gator-genericfx/unit.cc @@ -0,0 +1 @@ +#include "../../src/gator.cc" diff --git a/platform/src/gator.c b/platform/src/gator.c new file mode 100644 index 00000000..9c7d5457 --- /dev/null +++ b/platform/src/gator.c @@ -0,0 +1,59 @@ +/* + * File: gator.c + * + * Gator 2.0 unit header + * + * 2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#include "logue_wrap.h" + +const __unit_header UNIT_HEADER_TYPE unit_header = { +#ifdef UNIT_TARGET_PLATFORM_NTS3_KAOSS + .common = { +#endif + .header_size = sizeof(UNIT_HEADER_TYPE), + .target = UNIT_HEADER_TARGET_VALUE, + .api = UNIT_API_VERSION, + .dev_id = 0x44756B65U, + .unit_id = 0x32525447U, + .version = 0x00020000U, + .name = UNIT_NAME, + .num_params = PARAM_COUNT, + .params = { +#ifdef UNIT_TARGET_PLATFORM_NTS1_MKII + {0, 1, 0, 0, k_unit_param_type_onoff, 0, k_unit_param_frac_mode_fixed, 0, {"Gate"}}, + {0, 0, 0, 0, k_unit_param_type_none, 0, k_unit_param_frac_mode_fixed, 0, {""}}, +#if defined(UNIT_DELFX_H_) || defined(UNIT_REVFX_H_) + {0, 0, 0, 0, k_unit_param_type_none, 0, k_unit_param_frac_mode_fixed, 0, {""}}, +#endif +#endif + {0, 1, 0, 0, k_unit_param_type_onoff, 0, k_unit_param_frac_mode_fixed, 0, {"Gate"}}, + {0, 50, 0, 0, k_unit_param_type_none, 0, k_unit_param_frac_mode_fixed, 0, {"Pattern"}}, + {-1023, 0, 0, 0, k_unit_param_type_db, 1, k_unit_param_frac_mode_decimal, 0, {"Thresh"}}, + {0, 1023, 0, 0, k_unit_param_type_msec, 0, k_unit_param_frac_mode_decimal, 0, {"Time"}}, + {0, 1023, 0, 0, k_unit_param_type_msec, 0, k_unit_param_frac_mode_decimal, 0, {"Attack"}}, + {0, 1023, 0, 0, k_unit_param_type_msec, 0, k_unit_param_frac_mode_decimal, 0, {"Decay"}}, + {-1023, 0, 0, 0, k_unit_param_type_db, 1, k_unit_param_frac_mode_decimal, 0, {"Sustain"}}, + {0, 1023, 0, 0, k_unit_param_type_msec, 0, k_unit_param_frac_mode_decimal, 0, {"Release"}}, +#if defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined(UNIT_TARGET_MODULE_MASTERFX) + {0, 2, 0, 2, k_unit_param_type_strings, 0, k_unit_param_frac_mode_fixed, 0, {"Master"}}, + {0, 2, 0, 0, k_unit_param_type_strings, 0, k_unit_param_frac_mode_fixed, 0, {"Sidech"}}, + {0, 2, 0, 0, k_unit_param_type_strings, 0, k_unit_param_frac_mode_fixed, 0, {"Peak"}} +#endif + } +#ifdef UNIT_TARGET_PLATFORM_NTS3_KAOSS + }, + .default_mappings = { + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 1, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 50, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, -1023, 0, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 1023, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 1023, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 1023, 0}, + {k_genericfx_param_assign_depth, k_genericfx_curve_linear, k_genericfx_curve_unipolar, -1023, 0, 0}, + {k_genericfx_param_assign_none, k_genericfx_curve_linear, k_genericfx_curve_unipolar, 0, 1023, 0} + } +#endif +}; diff --git a/platform/src/gator.cc b/platform/src/gator.cc new file mode 100644 index 00000000..c93f2f5a --- /dev/null +++ b/platform/src/gator.cc @@ -0,0 +1,330 @@ +/* + * File: gator.cc + * + * Gator 2.0 unit + * + * 2020-2024 (c) Oleg Burdaev + * mailto: dukesrg@gmail.com + */ + +#include "logue_wrap.h" +#include "frac_value.h" + +#include +#include + +#include +#include + +#ifdef UNIT_TARGET_PLATFORM_DRUMLOGUE +#include +#endif + +#ifdef UNIT_OSC_H_ +#define VELOCITY_SENSITIVITY .5f +#define VELOCITY_LOW -144.f +#endif + +#include "peak_detect.h" +#include "gate_arp.h" +#include "envelopes.h" + +enum { + param_arp_gate = +#ifdef UNIT_OSC_H_ + k_num_unit_osc_fixed_param_id +#elif defined(UNIT_MODFX_H_) + k_num_unit_modfx_fixed_param_id +#elif defined(UNIT_DELFX_H_) + k_num_unit_delfx_fixed_param_id +#elif defined(UNIT_REVFX_H_) + k_num_unit_revfx_fixed_param_id +#elif defined(UNIT_GENERICFX_H_) + k_num_unit_genericfx_fixed_param_id +#else + 0U +#endif + , + param_arp_pattern, + param_peak_threshold, + param_peak_time, + param_eg_attack, + param_eg_decay, + param_eg_sustain, + param_eg_release, +#if (defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined(UNIT_TARGET_MODULE_MASTERFX)) + param_master, + param_sidechain, + param_peak_source, +#endif + param_num +}; + +#if (defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined(UNIT_TARGET_MODULE_MASTERFX)) +enum { + route_off = 0U, + route_on, + route_arp +}; + +enum { + source_master = 0U, + source_sidechain, + source_both +}; + +static uint32_t MasterRoute[2]; +#endif +static uint32_t PeakSourceMask = 0x0F; + +static int32_t Params[PARAM_COUNT]; + +static eg_adsr EG; + +#ifdef UNIT_OSC_H_ +static float Sustain; +static float Velocity = VELOCITY_LOW; + +fast_inline void set_velocity(float velocity) { + Velocity = (velocity - 127.f) * VELOCITY_SENSITIVITY; + EG.set_sustain(Velocity > Sustain ? Velocity : Sustain); +} + +fast_inline void set_sustain(float sustain) { + Sustain = sustain; + EG.set_sustain(Velocity > Sustain ? Velocity : Sustain); +} +#else +fast_inline void set_sustain(float sustain) { + EG.set_sustain(sustain); +} +#endif + +fast_inline void arp_gate_on_callback() { + EG.start(); +} + +fast_inline void arp_gate_off_callback() { + EG.stop(); +#ifdef UNIT_OSC_H_ + set_velocity(VELOCITY_LOW); +#endif +} + +static gate_arp ARP(&arp_gate_on_callback, &arp_gate_off_callback); + +fast_inline void peak_high_callback() { + ARP.start(); +} + +fast_inline void peak_low_callback() { + ARP.stop(); +} + +static peak_detect Peak(&peak_high_callback, &peak_low_callback); + +#ifdef UNIT_OSC_H_ +unit_runtime_osc_context_t *runtime_context; +#endif + +__unit_callback int8_t unit_init(const unit_runtime_desc_t * desc) { + if (!desc) + return k_unit_err_undef; + if (desc->target != UNIT_HEADER_TARGET_FIELD) + return k_unit_err_target; + if (!UNIT_API_IS_COMPAT(desc->api)) + return k_unit_err_api_version; + if (desc->samplerate != 48000) + return k_unit_err_samplerate; + if (desc->input_channels != UNIT_INPUT_CHANNELS || desc->output_channels != UNIT_OUTPUT_CHANNELS) + return k_unit_err_geometry; +#ifdef UNIT_OSC_H_ + runtime_context = (unit_runtime_osc_context_t *)desc->hooks.runtime_context; + runtime_context->notify_input_usage(k_runtime_osc_input_used); +#endif + return k_unit_err_none; +} + +__unit_callback void unit_reset() { + arp_gate_off_callback(); +} + +__unit_callback void unit_render(const float * in, float * out, uint32_t frames) { + float amp = EG.out(); +#ifdef UNIT_OSC_H_ + amp *= 1.f - q31_to_f32(runtime_context->shape_lfo); +#elif defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined (UNIT_TARGET_MODULE_MASTERFX) + float master_amp = MasterRoute[0] == route_arp ? amp : MasterRoute[0]; + float sidechain_amp = MasterRoute[1] == route_arp ? amp : MasterRoute[1]; + float32x4_t v_amp = {master_amp, master_amp, sidechain_amp, sidechain_amp}; +#endif + const float * __restrict in_p = in; + float * __restrict out_p = out; + const float * out_e = out_p + frames * UNIT_OUTPUT_CHANNELS; + for (; out_p != out_e; in_p += UNIT_INPUT_CHANNELS, out_p += UNIT_OUTPUT_CHANNELS) { +#ifdef UNIT_TARGET_PLATFORM_DRUMLOGUE +#ifdef UNIT_TARGET_MODULE_MASTERFX + float32x4_t v_in = vld1q_f32(in_p) * v_amp; + vst1_f32(out_p, vadd_f32(vget_low_f32(v_in), vget_high_f32(v_in))); +#else + vst1_f32(out_p, vld1_f32(in_p) * amp); +#endif +#else +#if UNIT_OUTPUT_CHANNELS == 1 + *out_p = (in_p[0] + in_p[1]) * .5f * amp; +#elif UNIT_OUTPUT_CHANNELS == 2 + out_p[0] = in_p[0] * amp; + out_p[1] = in_p[1] * amp; +#endif +#endif + } + EG.advance(frames); + ARP.advance(frames); + Peak.process(in, frames, UNIT_INPUT_CHANNELS, PeakSourceMask); +} + +__unit_callback void unit_set_param_value(uint8_t index, int32_t value) { + value = (int16_t)value; +#ifdef UNIT_TARGET_PLATFORM_NTS1_MKII + if (index == 0) { + Params[index] = value; + index = param_arp_gate; + } +#endif + Params[index] = value; + switch (index) { + case param_arp_gate: + if (value) + ARP.start(); + else + ARP.stop(); + break; + case param_arp_pattern: + ARP.set_pattern(value); + break; + case param_peak_threshold: + Peak.set_threshold(value * .1f); + break; + case param_peak_time: + Peak.set_time(value * .001f); + break; + case param_eg_attack: + EG.set_attack(value * .001f); + break; + case param_eg_decay: + EG.set_decay(value * .001f); + break; + case param_eg_sustain: + set_sustain(value * .1f); + break; + case param_eg_release: + EG.set_release(value * .001f); + break; +#if (defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined(UNIT_TARGET_MODULE_MASTERFX)) + case param_master: + case param_sidechain: + MasterRoute[index - param_master] = value; + break; + case param_peak_source: + switch (value) { + case source_master: + PeakSourceMask = 0x03; + break; + case source_sidechain: + PeakSourceMask = 0x0C; + break; + case source_both: + PeakSourceMask = 0x0F; + break; + } + break; +#endif + default: + break; + } +} + +__unit_callback int32_t unit_get_param_value(uint8_t index) { +#ifdef UNIT_TARGET_PLATFORM_NTS1_MKII + if (index == 0) + index = param_arp_gate; +#endif + return Params[index]; +} + +__unit_callback const char * unit_get_param_str_value(uint8_t index, int32_t value) { +// return unit_get_param_frac_value(index, value); + value = (int16_t)value; + switch (index) { +#if (defined(UNIT_TARGET_PLATFORM_DRUMLOGUE) && defined(UNIT_TARGET_MODULE_MASTERFX)) + static const char master_route[][4] = {"OFF", "ON", "ARP"}; + static const char peak_source[][7] = {"MASTER", "SIDECH", "BOTH"}; + case param_master: + case param_sidechain: + return master_route[value]; + case param_peak_source: + return peak_source[value]; +#endif + default: + break; + } + return nullptr; +} + +__unit_callback void unit_set_tempo(uint32_t tempo) { + ARP.set_tempo(tempo); +} + +#if defined(UNIT_TARGET_PLATFORM_NTS1_MKII) || defined(UNIT_TARGET_PLATFORM_NTS3_KAOSS) +__unit_callback void unit_tempo_4ppqn_tick(uint32_t counter) { + ARP.set_tempo_4ppqn_tick(counter); +}; +__unit_callback void unit_resume() {} + +__unit_callback void unit_suspend() {} +#endif + +#ifdef UNIT_OSC_H_ +__unit_callback void unit_note_on(uint8_t note, uint8_t velocity) { + (void)note; + set_velocity(velocity); + ARP.start(); +} + +__unit_callback void unit_note_off(uint8_t note) { + (void)note; + ARP.stop(); +} + +__unit_callback void unit_all_note_off() { + ARP.stop(); +} + +__unit_callback void unit_channel_pressure(uint8_t pressure) { + set_velocity(pressure); +} + +__unit_callback void unit_aftertouch(uint8_t note, uint8_t aftertouch) { + (void)note; + set_velocity(aftertouch); +} +#endif + +#ifdef UNIT_TARGET_PLATFORM_NTS3_KAOSS +__unit_callback void unit_touch_event(uint8_t id, uint8_t phase, uint32_t x, uint32_t y) { + (void)id; + (void)x; + (void)y; + switch (phase) { + case k_unit_touch_phase_began: + ARP.start(); + break; + case k_unit_touch_phase_ended: + case k_unit_touch_phase_cancelled: + ARP.stop(); + break; + default: + break; + } +} +#endif