├── .gitignore ├── .DS_Store ├── proto1.jpg ├── proto2.jpg ├── main ├── .DS_Store ├── component.mk ├── heavy │ ├── HvControlPrint.c │ ├── HvControlPrint.h │ ├── HvControlSystem.h │ ├── HvControlIf.h │ ├── HvControlCast.h │ ├── HvControlRandom.h │ ├── HvControlTabread.h │ ├── HvControlPack.h │ ├── HvControlSlice.h │ ├── HvControlTabhead.h │ ├── HvSignalSample.h │ ├── HvControlIf.c │ ├── HvControlVar.h │ ├── HvSignalDel1.c │ ├── HvSignalEnvelope.h │ ├── HvHeavyInternal.h │ ├── HvControlDelay.h │ ├── HvSignalSamphold.c │ ├── HvControlTabhead.c │ ├── HvControlUnop.h │ ├── HvControlTabread.c │ ├── HvUtils.c │ ├── HvControlRandom.c │ ├── HvSignalRPole.c │ ├── HvSignalSample.c │ ├── HvSignalDel1.h │ ├── HvSignalTabwrite.c │ ├── HvControlCast.c │ ├── HvControlBinop.h │ ├── HvControlSlice.c │ ├── HvControlSystem.c │ ├── HvControlUnop.c │ ├── HvSignalCPole.c │ ├── HvMessagePool.h │ ├── HvSignalTabread.c │ ├── HvControlPack.c │ ├── HvControlVar.c │ ├── HvTable.h │ ├── HvSignalVar.c │ ├── HvSignalLine.h │ ├── Heavy_heavy.h │ ├── HvSignalVar.h │ ├── HvMessageQueue.h │ ├── HvLightPipe.h │ ├── HvControlDelay.c │ ├── HvSignalRPole.h │ ├── HvControlBinop.c │ ├── HeavyContext.hpp │ ├── HvTable.c │ ├── HvMessagePool.c │ ├── HvLightPipe.c │ ├── HvSignalPhasor.c │ ├── HvSignalLine.c │ ├── HvSignalTabwrite.h │ ├── HvSignalPhasor.h │ └── HvSignalEnvelope.c ├── u8g2_esp32_hal.h ├── CMakeLists.txt └── WM8978.h ├── .gitattributes ├── kicad └── eurorack_engine │ ├── eurorack_engine-rescue.dcm │ ├── components │ ├── comp_74hct245.dcm │ ├── comp_microusb.dcm │ ├── comp_mpu6050.dcm │ ├── comp_onoffshim.dcm │ ├── comp_pam8406.dcm │ ├── comp_pcm5102.dcm │ ├── comp_rdm6300.dcm │ ├── comp_tcrt5000.dcm │ ├── comp_ws2812b.dcm │ ├── comp_raspberrypizerow.dcm │ ├── comp_ws2812b.lib │ ├── comp_pam8406.lib │ ├── comp_mpu6050.lib │ ├── comp_rdm6300.lib │ ├── comp_tcrt5000.lib │ ├── comp_onoffshim.lib │ ├── comp_pcm5102.lib │ ├── comp_74hct245.lib │ └── comp_microusb.lib │ ├── eurorack_engine.ods │ ├── gerbers │ ├── gerbers.zip │ ├── eurorack_engine-Edge_Cuts.gbr │ ├── eurorack_engine.drl │ └── eurorack_engine-B_SilkS.gbr │ ├── fp-lib-table │ ├── adc.sch │ ├── adc.sch-bak │ ├── inout.sch │ ├── power.sch │ ├── inout.sch-bak │ ├── power.sch-bak │ ├── file5F9CA336.sch-bak │ ├── sym-lib-table │ ├── footprints.pretty │ ├── microusb.kicad_mod │ ├── OnOffShim.kicad_mod │ ├── PAM8406.kicad_mod │ └── MPU6050.kicad_mod │ ├── eurorack_engine-rescue.lib │ ├── eurorack_engine.rules │ └── eurorack_engine.pro ├── Makefile ├── CMakeLists.txt ├── supportedobjects.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | components/u8g2/ 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/.DS_Store -------------------------------------------------------------------------------- /proto1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/proto1.jpg -------------------------------------------------------------------------------- /proto2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/proto2.jpg -------------------------------------------------------------------------------- /main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/main/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/eurorack_engine-rescue.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_74hct245.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_microusb.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_mpu6050.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_onoffshim.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_pam8406.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_pcm5102.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_rdm6300.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_tcrt5000.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_ws2812b.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_raspberrypizerow.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/eurorack_engine.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/kicad/eurorack_engine/eurorack_engine.ods -------------------------------------------------------------------------------- /kicad/eurorack_engine/gerbers/gerbers.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sinneb/esp32-hvcc/HEAD/kicad/eurorack_engine/gerbers/gerbers.zip -------------------------------------------------------------------------------- /kicad/eurorack_engine/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name footprints)(type KiCad)(uri ${KIPRJMOD}/footprints.pretty)(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := hello-world 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | project(hello-heavy) 7 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/adc.sch: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 3 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/adc.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 3 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/inout.sch: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A3 16535 11693 5 | encoding utf-8 6 | Sheet 4 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/power.sch: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 2 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/inout.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A3 16535 11693 5 | encoding utf-8 6 | Sheet 4 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/power.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 2 4 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/file5F9CA336.sch-bak: -------------------------------------------------------------------------------- 1 | EESchema Schematic File Version 4 2 | EELAYER 30 0 3 | EELAYER END 4 | $Descr A4 11693 8268 5 | encoding utf-8 6 | Sheet 1 1 7 | Title "" 8 | Date "" 9 | Rev "" 10 | Comp "" 11 | Comment1 "" 12 | Comment2 "" 13 | Comment3 "" 14 | Comment4 "" 15 | $EndDescr 16 | $EndSCHEMATC 17 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name comp_pcm5102)(type Legacy)(uri ${KIPRJMOD}/components/comp_pcm5102.lib)(options "")(descr "")) 3 | (lib (name eurogen-rescue)(type Legacy)(uri C:/Users/Arthur/Github/esp32-hvcc/schematics_v2/eurogen-rescue.lib)(options "")(descr "")) 4 | (lib (name eurorack_engine-rescue)(type Legacy)(uri ${KIPRJMOD}/eurorack_engine-rescue.lib)(options "")(descr "")) 5 | ) 6 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_ws2812b.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # WS2812B 5 | # 6 | DEF WS2812B U 0 40 Y Y 1 F N 7 | F0 "U" -100 -300 60 H V C CNN 8 | F1 "WS2812B" 0 300 60 H V C CNN 9 | F2 "" -500 -200 60 H I C CNN 10 | F3 "" -500 -200 60 H I C CNN 11 | DRAW 12 | S -200 200 200 -200 0 1 0 f 13 | X 5V_VCC 1 -400 100 200 R 50 50 1 1 W 14 | X DIN 2 -400 0 200 R 50 50 1 1 I 15 | X GND 3 -400 -100 200 R 50 50 1 1 W 16 | ENDDRAW 17 | ENDDEF 18 | # 19 | #End Library 20 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_pam8406.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # PAM8406 5 | # 6 | DEF PAM8406 IC 0 40 Y Y 1 F N 7 | F0 "IC" -200 -400 60 H V C CNN 8 | F1 "PAM8406" -50 200 60 H V C CNN 9 | F2 "" -300 -1650 60 H I C CNN 10 | F3 "" -300 -1650 60 H I C CNN 11 | DRAW 12 | X GND 2 500 0 200 L 50 50 1 0 W 13 | S 300 -500 -300 300 0 1 0 f 14 | X VCC 1 500 100 200 L 50 50 1 1 W 15 | X ROUT+ 3 500 -100 200 L 50 50 1 1 O 16 | X ROUT- 4 500 -200 200 L 50 50 1 1 O 17 | X LOUT+ 5 500 -300 200 L 50 50 1 1 O 18 | X LOUT- 6 500 -400 200 L 50 50 1 1 O 19 | X RIN 7 -500 0 200 R 50 50 1 1 I 20 | X GND 8 -500 -100 200 R 50 50 1 1 W 21 | X LIN 9 -500 -200 200 R 50 50 1 1 I 22 | ENDDRAW 23 | ENDDEF 24 | # 25 | #End Library 26 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_mpu6050.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # MPU6050 5 | # 6 | DEF MPU6050 IC 0 40 Y Y 1 F N 7 | F0 "IC" 200 -150 60 H V C CNN 8 | F1 "MPU6050" -50 -150 60 V V C CNN 9 | F2 "" -100 -700 60 H I C CNN 10 | F3 "" -100 -700 60 H I C CNN 11 | DRAW 12 | C 200 -450 71 0 1 0 N 13 | C 200 150 71 0 1 0 f 14 | S -450 -600 350 300 0 1 0 f 15 | X VCC 1 -650 200 200 R 50 50 1 1 W 16 | X GND 2 -650 100 200 R 50 50 1 1 W 17 | X SCL 3 -650 0 200 R 50 50 1 1 I 18 | X SDA 4 -650 -100 200 R 50 50 1 1 B 19 | X XDA 5 -650 -200 200 R 50 50 1 1 I 20 | X XCL 6 -650 -300 200 R 50 50 1 1 I 21 | X AD0 7 -650 -400 200 R 50 50 1 1 I 22 | X INT 8 -650 -500 200 R 50 50 1 1 O 23 | ENDDRAW 24 | ENDDEF 25 | # 26 | #End Library 27 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_rdm6300.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # RDM6300 5 | # 6 | DEF RDM6300 IC 0 40 Y Y 1 F N 7 | F0 "IC" -450 250 60 H V C CNN 8 | F1 "RDM6300" -50 0 60 H V C CNN 9 | F2 "" -250 -1500 60 H I C CNN 10 | F3 "" -250 -1500 60 H I C CNN 11 | DRAW 12 | S 650 350 -600 -350 0 1 0 f 13 | X VCC 1 150 550 200 D 50 50 1 1 W 14 | X GND 2 250 550 200 D 50 50 1 1 W 15 | X ~ 3 350 550 200 D 50 50 1 1 I 16 | X RX 4 450 550 200 D 50 50 1 1 I 17 | X TX 5 550 550 200 D 50 50 1 1 O 18 | X LED 6 550 -550 200 U 50 50 1 1 U 19 | X VCC 7 450 -550 200 U 50 50 1 1 W 20 | X GND 8 350 -550 200 U 50 50 1 1 W 21 | X ANT 9 -400 -550 200 U 50 50 1 1 O 22 | X ANT 10 -500 -550 200 U 50 50 1 1 P 23 | ENDDRAW 24 | ENDDEF 25 | # 26 | #End Library 27 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/gerbers/eurorack_engine-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.7)-1* 2 | G04 #@! TF.CreationDate,2020-10-22T22:29:39+02:00* 3 | G04 #@! TF.ProjectId,eurorack_engine,6575726f-7261-4636-9b5f-656e67696e65,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Profile,NP* 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW (5.1.7)-1) date 2020-10-22 22:29:39* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | G04 #@! TA.AperFunction,Profile* 14 | %ADD10C,0.050000*% 15 | G04 #@! TD* 16 | G04 APERTURE END LIST* 17 | D10* 18 | X0Y-127000000D02* 19 | X0Y0D01* 20 | X150500000Y-127000000D02* 21 | X0Y-127000000D01* 22 | X150500000Y0D02* 23 | X150500000Y-127000000D01* 24 | X0Y0D02* 25 | X150500000Y0D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_tcrt5000.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # TCRT5000 5 | # 6 | DEF TCRT5000 U 0 40 Y Y 1 F N 7 | F0 "U" -600 -50 60 H V C CNN 8 | F1 "TCRT5000" -575 75 60 H V C CNN 9 | F2 "" -150 -600 60 H I C CNN 10 | F3 "" -150 -600 60 H I C CNN 11 | DRAW 12 | S -250 -60 -260 60 0 1 0 F 13 | S -25 200 50 -200 0 1 0 N 14 | S 170 10 110 0 0 1 0 N 15 | P 2 0 1 0 -100 -180 -250 -30 N 16 | P 2 0 1 0 -100 170 -250 30 N 17 | P 4 0 1 0 -170 -60 -220 -110 -170 -110 -170 -60 F 18 | P 4 0 1 0 140 10 170 50 110 50 140 10 N 19 | P 4 0 1 0 200 170 140 170 140 -180 200 -180 N 20 | P 8 0 1 0 350 -100 350 50 350 100 250 200 -350 200 -350 -200 250 -200 350 -100 f 21 | X E 1 -100 -380 200 U 50 50 1 1 I 22 | X C 2 -100 370 200 D 50 50 1 1 I 23 | X C 3 200 -380 200 U 50 50 1 1 I 24 | X A 4 200 370 200 D 50 50 1 1 I 25 | ENDDRAW 26 | ENDDEF 27 | # 28 | #End Library 29 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_onoffshim.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # OnOffShim 5 | # 6 | DEF OnOffShim U 0 40 Y Y 1 F N 7 | F0 "U" -300 -500 60 H V C CNN 8 | F1 "OnOffShim" 0 400 60 H V C CNN 9 | F2 "" -4100 750 60 H I C CNN 10 | F3 "" -4100 750 60 H I C CNN 11 | DRAW 12 | S -350 350 350 -400 0 1 0 f 13 | X +5V 1 550 250 200 L 50 50 1 1 w 14 | X +5V 2 550 150 200 L 50 50 1 1 W 15 | X GND 3 550 50 200 L 50 50 1 1 w 16 | X X 4 550 -50 200 L 50 50 1 1 N 17 | X X 5 550 -150 200 L 50 50 1 1 N 18 | X X 6 550 -250 200 L 50 50 1 1 N 19 | X X 7 -550 250 200 R 50 50 1 1 N 20 | X X 8 -550 150 200 R 50 50 1 1 N 21 | X X 9 -550 50 200 R 50 50 1 1 N 22 | X Cut_Power 10 -550 -50 200 R 50 50 1 1 I 23 | X GND 11 -550 -150 200 R 50 50 1 1 W 24 | X Trigger 12 -550 -250 200 R 50 50 1 1 O 25 | X BTN 13 50 -600 200 U 50 50 1 1 I 26 | X BTN 14 150 -600 200 U 50 50 1 1 I 27 | ENDDRAW 28 | ENDDEF 29 | # 30 | #End Library 31 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_pcm5102.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # PCM5102 5 | # 6 | DEF PCM5102 IC 0 40 Y Y 1 F N 7 | F0 "IC" 1050 1050 60 H V C CNN 8 | F1 "PCM5102" 1050 1250 60 H V C CNN 9 | F2 "" 0 0 60 H I C CNN 10 | F3 "" 0 0 60 H I C CNN 11 | DRAW 12 | S 250 1350 1400 650 0 1 0 f 13 | X VIN 1 50 1250 200 R 50 50 1 1 W 14 | X GND 2 50 1150 200 R 50 50 1 1 W 15 | X LRCK 3 50 1050 200 R 50 50 1 1 I 16 | X DIN 4 50 950 200 R 50 50 1 1 I 17 | X BCK 5 50 850 200 R 50 50 1 1 I 18 | X SCK 6 50 750 200 R 50 50 1 1 I 19 | X FLT 7 500 450 200 U 50 50 1 1 U 20 | X DEMP 8 600 450 200 U 50 50 1 1 U 21 | X XSMT 9 700 450 200 U 50 50 1 1 U 22 | X FMT 10 800 450 200 U 50 50 1 1 U 23 | X A3V3 11 900 450 200 U 50 50 1 1 w 24 | X AGND 12 1000 450 200 U 50 50 1 1 w 25 | X ROUT 13 1100 450 200 U 50 50 1 1 O 26 | X AGND 14 1200 450 200 U 50 50 1 1 w 27 | X LOUT 15 1300 450 200 U 50 50 1 1 O 28 | ENDDRAW 29 | ENDDEF 30 | # 31 | #End Library 32 | -------------------------------------------------------------------------------- /main/heavy/HvControlPrint.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlPrint.h" 18 | 19 | void cPrint_onMessage(HeavyContextInterface *_c, const HvMessage *m, const char *name) { 20 | if (hv_getPrintHook(_c) != NULL) { 21 | char *s = msg_toString(m); 22 | hv_getPrintHook(_c)(_c, name, s, m); 23 | hv_free(s); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_74hct245.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # 74HCT245 5 | # 6 | DEF 74HCT245 U 0 40 Y Y 1 F N 7 | F0 "U" -200 -200 60 H V C CNN 8 | F1 "74HCT245" 0 -1300 60 H V C CNN 9 | F2 "" 0 0 60 H I C CNN 10 | F3 "" 0 0 60 H I C CNN 11 | DRAW 12 | A 0 -100 100 -1799 -1 0 1 0 N -100 -100 100 -100 13 | S -300 -100 300 -1350 0 1 0 f 14 | X DIR 1 -500 -300 200 R 50 50 1 1 I 15 | X A0 2 -500 -400 200 R 50 50 1 1 B 16 | X A1 3 -500 -500 200 R 50 50 1 1 B 17 | X A2 4 -500 -600 200 R 50 50 1 1 B 18 | X A3 5 -500 -700 200 R 50 50 1 1 B 19 | X A4 6 -500 -800 200 R 50 50 1 1 I 20 | X A5 7 -500 -900 200 R 50 50 1 1 B 21 | X A6 8 -500 -1000 200 R 50 50 1 1 B 22 | X A7 9 -500 -1100 200 R 50 50 1 1 B 23 | X GND 10 -500 -1200 200 R 50 50 1 1 W 24 | X VCC 20 500 -300 200 L 50 50 1 1 W 25 | X B7 11 500 -1200 200 L 50 50 1 1 B 26 | X B6 12 500 -1100 200 L 50 50 1 1 B 27 | X B5 13 500 -1000 200 L 50 50 1 1 B 28 | X B4 14 500 -900 200 L 50 50 1 1 B 29 | X B3 15 500 -800 200 L 50 50 1 1 B 30 | X B2 16 500 -700 200 L 50 50 1 1 B 31 | X B1 17 500 -600 200 L 50 50 1 1 B 32 | X B0 18 500 -500 200 L 50 50 1 1 B 33 | X NOT_OE 19 500 -400 200 L 50 50 1 1 I 34 | ENDDRAW 35 | ENDDEF 36 | # 37 | #End Library 38 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/components/comp_microusb.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # MicroUSBPowerSupply 5 | # 6 | DEF MicroUSBPowerSupply U 0 40 Y Y 1 F N 7 | F0 "U" 0 300 60 H V C CNN 8 | F1 "MicroUSBPowerSupply" 25 400 60 H V C CNN 9 | F2 "" -500 -1600 60 H I C CNN 10 | F3 "" -500 -1600 60 H I C CNN 11 | DRAW 12 | C -150 0 75 0 1 0 N 13 | C 150 0 75 0 1 0 N 14 | S -250 -300 250 250 0 1 0 f 15 | S -125 250 125 150 0 1 0 N 16 | X GND 1 -200 -500 200 U 50 50 1 1 w 17 | X ID 2 -100 -500 200 U 50 50 1 1 N 18 | X D+ 3 0 -500 200 U 50 50 1 1 I 19 | X D- 4 100 -500 200 U 50 50 1 1 I 20 | X VBUS 5 200 -500 200 U 50 50 1 1 w 21 | ENDDRAW 22 | ENDDEF 23 | # 24 | # comp_microusb 25 | # 26 | DEF comp_microusb U 0 40 Y Y 1 F N 27 | F0 "U" 0 300 60 H V C CNN 28 | F1 "comp_microusb" 25 400 60 H V C CNN 29 | F2 "" -500 -1600 60 H I C CNN 30 | F3 "" -500 -1600 60 H I C CNN 31 | DRAW 32 | C -150 0 75 0 1 0 N 33 | C 150 0 75 0 1 0 N 34 | S -250 -300 250 250 0 1 0 f 35 | S -125 250 125 150 0 1 0 N 36 | X GND 1 -200 -500 200 U 50 50 1 1 w 37 | X ID 2 -100 -500 200 U 50 50 1 1 N 38 | X D+ 3 0 -500 200 U 50 50 1 1 I 39 | X D- 4 100 -500 200 U 50 50 1 1 I 40 | X VBUS 5 200 -500 200 U 50 50 1 1 w 41 | ENDDRAW 42 | ENDDEF 43 | # 44 | #End Library 45 | -------------------------------------------------------------------------------- /main/heavy/HvControlPrint.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_PRINT_H_ 18 | #define _HEAVY_CONTROL_PRINT_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | void cPrint_onMessage(HeavyContextInterface *_c, const struct HvMessage *m, const char *name); 27 | 28 | #ifdef __cplusplus 29 | } // extern "C" 30 | #endif 31 | 32 | #endif // _HEAVY_CONTROL_PRINT_H_ 33 | -------------------------------------------------------------------------------- /main/heavy/HvControlSystem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_SYSTEM_H_ 18 | #define _HEAVY_CONTROL_SYSTEM_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | void cSystem_onMessage(HeavyContextInterface *_c, void *o, int letIn, const HvMessage *m, 27 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 28 | 29 | #ifdef __cplusplus 30 | } // extern "C" 31 | #endif 32 | 33 | #endif // _HEAVY_CONTROL_SYSTEM_H_ 34 | -------------------------------------------------------------------------------- /main/heavy/HvControlIf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_IF_H_ 18 | #define _HEAVY_CONTROL_IF_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlIf { 27 | bool k; 28 | } ControlIf; 29 | 30 | hv_size_t cIf_init(ControlIf *o, bool k); 31 | 32 | void cIf_onMessage(HeavyContextInterface *_c, ControlIf *o, int letIn, const HvMessage *m, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | #ifdef __cplusplus 36 | } // extern "C" 37 | #endif 38 | 39 | #endif // _HEAVY_CONTROL_IF_H_ 40 | -------------------------------------------------------------------------------- /main/heavy/HvControlCast.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_CAST_H_ 18 | #define _HEAVY_CONTROL_CAST_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum CastType { 27 | HV_CAST_BANG, 28 | HV_CAST_FLOAT, 29 | HV_CAST_SYMBOL 30 | } CastType; 31 | 32 | void cCast_onMessage(HeavyContextInterface *_c, CastType castType, int letIn, const HvMessage *m, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | #ifdef __cplusplus 36 | } // extern "C" 37 | #endif 38 | 39 | #endif // _HEAVY_CONTROL_CAST_H_ 40 | -------------------------------------------------------------------------------- /main/heavy/HvControlRandom.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_RANDOM_H_ 18 | #define _HEAVY_CONTROL_RANDOM_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlRandom { 27 | hv_uint32_t state; 28 | } ControlRandom; 29 | 30 | hv_size_t cRandom_init(ControlRandom *o, int seed); 31 | 32 | void cRandom_onMessage(HeavyContextInterface *_c, ControlRandom *o, int letIndex, const HvMessage *m, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | #ifdef __cplusplus 36 | } // extern "C" 37 | #endif 38 | 39 | #endif // _HEAVY_CONTROL_RANDOM_H_ 40 | -------------------------------------------------------------------------------- /main/heavy/HvControlTabread.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_TABREAD_H_ 18 | #define _HEAVY_CONTROL_TABREAD_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlTabread { 27 | HvTable *table; 28 | } ControlTabread; 29 | 30 | hv_size_t cTabread_init(ControlTabread *o, struct HvTable *table); 31 | 32 | void cTabread_onMessage(HeavyContextInterface *_c, ControlTabread *o, int letIn, const HvMessage *m, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | #ifdef __cplusplus 36 | } // extern "C" 37 | #endif 38 | 39 | #endif // _HEAVY_CONTROL_TABREAD_H_ 40 | -------------------------------------------------------------------------------- /main/heavy/HvControlPack.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_PACK_H_ 18 | #define _HEAVY_CONTROL_PACK_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlPack { 27 | HvMessage *msg; 28 | } ControlPack; 29 | 30 | hv_size_t cPack_init(ControlPack *o, int nargs, ...); 31 | 32 | void cPack_free(ControlPack *o); 33 | 34 | void cPack_onMessage(HeavyContextInterface *_c, ControlPack *o, int letIn, const HvMessage *m, 35 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | #endif 40 | 41 | #endif // _HEAVY_CONTROL_PACK_H_ 42 | -------------------------------------------------------------------------------- /main/heavy/HvControlSlice.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_SLICE_H_ 18 | #define _HEAVY_CONTROL_SLICE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlSlice { 27 | int i; // start index 28 | int n; // length of slice 29 | } ControlSlice; 30 | 31 | hv_size_t cSlice_init(ControlSlice *o, int i, int n); 32 | 33 | void cSlice_onMessage(HeavyContextInterface *_c, ControlSlice *o, int letIn, const HvMessage *m, 34 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 35 | 36 | #ifdef __cplusplus 37 | } // extern "C" 38 | #endif 39 | 40 | #endif // _HEAVY_CONTROL_SLICE_H_ 41 | -------------------------------------------------------------------------------- /main/heavy/HvControlTabhead.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_TABHEAD_H_ 18 | #define _HEAVY_CONTROL_TABHEAD_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlTabhead { 27 | struct HvTable *table; 28 | } ControlTabhead; 29 | 30 | hv_size_t cTabhead_init(ControlTabhead *o, struct HvTable *table); 31 | 32 | void cTabhead_onMessage(HeavyContextInterface *_c, ControlTabhead *o, int letIn, const HvMessage *m, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | #ifdef __cplusplus 36 | } // extern "C" 37 | #endif 38 | 39 | #endif // _HEAVY_CONTROL_TABHEAD_H_ 40 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/footprints.pretty/microusb.kicad_mod: -------------------------------------------------------------------------------- 1 | (module microusb (layer F.Cu) (tedit 5ABC1E24) 2 | (fp_text reference U1 (at 13.486 -12.557) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value "Micro USB Power Supply" (at 5.1 -6.7) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start 9 -9.7) (end 9 -13.7) (layer F.SilkS) (width 0.15)) 9 | (fp_line (start 1.5 -9.7) (end 1.5 -13.7) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start 1.5 -9.7) (end 9 -9.7) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start 12 -13.7) (end 12 1.4) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start -1.5 -13.7) (end 12 -13.7) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start -1.5 1.4) (end -1.5 -13.7) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start -1.5 1.4) (end 12 1.4) (layer F.SilkS) (width 0.15)) 15 | (pad 1 thru_hole circle (at 0 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 16 | (pad "" np_thru_hole circle (at 1 -4.1) (size 3.1 3.1) (drill 3.1) (layers *.Cu *.Mask)) 17 | (pad "" np_thru_hole circle (at 9.5 -4.1) (size 3.1 3.1) (drill 3.1) (layers *.Cu *.Mask)) 18 | (pad 2 thru_hole circle (at 2.54 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 19 | (pad 3 thru_hole circle (at 5.08 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 20 | (pad 4 thru_hole circle (at 7.62 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 21 | (pad 5 thru_hole circle (at 10.16 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 22 | ) 23 | -------------------------------------------------------------------------------- /main/heavy/HvSignalSample.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _SIGNAL_SAMPLE_H_ 18 | #define _SIGNAL_SAMPLE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct SignalSample { 27 | hv_uint32_t i; // timestamp at which to get sample 28 | } SignalSample; 29 | 30 | hv_size_t sSample_init(SignalSample *o); 31 | 32 | void __hv_sample_f(HeavyContextInterface *_c, SignalSample *o, hv_bInf_t bIn, 33 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 34 | 35 | void sSample_onMessage(HeavyContextInterface *_c, SignalSample *o, int letIndex, const HvMessage *m); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | #endif 40 | 41 | #endif // _SIGNAL_SAMPLE_H_ 42 | -------------------------------------------------------------------------------- /main/heavy/HvControlIf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlIf.h" 18 | 19 | hv_size_t cIf_init(ControlIf *o, bool k) { 20 | o->k = k; 21 | return 0; 22 | } 23 | 24 | void cIf_onMessage(HeavyContextInterface *_c, ControlIf *o, int letIn, const HvMessage *m, 25 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 26 | switch (letIn) { 27 | case 0: { 28 | // a "true" if will send the message from the right outlet 29 | // a "false" if gets sent out of the left outlet 30 | sendMessage(_c, o->k ? 1 : 0, m); 31 | break; 32 | } 33 | case 1: { 34 | if (msg_isFloat(m, 0)) { 35 | o->k = (msg_getFloat(m, 0) != 0.0f); 36 | } 37 | break; 38 | } 39 | default: return; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /main/heavy/HvControlVar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_VAR_H_ 18 | #define _HEAVY_CONTROL_VAR_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct ControlVar { 27 | Element e; // type is only every HV_MSG_FLOAT or HV_MSG_HASH 28 | } ControlVar; 29 | 30 | hv_size_t cVar_init_f(ControlVar *o, float k); 31 | 32 | hv_size_t cVar_init_s(ControlVar *o, const char *s); 33 | 34 | void cVar_free(ControlVar *o); 35 | 36 | void cVar_onMessage(HeavyContextInterface *_c, ControlVar *o, int letIn, const HvMessage *m, 37 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 38 | 39 | #ifdef __cplusplus 40 | } // extern "C" 41 | #endif 42 | 43 | #endif // _HEAVY_CONTROL_VAR_H_ 44 | -------------------------------------------------------------------------------- /main/heavy/HvSignalDel1.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalDel1.h" 18 | 19 | hv_size_t sDel1_init(SignalDel1 *o) { 20 | #if HV_SIMD_AVX 21 | o->x = _mm256_setzero_ps(); 22 | #elif HV_SIMD_SSE 23 | o->x = _mm_setzero_ps(); 24 | #elif HV_SIMD_NEON 25 | o->x = vdupq_n_f32(0.0f); 26 | #else 27 | o->x = 0.0f; 28 | #endif 29 | return 0; 30 | } 31 | 32 | void sDel1_onMessage(HeavyContextInterface *_c, SignalDel1 *o, int letIn, const HvMessage *m) { 33 | if (letIn == 2) { 34 | if (msg_compareSymbol(m, 0, "clear")) { 35 | #if HV_SIMD_AVX 36 | o->x = _mm256_setzero_ps(); 37 | #elif HV_SIMD_SSE 38 | o->x = _mm_setzero_ps(); 39 | #elif HV_SIMD_NEON 40 | o->x = vdupq_n_f32(0.0f); 41 | #else 42 | o->x = 0.0f; 43 | #endif 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/eurorack_engine-rescue.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # EURO_PWR_2x5-eurocad-eurogen-rescue 5 | # 6 | DEF EURO_PWR_2x5-eurocad-eurogen-rescue J 0 40 Y Y 1 F N 7 | F0 "J" 0 -300 60 H V C CNN 8 | F1 "EURO_PWR_2x5-eurocad-eurogen-rescue" 0 300 60 H V C CNN 9 | F2 "" 0 0 60 H V C CNN 10 | F3 "" 0 0 60 H V C CNN 11 | DRAW 12 | S -250 250 250 -250 0 1 0 f 13 | X +12V 1 -450 200 200 R 50 50 1 1 W 14 | X -12V 10 450 -200 200 L 50 50 1 1 W 15 | X +12V 2 450 200 200 L 50 50 1 1 W 16 | X GND 3 -450 100 200 R 50 50 1 1 W 17 | X GND 4 450 100 200 L 50 50 1 1 W 18 | X GND 5 -450 0 200 R 50 50 1 1 W 19 | X GND 6 450 0 200 L 50 50 1 1 W 20 | X GND 7 -450 -100 200 R 50 50 1 1 W 21 | X GND 8 450 -100 200 L 50 50 1 1 W 22 | X -12V 9 -450 -200 200 R 50 50 1 1 W 23 | ENDDRAW 24 | ENDDEF 25 | # 26 | # PJ301M-12-eurocad-eurogen-rescue 27 | # 28 | DEF PJ301M-12-eurocad-eurogen-rescue J 0 40 Y Y 1 F N 29 | F0 "J" -350 -200 50 H V C CNN 30 | F1 "PJ301M-12-eurocad-eurogen-rescue" -150 250 50 H V C CNN 31 | F2 "" 0 0 50 H V C CNN 32 | F3 "" 0 0 50 H V C CNN 33 | DRAW 34 | S -450 150 -400 -100 0 1 0 F 35 | S 300 -150 -400 200 0 1 0 N 36 | P 3 0 1 0 150 0 300 0 300 0 N 37 | P 4 0 1 0 0 -100 -50 -50 -100 -100 -100 -100 N 38 | P 4 0 1 0 0 -100 300 -100 300 -100 300 -100 N 39 | P 4 0 1 0 50 -50 100 -100 150 -50 150 -50 N 40 | P 4 0 1 0 150 0 100 0 100 -100 100 -100 N 41 | P 5 0 1 0 300 150 -250 150 -300 100 -350 150 -350 150 N 42 | X ~ 1 450 150 150 L 50 50 1 1 P 43 | X ~ 2 450 0 150 L 50 50 1 1 P 44 | X ~ 3 450 -100 150 L 50 50 1 1 P 45 | ENDDRAW 46 | ENDDEF 47 | # 48 | #End Library 49 | -------------------------------------------------------------------------------- /main/heavy/HvSignalEnvelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _SIGNAL_ENVELOPE_H_ 18 | #define _SIGNAL_ENVELOPE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct SignalEnvelope { 27 | int windowSize; 28 | int period; 29 | int numSamplesInBuffer; 30 | float *hanningWeights; 31 | float *buffer; 32 | } SignalEnvelope; 33 | 34 | hv_size_t sEnv_init(SignalEnvelope *o, int windowSize, int period); 35 | 36 | void sEnv_free(SignalEnvelope *o); 37 | 38 | void sEnv_process(HeavyContextInterface *_c, SignalEnvelope *o, hv_bInf_t bIn, 39 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 40 | 41 | #ifdef __cplusplus 42 | } // extern "C" 43 | #endif 44 | 45 | #endif // _SIGNAL_ENVELOPE_H_ 46 | -------------------------------------------------------------------------------- /main/heavy/HvHeavyInternal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_INTERNAL_H_ 18 | #define _HEAVY_INTERNAL_H_ 19 | 20 | #include "HvHeavy.h" 21 | #include "HvUtils.h" 22 | #include "HvTable.h" 23 | #include "HvMessage.h" 24 | #include "HvMath.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /** 31 | * 32 | */ 33 | HvTable *hv_table_get(HeavyContextInterface *c, hv_uint32_t tableHash); 34 | 35 | /** 36 | * 37 | */ 38 | void hv_scheduleMessageForReceiver(HeavyContextInterface *c, hv_uint32_t receiverHash, HvMessage *m); 39 | 40 | /** 41 | * 42 | */ 43 | HvMessage *hv_scheduleMessageForObject(HeavyContextInterface *c, const HvMessage *m, 44 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *), 45 | int letIndex); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /main/heavy/HvControlDelay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_DELAY_H_ 18 | #define _HEAVY_CONTROL_DELAY_H_ 19 | 20 | #define __HV_DELAY_MAX_MESSAGES 8 21 | 22 | #include "HvHeavyInternal.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | typedef struct ControlDelay { 29 | hv_uint32_t delay; // delay in samples 30 | HvMessage *msgs[__HV_DELAY_MAX_MESSAGES]; 31 | } ControlDelay; 32 | 33 | hv_size_t cDelay_init(HeavyContextInterface *_c, ControlDelay *o, float delayMs); 34 | 35 | void cDelay_onMessage(HeavyContextInterface *_c, ControlDelay *o, int letIn, const HvMessage *m, 36 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 37 | 38 | void cDelay_clearExecutingMessage(ControlDelay *o, const HvMessage *m); 39 | 40 | #ifdef __cplusplus 41 | } // extern "C" 42 | #endif 43 | 44 | #endif // _HEAVY_CONTROL_DELAY_H_ 45 | -------------------------------------------------------------------------------- /main/heavy/HvSignalSamphold.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalSamphold.h" 18 | 19 | hv_size_t sSamphold_init(SignalSamphold *o) { 20 | #if HV_SIMD_AVX 21 | o->s = _mm256_setzero_ps(); 22 | #elif HV_SIMD_SSE 23 | o->s = _mm_setzero_ps(); 24 | #elif HV_SIMD_NEON 25 | o->s = vdupq_n_f32(0.0f); 26 | #else 27 | o->s = 0.0f; 28 | #endif 29 | return 0; 30 | } 31 | 32 | void sSamphold_onMessage(HeavyContextInterface *_c, SignalSamphold *o, int letIndex, 33 | const HvMessage *m, void *sendMessage) { 34 | switch (letIndex) { 35 | case 2: { 36 | if (msg_isFloat(m,0)) { 37 | #if HV_SIMD_AVX 38 | o->s = _mm256_set1_ps(msg_getFloat(m,0)); 39 | #elif HV_SIMD_SSE 40 | o->s = _mm_set1_ps(msg_getFloat(m,0)); 41 | #elif HV_SIMD_NEON 42 | o->s = vdupq_n_f32(msg_getFloat(m,0)); 43 | #else 44 | o->s = msg_getFloat(m,0); 45 | #endif 46 | } 47 | break; 48 | } 49 | default: break; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /main/heavy/HvControlTabhead.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlTabhead.h" 18 | 19 | hv_size_t cTabhead_init(ControlTabhead *o, HvTable *table) { 20 | o->table = table; 21 | return 0; 22 | } 23 | 24 | void cTabhead_onMessage(HeavyContextInterface *_c, ControlTabhead *o, int letIn, const HvMessage *m, 25 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 26 | switch (letIn) { 27 | case 0: { 28 | if (msg_getType(m,0) == HV_MSG_BANG) { 29 | // get current head of table 30 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 31 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getHead(o->table)); 32 | sendMessage(_c, 0, n); 33 | } 34 | break; 35 | } 36 | case 1: { 37 | if (msg_isHashLike(m,0)) { 38 | // set a new table 39 | o->table = hv_table_get(_c, msg_getHash(m,0)); 40 | } 41 | break; 42 | } 43 | default: break; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /main/u8g2_esp32_hal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * u8g2_esp32_hal.h 3 | * 4 | * Created on: Feb 12, 2017 5 | * Author: kolban 6 | */ 7 | 8 | #ifndef U8G2_ESP32_HAL_H_ 9 | #define U8G2_ESP32_HAL_H_ 10 | #include "u8g2.h" 11 | 12 | #include "driver/gpio.h" 13 | #include "driver/spi_master.h" 14 | #include "driver/i2c.h" 15 | 16 | #define U8G2_ESP32_HAL_UNDEFINED (-1) 17 | 18 | #define I2C_MASTER_NUM I2C_NUM_1 // I2C port number for master dev 19 | #define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master do not need buffer 20 | #define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master do not need buffer 21 | #define I2C_MASTER_FREQ_HZ 100000 // I2C master clock frequency 22 | #define ACK_CHECK_EN 0x1 // I2C master will check ack from slave 23 | #define ACK_CHECK_DIS 0x0 // I2C master will not check ack from slave 24 | 25 | typedef struct { 26 | gpio_num_t clk; 27 | gpio_num_t mosi; 28 | gpio_num_t sda; // data for I²C 29 | gpio_num_t scl; // clock for I²C 30 | gpio_num_t cs; 31 | gpio_num_t reset; 32 | gpio_num_t dc; 33 | } u8g2_esp32_hal_t ; 34 | 35 | #define U8G2_ESP32_HAL_DEFAULT {(gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED, (gpio_num_t)U8G2_ESP32_HAL_UNDEFINED } 36 | 37 | void u8g2_esp32_hal_init(u8g2_esp32_hal_t u8g2_esp32_hal_param); 38 | uint8_t u8g2_esp32_spi_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 39 | uint8_t u8g2_esp32_i2c_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 40 | uint8_t u8g2_esp32_gpio_and_delay_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 41 | #endif /* U8G2_ESP32_HAL_H_ */ 42 | -------------------------------------------------------------------------------- /main/heavy/HvControlUnop.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_UNOP_H_ 18 | #define _HEAVY_CONTROL_UNOP_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum UnopType { 27 | HV_UNOP_ASIN, 28 | HV_UNOP_ASINH, 29 | HV_UNOP_ACOS, 30 | HV_UNOP_ACOSH, 31 | HV_UNOP_ATAN, 32 | HV_UNOP_ATANH, 33 | HV_UNOP_SIN, 34 | HV_UNOP_SINH, 35 | HV_UNOP_COS, 36 | HV_UNOP_COSH, 37 | HV_UNOP_TAN, 38 | HV_UNOP_TANH, 39 | HV_UNOP_EXP, 40 | HV_UNOP_ABS, 41 | HV_UNOP_SQRT, 42 | HV_UNOP_LOG, 43 | HV_UNOP_LOG2, 44 | HV_UNOP_LOG10, 45 | HV_UNOP_CEIL, 46 | HV_UNOP_FLOOR, 47 | HV_UNOP_ROUND 48 | } UnopType; 49 | 50 | void cUnop_onMessage(HeavyContextInterface *_c, UnopType op, const struct HvMessage *m, 51 | void (*sendMessage)(HeavyContextInterface *, int, const struct HvMessage *)); 52 | 53 | #ifdef __cplusplus 54 | } // extern "C" 55 | #endif 56 | 57 | #endif // _HEAVY_CONTROL_UNOP_H_ 58 | -------------------------------------------------------------------------------- /main/heavy/HvControlTabread.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlTabread.h" 18 | 19 | hv_size_t cTabread_init(ControlTabread *o, struct HvTable *table) { 20 | o->table = table; 21 | return 0; 22 | } 23 | 24 | void cTabread_onMessage(HeavyContextInterface *_c, ControlTabread *o, int letIn, const HvMessage *m, 25 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 26 | switch (letIn) { 27 | case 0: { 28 | if (msg_isFloat(m,0) && msg_getFloat(m,0) >= 0.0f && o->table != NULL) { 29 | const hv_uint32_t x = (hv_uint32_t) msg_getFloat(m,0); 30 | if (x < hTable_getSize(o->table)) { 31 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 32 | msg_initWithFloat(n, msg_getTimestamp(m), hTable_getBuffer(o->table)[x]); 33 | sendMessage(_c, 0, n); 34 | } 35 | } 36 | break; 37 | } 38 | case 1: { 39 | if (msg_isHashLike(m,0)) { 40 | o->table = hv_table_get(_c, msg_getHash(m,0)); 41 | } 42 | break; 43 | } 44 | default: return; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /main/heavy/HvUtils.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvUtils.h" 18 | 19 | hv_uint32_t hv_string_to_hash(const char *str) { 20 | // this hash is based MurmurHash2 21 | // http://en.wikipedia.org/wiki/MurmurHash 22 | // https://sites.google.com/site/murmurhash/ 23 | static const hv_uint32_t n = 0x5bd1e995; 24 | static const hv_int32_t r = 24; 25 | 26 | if (str == NULL) return 0; 27 | 28 | hv_uint32_t len = (hv_uint32_t) hv_strlen(str); 29 | hv_uint32_t x = len; // seed (0) ^ len 30 | 31 | while (len >= 4) { 32 | #if HV_EMSCRIPTEN 33 | hv_uint32_t k = str[0] | (str[1] << 8) | (str[2] << 16) | (str[3] << 24); 34 | #else 35 | hv_uint32_t k = *((hv_uint32_t *) str); 36 | #endif 37 | k *= n; 38 | k ^= (k >> r); 39 | k *= n; 40 | x *= n; 41 | x ^= k; 42 | str += 4; len -= 4; 43 | } 44 | switch (len) { 45 | case 3: x ^= (str[2] << 16); 46 | case 2: x ^= (str[1] << 8); 47 | case 1: x ^= str[0]; x *= n; 48 | default: break; 49 | } 50 | x ^= (x >> 13); 51 | x *= n; 52 | x ^= (x >> 15); 53 | return x; 54 | } 55 | -------------------------------------------------------------------------------- /main/heavy/HvControlRandom.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlRandom.h" 18 | 19 | // http://www.firstpr.com.au/dsp/rand31 20 | // http://en.wikipedia.org/wiki/Lehmer_random_number_generator 21 | 22 | hv_size_t cRandom_init(ControlRandom *o, int seed) { 23 | o->state = (seed != 0) ? seed : 1; 24 | return 0; 25 | } 26 | 27 | void cRandom_onMessage(HeavyContextInterface *_c, ControlRandom *o, int inletIndex, const HvMessage *m, 28 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 29 | switch (inletIndex) { 30 | case 0: { 31 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 32 | o->state = (hv_uint32_t) ((((unsigned long long) o->state) * 279470273UL) % 4294967291UL); 33 | float f = ((float) (o->state >> 9)) * 0.00000011920929f; 34 | msg_initWithFloat(n, msg_getTimestamp(m), f); 35 | sendMessage(_c, 0, n); 36 | break; 37 | } 38 | case 1: { 39 | if (msg_isFloat(m,0)) { 40 | o->state = (hv_uint32_t) msg_getFloat(m,0); 41 | } 42 | break; 43 | } 44 | default: break; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /main/heavy/HvSignalRPole.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalRPole.h" 18 | 19 | hv_size_t sRPole_init(SignalRPole *o) { 20 | #if HV_SIMD_AVX 21 | sDel1_init(&o->sDel1_fxiLN); 22 | sDel1_init(&o->sDel1_kjkpV); 23 | sDel1_init(&o->sDel1_dkIWc); 24 | sDel1_init(&o->sDel1_bVeoW); 25 | sDel1_init(&o->sDel1_PulZn); 26 | sDel1_init(&o->sDel1_yTFig); 27 | sDel1_init(&o->sDel1_Is9Qf); 28 | sDel1_init(&o->sDel1_LIyNt); 29 | sDel1_init(&o->sDel1_VqpU3); 30 | sDel1_init(&o->sDel1_ZVYeg); 31 | sDel1_init(&o->sDel1_IVAZh); 32 | sDel1_init(&o->sDel1_F8WrY); 33 | sDel1_init(&o->sDel1_rkFMy); 34 | sDel1_init(&o->sDel1_BeqSK); 35 | __hv_zero_f(&o->ym); 36 | #elif HV_SIMD_SSE || HV_SIMD_NEON 37 | sDel1_init(&o->sDel1_i8Twk); 38 | sDel1_init(&o->sDel1_KYibU); 39 | sDel1_init(&o->sDel1_spa5V); 40 | sDel1_init(&o->sDel1_3HXdb); 41 | sDel1_init(&o->sDel1_Aj1oK); 42 | sDel1_init(&o->sDel1_jNX1g); 43 | __hv_zero_f(&o->ym); 44 | #else 45 | o->ym = 0.0f; 46 | #endif 47 | return 0; 48 | } 49 | 50 | void sRPole_onMessage(HeavyContextInterface *_c, SignalRPole *o, int letIn, const HvMessage *m) { 51 | // TODO 52 | } 53 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS "main.cpp" 3 | "WM8978.cpp" 4 | "rotary_encoder.cpp" 5 | "heavy/Heavy_heavy.cpp" 6 | "heavy/HeavyContext.cpp" 7 | "heavy/HvHeavy.cpp" 8 | "heavy/HvLightPipe.c" 9 | "heavy/HvMessage.c" 10 | "heavy/HvMessagePool.c" 11 | "heavy/HvMessageQueue.c" 12 | "heavy/HvSignalDel1.c" 13 | "heavy/HvSignalLine.c" 14 | "heavy/HvSignalPhasor.c" 15 | "heavy/HvSignalRPole.c" 16 | "heavy/HvSignalSamphold.c" 17 | "heavy/HvSignalSample.c" 18 | "heavy/HvSignalVar.c" 19 | "heavy/HvSignalLine.c" 20 | "heavy/HvSignalTabread.c" 21 | "heavy/HvSignalTabwrite.c" 22 | "heavy/HvTable.c" 23 | "heavy/HvUtils.c" 24 | "heavy/HvControlBinop.c" 25 | "heavy/HvControlVar.c" 26 | "heavy/HvControlCast.c" 27 | "heavy/HvControlDelay.c" 28 | "heavy/HvControlSystem.c" 29 | "heavy/HvControlVar.c" 30 | "heavy/HvControlIf.c" 31 | "heavy/HvControlPack.c" 32 | "heavy/HvControlRandom.c" 33 | "heavy/HvControlTabread.c" 34 | "heavy/HvControlPrint.c" 35 | "heavy/HvControlSlice.c" 36 | "heavy/HvControlUnop.c" 37 | "heavy/HvSignalCPole.c" 38 | "heavy/HvSignalEnvelope.c" 39 | "heavy/HvControlTabhead.c" 40 | INCLUDE_DIRS "heavy/") 41 | 42 | set_source_files_properties("heavy/HvHeavy.cpp" 43 | PROPERTIES COMPILE_FLAGS 44 | -Wno-unknown-pragmas 45 | ) 46 | 47 | set(CMAKE_C_FLAGS "-Werror=all -Werror=extra \ 48 | -fPIE -fstack-check -fstack-protector-all -ftrapv -D_FORTIFY_SOURCE=2 \ 49 | -Wno-error=undef -Wno-implicit-fallthrough -Wunsuffixed-float-constants\ 50 | -Werror=unused -Werror=stringop-overflow=4 -Wno-missing-field-initializers") 51 | 52 | add_definitions("-ffast-math -DHV_SIMD_NONE -D__unix") 53 | #add_definitions("-ffast-math -DNDEBUG -DHV_SIMD_NONE") 54 | -------------------------------------------------------------------------------- /main/heavy/HvSignalSample.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalSample.h" 18 | 19 | #define __HV_SAMPLE_NULL -1 20 | 21 | hv_size_t sSample_init(SignalSample *o) { 22 | o->i = __HV_SAMPLE_NULL; 23 | return 0; 24 | } 25 | 26 | void sSample_onMessage(HeavyContextInterface *_c, SignalSample *o, int letIndex, const HvMessage *m) { 27 | o->i = msg_getTimestamp(m); 28 | } 29 | 30 | void __hv_sample_f(HeavyContextInterface *_c, SignalSample *o, hv_bInf_t bIn, 31 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 32 | if (o->i != __HV_SAMPLE_NULL) { 33 | 34 | #if HV_SIMD_AVX || HV_SIMD_SSE 35 | const float *const b = (float *) &bIn; 36 | float out = b[o->i & HV_N_SIMD_MASK]; 37 | #elif HV_SIMD_NEON 38 | float out = bIn[o->i & HV_N_SIMD_MASK]; 39 | #else // HV_SIMD_NONE 40 | float out = bIn; 41 | #endif 42 | 43 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 44 | hv_uint32_t ts = (o->i + HV_N_SIMD) & ~HV_N_SIMD_MASK; // start of next block 45 | msg_initWithFloat(n, ts, out); 46 | hv_scheduleMessageForObject(_c, n, sendMessage, 0); 47 | o->i = __HV_SAMPLE_NULL; // reset the index 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /main/heavy/HvSignalDel1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _SIGNAL_DEL1_H_ 18 | #define _SIGNAL_DEL1_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct SignalDel1 { 27 | hv_bufferf_t x; 28 | } SignalDel1; 29 | 30 | hv_size_t sDel1_init(SignalDel1 *o); 31 | 32 | void sDel1_onMessage(HeavyContextInterface *_c, SignalDel1 *o, int letIn, const HvMessage *m); 33 | 34 | static inline void __hv_del1_f(SignalDel1 *o, hv_bInf_t bIn0, hv_bOutf_t bOut) { 35 | #if HV_SIMD_AVX 36 | __m256 x = _mm256_permute_ps(bIn0, _MM_SHUFFLE(2,1,0,3)); // [3 0 1 2 7 4 5 6] 37 | __m256 n = _mm256_permute2f128_ps(o->x,x,0x1); // [h e f g 3 0 1 2] 38 | *bOut = _mm256_blend_ps(x, n, 0x11); // [h 0 1 2 3 4 5 6] 39 | o->x = x; 40 | #elif HV_SIMD_SSE 41 | __m128 n = _mm_blend_ps(o->x, bIn0, 0x7); 42 | *bOut = _mm_shuffle_ps(n, n, _MM_SHUFFLE(2,1,0,3)); 43 | o->x = bIn0; 44 | #elif HV_SIMD_NEON 45 | *bOut = vextq_f32(o->x, bIn0, 3); 46 | o->x = bIn0; 47 | #else 48 | *bOut = o->x; 49 | o->x = bIn0; 50 | #endif 51 | } 52 | 53 | #ifdef __cplusplus 54 | } // extern "C" 55 | #endif 56 | 57 | #endif // _SIGNAL_DEL1_H_ 58 | -------------------------------------------------------------------------------- /main/heavy/HvSignalTabwrite.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalTabwrite.h" 18 | 19 | hv_size_t sTabwrite_init(SignalTabwrite *o, HvTable *table) { 20 | o->table = table; 21 | o->head = 0; 22 | return 0; 23 | } 24 | 25 | void sTabwrite_onMessage(HeavyContextInterface *_c, SignalTabwrite *o, int letIn, const HvMessage *m, 26 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 27 | switch (letIn) { 28 | // inlet 0 is the signal inlet 29 | case 1: { 30 | switch (msg_getType(m,0)) { 31 | case HV_MSG_BANG: o->head = 0; break; 32 | case HV_MSG_FLOAT: { 33 | o->head = (msg_getFloat(m,0) >= 0.0f) ? (hv_uint32_t) msg_getFloat(m,0) : HV_TABWRITE_STOPPED; 34 | break; 35 | } 36 | case HV_MSG_SYMBOL: { 37 | if (msg_compareSymbol(m, 0, "stop")) { 38 | o->head = HV_TABWRITE_STOPPED; 39 | } 40 | break; 41 | } 42 | default: break; 43 | } 44 | break; 45 | } 46 | case 2: { 47 | if (msg_isHashLike(m,0)) { 48 | o->table = hv_table_get(_c, msg_getHash(m,0)); 49 | } 50 | break; 51 | } 52 | default: break; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /main/heavy/HvControlCast.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlCast.h" 18 | 19 | void cCast_onMessage(HeavyContextInterface *_c, CastType castType, int letIn, const HvMessage *m, 20 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 21 | switch (castType) { 22 | case HV_CAST_BANG: { 23 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 24 | msg_initWithBang(n, msg_getTimestamp(m)); 25 | sendMessage(_c, 0, n); 26 | break; 27 | } 28 | case HV_CAST_FLOAT: { 29 | if (msg_isFloat(m, 0)) { 30 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 31 | msg_initWithFloat(n, msg_getTimestamp(m), msg_getFloat(m, 0)); 32 | sendMessage(_c, 0, n); 33 | } 34 | break; 35 | } 36 | case HV_CAST_SYMBOL: { 37 | switch (msg_getType(m, 0)) { 38 | case HV_MSG_BANG: { 39 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 40 | msg_initWithSymbol(n, msg_getTimestamp(m), "bang"); 41 | sendMessage(_c, 0, n); 42 | break; 43 | } 44 | case HV_MSG_FLOAT: { 45 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 46 | msg_initWithSymbol(n, msg_getTimestamp(m), "float"); 47 | sendMessage(_c, 0, n); 48 | break; 49 | } 50 | case HV_MSG_SYMBOL: { 51 | sendMessage(_c, 0, m); 52 | break; 53 | } 54 | default: return; 55 | } 56 | break; 57 | } 58 | default: return; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /main/heavy/HvControlBinop.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTROL_BINOP_H_ 18 | #define _HEAVY_CONTROL_BINOP_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum BinopType { 27 | HV_BINOP_ADD, 28 | HV_BINOP_SUBTRACT, 29 | HV_BINOP_MULTIPLY, 30 | HV_BINOP_DIVIDE, 31 | HV_BINOP_INT_DIV, 32 | HV_BINOP_MOD_BIPOLAR, 33 | HV_BINOP_MOD_UNIPOLAR, 34 | HV_BINOP_BIT_LEFTSHIFT, 35 | HV_BINOP_BIT_RIGHTSHIFT, 36 | HV_BINOP_BIT_AND, 37 | HV_BINOP_BIT_XOR, 38 | HV_BINOP_BIT_OR, 39 | HV_BINOP_EQ, 40 | HV_BINOP_NEQ, 41 | HV_BINOP_LOGICAL_AND, 42 | HV_BINOP_LOGICAL_OR, 43 | HV_BINOP_LESS_THAN, 44 | HV_BINOP_LESS_THAN_EQL, 45 | HV_BINOP_GREATER_THAN, 46 | HV_BINOP_GREATER_THAN_EQL, 47 | HV_BINOP_MAX, 48 | HV_BINOP_MIN, 49 | HV_BINOP_POW, 50 | HV_BINOP_ATAN2 51 | } BinopType; 52 | 53 | typedef struct ControlBinop { 54 | float k; 55 | } ControlBinop; 56 | 57 | hv_size_t cBinop_init(ControlBinop *o, float k); 58 | 59 | void cBinop_onMessage(HeavyContextInterface *_c, ControlBinop *o, BinopType op, int letIn, 60 | const HvMessage *m, 61 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 62 | 63 | void cBinop_k_onMessage(HeavyContextInterface *_c, void *o, BinopType op, float k, 64 | int letIn, const HvMessage *m, 65 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 66 | 67 | #ifdef __cplusplus 68 | } // extern "C" 69 | #endif 70 | 71 | #endif // _HEAVY_CONTROL_BINOP_H_ 72 | -------------------------------------------------------------------------------- /main/heavy/HvControlSlice.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlSlice.h" 18 | 19 | hv_size_t cSlice_init(ControlSlice *o, int i, int n) { 20 | o->i = i; 21 | o->n = n; 22 | return 0; 23 | } 24 | 25 | void cSlice_onMessage(HeavyContextInterface *_c, ControlSlice *o, int letIn, const HvMessage *m, 26 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 27 | switch (letIn) { 28 | case 0: { 29 | // if the start point is greater than the number of elements in the source message, do nothing 30 | if (o->i < msg_getNumElements(m)) { 31 | int x = msg_getNumElements(m) - o->i; // number of elements in the new message 32 | if (o->n > 0) x = hv_min_i(x, o->n); 33 | HvMessage *n = HV_MESSAGE_ON_STACK(x); 34 | msg_init(n, x, msg_getTimestamp(m)); 35 | hv_memcpy(&n->elem, &m->elem+o->i, x*sizeof(Element)); 36 | sendMessage(_c, 0, n); 37 | } else { 38 | // if nothing can be sliced, send a bang out of the right outlet 39 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 40 | msg_initWithBang(n, msg_getTimestamp(m)); 41 | sendMessage(_c, 1, n); 42 | } 43 | break; 44 | } 45 | case 1: { 46 | if (msg_isFloat(m,0)) { 47 | o->i = (int) msg_getFloat(m,0); 48 | if (msg_isFloat(m,1)) { 49 | o->n = (int) msg_getFloat(m,1); 50 | } 51 | } 52 | break; 53 | } 54 | case 2: { 55 | if (msg_isFloat(m,0)) { 56 | o->n = (int) msg_getFloat(m,0); 57 | } 58 | break; 59 | } 60 | default: break; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /main/heavy/HvControlSystem.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlSystem.h" 18 | 19 | void cSystem_onMessage(HeavyContextInterface *_c, void *o, int letIn, const HvMessage *m, 20 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 21 | 22 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 23 | if (msg_compareSymbol(m, 0, "samplerate")) { 24 | 25 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hv_getSampleRate(_c)); 26 | } else if (msg_compareSymbol(m, 0, "numInputChannels")) { 27 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hv_getNumInputChannels(_c)); 28 | } else if (msg_compareSymbol(m, 0, "numOutputChannels")) { 29 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hv_getNumOutputChannels(_c)); 30 | } else if (msg_compareSymbol(m, 0, "currentTime")) { 31 | msg_initWithFloat(n, msg_getTimestamp(m), (float) msg_getTimestamp(m)); 32 | } else if (msg_compareSymbol(m, 0, "table")) { 33 | // NOTE(mhroth): no need to check message format for symbols as table lookup will fail otherwise 34 | HvTable *table = hv_table_get(_c, msg_getHash(m,1)); 35 | if (table != NULL) { 36 | if (msg_compareSymbol(m, 2, "length")) { 37 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getLength(table)); 38 | } else if (msg_compareSymbol(m, 2, "size")) { 39 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getSize(table)); 40 | } else if (msg_compareSymbol(m, 2, "head")) { 41 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getHead(table)); 42 | } else return; 43 | } else return; 44 | } else return; 45 | sendMessage(_c, 0, n); 46 | } 47 | -------------------------------------------------------------------------------- /main/heavy/HvControlUnop.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlUnop.h" 18 | 19 | void cUnop_onMessage(HeavyContextInterface *_c, UnopType op, const HvMessage *m, 20 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 21 | if (msg_isFloat(m, 0)) { 22 | float f = msg_getFloat(m, 0); 23 | switch (op) { 24 | case HV_UNOP_SIN: f = hv_sin_f(f); break; 25 | case HV_UNOP_SINH: f = hv_sinh_f(f); break; 26 | case HV_UNOP_COS: f = hv_cos_f(f); break; 27 | case HV_UNOP_COSH: f = hv_cosh_f(f); break; 28 | case HV_UNOP_TAN: f = hv_tan_f(f); break; 29 | case HV_UNOP_TANH: f = hv_tanh_f(f); break; 30 | case HV_UNOP_ASIN: f = hv_asin_f(f); break; 31 | case HV_UNOP_ASINH: f = hv_asinh_f(f); break; 32 | case HV_UNOP_ACOS: f = hv_acos_f(f); break; 33 | case HV_UNOP_ACOSH: f = hv_acosh_f(f); break; 34 | case HV_UNOP_ATAN: f = hv_atan_f(f); break; 35 | case HV_UNOP_ATANH: f = hv_atanh_f(f); break; 36 | case HV_UNOP_EXP: f = hv_exp_f(f); break; 37 | case HV_UNOP_ABS: f = hv_abs_f(f); break; 38 | case HV_UNOP_SQRT: f = (f > 0.0f) ? hv_sqrt_f(f) : 0.0f; break; 39 | case HV_UNOP_LOG: f = (f > 0.0f) ? hv_log_f(f) : 0.0f; break; 40 | case HV_UNOP_LOG2: f = (f > 0.0f) ? (1.442695040888963f*hv_log_f(f)) : 0.0f; break; 41 | case HV_UNOP_LOG10: f = (f > 0.0f) ? (0.434294481903252f*hv_log_f(f)) : 0.0f; break; 42 | case HV_UNOP_CEIL: f = hv_ceil_f(f); break; 43 | case HV_UNOP_FLOOR: f = hv_floor_f(f); break; 44 | case HV_UNOP_ROUND: f = hv_round_f(f); break; 45 | default: return; 46 | } 47 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 48 | msg_initWithFloat(n, m->timestamp, f); 49 | sendMessage(_c, 0, n); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /main/heavy/HvSignalCPole.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalCPole.h" 18 | 19 | hv_size_t sCPole_init(SignalCPole *o) { 20 | #if HV_SIMD_AVX 21 | sDel1_init(&o->sDel1_8kZ3w); 22 | sDel1_init(&o->sDel1_sy3YC); 23 | sDel1_init(&o->sDel1_GjjjE); 24 | sDel1_init(&o->sDel1_52HYk); 25 | sDel1_init(&o->sDel1_lXpu3); 26 | sDel1_init(&o->sDel1_orza7); 27 | sDel1_init(&o->sDel1_K7tpr); 28 | sDel1_init(&o->sDel1_yfNee); 29 | sDel1_init(&o->sDel1_hl63z); 30 | sDel1_init(&o->sDel1_etJkN); 31 | sDel1_init(&o->sDel1_BW4zg); 32 | sDel1_init(&o->sDel1_0z8gy); 33 | sDel1_init(&o->sDel1_0F5sm); 34 | sDel1_init(&o->sDel1_i4rAW); 35 | sDel1_init(&o->sDel1_ux1Jv); 36 | sDel1_init(&o->sDel1_FVaak); 37 | sDel1_init(&o->sDel1_oEc0p); 38 | sDel1_init(&o->sDel1_1AVVz); 39 | sDel1_init(&o->sDel1_qp6ty); 40 | sDel1_init(&o->sDel1_bkttO); 41 | sDel1_init(&o->sDel1_60VsH); 42 | sDel1_init(&o->sDel1_TbY4f); 43 | sDel1_init(&o->sDel1_bNHHm); 44 | sDel1_init(&o->sDel1_mijYH); 45 | sDel1_init(&o->sDel1_anxSw); 46 | sDel1_init(&o->sDel1_YiP2h); 47 | sDel1_init(&o->sDel1_anyeH); 48 | sDel1_init(&o->sDel1_Vtq0Y); 49 | __hv_zero_f(&o->ymr); 50 | __hv_zero_f(&o->ymi); 51 | #elif HV_SIMD_SSE || HV_SIMD_NEON 52 | sDel1_init(&o->sDel1_j0EQa); 53 | sDel1_init(&o->sDel1_4REN6); 54 | sDel1_init(&o->sDel1_5z88r); 55 | sDel1_init(&o->sDel1_CxDdp); 56 | sDel1_init(&o->sDel1_8zCWF); 57 | sDel1_init(&o->sDel1_1A4op); 58 | sDel1_init(&o->sDel1_ldSdM); 59 | sDel1_init(&o->sDel1_sOZ64); 60 | sDel1_init(&o->sDel1_mpbqn); 61 | sDel1_init(&o->sDel1_sBC7F); 62 | sDel1_init(&o->sDel1_bZG8k); 63 | sDel1_init(&o->sDel1_Wtjof); 64 | __hv_zero_f(&o->ymr); 65 | __hv_zero_f(&o->ymi); 66 | #else 67 | o->ymr = 0.0f; 68 | o->ymi = 0.0f; 69 | #endif 70 | return 0; 71 | } 72 | 73 | void sCPole_onMessage(HeavyContextInterface *_c, SignalCPole *o, int letIn, const HvMessage *m) { 74 | // TODO 75 | } 76 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/eurorack_engine.rules: -------------------------------------------------------------------------------- 1 | 2 | (rules PCB eurorack_engine 3 | (snap_angle 4 | fortyfive_degree 5 | ) 6 | (autoroute_settings 7 | (fanout off) 8 | (autoroute on) 9 | (postroute on) 10 | (vias on) 11 | (via_costs 50) 12 | (plane_via_costs 5) 13 | (start_ripup_costs 100) 14 | (start_pass_no 1673) 15 | (layer_rule F.Cu 16 | (active on) 17 | (preferred_direction horizontal) 18 | (preferred_direction_trace_costs 1.0) 19 | (against_preferred_direction_trace_costs 2.2) 20 | ) 21 | (layer_rule B.Cu 22 | (active on) 23 | (preferred_direction vertical) 24 | (preferred_direction_trace_costs 1.0) 25 | (against_preferred_direction_trace_costs 1.8) 26 | ) 27 | ) 28 | (rule 29 | (width 250.0) 30 | (clear 200.2) 31 | (clear 125.0 (type smd_to_turn_gap)) 32 | (clear 50.0 (type smd_smd)) 33 | ) 34 | (padstack "Via[0-1]_800:400_um" 35 | (shape 36 | (circle F.Cu 800.0 0.0 0.0) 37 | ) 38 | (shape 39 | (circle B.Cu 800.0 0.0 0.0) 40 | ) 41 | (attach off) 42 | ) 43 | (via 44 | "Via[0-1]_800:400_um" "Via[0-1]_800:400_um" default 45 | ) 46 | (via 47 | "Via[0-1]_800:400_um-kicad_default" "Via[0-1]_800:400_um" "kicad_default" 48 | ) 49 | (via_rule 50 | default "Via[0-1]_800:400_um" 51 | ) 52 | (via_rule 53 | "kicad_default" "Via[0-1]_800:400_um-kicad_default" 54 | ) 55 | (class default 56 | (clearance_class default) 57 | (via_rule default) 58 | (rule 59 | (width 250.0) 60 | ) 61 | (circuit 62 | (use_layer F.Cu B.Cu) 63 | ) 64 | ) 65 | (class "kicad_default" 66 | GND "Net-(C1-Pad1)" +3V3 +12V "-12V" "Net-(D1-Pad2)" "Net-(D2-Pad2)" "Net-(D3-Pad2)" 67 | "Net-(D4-Pad2)" /bck1 /din1 /lrck1 /bck2 /din2 /lrck2 "Net-(J2-Pad3)" 68 | "Net-(J3-Pad3)" "Net-(J4-Pad3)" "Net-(J5-Pad3)" "Net-(J6-Pad3)" "Net-(J7-Pad3)" "Net-(J8-Pad3)" /led1 /led2 69 | /led3 /led4 "Net-(R12-Pad1)" "Net-(R11-Pad2)" "Net-(R12-Pad2)" "Net-(R13-Pad2)" "Net-(R21-Pad2)" "Net-(R22-Pad2)" 70 | "Net-(R23-Pad1)" "Net-(R24-Pad1)" /button4 /button1 /button2 /button3 "Net-(C2-Pad1)" "/codec_out_2" 71 | "/codec_out_1" "/codec_out_4" "/codec_out_3" "/adc_mosi" "/adc_miso" "/adc_cs" "/adc_clk" "/aref_-10v" 72 | "Net-(J1-Pad3)" "Net-(R5-Pad2)" "Net-(R6-Pad2)" "Net-(R11-Pad1)" "Net-(R10-Pad2)" "/adc_ch1" "Net-(R19-Pad2)" "Net-(R20-Pad2)" 73 | "Net-(R27-Pad2)" "Net-(R28-Pad2)" "/adc_ch3" "/adc_ch2" "/adc_ch4" "/adc_ch6" "/adc_ch7" "/adc_ch5" 74 | "/adc_ch0" 75 | (clearance_class "kicad_default") 76 | (via_rule kicad_default) 77 | (rule 78 | (width 250.0) 79 | ) 80 | (circuit 81 | (use_layer F.Cu B.Cu) 82 | ) 83 | ) 84 | ) -------------------------------------------------------------------------------- /main/heavy/HvMessagePool.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _MESSAGE_POOL_H_ 18 | #define _MESSAGE_POOL_H_ 19 | 20 | #include "HvUtils.h" 21 | 22 | #define MP_NUM_MESSAGE_LISTS 4 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | typedef struct HvMessagePoolList { 29 | struct MessageListNode *head; // list of currently available blocks 30 | struct MessageListNode *pool; // list of currently used blocks 31 | } HvMessagePoolList; 32 | 33 | typedef struct HvMessagePool { 34 | char *buffer; // the buffer of all messages 35 | hv_size_t bufferSize; // in bytes 36 | hv_size_t bufferIndex; // the number of total reserved bytes 37 | 38 | HvMessagePoolList lists[MP_NUM_MESSAGE_LISTS]; 39 | } HvMessagePool; 40 | 41 | /** 42 | * The HvMessagePool is a basic memory management system. It reserves a large block of memory at initialisation 43 | * and proceeds to divide this block into smaller chunks (usually 512 bytes) as they are needed. These chunks are 44 | * further divided into 32, 64, 128, or 256 sections. Each of these sections is managed by a HvMessagePoolList (MPL). 45 | * An MPL is a linked-list data structure which is initialised such that its own pool of listnodes is filled with nodes 46 | * that point at each subblock (e.g. each 32-byte block of a 512-block chunk). 47 | * 48 | * HvMessagePool is loosely inspired by TCMalloc. http://goog-perftools.sourceforge.net/doc/tcmalloc.html 49 | */ 50 | 51 | hv_size_t mp_init(struct HvMessagePool *mp, hv_size_t numKB); 52 | 53 | void mp_free(struct HvMessagePool *mp); 54 | 55 | /** 56 | * Adds a message to the pool and returns a pointer to the copy. Returns NULL 57 | * if no space was available in the pool. 58 | */ 59 | struct HvMessage *mp_addMessage(struct HvMessagePool *mp, const struct HvMessage *m); 60 | 61 | void mp_freeMessage(struct HvMessagePool *mp, struct HvMessage *m); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif // _MESSAGE_POOL_H_ 68 | -------------------------------------------------------------------------------- /main/heavy/HvSignalTabread.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalTabread.h" 18 | 19 | hv_size_t sTabread_init(SignalTabread *o, HvTable *table, bool forceAlignedLoads) { 20 | o->table = table; 21 | o->head = 0; 22 | o->forceAlignedLoads = forceAlignedLoads; 23 | return 0; 24 | } 25 | 26 | void sTabread_onMessage(HeavyContextInterface *_c, SignalTabread *o, int letIn, const HvMessage *m, 27 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 28 | switch (letIn) { 29 | case 0: { 30 | if (o->table != NULL) { 31 | switch (msg_getType(m,0)) { 32 | case HV_MSG_BANG: o->head = 0; break; 33 | case HV_MSG_FLOAT: { 34 | hv_uint32_t h = (hv_uint32_t) hv_abs_f(msg_getFloat(m,0)); 35 | if (msg_getFloat(m,0) < 0.0f) { 36 | // if input is negative, wrap around the end of the table 37 | h = hTable_getSize(o->table) - h; 38 | } 39 | o->head = o->forceAlignedLoads ? (h & ~HV_N_SIMD_MASK) : h; 40 | 41 | // output new head 42 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 43 | msg_initWithFloat(n, msg_getTimestamp(m), (float) o->head); 44 | sendMessage(_c, 1, n); 45 | break; 46 | } 47 | default: break; 48 | } 49 | } 50 | break; 51 | } 52 | case 1: { 53 | if (msg_isHashLike(m,0)) { 54 | o->table = hv_table_get(_c, msg_getHash(m,0)); 55 | } 56 | break; 57 | } 58 | default: break; 59 | } 60 | } 61 | 62 | 63 | 64 | #if HV_APPLE 65 | #pragma mark - Tabhead 66 | #endif 67 | 68 | void sTabhead_onMessage(HeavyContextInterface *_c, SignalTabhead *o, const HvMessage *m) { 69 | if (msg_isHashLike(m,0)) { 70 | o->table = hv_table_get(_c, msg_getHash(m,0)); 71 | } 72 | } 73 | 74 | hv_size_t sTabhead_init(SignalTabhead *o, HvTable *table) { 75 | o->table = table; 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /main/heavy/HvControlPack.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlPack.h" 18 | 19 | hv_size_t cPack_init(ControlPack *o, int nargs, ...) { 20 | hv_size_t numBytes = msg_getCoreSize(nargs); 21 | o->msg = (HvMessage *) hv_malloc(numBytes); 22 | hv_assert(o->msg != NULL); 23 | msg_init(o->msg, nargs, 0); 24 | 25 | // variable arguments are used as float initialisers for the pack elements 26 | va_list ap; 27 | va_start(ap, nargs); 28 | for (int i = 0; i < nargs; ++i) { 29 | msg_setFloat(o->msg, i, (float) va_arg(ap, double)); 30 | } 31 | va_end(ap); 32 | return numBytes; 33 | } 34 | 35 | void cPack_free(ControlPack *o) { 36 | hv_free(o->msg); 37 | } 38 | 39 | void cPack_onMessage(HeavyContextInterface *_c, ControlPack *o, int letIn, const HvMessage *m, 40 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 41 | // ensure let index is less than number elements in internal msg 42 | int numElements = msg_getNumElements(o->msg); 43 | switch (letIn) { 44 | case 0: { // first inlet stores all values of input msg and triggers an output 45 | for (int i = hv_min_i(numElements, msg_getNumElements(m))-1; i >= 0; --i) { 46 | switch (msg_getType(m, i)) { 47 | case HV_MSG_FLOAT: msg_setFloat(o->msg, i, msg_getFloat(m, i)); break; 48 | case HV_MSG_SYMBOL: 49 | case HV_MSG_HASH: msg_setHash(o->msg, i, msg_getHash(m, i)); break; 50 | default: break; 51 | } 52 | } 53 | msg_setTimestamp(o->msg, msg_getTimestamp(m)); 54 | sendMessage(_c, 0, o->msg); 55 | break; 56 | } 57 | default: { // rest of inlets just store values 58 | switch (msg_getType(m, 0)) { 59 | case HV_MSG_FLOAT: msg_setFloat(o->msg, letIn, msg_getFloat(m, 0)); break; 60 | case HV_MSG_SYMBOL: 61 | case HV_MSG_HASH: msg_setHash(o->msg, letIn, msg_getHash(m, 0)); break; 62 | default: break; 63 | } 64 | break; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /supportedobjects.md: -------------------------------------------------------------------------------- 1 | Supported puredata objects: 2 | 3 | - `<` 4 | - `<<` 5 | - `<=` 6 | - `==` 7 | - `>` 8 | - `>=` 9 | - `>>` 10 | - `|` 11 | - `||` 12 | - `-` 13 | - `-~` 14 | - `!=` 15 | - `/` 16 | - `/~` 17 | - `*` 18 | - `*~` 19 | - `&` 20 | - `&&` 21 | - `%` 22 | - `+` 23 | - `+~` 24 | - `abs` 25 | - `abs~` 26 | - `adc~` 27 | - `atan` 28 | - `atan2` 29 | - `b` 30 | - `bang` 31 | - `bendin` 32 | - `bendout` 33 | - `biquad~` 34 | - `bng` 35 | - `bp~` 36 | - `catch~` 37 | - `change` 38 | - `clip` 39 | - `clip~` 40 | - `cnv` 41 | - `cos` 42 | - `cos~` 43 | - `cpole~` 44 | - `ctlin` 45 | - `ctlout` 46 | - `czero~` 47 | - `czero_rev~` 48 | - `dac~` 49 | - `dbtopow` 50 | - `dbtopow~` 51 | - `dbtorms` 52 | - `dbtorms~` 53 | - `declare` 54 | - `del` 55 | - `delay` 56 | - `delread~` 57 | - `delwrite~` 58 | - `div` 59 | - `env~` 60 | - `exp` 61 | - `exp~` 62 | - `f` 63 | - `float` 64 | - `floatatom` 65 | - `ftom` 66 | - `ftom~` 67 | - `hip~` 68 | - `hradio` 69 | - `hsl` 70 | - `i` 71 | - `inlet` 72 | - `inlet~` 73 | - `int` 74 | - `line` 75 | - `line~` 76 | - `loadbang` 77 | - `log` 78 | - `lop~` 79 | - `makenote` 80 | - `max` 81 | - `max~` 82 | - `metro` 83 | - `min` 84 | - `min~` 85 | - `mod` 86 | - `moses` 87 | - `mtof` 88 | - `mtof~` 89 | - `nbx` 90 | - `noise~` 91 | - `notein` 92 | - `noteout` 93 | - `osc~` 94 | - `outlet` 95 | - `outlet~` 96 | - `pack` 97 | - `pgmin` 98 | - `pgmout` 99 | - `phasor~` 100 | - `pipe` 101 | - `poly` 102 | - `pow` 103 | - `pow~` 104 | - `powtodb` 105 | - `powtodb~` 106 | - `print` 107 | - `q8_rsqrt~` 108 | - `q8_sqrt~` 109 | - `r` 110 | - `r~` 111 | - `random` 112 | - `receive` 113 | - `receive~` 114 | - `rmstodb` 115 | - `rmstodb~` 116 | - `route` 117 | - `rpole~` 118 | - `rsqrt~` 119 | - `rzero~` 120 | - `rzero_rev~` 121 | - `s` 122 | - `s~` 123 | - `samphold~` 124 | - `samplerate~` 125 | - `sel` 126 | - `select` 127 | - `send` 128 | - `send~` 129 | - `sig~` 130 | - `sin` 131 | - `snapshot~` 132 | - `spigot` 133 | - `sqrt` 134 | - `sqrt~` 135 | - `swap` 136 | - `symbol` 137 | - `symbolatom` 138 | - `t` 139 | - `table` 140 | - `tabosc4~` 141 | - `tabplay~` 142 | - `tabread` 143 | - `tabread~` 144 | - `tabread4~` 145 | - `tabwrite` 146 | - `tabwrite~` 147 | - `tan` 148 | - `tgl` 149 | - `throw~` 150 | - `timer` 151 | - `touchin` 152 | - `touchout` 153 | - `trigger` 154 | - `unpack` 155 | - `until` 156 | - `vcf~` 157 | - `vd~` 158 | - `vradio` 159 | - `vsl` 160 | - `wrap` 161 | - `wrap~` 162 | -------------------------------------------------------------------------------- /main/heavy/HvControlVar.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlVar.h" 18 | 19 | hv_size_t cVar_init_f(ControlVar *o, float k) { 20 | o->e.type = HV_MSG_FLOAT; 21 | o->e.data.f = k; 22 | return 0; 23 | } 24 | 25 | hv_size_t cVar_init_s(ControlVar *o, const char *s) { 26 | o->e.type = HV_MSG_HASH; 27 | o->e.data.h = hv_string_to_hash(s); 28 | return 0; 29 | } 30 | 31 | void cVar_free(ControlVar *o) { 32 | // nothing to do 33 | } 34 | 35 | void cVar_onMessage(HeavyContextInterface *_c, ControlVar *o, int letIn, const HvMessage *m, 36 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 37 | switch (letIn) { 38 | case 0: { 39 | switch (msg_getType(m,0)) { 40 | case HV_MSG_BANG: { 41 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 42 | if (o->e.type == HV_MSG_FLOAT) msg_initWithFloat(n, msg_getTimestamp(m), o->e.data.f); 43 | else if (o->e.type == HV_MSG_HASH) msg_initWithHash(n, msg_getTimestamp(m), o->e.data.h); 44 | else return; 45 | sendMessage(_c, 0, n); 46 | break; 47 | } 48 | case HV_MSG_FLOAT: { 49 | o->e.type = HV_MSG_FLOAT; 50 | o->e.data.f = msg_getFloat(m,0); 51 | sendMessage(_c, 0, m); 52 | break; 53 | } 54 | case HV_MSG_SYMBOL: 55 | case HV_MSG_HASH: { 56 | o->e.type = HV_MSG_HASH; 57 | o->e.data.h = msg_getHash(m,0); 58 | sendMessage(_c, 0, m); 59 | break; 60 | } 61 | default: return; 62 | } 63 | break; 64 | } 65 | case 1: { 66 | switch (msg_getType(m,0)) { 67 | case HV_MSG_FLOAT: { 68 | o->e.type = HV_MSG_FLOAT; 69 | o->e.data.f = msg_getFloat(m,0); 70 | break; 71 | } 72 | case HV_MSG_SYMBOL: 73 | case HV_MSG_HASH: { 74 | o->e.type = HV_MSG_HASH; 75 | o->e.data.h = msg_getHash(m,0); 76 | break; 77 | } 78 | default: break; 79 | } 80 | } 81 | default: return; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /main/heavy/HvTable.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_TABLE_H_ 18 | #define _HEAVY_TABLE_H_ 19 | 20 | #include "HvHeavy.h" 21 | #include "HvUtils.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | typedef struct HvTable { 28 | float *buffer; 29 | // the number of values that the table is requested to have 30 | hv_uint32_t length; 31 | 32 | // the number of usable values that the table actually has 33 | // this is always an even multiple of HV_N_SIMD 34 | hv_uint32_t size; 35 | 36 | // Note that the true size of the table is (size + HV_N_SIMD), 37 | // with the trailing values used by the system, e.g. to create a circular 38 | // buffer 39 | hv_uint32_t allocated; 40 | 41 | hv_uint32_t head; // the most recently written point 42 | } HvTable; 43 | 44 | hv_size_t hTable_init(HvTable *o, int length); 45 | 46 | hv_size_t hTable_initWithData(HvTable *o, int length, const float *data); 47 | 48 | hv_size_t hTable_initWithFinalData(HvTable *o, int length, float *data); 49 | 50 | void hTable_free(HvTable *o); 51 | 52 | int hTable_resize(HvTable *o, hv_uint32_t newLength); 53 | 54 | void hTable_onMessage(HeavyContextInterface *_c, HvTable *o, int letIn, const HvMessage *m, 55 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 56 | 57 | static inline float *hTable_getBuffer(HvTable *o) { 58 | return o->buffer; 59 | } 60 | 61 | // the user-requested length of the table (number of floats) 62 | static inline hv_uint32_t hTable_getLength(HvTable *o) { 63 | return o->length; 64 | } 65 | 66 | // the usable length of the table (an even multiple of HV_N_SIMD) 67 | static inline hv_uint32_t hTable_getSize(HvTable *o) { 68 | return o->size; 69 | } 70 | 71 | // the number of floats allocated to this table (usually size + HV_N_SIMD) 72 | static inline hv_uint32_t hTable_getAllocated(HvTable *o) { 73 | return o->allocated; 74 | } 75 | 76 | static inline hv_uint32_t hTable_getHead(HvTable *o) { 77 | return o->head; 78 | } 79 | 80 | static inline void hTable_setHead(HvTable *o, hv_uint32_t head) { 81 | o->head = head; 82 | } 83 | 84 | #ifdef __cplusplus 85 | } // extern "C" 86 | #endif 87 | 88 | #endif // _HEAVY_TABLE_H_ 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ESP32-DevKitC & hvcc 3 | 4 | This repo demonstrates a single file solution for running [hvcc](https://github.com/enzienaudio/hvcc) sources on the [ESP32-devkitc](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/get-started-devkitc.html), inspired by the [Faust ESP32 architecture example](https://faust.grame.fr/doc/tutorials/#dsp-on-the-esp32-with-faust). The hvcc compiler leverages the use of (a subset of) puredata operators on the cheap and fast esp32 uprocessor. The ESP32-devkitc combined with one PCM5102 CODEC, one WM8731 CODEC and an 8 port MCP3208 ADC provides a complete and available audio development platform with a very reasonable pricetag. UI provided via 4 buttons, 4 potentiometers and 4 leds. 5 | 6 | # Goal 7 | 8 | The goal of this development is to realise a generic eurorack module that is based on the ESP32 and programmable via puredata. Each cheap module consists of four control voltage inputs and four audio / cv outputs (all io -5v -> +5v and fully eurorack compatible). All parts are easily obtainable and all software and hardware is open source, so ordering your own set of PCB's is also possible 9 | 10 | # Status 11 | 15-nov-2020: Replaced one of the PCM5102 with a WM8731 to have audio stereo line in over i2s 12 | 13 | 25-oct-2020: PCB design ready, gerbers generated and boards ordered. 14 | 15 | 18-oct-2020: Code cleanup and PCB design ongoing. Current schematic tested and working! 16 | 17 | # Installation 18 | 19 | - Install Espressif IoT Development Framework 4.1, the official development framework for ESP32. 20 | - Install the hvcc compiler 21 | - Clone this repo 22 | 23 | # Hardware setup 24 | 25 | Check the Kicad schematics in the schematics folder 26 | 27 | # Usage 28 | 29 | - Create your puredata patch, using the [supported objects](supportedobjects.md) only. Use `tabread` with a $0-array instead of the `table` object, seems to work better. 30 | - Issue a Issue a `python2.7 hvcc.py input.pd -o ./heavy/` to generate the source files, where input.pd is your puredata patch 31 | - MAC: compile using hvcc and libs and copy to project subdir: `python2.7 hvcc.py esp32_2.pd -p ./Hoclib/ ./Josephlarralde/ ./ParkinsonHashizume/ ./MikeMorenoAudio/ ./Heavylib -o ./heavy/ ; cp ./heavy/c/Heavy_heavy.* ~/Documents/GitHub/esp32-hvcc/main/heavy/` 32 | - WIN: compile and copy: `c:\Python27\python.exe` rest as above, then a `copy /Y heavy\c\Heavy_* c:\Users\Arthur\Github\esp32-hvcc\main\heavy` 33 | - Add all heavy c and cpp sources to /main/CMakeLists.txt (only when adding new objects) 34 | - Run `idf.py -p /dev/tty.SLAB_USBtoUART flash monitor` to compile, upload and monitor the esp32 binary 35 | - MAC: `idf.py -p /dev/cu.usbserial-1A14301 -b 921600 flash monitor` 36 | - WIN: `idf.py -p COM4 -b 921600 flash monitor` 37 | - Enjoy your pd patch! 38 | 39 | # Performance 40 | 41 | A large and nice sounding puredata patch from "manwithfeathers" on rebeltech.org named ["Fascination IV"](https://www.rebeltech.org/patch-library/patch/Fascination_IV) yields about 60% performance of the ESP32 which looks like a very nice performance / cost ratio! 42 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/footprints.pretty/OnOffShim.kicad_mod: -------------------------------------------------------------------------------- 1 | (module OnOffShim (layer F.Cu) (tedit 5AC7C9BF) 2 | (fp_text reference U5 (at -8.33 -16.24) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value OnOffShim (at -0.29 -18.64) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start 5.98 -12.15) (end 6.78 -12.95) (layer F.SilkS) (width 0.15)) 9 | (fp_line (start 6.78 -12.95) (end 7.88 -11.85) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start 7.88 -11.85) (end 7.08 -11.05) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start 4.78 -13.35) (end 3.08 -11.65) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start 3.08 -11.65) (end 6.38 -8.35) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start 4.78 -13.35) (end 8.08 -10.05) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start 8.08 -10.05) (end 6.38 -8.35) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start 4.78 -14.15) (end 8.88 -10.05) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start 8.88 -10.05) (end 8.88 8.05) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start -6.02 -15.65) (end -6.02 -9.65) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start -6.02 -9.65) (end 1.98 -9.65) (layer F.SilkS) (width 0.15)) 19 | (fp_line (start 1.98 -9.65) (end 1.98 -15.65) (layer F.SilkS) (width 0.15)) 20 | (fp_line (start 1.98 -15.65) (end -5.92 -15.65) (layer F.SilkS) (width 0.15)) 21 | (fp_line (start -7.52 17.85) (end -7.52 -14.15) (layer F.SilkS) (width 0.15)) 22 | (fp_line (start -7.52 -14.15) (end 4.78 -14.15) (layer F.SilkS) (width 0.15)) 23 | (fp_line (start -7.52 17.85) (end 2.58 17.85) (layer F.SilkS) (width 0.15)) 24 | (fp_line (start 2.58 17.85) (end 2.58 8.05) (layer F.SilkS) (width 0.15)) 25 | (fp_line (start 2.58 8.05) (end 8.88 8.05) (layer F.SilkS) (width 0.15)) 26 | (pad 1 thru_hole circle (at 6.62 -6.25) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 27 | (pad 2 thru_hole circle (at 6.62 -3.71) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 28 | (pad 3 thru_hole circle (at 6.62 -1.17) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 29 | (pad 4 thru_hole circle (at 6.62 1.37) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 30 | (pad 5 thru_hole circle (at 6.62 3.91) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 31 | (pad 6 thru_hole circle (at 6.62 6.45) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 32 | (pad 7 thru_hole circle (at 4.08 -6.25) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 33 | (pad 8 thru_hole circle (at 4.08 -3.71) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 34 | (pad 9 thru_hole circle (at 4.08 -1.17) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 35 | (pad 10 thru_hole circle (at 4.08 1.37) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 36 | (pad 11 thru_hole circle (at 4.08 3.91) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 37 | (pad 12 thru_hole circle (at 4.08 6.45) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 38 | (pad 13 thru_hole circle (at -5.32 15.45) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 39 | (pad 14 thru_hole circle (at -5.32 12.91) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 40 | ) 41 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/footprints.pretty/PAM8406.kicad_mod: -------------------------------------------------------------------------------- 1 | (module PAM8406 (layer F.Cu) (tedit 5ABC1A8B) 2 | (fp_text reference IC4 (at -16.3845 -18.206) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value "PAM8406 Audio Amplifier" (at -3.113 -17.19) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start -7.558 -14.65) (end -7.558 -15.285) (layer F.SilkS) (width 0.15)) 9 | (fp_line (start -7.558 -15.285) (end -9.463 -15.285) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start -9.463 -15.285) (end -9.463 -14.65) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start -9.463 -14.65) (end -7.558 -14.65) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start -6.923 -0.045) (end -6.923 -1.95) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start -6.923 -1.95) (end -7.558 -1.95) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start -7.558 -1.95) (end -7.558 -0.045) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start -7.558 -0.045) (end -6.923 -0.045) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start -5.018 -3.855) (end 0.062 -3.855) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start 0.062 -3.855) (end 0.062 -13.38) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start 0.062 -13.38) (end -5.018 -13.38) (layer F.SilkS) (width 0.15)) 19 | (fp_line (start -5.018 -13.38) (end -5.018 -3.855) (layer F.SilkS) (width 0.15)) 20 | (fp_line (start -14.543 2) (end 9.457 2) (layer F.SilkS) (width 0.15)) 21 | (fp_line (start -14.543 -21) (end -14.543 2) (layer F.SilkS) (width 0.15)) 22 | (fp_line (start 9.457 -21) (end 9.457 2) (layer F.SilkS) (width 0.15)) 23 | (fp_line (start -14.543 -21) (end 9.457 -21) (layer F.SilkS) (width 0.15)) 24 | (pad "" np_thru_hole circle (at 7.207 -18.45) (size 2.5 2.5) (drill 2.5) (layers *.Cu *.Mask)) 25 | (pad "" np_thru_hole circle (at 7.207 -0.55) (size 2.5 2.5) (drill 2.5) (layers *.Cu *.Mask)) 26 | (pad "" np_thru_hole circle (at -12.293 -0.55) (size 2.5 2.5) (drill 2.5) (layers *.Cu *.Mask)) 27 | (pad "" np_thru_hole circle (at -12.293 -18.45) (size 2.5 2.5) (drill 2.5) (layers *.Cu *.Mask)) 28 | (pad "" np_thru_hole circle (at -10.443 -9) (size 11 11) (drill 11) (layers *.Cu *.Mask)) 29 | (pad "" np_thru_hole circle (at 5.36 -9) (size 11 11) (drill 11) (layers *.Cu *.Mask)) 30 | (pad 1 thru_hole circle (at 3.81 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 31 | (pad 2 thru_hole circle (at 1.27 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 32 | (pad 3 thru_hole circle (at -1.27 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 33 | (pad 4 thru_hole circle (at -3.81 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 34 | (pad 5 thru_hole circle (at -6.35 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 35 | (pad 6 thru_hole circle (at -8.89 -19.6) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 36 | (pad 7 thru_hole circle (at 0 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 37 | (pad 8 thru_hole circle (at -2.54 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 38 | (pad 9 thru_hole circle (at -5.08 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 39 | ) 40 | -------------------------------------------------------------------------------- /main/heavy/HvSignalVar.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalVar.h" 18 | 19 | // __var~f 20 | 21 | static void sVarf_update(SignalVarf *o, float k, float step, bool reverse) { 22 | #if HV_SIMD_AVX 23 | if (reverse) o->v = _mm256_setr_ps(k+7.0f*step, k+6.0f*step, k+5.0f*step, k+4.0f*step, k+3.0f*step, k+2.0f*step, k+step, k); 24 | else o->v = _mm256_set_ps(k+7.0f*step, k+6.0f*step, k+5.0f*step, k+4.0f*step, k+3.0f*step, k+2.0f*step, k+step, k); 25 | #elif HV_SIMD_SSE 26 | if (reverse) o->v = _mm_setr_ps(k+3.0f*step, k+2.0f*step, k+step, k); 27 | else o->v = _mm_set_ps(k+3.0f*step, k+2.0f*step, k+step, k); 28 | #elif HV_SIMD_NEON 29 | if (reverse) o->v = (float32x4_t) {3.0f*step+k, 2.0f*step+k, step+k, k}; 30 | else o->v = (float32x4_t) {k, step+k, 2.0f*step+k, 3.0f*step+k}; 31 | #else // HV_SIMD_NONE 32 | o->v = k; 33 | #endif 34 | } 35 | 36 | hv_size_t sVarf_init(SignalVarf *o, float k, float step, bool reverse) { 37 | sVarf_update(o, k, step, reverse); 38 | return 0; 39 | } 40 | 41 | void sVarf_onMessage(HeavyContextInterface *_c, SignalVarf *o, const HvMessage *m) { 42 | if (msg_isFloat(m,0)) { 43 | sVarf_update(o, msg_getFloat(m,0), msg_isFloat(m,1) ? msg_getFloat(m,1) : 0.0f, msg_getNumElements(m) == 3); 44 | } 45 | } 46 | 47 | 48 | 49 | // __var~i 50 | 51 | static void sVari_update(SignalVari *o, int k, int step, bool reverse) { 52 | #if HV_SIMD_AVX 53 | if (reverse) o->v = _mm256_setr_epi32(k+7*step, k+6*step, k+5*step, k+4*step, k+3*step, k+2*step, k+step, k); 54 | else o->v = _mm256_set_epi32(k+7*step, k+6*step, k+5*step, k+4*step, k+3*step, k+2*step, k+step, k); 55 | #elif HV_SIMD_SSE 56 | if (reverse) o->v = _mm_setr_epi32(k+3*step, k+2*step, k+step, k); 57 | else o->v = _mm_set_epi32(k+3*step, k+2*step, k+step, k); 58 | #elif HV_SIMD_NEON 59 | if (reverse) o->v = (int32x4_t) {3*step+k, 2*step+k, step+k, k}; 60 | else o->v = (int32x4_t) {k, step+k, 2*step+k, 3*step+k}; 61 | #else // HV_SIMD_NEON 62 | o->v = k; 63 | #endif 64 | } 65 | 66 | hv_size_t sVari_init(SignalVari *o, int k, int step, bool reverse) { 67 | sVari_update(o, k, step, reverse); 68 | return 0; 69 | } 70 | 71 | void sVari_onMessage(HeavyContextInterface *_c, SignalVari *o, const HvMessage *m) { 72 | if (msg_isFloat(m,0)) { 73 | sVari_update(o, (int) msg_getFloat(m,0), msg_isFloat(m,1) ? (int) msg_getFloat(m,1) : 0, msg_getNumElements(m) == 3); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /main/heavy/HvSignalLine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _SIGNAL_LINE_H_ 18 | #define _SIGNAL_LINE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct SignalLine { 27 | #if HV_SIMD_AVX 28 | __m128i n; // remaining samples to target 29 | #else 30 | hv_bufferi_t n; // remaining samples to target 31 | #endif 32 | hv_bufferf_t x; // current output 33 | hv_bufferf_t m; // increment 34 | hv_bufferf_t t; // target value 35 | } SignalLine; 36 | 37 | hv_size_t sLine_init(SignalLine *o); 38 | 39 | static inline void __hv_line_f(SignalLine *o, hv_bOutf_t bOut) { 40 | #if HV_SIMD_AVX 41 | __m128i n = o->n; 42 | __m128i masklo = _mm_cmplt_epi32(n, _mm_setzero_si128()); // n < 0 43 | n = _mm_sub_epi32(n, _mm_set1_epi32(4)); // subtract HV_N_SIMD from remaining samples 44 | __m128i maskhi = _mm_cmplt_epi32(n, _mm_setzero_si128()); 45 | o->n = _mm_sub_epi32(n, _mm_set1_epi32(4)); 46 | __m256 mask = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_castsi128_ps(masklo)), _mm_castsi128_ps(maskhi), 1); 47 | 48 | __m256 x = o->x; 49 | *bOut = _mm256_or_ps(_mm256_and_ps(mask, o->t), _mm256_andnot_ps(mask, x)); 50 | 51 | // add slope from sloped samples 52 | o->x = _mm256_add_ps(x, o->m); 53 | #elif HV_SIMD_SSE 54 | __m128i n = o->n; 55 | __m128 mask = _mm_castsi128_ps(_mm_cmplt_epi32(n, _mm_setzero_si128())); // n < 0 56 | 57 | __m128 x = o->x; 58 | *bOut = _mm_or_ps(_mm_and_ps(mask, o->t), _mm_andnot_ps(mask, x)); 59 | 60 | // subtract HV_N_SIMD from remaining samples 61 | o->n = _mm_sub_epi32(n, _mm_set1_epi32(HV_N_SIMD)); 62 | 63 | // add slope from sloped samples 64 | o->x = _mm_add_ps(x, o->m); 65 | #elif HV_SIMD_NEON 66 | int32x4_t n = o->n; 67 | int32x4_t mask = vreinterpretq_s32_u32(vcltq_s32(n, vdupq_n_s32(0))); 68 | float32x4_t x = o->x; 69 | *bOut = vreinterpretq_f32_s32(vorrq_s32( 70 | vandq_s32(mask, vreinterpretq_s32_f32(o->t)), 71 | vbicq_s32(vreinterpretq_s32_f32(x), mask))); 72 | o->n = vsubq_s32(n, vdupq_n_s32(HV_N_SIMD)); 73 | o->x = vaddq_f32(x, o->m); 74 | #else // HV_SIMD_NONE 75 | *bOut = (o->n < 0) ? o->t : o->x; 76 | o->n -= HV_N_SIMD; 77 | o->x += o->m; 78 | #endif 79 | } 80 | 81 | void sLine_onMessage(HeavyContextInterface *_c, SignalLine *o, int letIndex, 82 | const HvMessage *m, void *sendMessage); 83 | 84 | #ifdef __cplusplus 85 | } // extern "C" 86 | #endif 87 | 88 | #endif // _SIGNAL_LINE_H_ 89 | -------------------------------------------------------------------------------- /main/WM8978.h: -------------------------------------------------------------------------------- 1 | #ifndef __WM8978_H 2 | #define __WM8978_H 3 | 4 | #include 5 | #include 6 | #include "esp_types.h" 7 | #include "esp_err.h" 8 | 9 | #define I2C_MASTER_NUM 1 /*!< I2C port number for master dev */ 10 | #define I2C_MASTER_SCL_IO 32 // * 18 11 | #define I2C_MASTER_SDA_IO 33 // * 19 12 | #define I2C_MASTER_FREQ_HZ 100000 13 | #define I2C_MASTER_TX_BUF_DISABLE 0 14 | #define I2C_MASTER_RX_BUF_DISABLE 0 15 | 16 | #define WM8978_ADDR 0X1A //WM8978 0X1B -> WM8978.2 17 | 18 | #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ 19 | #define ACK_CHECK_EN 0x1 20 | 21 | #define EQ1_80Hz 0X00 22 | #define EQ1_105Hz 0X01 23 | #define EQ1_135Hz 0X02 24 | #define EQ1_175Hz 0X03 25 | 26 | #define EQ2_230Hz 0X00 27 | #define EQ2_300Hz 0X01 28 | #define EQ2_385Hz 0X02 29 | #define EQ2_500Hz 0X03 30 | 31 | #define EQ3_650Hz 0X00 32 | #define EQ3_850Hz 0X01 33 | #define EQ3_1100Hz 0X02 34 | #define EQ3_14000Hz 0X03 35 | 36 | #define EQ4_1800Hz 0X00 37 | #define EQ4_2400Hz 0X01 38 | #define EQ4_3200Hz 0X02 39 | #define EQ4_4100Hz 0X03 40 | 41 | #define EQ5_5300Hz 0X00 42 | #define EQ5_6900Hz 0X01 43 | #define EQ5_9000Hz 0X02 44 | #define EQ5_11700Hz 0X03 45 | 46 | class WM8978 47 | { 48 | public: 49 | uint8_t init(uint8_t id); 50 | void initI2C(void); 51 | void addaCfg(uint8_t dacen,uint8_t adcen); 52 | void inputCfg(uint8_t micen,uint8_t lineinen,uint8_t auxen); 53 | void outputCfg(uint8_t dacen,uint8_t bpsen); 54 | void micGain(uint8_t gain); 55 | void lineinGain(uint8_t gain); 56 | void auxGain(uint8_t gain); 57 | uint8_t writeReg(uint8_t reg,uint16_t val); 58 | esp_err_t writeRegwithError(uint8_t reg,uint8_t val); 59 | uint16_t readReg(uint8_t reg); 60 | void hpVolSet(uint8_t voll,uint8_t volr); 61 | void spkVolSet(uint8_t volx); 62 | void i2sCfg(uint8_t fmt,uint8_t len); 63 | void threeDSet(uint8_t depth); 64 | void eq3DDir(uint8_t dir); 65 | void eq1Set(uint8_t cfreq,uint8_t gain); 66 | void eq2Set(uint8_t cfreq,uint8_t gain); 67 | void eq3Set(uint8_t cfreq,uint8_t gain); 68 | void eq4Set(uint8_t cfreq,uint8_t gain); 69 | void eq5Set(uint8_t cfreq,uint8_t gain); 70 | void noiseSet(uint8_t enable,uint8_t gain); 71 | void alcSet(uint8_t enable, uint8_t maxgain, uint8_t mingain); 72 | 73 | void setLeftLineIn(int32_t LRINBOTH, int32_t LINMUTE, float LINVOL); 74 | void setRightLineIn(int32_t RLINBOTH, int32_t RINMUTE, float RINVOL); 75 | void setLeftHeadphoneOut(int32_t LRHPBOTH, int32_t LZCEN, int32_t LHPVOL); 76 | void setRightHeadphoneOut(int32_t RLHPBOTH, int32_t RZCEN, int32_t RHPVOL); 77 | void setAnalogueAudioPathControl(int32_t SIDEATT, int32_t SIDETONE, int32_t DACSEL, int32_t BYPASS, int32_t INSEL, int32_t MUTEMIC, int32_t MICBOOST); 78 | void setDigitalAudioPathControl(int32_t HPOR, int32_t DACMU, int32_t DEEMP, int32_t ADCHPD); 79 | void setPowerDownControl(int32_t POWEROFF, int32_t CLKOUTPD, int32_t OSCPD, int32_t OUTPD, int32_t DACPD, int32_t ADCPD, int32_t MICPD, int32_t LINEINPD); 80 | void setDigitalAudioInterfaceFormat(int32_t BCLKINV, int32_t MS, int32_t LRSWAP, int32_t LRP, int32_t IWL, int32_t FORMAT); 81 | void setSamplingControl(int32_t CLKODIV2, int32_t CLKIDIV2, int32_t SR, int32_t BOSR, int32_t USBNORM); 82 | void setActiveControl(int32_t ACTIVE); 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /main/heavy/Heavy_heavy.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020 Enzien Audio, Ltd. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions, and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the phrase "powered by heavy", 11 | * the heavy logo, and a hyperlink to https://enzienaudio.com, all in a visible 12 | * form. 13 | * 14 | * 2.1 If the Application is distributed in a store system (for example, 15 | * the Apple "App Store" or "Google Play"), the phrase "powered by heavy" 16 | * shall be included in the app description or the copyright text as well as 17 | * the in the app itself. The heavy logo will shall be visible in the app 18 | * itself as well. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | 33 | #ifndef _HEAVY_HEAVY_H_ 34 | #define _HEAVY_HEAVY_H_ 35 | 36 | #include "HvHeavy.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #if HV_APPLE 43 | #pragma mark - Heavy Context 44 | #endif 45 | 46 | typedef enum { 47 | HV_HEAVY_PARAM_IN_POT1 = 0x3AE704A5, // pot1 48 | HV_HEAVY_PARAM_IN_POT2 = 0xDDC4EBDB, // pot2 49 | HV_HEAVY_PARAM_IN_POT5 = 0xF2BC7D02, // pot5 50 | } Hv_heavy_ParameterIn; 51 | 52 | 53 | /** 54 | * Creates a new patch instance. 55 | * Sample rate should be positive and in Hertz, e.g. 44100.0. 56 | */ 57 | HeavyContextInterface *hv_heavy_new(double sampleRate); 58 | 59 | /** 60 | * Creates a new patch instance. 61 | * @param sampleRate Sample rate should be positive (> 0) and in Hertz, e.g. 48000.0. 62 | * @param poolKb Pool size is in kilobytes, and determines the maximum amount of memory 63 | * allocated to messages at any time. By default this is 10 KB. 64 | * @param inQueueKb The size of the input message queue in kilobytes. It determines the 65 | * amount of memory dedicated to holding scheduled messages between calls to 66 | * process(). Default is 2 KB. 67 | * @param outQueueKb The size of the output message queue in kilobytes. It determines the 68 | * amount of memory dedicated to holding scheduled messages to the default sendHook. 69 | * See getNextSentMessage() for info on accessing these messages. Default is 0 KB. 70 | */ 71 | HeavyContextInterface *hv_heavy_new_with_options(double sampleRate, int poolKb, int inQueueKb, int outQueueKb); 72 | 73 | #ifdef __cplusplus 74 | } // extern "C" 75 | #endif 76 | 77 | #endif // _HEAVY_HEAVY_H_ 78 | -------------------------------------------------------------------------------- /main/heavy/HvSignalVar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_SIGNAL_VAR_H_ 18 | #define _HEAVY_SIGNAL_VAR_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | // __var~f, __varread~f, __varwrite~f 27 | 28 | typedef struct SignalVarf { 29 | hv_bufferf_t v; 30 | } SignalVarf; 31 | 32 | hv_size_t sVarf_init(SignalVarf *o, float k, float step, bool reverse); 33 | 34 | static inline void __hv_varread_f(SignalVarf *o, hv_bOutf_t bOut) { 35 | *bOut = o->v; 36 | } 37 | 38 | static inline void __hv_varwrite_f(SignalVarf *o, hv_bInf_t bIn) { 39 | o->v = bIn; 40 | } 41 | 42 | void sVarf_onMessage(HeavyContextInterface *_c, SignalVarf *o, const HvMessage *m); 43 | 44 | 45 | 46 | // __var~i, __varread~i, __varwrite~i 47 | 48 | typedef struct SignalVari { 49 | hv_bufferi_t v; 50 | } SignalVari; 51 | 52 | hv_size_t sVari_init(SignalVari *o, int k, int step, bool reverse); 53 | 54 | static inline void __hv_varread_i(SignalVari *o, hv_bOuti_t bOut) { 55 | *bOut = o->v; 56 | } 57 | 58 | static inline void __hv_varwrite_i(SignalVari *o, hv_bIni_t bIn) { 59 | o->v = bIn; 60 | } 61 | 62 | void sVari_onMessage(HeavyContextInterface *_c, SignalVari *o, const HvMessage *m); 63 | 64 | 65 | 66 | // __var_k~f, __var_k~i 67 | 68 | #if HV_SIMD_AVX 69 | #define __hv_var_k_i(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm256_set_epi32(_h,_g,_f,_e,_d,_c,_b,_a) 70 | #define __hv_var_k_i_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm256_set_epi32(_a,_b,_c,_d,_e,_f,_g,_h) 71 | #define __hv_var_k_f(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm256_set_ps(_h,_g,_f,_e,_d,_c,_b,_a) 72 | #define __hv_var_k_f_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm256_set_ps(_a,_b,_c,_d,_e,_f,_g,_h) 73 | #elif HV_SIMD_SSE 74 | #define __hv_var_k_i(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm_set_epi32(_d,_c,_b,_a) 75 | #define __hv_var_k_i_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm_set_epi32(_a,_b,_c,_d) 76 | #define __hv_var_k_f(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm_set_ps(_d,_c,_b,_a) 77 | #define __hv_var_k_f_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_mm_set_ps(_a,_b,_c,_d) 78 | #elif HV_SIMD_NEON 79 | #define __hv_var_k_i(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((int32x4_t) {_a,_b,_c,_d}) 80 | #define __hv_var_k_i_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((int32x4_t) {_d,_c,_b,_a}) 81 | #define __hv_var_k_f(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((float32x4_t) {_a,_b,_c,_d}) 82 | #define __hv_var_k_f_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((float32x4_t) {_d,_c,_b,_a}) 83 | #else // HV_SIMD_NONE 84 | #define __hv_var_k_i(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a 85 | #define __hv_var_k_i_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a 86 | #define __hv_var_k_f(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a 87 | #define __hv_var_k_f_r(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a 88 | #endif 89 | 90 | #ifdef __cplusplus 91 | } // extern "C" 92 | #endif 93 | 94 | #endif // _HEAVY_SIGNAL_VAR_H_ 95 | -------------------------------------------------------------------------------- /main/heavy/HvMessageQueue.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _MESSAGE_QUEUE_H_ 18 | #define _MESSAGE_QUEUE_H_ 19 | 20 | #include "HvMessage.h" 21 | #include "HvMessagePool.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | class HeavyContextInterface; 29 | #else 30 | typedef struct HeavyContextInterface HeavyContextInterface; 31 | #endif 32 | 33 | typedef struct MessageNode { 34 | struct MessageNode *prev; // doubly linked list 35 | struct MessageNode *next; 36 | HvMessage *m; 37 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *); 38 | int let; 39 | } MessageNode; 40 | 41 | /** A doubly linked list containing scheduled messages. */ 42 | typedef struct HvMessageQueue { 43 | MessageNode *head; // the head of the queue 44 | MessageNode *tail; // the tail of the queue 45 | MessageNode *pool; // the head of the reserve pool 46 | HvMessagePool mp; 47 | } HvMessageQueue; 48 | 49 | hv_size_t mq_initWithPoolSize(HvMessageQueue *q, hv_size_t poolSizeKB); 50 | 51 | void mq_free(HvMessageQueue *q); 52 | 53 | int mq_size(HvMessageQueue *q); 54 | 55 | static inline HvMessage *mq_node_getMessage(MessageNode *n) { 56 | return n->m; 57 | } 58 | 59 | static inline int mq_node_getLet(MessageNode *n) { 60 | return n->let; 61 | } 62 | 63 | static inline bool mq_hasMessage(HvMessageQueue *q) { 64 | return (q->head != NULL); 65 | } 66 | 67 | // true if there is a message and it occurs before (<) timestamp 68 | static inline bool mq_hasMessageBefore(HvMessageQueue *const q, const hv_uint32_t timestamp) { 69 | return mq_hasMessage(q) && (msg_getTimestamp(mq_node_getMessage(q->head)) < timestamp); 70 | } 71 | 72 | static inline MessageNode *mq_peek(HvMessageQueue *q) { 73 | return q->head; 74 | } 75 | 76 | /** Appends the message to the end of the queue. */ 77 | HvMessage *mq_addMessage(HvMessageQueue *q, const HvMessage *m, int let, 78 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 79 | 80 | /** Insert in ascending order the message acccording to its timestamp. */ 81 | HvMessage *mq_addMessageByTimestamp(HvMessageQueue *q, const HvMessage *m, int let, 82 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 83 | 84 | /** Pop the message at the head of the queue (and free its memory). */ 85 | void mq_pop(HvMessageQueue *q); 86 | 87 | /** Remove a message from the queue (and free its memory) */ 88 | bool mq_removeMessage(HvMessageQueue *q, HvMessage *m, 89 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 90 | 91 | /** Clears (and frees) all messages in the queue. */ 92 | void mq_clear(HvMessageQueue *q); 93 | 94 | /** Removes all messages occuring at or after the given timestamp. */ 95 | void mq_clearAfter(HvMessageQueue *q, const hv_uint32_t timestamp); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif // _MESSAGE_QUEUE_H_ 102 | -------------------------------------------------------------------------------- /main/heavy/HvLightPipe.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_LIGHTPIPE_H_ 18 | #define _HEAVY_LIGHTPIPE_H_ 19 | 20 | #include "HvUtils.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * This pipe assumes that there is only one producer thread and one consumer 28 | * thread. This data structure does not support any other configuration. 29 | */ 30 | typedef struct HvLightPipe { 31 | char *buffer; 32 | char *writeHead; 33 | char *readHead; 34 | hv_uint32_t len; 35 | hv_uint32_t remainingBytes; // total bytes from write head to end 36 | } HvLightPipe; 37 | 38 | /** 39 | * Initialise the pipe with a given length, in bytes. 40 | * @return Returns the size of the pipe in bytes. 41 | */ 42 | hv_uint32_t hLp_init(HvLightPipe *q, hv_uint32_t numBytes); 43 | 44 | /** 45 | * Frees the internal buffer. 46 | * @param q The light pipe. 47 | */ 48 | void hLp_free(HvLightPipe *q); 49 | 50 | /** 51 | * Indicates if data is available for reading. 52 | * @param q The light pipe. 53 | * 54 | * @return Returns the number of bytes available for reading. Zero if no bytes 55 | * are available. 56 | */ 57 | hv_uint32_t hLp_hasData(HvLightPipe *q); 58 | 59 | /** 60 | * Returns a pointer to a location in the pipe where numBytes can be written. 61 | * 62 | * @param numBytes The number of bytes to be written. 63 | * @return A pointer to a location where those bytes can be written. Returns 64 | * NULL if no more space is available. Successive calls to this 65 | * function may eventually return a valid pointer because the readhead 66 | * has been advanced on another thread. 67 | */ 68 | char *hLp_getWriteBuffer(HvLightPipe *q, hv_uint32_t numBytes); 69 | 70 | /** 71 | * Indicates to the pipe how many bytes have been written. 72 | * 73 | * @param numBytes The number of bytes written. In general this should be the 74 | * same value as was passed to the preceeding call to 75 | * hLp_getWriteBuffer(). 76 | */ 77 | void hLp_produce(HvLightPipe *q, hv_uint32_t numBytes); 78 | 79 | /** 80 | * Returns the current read buffer, indicating the number of bytes available 81 | * for reading. 82 | * @param q The light pipe. 83 | * @param numBytes This value will be filled with the number of bytes available 84 | * for reading. 85 | * 86 | * @return A pointer to the read buffer. 87 | */ 88 | char *hLp_getReadBuffer(HvLightPipe *q, hv_uint32_t *numBytes); 89 | 90 | /** 91 | * Indicates that the next set of bytes have been read and are no longer needed. 92 | * @param q The light pipe. 93 | */ 94 | void hLp_consume(HvLightPipe *q); 95 | 96 | // resets the queue to it's initialised state 97 | // This should be done when only one thread is accessing the pipe. 98 | void hLp_reset(HvLightPipe *q); 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif // _HEAVY_LIGHTPIPE_H_ 105 | -------------------------------------------------------------------------------- /main/heavy/HvControlDelay.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlDelay.h" 18 | 19 | hv_size_t cDelay_init(HeavyContextInterface *_c, ControlDelay *o, float delayMs) { 20 | o->delay = hv_millisecondsToSamples(_c, delayMs); 21 | hv_memclear(o->msgs, __HV_DELAY_MAX_MESSAGES*sizeof(HvMessage *)); 22 | return 0; 23 | } 24 | 25 | void cDelay_onMessage(HeavyContextInterface *_c, ControlDelay *o, int letIn, const HvMessage *m, 26 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 27 | switch (letIn) { 28 | case 0: { 29 | if (msg_compareSymbol(m, 0, "flush")) { 30 | // send all messages immediately 31 | for (int i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) { 32 | HvMessage *n = o->msgs[i]; 33 | if (n != NULL) { 34 | msg_setTimestamp(n, msg_getTimestamp(m)); // update the timestamp to now 35 | sendMessage(_c, 0, n); // send the message 36 | hv_cancelMessage(_c, n, sendMessage); // then clear it 37 | // NOTE(mhroth): there may be a problem here if a flushed message causes a clear message to return 38 | // to this object in the same step 39 | } 40 | } 41 | hv_memclear(o->msgs, __HV_DELAY_MAX_MESSAGES*sizeof(HvMessage *)); 42 | } else if (msg_compareSymbol(m, 0, "clear")) { 43 | // cancel (clear) all (pending) messages 44 | for (int i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) { 45 | HvMessage *n = o->msgs[i]; 46 | if (n != NULL) { 47 | hv_cancelMessage(_c, n, sendMessage); 48 | } 49 | } 50 | hv_memclear(o->msgs, __HV_DELAY_MAX_MESSAGES*sizeof(HvMessage *)); 51 | } else { 52 | hv_uint32_t ts = msg_getTimestamp(m); 53 | msg_setTimestamp((HvMessage *) m, ts+o->delay); // update the timestamp to set the delay 54 | int i; 55 | for (i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) { 56 | if (o->msgs[i] == NULL) { 57 | o->msgs[i] = hv_scheduleMessageForObject(_c, m, sendMessage, 0); 58 | break; 59 | } 60 | } 61 | hv_assert((i < __HV_DELAY_MAX_MESSAGES) && // scheduled message limit reached 62 | "[__delay] cannot track any more messages. Try increasing the size of __HV_DELAY_MAX_MESSAGES."); 63 | msg_setTimestamp((HvMessage *) m, ts); // return to the original timestamp 64 | } 65 | break; 66 | } 67 | case 1: { 68 | if (msg_isFloat(m,0)) { 69 | // set delay in milliseconds (cannot be negative!) 70 | o->delay = hv_millisecondsToSamples(_c, msg_getFloat(m,0)); 71 | } 72 | break; 73 | } 74 | case 2: { 75 | if (msg_isFloat(m,0)) { 76 | // set delay in samples (cannot be negative!) 77 | o->delay = (hv_uint32_t) hv_max_f(0.0f, msg_getFloat(m,0)); 78 | } 79 | break; 80 | } 81 | default: break; 82 | } 83 | } 84 | 85 | void cDelay_clearExecutingMessage(ControlDelay *o, const HvMessage *m) { 86 | for (int i = 0; i < __HV_DELAY_MAX_MESSAGES; ++i) { 87 | if (o->msgs[i] == m) { 88 | o->msgs[i] = NULL; 89 | break; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /main/heavy/HvSignalRPole.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _SIGNAL_RPOLE_H_ 18 | #define _SIGNAL_RPOLE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | #include "HvSignalDel1.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | // implements y[n] = x[n] - a*y[n-1] 28 | // H(z) = 1/(1+a*z^-1) 29 | typedef struct SignalRPole { 30 | #if HV_SIMD_AVX 31 | SignalDel1 sDel1_fxiLN; 32 | SignalDel1 sDel1_kjkpV; 33 | SignalDel1 sDel1_dkIWc; 34 | SignalDel1 sDel1_bVeoW; 35 | SignalDel1 sDel1_PulZn; 36 | SignalDel1 sDel1_yTFig; 37 | SignalDel1 sDel1_Is9Qf; 38 | SignalDel1 sDel1_LIyNt; 39 | SignalDel1 sDel1_VqpU3; 40 | SignalDel1 sDel1_ZVYeg; 41 | SignalDel1 sDel1_IVAZh; 42 | SignalDel1 sDel1_F8WrY; 43 | SignalDel1 sDel1_rkFMy; 44 | SignalDel1 sDel1_BeqSK; 45 | hv_bufferf_t ym; 46 | #elif HV_SIMD_SSE || HV_SIMD_NEON 47 | SignalDel1 sDel1_i8Twk; 48 | SignalDel1 sDel1_KYibU; 49 | SignalDel1 sDel1_spa5V; 50 | SignalDel1 sDel1_3HXdb; 51 | SignalDel1 sDel1_Aj1oK; 52 | SignalDel1 sDel1_jNX1g; 53 | hv_bufferf_t ym; 54 | #else 55 | hv_bufferf_t ym; 56 | #endif 57 | } SignalRPole; 58 | 59 | hv_size_t sRPole_init(SignalRPole *o); 60 | 61 | void sRPole_onMessage(HeavyContextInterface *_c, SignalRPole *o, int letIn, const HvMessage *m); 62 | 63 | static inline void __hv_rpole_f(SignalRPole *o, hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) { 64 | #if HV_SIMD_AVX 65 | hv_bufferf_t a, b, c, d, e, f, g, i, j, k, l, m, n; 66 | __hv_del1_f(&o->sDel1_fxiLN, bIn1, &a); 67 | __hv_mul_f(bIn1, a, &b); 68 | __hv_del1_f(&o->sDel1_kjkpV, a, &a); 69 | __hv_mul_f(b, a, &c); 70 | __hv_del1_f(&o->sDel1_dkIWc, a, &a); 71 | __hv_mul_f(c, a, &d); 72 | __hv_del1_f(&o->sDel1_bVeoW, a, &a); 73 | __hv_mul_f(d, a, &e); 74 | __hv_del1_f(&o->sDel1_PulZn, a, &a); 75 | __hv_mul_f(e, a, &f); 76 | __hv_del1_f(&o->sDel1_yTFig, a, &a); 77 | __hv_mul_f(f, a, &g); 78 | __hv_del1_f(&o->sDel1_Is9Qf, a, &a); 79 | __hv_mul_f(g, a, &a); 80 | __hv_del1_f(&o->sDel1_LIyNt, bIn0, &i); 81 | __hv_del1_f(&o->sDel1_VqpU3, i, &j); 82 | __hv_del1_f(&o->sDel1_ZVYeg, j, &k); 83 | __hv_del1_f(&o->sDel1_IVAZh, k, &l); 84 | __hv_del1_f(&o->sDel1_F8WrY, l, &m); 85 | __hv_del1_f(&o->sDel1_rkFMy, m, &n); 86 | __hv_mul_f(i, bIn1, &i); 87 | __hv_sub_f(bIn0, i, &i); 88 | __hv_fma_f(j, b, i, &i); 89 | __hv_mul_f(k, c, &c); 90 | __hv_sub_f(i, c, &c); 91 | __hv_fma_f(l, d, c, &c); 92 | __hv_mul_f(m, e, &e); 93 | __hv_sub_f(c, e, &e); 94 | __hv_fma_f(n, f, e, &e); 95 | __hv_del1_f(&o->sDel1_BeqSK, n, &n); 96 | __hv_mul_f(n, g, &g); 97 | __hv_sub_f(e, g, &g); 98 | __hv_fma_f(a, o->ym, g, &g); 99 | o->ym = g; 100 | *bOut = g; 101 | #elif HV_SIMD_SSE || HV_SIMD_NEON 102 | hv_bufferf_t a, b, c, e, f; 103 | __hv_del1_f(&o->sDel1_i8Twk, bIn1, &a); 104 | __hv_mul_f(bIn1, a, &b); 105 | __hv_del1_f(&o->sDel1_KYibU, a, &a); 106 | __hv_mul_f(b, a, &c); 107 | __hv_del1_f(&o->sDel1_spa5V, a, &a); 108 | __hv_mul_f(c, a, &a); 109 | __hv_del1_f(&o->sDel1_3HXdb, bIn0, &e); 110 | __hv_del1_f(&o->sDel1_Aj1oK, e, &f); 111 | __hv_mul_f(e, bIn1, &e); 112 | __hv_sub_f(bIn0, e, &e); 113 | __hv_fma_f(f, b, e, &e); 114 | __hv_del1_f(&o->sDel1_jNX1g, f, &f); 115 | __hv_mul_f(f, c, &c); 116 | __hv_sub_f(e, c, &c); 117 | __hv_fma_f(a, o->ym, c, &c); 118 | o->ym = c; 119 | *bOut = c; 120 | #else 121 | *bOut = bIn0 - bIn1 * o->ym; 122 | o->ym = *bOut; 123 | #endif 124 | } 125 | 126 | #ifdef __cplusplus 127 | } // extern "C" 128 | #endif 129 | 130 | #endif // _SIGNAL_RPOLE_H_ 131 | -------------------------------------------------------------------------------- /main/heavy/HvControlBinop.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvControlBinop.h" 18 | 19 | hv_size_t cBinop_init(ControlBinop *o, float k) { 20 | o->k = k; 21 | return 0; 22 | } 23 | 24 | static float cBinop_perform_op(BinopType op, float f, float k) { 25 | switch (op) { 26 | case HV_BINOP_ADD: return f + k; 27 | case HV_BINOP_SUBTRACT: return f - k; 28 | case HV_BINOP_MULTIPLY: return f * k; 29 | case HV_BINOP_DIVIDE: return (k != 0.0f) ? (f/k) : 0.0f; 30 | case HV_BINOP_INT_DIV: { 31 | const int ik = (int) k; 32 | return (ik != 0) ? (float) (((int) f) / ik) : 0.0f; 33 | } 34 | case HV_BINOP_MOD_BIPOLAR: { 35 | const int ik = (int) k; 36 | return (ik != 0) ? (float) (((int) f) % ik) : 0.0f; 37 | } 38 | case HV_BINOP_MOD_UNIPOLAR: { 39 | f = (k == 0.0f) ? 0.0f : (float) ((int) f % (int) k); 40 | return (f < 0.0f) ? f + hv_abs_f(k) : f; 41 | } 42 | case HV_BINOP_BIT_LEFTSHIFT: return (float) (((int) f) << ((int) k)); 43 | case HV_BINOP_BIT_RIGHTSHIFT: return (float) (((int) f) >> ((int) k)); 44 | case HV_BINOP_BIT_AND: return (float) ((int) f & (int) k); 45 | case HV_BINOP_BIT_XOR: return (float) ((int) f ^ (int) k); 46 | case HV_BINOP_BIT_OR: return (float) ((int) f | (int) k); 47 | case HV_BINOP_EQ: return (f == k) ? 1.0f : 0.0f; 48 | case HV_BINOP_NEQ: return (f != k) ? 1.0f : 0.0f; 49 | case HV_BINOP_LOGICAL_AND: return ((f == 0.0f) || (k == 0.0f)) ? 0.0f : 1.0f; 50 | case HV_BINOP_LOGICAL_OR: return ((f == 0.0f) && (k == 0.0f)) ? 0.0f : 1.0f; 51 | case HV_BINOP_LESS_THAN: return (f < k) ? 1.0f : 0.0f; 52 | case HV_BINOP_LESS_THAN_EQL: return (f <= k) ? 1.0f : 0.0f; 53 | case HV_BINOP_GREATER_THAN: return (f > k) ? 1.0f : 0.0f; 54 | case HV_BINOP_GREATER_THAN_EQL: return (f >= k) ? 1.0f : 0.0f; 55 | case HV_BINOP_MAX: return hv_max_f(f, k); 56 | case HV_BINOP_MIN: return hv_min_f(f, k); 57 | case HV_BINOP_POW: return (f > 0.0f) ? hv_pow_f(f, k) : 0.0f; 58 | case HV_BINOP_ATAN2: return ((f == 0.0f) && (k == 0.0f)) ? 0.0f : hv_atan2_f(f, k); 59 | default: return 0.0f; 60 | } 61 | } 62 | 63 | void cBinop_onMessage(HeavyContextInterface *_c, ControlBinop *o, BinopType op, int letIn, 64 | const HvMessage *m, 65 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 66 | switch (letIn) { 67 | case 0: { 68 | if (msg_isFloat(m, 0)) { 69 | // Note(joe): supporting Pd's ability to perform operations of packs 70 | // of floats is likely to not be supported in the future. 71 | if (msg_isFloat(m, 1)) o->k = msg_getFloat(m, 1); 72 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 73 | float f = cBinop_perform_op(op, msg_getFloat(m, 0), o->k); 74 | msg_initWithFloat(n, msg_getTimestamp(m), f); 75 | sendMessage(_c, 0, n); 76 | } 77 | break; 78 | } 79 | case 1: { 80 | if (msg_isFloat(m, 0)) { 81 | o->k = msg_getFloat(m, 0); 82 | } 83 | break; 84 | } 85 | default: break; 86 | } 87 | } 88 | 89 | void cBinop_k_onMessage(HeavyContextInterface *_c, void *o, BinopType op, float k, 90 | int letIn, const HvMessage *m, 91 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 92 | if (msg_isFloat(m, 0)) { 93 | // NOTE(mhroth): Heavy does not support sending bangs to binop objects to return the previous output 94 | float f = (msg_isFloat(m, 1)) ? msg_getFloat(m, 1) : k; 95 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 96 | f = cBinop_perform_op(op, msg_getFloat(m, 0), f); 97 | msg_initWithFloat(n, msg_getTimestamp(m), f); 98 | sendMessage(_c, 0, n); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /main/heavy/HeavyContext.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_CONTEXT_H_ 18 | #define _HEAVY_CONTEXT_H_ 19 | 20 | #include "HeavyContextInterface.hpp" 21 | #include "HvLightPipe.h" 22 | #include "HvMessageQueue.h" 23 | #include "HvMath.h" 24 | 25 | struct HvTable; 26 | 27 | class HeavyContext : public HeavyContextInterface { 28 | 29 | public: 30 | HeavyContext(double sampleRate, int poolKb=10, int inQueueKb=2, int outQueueKb=0); 31 | virtual ~HeavyContext(); 32 | 33 | int getSize() override { return (int) numBytes; } 34 | 35 | double getSampleRate() override { return sampleRate; } 36 | 37 | hv_uint32_t getCurrentSample() override { return blockStartTimestamp; } 38 | float samplesToMilliseconds(hv_uint32_t numSamples) override { return (float) (1000.0*numSamples/sampleRate); } 39 | hv_uint32_t millisecondsToSamples(float ms) override { return (hv_uint32_t) (hv_max_f(0.0f,ms)*sampleRate/1000.0); } 40 | 41 | void setUserData(void *x) override { userData = x; } 42 | void *getUserData() override { return userData; } 43 | 44 | // hook management 45 | void setSendHook(HvSendHook_t *f) override { sendHook = f; } 46 | HvSendHook_t *getSendHook() override { return sendHook; } 47 | 48 | void setPrintHook(HvPrintHook_t *f) override { printHook = f; } 49 | HvPrintHook_t *getPrintHook() override { return printHook; } 50 | 51 | // message scheduling 52 | bool sendMessageToReceiver(hv_uint32_t receiverHash, double delayMs, HvMessage *m) override; 53 | bool sendMessageToReceiverV(hv_uint32_t receiverHash, double delayMs, const char *fmt, ...) override; 54 | bool sendFloatToReceiver(hv_uint32_t receiverHash, float f) override; 55 | bool sendBangToReceiver(hv_uint32_t receiverHash) override; 56 | bool sendSymbolToReceiver(hv_uint32_t receiverHash, const char *symbol) override; 57 | bool cancelMessage(HvMessage *m, void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) override; 58 | 59 | // table manipulation 60 | float *getBufferForTable(hv_uint32_t tableHash) override; 61 | int getLengthForTable(hv_uint32_t tableHash) override; 62 | bool setLengthForTable(hv_uint32_t tableHash, hv_uint32_t newSampleLength) override; 63 | 64 | // lock control 65 | void lockAcquire() override; 66 | bool lockTry() override; 67 | void lockRelease() override; 68 | 69 | // message queue management 70 | void setInputMessageQueueSize(int inQueueKb) override; 71 | void setOutputMessageQueueSize(int outQueueKb) override; 72 | bool getNextSentMessage(hv_uint32_t *destinationHash, HvMessage *outMsg, hv_size_t msgLength) override; 73 | 74 | // utility functions 75 | static hv_uint32_t getHashForString(const char *str); 76 | 77 | protected: 78 | virtual HvTable *getTableForHash(hv_uint32_t tableHash) = 0; 79 | friend HvTable *_hv_table_get(HeavyContextInterface *, hv_uint32_t); 80 | 81 | virtual void scheduleMessageForReceiver(hv_uint32_t receiverHash, HvMessage *m) = 0; 82 | friend void _hv_scheduleMessageForReceiver(HeavyContextInterface *, hv_uint32_t, HvMessage *); 83 | 84 | HvMessage *scheduleMessageForObject(const HvMessage *, 85 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *), 86 | int); 87 | friend HvMessage *_hv_scheduleMessageForObject(HeavyContextInterface *, const HvMessage *, 88 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *), 89 | int); 90 | 91 | friend void defaultSendHook(HeavyContextInterface *, const char *, hv_uint32_t, const HvMessage *); 92 | 93 | // object state 94 | double sampleRate; 95 | hv_uint32_t blockStartTimestamp; 96 | hv_size_t numBytes; 97 | HvMessageQueue mq; 98 | HvSendHook_t *sendHook; 99 | HvPrintHook_t *printHook; 100 | void *userData; 101 | HvLightPipe inQueue; 102 | HvLightPipe outQueue; 103 | hv_atomic_bool inQueueLock; 104 | hv_atomic_bool outQueueLock; 105 | }; 106 | 107 | #endif // _HEAVY_CONTEXT_H_ 108 | -------------------------------------------------------------------------------- /main/heavy/HvTable.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvTable.h" 18 | #include "HvMessage.h" 19 | 20 | hv_size_t hTable_init(HvTable *o, int length) { 21 | o->length = length; 22 | // true size of the table is always an integer multple of HV_N_SIMD 23 | o->size = (length + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK; 24 | // add an extra length for mirroring 25 | o->allocated = o->size + HV_N_SIMD; 26 | o->head = 0; 27 | hv_size_t numBytes = o->allocated * sizeof(float); 28 | o->buffer = (float *) hv_malloc(numBytes); 29 | hv_assert(o->buffer != NULL); 30 | hv_memclear(o->buffer, numBytes); 31 | return numBytes; 32 | } 33 | 34 | hv_size_t hTable_initWithData(HvTable *o, int length, const float *data) { 35 | o->length = length; 36 | o->size = (length + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK; 37 | o->allocated = o->size + HV_N_SIMD; 38 | o->head = 0; 39 | hv_size_t numBytes = o->size * sizeof(float); 40 | o->buffer = (float *) hv_malloc(numBytes); 41 | hv_assert(o->buffer != NULL); 42 | hv_memclear(o->buffer, numBytes); 43 | hv_memcpy(o->buffer, data, length*sizeof(float)); 44 | return numBytes; 45 | } 46 | 47 | hv_size_t hTable_initWithFinalData(HvTable *o, int length, float *data) { 48 | o->length = length; 49 | o->size = length; 50 | o->allocated = length; 51 | o->buffer = data; 52 | o->head = 0; 53 | return 0; 54 | } 55 | 56 | void hTable_free(HvTable *o) { 57 | hv_free(o->buffer); 58 | } 59 | 60 | int hTable_resize(HvTable *o, hv_uint32_t newLength) { 61 | // TODO(mhroth): update context with memory allocated by table 62 | // NOTE(mhroth): mirrored bytes are not necessarily carried over 63 | const hv_uint32_t newSize = (newLength + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK; 64 | if (newSize == o->size) return 0; // early exit if no change in size 65 | const hv_uint32_t oldSizeBytes = (hv_uint32_t) (o->size * sizeof(float)); 66 | const hv_uint32_t newAllocated = newSize + HV_N_SIMD; 67 | const hv_uint32_t newAllocatedBytes = (hv_uint32_t) (newAllocated * sizeof(float)); 68 | 69 | float *b = (float *) hv_realloc(o->buffer, newAllocatedBytes); 70 | hv_assert(b != NULL); // error while reallocing! 71 | // ensure that hv_realloc has given us a correctly aligned buffer 72 | if ((((hv_uintptr_t) (const void *) b) & ((0x1< o->size) { 74 | hv_memclear(b + o->size, (newAllocated - o->size) * sizeof(float)); // clear new parts of the buffer 75 | } 76 | o->buffer = b; 77 | } else { 78 | // if not, we have to re-malloc ourselves 79 | char *c = (char *) hv_malloc(newAllocatedBytes); 80 | hv_assert(c != NULL); // error while allocating new buffer! 81 | if (newAllocatedBytes > oldSizeBytes) { 82 | hv_memcpy(c, b, oldSizeBytes); 83 | hv_memclear(c + oldSizeBytes, newAllocatedBytes - oldSizeBytes); 84 | } else { 85 | hv_memcpy(c, b, newAllocatedBytes); 86 | } 87 | hv_free(b); 88 | o->buffer = (float *) c; 89 | } 90 | o->length = newLength; 91 | o->size = newSize; 92 | o->allocated = newAllocated; 93 | return (int) (newAllocated - oldSizeBytes - (HV_N_SIMD*sizeof(float))); 94 | } 95 | 96 | void hTable_onMessage(HeavyContextInterface *_c, HvTable *o, int letIn, const HvMessage *m, 97 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 98 | if (msg_compareSymbol(m,0,"resize") && msg_isFloat(m,1) && msg_getFloat(m,1) >= 0.0f) { 99 | hTable_resize(o, (int) hv_ceil_f(msg_getFloat(m,1))); // apply ceil to ensure that tables always have enough space 100 | 101 | // send out the new size of the table 102 | HvMessage *n = HV_MESSAGE_ON_STACK(1); 103 | msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getSize(o)); 104 | sendMessage(_c, 0, n); 105 | } 106 | 107 | else if (msg_compareSymbol(m,0,"mirror")) { 108 | hv_memcpy(o->buffer+o->size, o->buffer, HV_N_SIMD*sizeof(float)); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/eurorack_engine.pro: -------------------------------------------------------------------------------- 1 | update=19/10/2020 22:37:08 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [cvpcb] 9 | version=1 10 | NetIExt=net 11 | [eeschema] 12 | version=1 13 | LibDir= 14 | [eeschema/libraries] 15 | [schematic_editor] 16 | version=1 17 | PageLayoutDescrFile= 18 | PlotDirectoryName= 19 | SubpartIdSeparator=0 20 | SubpartFirstId=65 21 | NetFmtName=Pcbnew 22 | SpiceAjustPassiveValues=0 23 | LabSize=50 24 | ERC_TestSimilarLabels=1 25 | [pcbnew] 26 | version=1 27 | PageLayoutDescrFile= 28 | LastNetListRead=eurorack_engine.net 29 | CopperLayerCount=2 30 | BoardThickness=1.6 31 | AllowMicroVias=0 32 | AllowBlindVias=0 33 | RequireCourtyardDefinitions=0 34 | ProhibitOverlappingCourtyards=1 35 | MinTrackWidth=0.2 36 | MinViaDiameter=0.4 37 | MinViaDrill=0.3 38 | MinMicroViaDiameter=0.2 39 | MinMicroViaDrill=0.09999999999999999 40 | MinHoleToHole=0.25 41 | TrackWidth1=0.25 42 | ViaDiameter1=0.8 43 | ViaDrill1=0.4 44 | dPairWidth1=0.2 45 | dPairGap1=0.25 46 | dPairViaGap1=0.25 47 | SilkLineWidth=0.12 48 | SilkTextSizeV=1 49 | SilkTextSizeH=1 50 | SilkTextSizeThickness=0.15 51 | SilkTextItalic=0 52 | SilkTextUpright=1 53 | CopperLineWidth=0.2 54 | CopperTextSizeV=1.5 55 | CopperTextSizeH=1.5 56 | CopperTextThickness=0.3 57 | CopperTextItalic=0 58 | CopperTextUpright=1 59 | EdgeCutLineWidth=0.05 60 | CourtyardLineWidth=0.05 61 | OthersLineWidth=0.15 62 | OthersTextSizeV=1 63 | OthersTextSizeH=1 64 | OthersTextSizeThickness=0.15 65 | OthersTextItalic=0 66 | OthersTextUpright=1 67 | SolderMaskClearance=0.051 68 | SolderMaskMinWidth=0.25 69 | SolderPasteClearance=0 70 | SolderPasteRatio=0 71 | [pcbnew/Layer.F.Cu] 72 | Name=F.Cu 73 | Type=0 74 | Enabled=1 75 | [pcbnew/Layer.In1.Cu] 76 | Name=In1.Cu 77 | Type=0 78 | Enabled=0 79 | [pcbnew/Layer.In2.Cu] 80 | Name=In2.Cu 81 | Type=0 82 | Enabled=0 83 | [pcbnew/Layer.In3.Cu] 84 | Name=In3.Cu 85 | Type=0 86 | Enabled=0 87 | [pcbnew/Layer.In4.Cu] 88 | Name=In4.Cu 89 | Type=0 90 | Enabled=0 91 | [pcbnew/Layer.In5.Cu] 92 | Name=In5.Cu 93 | Type=0 94 | Enabled=0 95 | [pcbnew/Layer.In6.Cu] 96 | Name=In6.Cu 97 | Type=0 98 | Enabled=0 99 | [pcbnew/Layer.In7.Cu] 100 | Name=In7.Cu 101 | Type=0 102 | Enabled=0 103 | [pcbnew/Layer.In8.Cu] 104 | Name=In8.Cu 105 | Type=0 106 | Enabled=0 107 | [pcbnew/Layer.In9.Cu] 108 | Name=In9.Cu 109 | Type=0 110 | Enabled=0 111 | [pcbnew/Layer.In10.Cu] 112 | Name=In10.Cu 113 | Type=0 114 | Enabled=0 115 | [pcbnew/Layer.In11.Cu] 116 | Name=In11.Cu 117 | Type=0 118 | Enabled=0 119 | [pcbnew/Layer.In12.Cu] 120 | Name=In12.Cu 121 | Type=0 122 | Enabled=0 123 | [pcbnew/Layer.In13.Cu] 124 | Name=In13.Cu 125 | Type=0 126 | Enabled=0 127 | [pcbnew/Layer.In14.Cu] 128 | Name=In14.Cu 129 | Type=0 130 | Enabled=0 131 | [pcbnew/Layer.In15.Cu] 132 | Name=In15.Cu 133 | Type=0 134 | Enabled=0 135 | [pcbnew/Layer.In16.Cu] 136 | Name=In16.Cu 137 | Type=0 138 | Enabled=0 139 | [pcbnew/Layer.In17.Cu] 140 | Name=In17.Cu 141 | Type=0 142 | Enabled=0 143 | [pcbnew/Layer.In18.Cu] 144 | Name=In18.Cu 145 | Type=0 146 | Enabled=0 147 | [pcbnew/Layer.In19.Cu] 148 | Name=In19.Cu 149 | Type=0 150 | Enabled=0 151 | [pcbnew/Layer.In20.Cu] 152 | Name=In20.Cu 153 | Type=0 154 | Enabled=0 155 | [pcbnew/Layer.In21.Cu] 156 | Name=In21.Cu 157 | Type=0 158 | Enabled=0 159 | [pcbnew/Layer.In22.Cu] 160 | Name=In22.Cu 161 | Type=0 162 | Enabled=0 163 | [pcbnew/Layer.In23.Cu] 164 | Name=In23.Cu 165 | Type=0 166 | Enabled=0 167 | [pcbnew/Layer.In24.Cu] 168 | Name=In24.Cu 169 | Type=0 170 | Enabled=0 171 | [pcbnew/Layer.In25.Cu] 172 | Name=In25.Cu 173 | Type=0 174 | Enabled=0 175 | [pcbnew/Layer.In26.Cu] 176 | Name=In26.Cu 177 | Type=0 178 | Enabled=0 179 | [pcbnew/Layer.In27.Cu] 180 | Name=In27.Cu 181 | Type=0 182 | Enabled=0 183 | [pcbnew/Layer.In28.Cu] 184 | Name=In28.Cu 185 | Type=0 186 | Enabled=0 187 | [pcbnew/Layer.In29.Cu] 188 | Name=In29.Cu 189 | Type=0 190 | Enabled=0 191 | [pcbnew/Layer.In30.Cu] 192 | Name=In30.Cu 193 | Type=0 194 | Enabled=0 195 | [pcbnew/Layer.B.Cu] 196 | Name=B.Cu 197 | Type=0 198 | Enabled=1 199 | [pcbnew/Layer.B.Adhes] 200 | Enabled=1 201 | [pcbnew/Layer.F.Adhes] 202 | Enabled=1 203 | [pcbnew/Layer.B.Paste] 204 | Enabled=1 205 | [pcbnew/Layer.F.Paste] 206 | Enabled=1 207 | [pcbnew/Layer.B.SilkS] 208 | Enabled=1 209 | [pcbnew/Layer.F.SilkS] 210 | Enabled=1 211 | [pcbnew/Layer.B.Mask] 212 | Enabled=1 213 | [pcbnew/Layer.F.Mask] 214 | Enabled=1 215 | [pcbnew/Layer.Dwgs.User] 216 | Enabled=1 217 | [pcbnew/Layer.Cmts.User] 218 | Enabled=1 219 | [pcbnew/Layer.Eco1.User] 220 | Enabled=1 221 | [pcbnew/Layer.Eco2.User] 222 | Enabled=1 223 | [pcbnew/Layer.Edge.Cuts] 224 | Enabled=1 225 | [pcbnew/Layer.Margin] 226 | Enabled=1 227 | [pcbnew/Layer.B.CrtYd] 228 | Enabled=1 229 | [pcbnew/Layer.F.CrtYd] 230 | Enabled=1 231 | [pcbnew/Layer.B.Fab] 232 | Enabled=1 233 | [pcbnew/Layer.F.Fab] 234 | Enabled=1 235 | [pcbnew/Layer.Rescue] 236 | Enabled=0 237 | [pcbnew/Netclasses] 238 | [pcbnew/Netclasses/Default] 239 | Name=Default 240 | Clearance=0.2 241 | TrackWidth=0.25 242 | ViaDiameter=0.8 243 | ViaDrill=0.4 244 | uViaDiameter=0.3 245 | uViaDrill=0.1 246 | dPairWidth=0.2 247 | dPairGap=0.25 248 | dPairViaGap=0.25 249 | -------------------------------------------------------------------------------- /main/heavy/HvMessagePool.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvMessagePool.h" 18 | #include "HvMessage.h" 19 | 20 | // the number of bytes reserved at a time from the pool 21 | #define MP_BLOCK_SIZE_BYTES 512 22 | 23 | #if HV_APPLE 24 | #pragma mark - MessageList 25 | #endif 26 | 27 | typedef struct MessageListNode { 28 | char *p; 29 | struct MessageListNode *next; 30 | } MessageListNode; 31 | 32 | static inline bool ml_hasAvailable(HvMessagePoolList *ml) { 33 | return (ml->head != NULL); 34 | } 35 | 36 | static char *ml_pop(HvMessagePoolList *ml) { 37 | MessageListNode *n = ml->head; 38 | ml->head = n->next; 39 | n->next = ml->pool; 40 | ml->pool = n; 41 | char *const p = n->p; 42 | n->p = NULL; // set to NULL to make it clear that this node does not have a valid buffer 43 | return p; 44 | } 45 | 46 | /** Push a MessageListNode with the given pointer onto the head of the queue. */ 47 | static void ml_push(HvMessagePoolList *ml, void *p) { 48 | MessageListNode *n = NULL; 49 | if (ml->pool != NULL) { 50 | // take an empty MessageListNode from the pool 51 | n = ml->pool; 52 | ml->pool = n->next; 53 | } else { 54 | // a MessageListNode is not available, allocate one 55 | n = (MessageListNode *) hv_malloc(sizeof(MessageListNode)); 56 | hv_assert(n != NULL); 57 | } 58 | n->p = (char *) p; 59 | n->next = ml->head; 60 | ml->head = n; // push to the front of the queue 61 | } 62 | 63 | static void ml_free(HvMessagePoolList *ml) { 64 | if (ml != NULL) { 65 | while (ml_hasAvailable(ml)) { 66 | ml_pop(ml); 67 | } 68 | while (ml->pool != NULL) { 69 | MessageListNode *n = ml->pool; 70 | ml->pool = n->next; 71 | hv_free(n); 72 | } 73 | } 74 | } 75 | 76 | #if HV_APPLE 77 | #pragma mark - HvMessagePool 78 | #endif 79 | 80 | static hv_size_t mp_messagelistIndexForSize(hv_size_t byteSize) { 81 | return (hv_size_t) hv_max_i((hv_min_max_log2((hv_uint32_t) byteSize) - 5), 0); 82 | } 83 | 84 | hv_size_t mp_init(HvMessagePool *mp, hv_size_t numKB) { 85 | mp->bufferSize = numKB * 1024; 86 | mp->buffer = (char *) hv_malloc(mp->bufferSize); 87 | hv_assert(mp->buffer != NULL); 88 | mp->bufferIndex = 0; 89 | 90 | // initialise all message lists 91 | for (int i = 0; i < MP_NUM_MESSAGE_LISTS; i++) { 92 | mp->lists[i].head = NULL; 93 | mp->lists[i].pool = NULL; 94 | } 95 | 96 | return mp->bufferSize; 97 | } 98 | 99 | void mp_free(HvMessagePool *mp) { 100 | hv_free(mp->buffer); 101 | for (int i = 0; i < MP_NUM_MESSAGE_LISTS; i++) { 102 | ml_free(&mp->lists[i]); 103 | } 104 | } 105 | 106 | void mp_freeMessage(HvMessagePool *mp, HvMessage *m) { 107 | const hv_size_t b = msg_getSize(m); // the number of bytes that a message occupies in memory 108 | const hv_size_t i = mp_messagelistIndexForSize(b); // the HvMessagePoolList index in the pool 109 | HvMessagePoolList *ml = &mp->lists[i]; 110 | const hv_size_t chunkSize = 32 << i; 111 | hv_memclear(m, chunkSize); // clear the chunk, just in case 112 | ml_push(ml, m); 113 | } 114 | 115 | HvMessage *mp_addMessage(HvMessagePool *mp, const HvMessage *m) { 116 | const hv_size_t b = msg_getSize(m); 117 | // determine the message list index to allocate data from based on the msg size 118 | // smallest chunk size is 32 bytes 119 | const hv_size_t i = mp_messagelistIndexForSize(b); 120 | 121 | hv_assert(i < MP_NUM_MESSAGE_LISTS); // how many chunk sizes do we want to support? 32, 64, 128, 256 at the moment 122 | HvMessagePoolList *ml = &mp->lists[i]; 123 | const hv_size_t chunkSize = 32 << i; 124 | 125 | if (ml_hasAvailable(ml)) { 126 | char *buf = ml_pop(ml); 127 | msg_copyToBuffer(m, buf, chunkSize); 128 | return (HvMessage *) buf; 129 | } else { 130 | // if no appropriately sized buffer is immediately available, increase the size of the used buffer 131 | const hv_size_t newIndex = mp->bufferIndex + MP_BLOCK_SIZE_BYTES; 132 | hv_assert((newIndex <= mp->bufferSize) && 133 | "The message pool buffer size has been exceeded. The context cannot store more messages. " 134 | "Try using the new_with_options() initialiser with a larger pool size (default is 10KB)."); 135 | 136 | for (hv_size_t j = mp->bufferIndex; j < newIndex; j += chunkSize) { 137 | ml_push(ml, mp->buffer + j); // push new nodes onto the list with chunk pointers 138 | } 139 | mp->bufferIndex = newIndex; 140 | char *buf = ml_pop(ml); 141 | msg_copyToBuffer(m, buf, chunkSize); 142 | return (HvMessage *) buf; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /main/heavy/HvLightPipe.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvLightPipe.h" 18 | 19 | #if __SSE__ || HV_SIMD_SSE 20 | #include 21 | #define hv_sfence() _mm_sfence() 22 | #elif __arm__ || HV_SIMD_NEON 23 | #if __ARM_ACLE 24 | #include 25 | // https://msdn.microsoft.com/en-us/library/hh875058.aspx#BarrierRestrictions 26 | // http://doxygen.reactos.org/d8/d47/armintr_8h_a02be7ec76ca51842bc90d9b466b54752.html 27 | #define hv_sfence() __dmb(0xE) /* _ARM_BARRIER_ST */ 28 | #elif defined(__GNUC__) 29 | #define hv_sfence() __asm__ volatile ("dmb 0xE":::"memory") 30 | #else 31 | // http://stackoverflow.com/questions/19965076/gcc-memory-barrier-sync-synchronize-vs-asm-volatile-memory 32 | #define hv_sfence() __sync_synchronize() 33 | #endif 34 | #elif HV_WIN 35 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684208(v=vs.85).aspx 36 | #define hv_sfence() _WriteBarrier() 37 | #else 38 | #define hv_sfence() __asm__ volatile("" : : : "memory") 39 | #endif 40 | 41 | #define HLP_STOP 0 42 | #define HLP_LOOP 0xFFFFFFFF 43 | #define HLP_SET_UINT32_AT_BUFFER(a, b) (*((hv_uint32_t *) (a)) = (b)) 44 | #define HLP_GET_UINT32_AT_BUFFER(a) (*((hv_uint32_t *) (a))) 45 | 46 | hv_uint32_t hLp_init(HvLightPipe *q, hv_uint32_t numBytes) { 47 | if (numBytes > 0) { 48 | q->buffer = (char *) hv_malloc(numBytes); 49 | hv_assert(q->buffer != NULL); 50 | HLP_SET_UINT32_AT_BUFFER(q->buffer, HLP_STOP); 51 | } else { 52 | q->buffer = NULL; 53 | } 54 | q->writeHead = q->buffer; 55 | q->readHead = q->buffer; 56 | q->len = numBytes; 57 | q->remainingBytes = numBytes; 58 | return numBytes; 59 | } 60 | 61 | void hLp_free(HvLightPipe *q) { 62 | hv_free(q->buffer); 63 | } 64 | 65 | hv_uint32_t hLp_hasData(HvLightPipe *q) { 66 | hv_uint32_t x = HLP_GET_UINT32_AT_BUFFER(q->readHead); 67 | if (x == HLP_LOOP) { 68 | q->readHead = q->buffer; 69 | x = HLP_GET_UINT32_AT_BUFFER(q->readHead); 70 | } 71 | return x; 72 | } 73 | 74 | char *hLp_getWriteBuffer(HvLightPipe *q, hv_uint32_t bytesToWrite) { 75 | char *const readHead = q->readHead; 76 | char *const oldWriteHead = q->writeHead; 77 | const hv_uint32_t totalByteRequirement = bytesToWrite + 2*sizeof(hv_uint32_t); 78 | 79 | // check if there is enough space to write the data in the remaining 80 | // length of the buffer 81 | if (totalByteRequirement <= q->remainingBytes) { 82 | char *const newWriteHead = oldWriteHead + sizeof(hv_uint32_t) + bytesToWrite; 83 | 84 | // check if writing would overwrite existing data in the pipe (return NULL if so) 85 | if ((oldWriteHead < readHead) && (newWriteHead >= readHead)) return NULL; 86 | else return (oldWriteHead + sizeof(hv_uint32_t)); 87 | } else { 88 | // there isn't enough space, try looping around to the start 89 | if (totalByteRequirement <= q->len) { 90 | if ((oldWriteHead < readHead) || ((q->buffer + totalByteRequirement) > readHead)) { 91 | return NULL; // overwrite condition 92 | } else { 93 | q->writeHead = q->buffer; 94 | q->remainingBytes = q->len; 95 | HLP_SET_UINT32_AT_BUFFER(q->buffer, HLP_STOP); 96 | hv_sfence(); 97 | HLP_SET_UINT32_AT_BUFFER(oldWriteHead, HLP_LOOP); 98 | return q->buffer + sizeof(hv_uint32_t); 99 | } 100 | } else { 101 | return NULL; // there isn't enough space to write the data 102 | } 103 | } 104 | } 105 | 106 | void hLp_produce(HvLightPipe *q, hv_uint32_t numBytes) { 107 | hv_assert(q->remainingBytes >= (numBytes + 2*sizeof(hv_uint32_t))); 108 | q->remainingBytes -= (sizeof(hv_uint32_t) + numBytes); 109 | char *const oldWriteHead = q->writeHead; 110 | q->writeHead += (sizeof(hv_uint32_t) + numBytes); 111 | HLP_SET_UINT32_AT_BUFFER(q->writeHead, HLP_STOP); 112 | 113 | // save everything before this point to memory 114 | hv_sfence(); 115 | 116 | // then save this 117 | HLP_SET_UINT32_AT_BUFFER(oldWriteHead, numBytes); 118 | } 119 | 120 | char *hLp_getReadBuffer(HvLightPipe *q, hv_uint32_t *numBytes) { 121 | *numBytes = HLP_GET_UINT32_AT_BUFFER(q->readHead); 122 | char *const readBuffer = q->readHead + sizeof(hv_uint32_t); 123 | return readBuffer; 124 | } 125 | 126 | void hLp_consume(HvLightPipe *q) { 127 | hv_assert(HLP_GET_UINT32_AT_BUFFER(q->readHead) != HLP_STOP); 128 | q->readHead += sizeof(hv_uint32_t) + HLP_GET_UINT32_AT_BUFFER(q->readHead); 129 | } 130 | 131 | void hLp_reset(HvLightPipe *q) { 132 | q->writeHead = q->buffer; 133 | q->readHead = q->buffer; 134 | q->remainingBytes = q->len; 135 | memset(q->buffer, 0, q->len); 136 | } 137 | -------------------------------------------------------------------------------- /main/heavy/HvSignalPhasor.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalPhasor.h" 18 | 19 | #define HV_PHASOR_2_32 4294967296.0 20 | 21 | #if HV_SIMD_AVX 22 | static void sPhasor_updatePhase(SignalPhasor *o, float p) { 23 | o->phase = _mm256_set1_ps(p+1.0f); // o->phase is in range [1,2] 24 | #elif HV_SIMD_SSE 25 | static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) { 26 | o->phase = _mm_set1_epi32(p); 27 | #elif HV_SIMD_NEON 28 | static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) { 29 | o->phase = vdupq_n_u32(p); 30 | #else // HV_SIMD_NONE 31 | static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) { 32 | o->phase = p; 33 | #endif 34 | } 35 | 36 | // input phase is in the range of [0,1]. It is independent of o->phase. 37 | #if HV_SIMD_AVX 38 | static void sPhasor_k_updatePhase(SignalPhasor *o, float p) { 39 | o->phase = _mm256_set_ps( 40 | p+1.0f+7.0f*o->step.f2sc, p+1.0f+6.0f*o->step.f2sc, 41 | p+1.0f+5.0f*o->step.f2sc, p+1.0f+4.0f*o->step.f2sc, 42 | p+1.0f+3.0f*o->step.f2sc, p+1.0f+2.0f*o->step.f2sc, 43 | p+1.0f+o->step.f2sc, p+1.0f); 44 | 45 | // ensure that o->phase is still in range [1,2] 46 | o->phase = _mm256_or_ps(_mm256_andnot_ps( 47 | _mm256_set1_ps(-INFINITY), o->phase), _mm256_set1_ps(1.0f)); 48 | #elif HV_SIMD_SSE 49 | static void sPhasor_k_updatePhase(SignalPhasor *o, hv_uint32_t p) { 50 | o->phase = _mm_set_epi32(3*o->step.s+p, 2*o->step.s+p, o->step.s+p, p); 51 | #elif HV_SIMD_NEON 52 | static void sPhasor_k_updatePhase(SignalPhasor *o, hv_uint32_t p) { 53 | o->phase = (uint32x4_t) {p, o->step.s+p, 2*o->step.s+p, 3*o->step.s+p}; 54 | #else // HV_SIMD_NONE 55 | static void sPhasor_k_updatePhase(SignalPhasor *o, hv_uint32_t p) { 56 | o->phase = p; 57 | #endif 58 | } 59 | 60 | static void sPhasor_k_updateFrequency(SignalPhasor *o, float f, double r) { 61 | #if HV_SIMD_AVX 62 | o->step.f2sc = (float) (f/r); 63 | o->inc = _mm256_set1_ps((float) (8.0f*f/r)); 64 | sPhasor_k_updatePhase(o, o->phase[0]); 65 | #elif HV_SIMD_SSE 66 | o->step.s = (hv_int32_t) (f*(HV_PHASOR_2_32/r)); 67 | o->inc = _mm_set1_epi32(4*o->step.s); 68 | const hv_uint32_t *const p = (hv_uint32_t *) &o->phase; 69 | sPhasor_k_updatePhase(o, p[0]); 70 | #elif HV_SIMD_NEON 71 | o->step.s = (hv_int32_t) (f*(HV_PHASOR_2_32/r)); 72 | o->inc = vdupq_n_s32(4*o->step.s); 73 | sPhasor_k_updatePhase(o, vgetq_lane_u32(o->phase, 0)); 74 | #else // HV_SIMD_NONE 75 | o->step.s = (hv_int32_t) (f*(HV_PHASOR_2_32/r)); 76 | o->inc = o->step.s; 77 | // no need to update phase 78 | #endif 79 | } 80 | 81 | hv_size_t sPhasor_init(SignalPhasor *o, double samplerate) { 82 | #if HV_SIMD_AVX 83 | o->phase = _mm256_set1_ps(1.0f); 84 | o->inc = _mm256_setzero_ps(); 85 | o->step.f2sc = (float) (1.0/samplerate); 86 | #elif HV_SIMD_SSE 87 | o->phase = _mm_setzero_si128(); 88 | o->inc = _mm_setzero_si128(); 89 | o->step.f2sc = (float) (HV_PHASOR_2_32/samplerate); 90 | #elif HV_SIMD_NEON 91 | o->phase = vdupq_n_u32(0); 92 | o->inc = vdupq_n_s32(0); 93 | o->step.f2sc = (float) (HV_PHASOR_2_32/samplerate); 94 | #else // HV_SIMD_NONE 95 | o->phase = 0; 96 | o->inc = 0; 97 | o->step.f2sc = (float) (HV_PHASOR_2_32/samplerate); 98 | #endif 99 | return 0; 100 | } 101 | 102 | void sPhasor_onMessage(HeavyContextInterface *_c, SignalPhasor *o, int letIn, const HvMessage *m) { 103 | if (letIn == 1) { 104 | if (msg_isFloat(m,0)) { 105 | float p = msg_getFloat(m,0); 106 | while (p < 0.0f) p += 1.0f; // wrap phase to [0,1] 107 | while (p > 1.0f) p -= 1.0f; 108 | #if HV_SIMD_AVX 109 | sPhasor_updatePhase(o, p); 110 | #else // HV_SIMD_SSE || HV_SIMD_NEON || HV_SIMD_NONE 111 | sPhasor_updatePhase(o, (hv_uint32_t) (p * HV_PHASOR_2_32)); 112 | #endif 113 | } 114 | } 115 | } 116 | 117 | hv_size_t sPhasor_k_init(SignalPhasor *o, float frequency, double samplerate) { 118 | __hv_zero_i((hv_bOuti_t) &o->phase); 119 | sPhasor_k_updateFrequency(o, frequency, samplerate); 120 | return 0; 121 | } 122 | 123 | void sPhasor_k_onMessage(HeavyContextInterface *_c, SignalPhasor *o, int letIn, const HvMessage *m) { 124 | if (msg_isFloat(m,0)) { 125 | switch (letIn) { 126 | case 0: sPhasor_k_updateFrequency(o, msg_getFloat(m,0), hv_getSampleRate(_c)); break; 127 | case 1: { 128 | float p = msg_getFloat(m,0); 129 | while (p < 0.0f) p += 1.0f; // wrap phase to [0,1] 130 | while (p > 1.0f) p -= 1.0f; 131 | #if HV_SIMD_AVX 132 | sPhasor_k_updatePhase(o, p); 133 | #else // HV_SIMD_SSE || HV_SIMD_NEON || HV_SIMD_NONE 134 | sPhasor_k_updatePhase(o, (hv_uint32_t) (p * HV_PHASOR_2_32)); 135 | #endif 136 | break; 137 | } 138 | default: break; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /main/heavy/HvSignalLine.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalLine.h" 18 | 19 | hv_size_t sLine_init(SignalLine *o) { 20 | #if HV_SIMD_AVX 21 | o->n = _mm_setzero_si128(); 22 | o->x = _mm256_setzero_ps(); 23 | o->m = _mm256_setzero_ps(); 24 | o->t = _mm256_setzero_ps(); 25 | #elif HV_SIMD_SSE 26 | o->n = _mm_setzero_si128(); 27 | o->x = _mm_setzero_ps(); 28 | o->m = _mm_setzero_ps(); 29 | o->t = _mm_setzero_ps(); 30 | #elif HV_SIMD_NEON 31 | o->n = vdupq_n_s32(0); 32 | o->x = vdupq_n_f32(0.0f); 33 | o->m = vdupq_n_f32(0.0f); 34 | o->t = vdupq_n_f32(0.0f); 35 | #else // HV_SIMD_NONE 36 | o->n = 0; 37 | o->x = 0.0f; 38 | o->m = 0.0f; 39 | o->t = 0.0f; 40 | #endif 41 | return 0; 42 | } 43 | 44 | void sLine_onMessage(HeavyContextInterface *_c, SignalLine *o, int letIn, 45 | const HvMessage *m, void *sendMessage) { 46 | if (msg_isFloat(m,0)) { 47 | if (msg_isFloat(m,1)) { 48 | // new ramp 49 | int n = (int) hv_millisecondsToSamples(_c, msg_getFloat(m,1)); 50 | #if HV_SIMD_AVX 51 | float x = (o->n[1] > 0) ? (o->x[7] + (o->m[7]/8.0f)) : o->t[7]; // current output value 52 | float s = (msg_getFloat(m,0) - x) / ((float) n); // slope per sample 53 | o->n = _mm_set_epi32(n-3, n-2, n-1, n); 54 | o->x = _mm256_set_ps(x+7.0f*s, x+6.0f*s, x+5.0f*s, x+4.0f*s, x+3.0f*s, x+2.0f*s, x+s, x); 55 | o->m = _mm256_set1_ps(8.0f*s); 56 | o->t = _mm256_set1_ps(msg_getFloat(m,0)); 57 | #elif HV_SIMD_SSE 58 | const hv_int32_t *const on = (hv_int32_t *) &o->n; 59 | const float *const ox = (float *) &o->x; 60 | const float *const om = (float *) &o->m; 61 | const float *const ot = (float *) &o->t; 62 | 63 | float x = (on[3] > 0) ? (ox[3] + (om[3]/4.0f)) : ot[3]; 64 | float s = (msg_getFloat(m,0) - x) / ((float) n); // slope per sample 65 | o->n = _mm_set_epi32(n-3, n-2, n-1, n); 66 | o->x = _mm_set_ps(x+3.0f*s, x+2.0f*s, x+s, x); 67 | o->m = _mm_set1_ps(4.0f*s); 68 | o->t = _mm_set1_ps(msg_getFloat(m,0)); 69 | #elif HV_SIMD_NEON 70 | float x = (o->n[3] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3]; 71 | float s = (msg_getFloat(m,0) - x) / ((float) n); 72 | o->n = (int32x4_t) {n, n-1, n-2, n-3}; 73 | o->x = (float32x4_t) {x, x+s, x+2.0f*s, x+3.0f*s}; 74 | o->m = vdupq_n_f32(4.0f*s); 75 | o->t = vdupq_n_f32(msg_getFloat(m,0)); 76 | #else // HV_SIMD_NONE 77 | o->x = (o->n > 0) ? (o->x + o->m) : o->t; // new current value 78 | o->n = n; // new distance to target 79 | o->m = (msg_getFloat(m,0) - o->x) / ((float) n); // slope per sample 80 | o->t = msg_getFloat(m,0); 81 | #endif 82 | } else { 83 | // Jump to value 84 | #if HV_SIMD_AVX 85 | o->n = _mm_setzero_si128(); 86 | o->x = _mm256_set1_ps(msg_getFloat(m,0)); 87 | o->m = _mm256_setzero_ps(); 88 | o->t = _mm256_set1_ps(msg_getFloat(m,0)); 89 | #elif HV_SIMD_SSE 90 | o->n = _mm_setzero_si128(); 91 | o->x = _mm_set1_ps(msg_getFloat(m,0)); 92 | o->m = _mm_setzero_ps(); 93 | o->t = _mm_set1_ps(msg_getFloat(m,0)); 94 | #elif HV_SIMD_NEON 95 | o->n = vdupq_n_s32(0); 96 | o->x = vdupq_n_f32(msg_getFloat(m,0)); 97 | o->m = vdupq_n_f32(0.0f); 98 | o->t = vdupq_n_f32(msg_getFloat(m,0)); 99 | #else // HV_SIMD_NONE 100 | o->n = 0; 101 | o->x = msg_getFloat(m,0); 102 | o->m = 0.0f; 103 | o->t = msg_getFloat(m,0); 104 | #endif 105 | } 106 | } else if (msg_compareSymbol(m,0,"stop")) { 107 | // Stop line at current position 108 | #if HV_SIMD_AVX 109 | // note o->n[1] is a 64-bit integer; two packed 32-bit ints. We only want to know if the high int is positive, 110 | // which can be done simply by testing the long int for positiveness. 111 | float x = (o->n[1] > 0) ? (o->x[7] + (o->m[7]/8.0f)) : o->t[7]; 112 | o->n = _mm_setzero_si128(); 113 | o->x = _mm256_set1_ps(x); 114 | o->m = _mm256_setzero_ps(); 115 | o->t = _mm256_set1_ps(x); 116 | #elif HV_SIMD_SSE 117 | const hv_int32_t *const on = (hv_int32_t *) &o->n; 118 | const float *const ox = (float *) &o->x; 119 | const float *const om = (float *) &o->m; 120 | const float *const ot = (float *) &o->t; 121 | float x = (on[3] > 0) ? (ox[3] + (om[3]/4.0f)) : ot[3]; 122 | o->n = _mm_setzero_si128(); 123 | o->x = _mm_set1_ps(x); 124 | o->m = _mm_setzero_ps(); 125 | o->t = _mm_set1_ps(x); 126 | #elif HV_SIMD_NEON 127 | float x = (o->n[3] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3]; 128 | o->n = vdupq_n_s32(0); 129 | o->x = vdupq_n_f32(x); 130 | o->m = vdupq_n_f32(0.0f); 131 | o->t = vdupq_n_f32(x); 132 | #else // HV_SIMD_NONE 133 | o->n = 0; 134 | o->x += o->m; 135 | o->m = 0.0f; 136 | o->t = o->x; 137 | #endif 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/gerbers/eurorack_engine.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad (5.1.7)-1} date 10/22/20 22:30:17 3 | ; FORMAT={-:-/ absolute / inch / decimal} 4 | ; #@! TF.CreationDate,2020-10-22T22:30:17+02:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,(5.1.7)-1 6 | FMAT,2 7 | INCH 8 | T1C0.0157 9 | T2C0.0295 10 | T3C0.0315 11 | T4C0.0354 12 | T5C0.0394 13 | T6C0.0409 14 | T7C0.0433 15 | T8C0.0512 16 | T9C0.0630 17 | T10C0.0787 18 | T11C0.1260 19 | % 20 | G90 21 | G05 22 | T1 23 | X4.643Y-2.0123 24 | T2 25 | X4.79Y-2.03 26 | X4.79Y-2.08 27 | X4.79Y-2.13 28 | T3 29 | X3.23Y-3.46 30 | X3.53Y-3.46 31 | X3.94Y-3.25 32 | X4.24Y-3.25 33 | X5.16Y-1.98 34 | X5.16Y-2.1769 35 | X1.16Y-1.9 36 | X1.46Y-1.9 37 | X5.32Y-1.99 38 | X5.62Y-1.99 39 | X0.8465Y-0.9055 40 | X1.1465Y-0.9055 41 | X4.33Y-0.97 42 | X4.63Y-0.97 43 | X4.3231Y-1.12 44 | X4.52Y-1.12 45 | X4.22Y-3.47 46 | X4.52Y-3.47 47 | X1.3535Y-0.9055 48 | X1.6535Y-0.9055 49 | X1.96Y-1.9 50 | X2.26Y-1.9 51 | X3.88Y-0.82 52 | X3.88Y-0.92 53 | X3.88Y-1.02 54 | X3.88Y-1.12 55 | X3.88Y-1.22 56 | X3.88Y-1.32 57 | X3.88Y-1.42 58 | X4.18Y-0.82 59 | X4.18Y-0.92 60 | X4.18Y-1.02 61 | X4.18Y-1.12 62 | X4.18Y-1.22 63 | X4.18Y-1.32 64 | X4.18Y-1.42 65 | X4.96Y-3.58 66 | X4.96Y-3.88 67 | X3.81Y-2.08 68 | X3.81Y-2.18 69 | X3.81Y-2.28 70 | X3.81Y-2.38 71 | X3.81Y-2.48 72 | X3.81Y-2.58 73 | X3.81Y-2.68 74 | X3.81Y-2.78 75 | X4.11Y-2.08 76 | X4.11Y-2.18 77 | X4.11Y-2.28 78 | X4.11Y-2.38 79 | X4.11Y-2.48 80 | X4.11Y-2.58 81 | X4.11Y-2.68 82 | X4.11Y-2.78 83 | X3.94Y-4.29 84 | X4.24Y-4.29 85 | X3.49Y-4.29 86 | X3.79Y-4.29 87 | X4.96Y-1.43 88 | X4.96Y-1.73 89 | X4.14Y-0.61 90 | X4.44Y-0.61 91 | X3.62Y-1.62 92 | X3.92Y-1.62 93 | X2.81Y-1.91 94 | X3.11Y-1.91 95 | X3.46Y-3.25 96 | X3.76Y-3.25 97 | X1.885Y-0.9055 98 | X2.185Y-0.9055 99 | X3.37Y-3.77 100 | X3.5669Y-3.77 101 | X3.25Y-3.92 102 | X3.55Y-3.92 103 | X4.23Y-4.1 104 | X4.53Y-4.1 105 | X4.23Y-3.66 106 | X4.53Y-3.66 107 | X4.7716Y-2.48 108 | X4.87Y-2.48 109 | X3.24Y-4.1 110 | X3.54Y-4.1 111 | X2.3819Y-0.9055 112 | X2.6819Y-0.9055 113 | X4.52Y-2.3531 114 | X4.52Y-2.55 115 | X4.34Y-1.27 116 | X4.64Y-1.27 117 | X4.33Y-0.8 118 | X4.63Y-0.8 119 | X3.61Y-0.61 120 | X3.91Y-0.61 121 | X3.43Y-1.43 122 | X3.73Y-1.43 123 | X4.34Y-1.43 124 | X4.64Y-1.43 125 | X3.43Y-1.27 126 | X3.73Y-1.27 127 | X4.23Y-3.87 128 | X4.53Y-3.87 129 | X3.5331Y-1.12 130 | X3.73Y-1.12 131 | X3.72Y-3.47 132 | X3.72Y-3.57 133 | X3.72Y-3.67 134 | X3.72Y-3.77 135 | X3.72Y-3.87 136 | X3.72Y-3.97 137 | X3.72Y-4.07 138 | X4.02Y-3.47 139 | X4.02Y-3.57 140 | X4.02Y-3.67 141 | X4.02Y-3.77 142 | X4.02Y-3.87 143 | X4.02Y-3.97 144 | X4.02Y-4.07 145 | X5.15Y-2.76 146 | X5.15Y-3.06 147 | X3.24Y-3.62 148 | X3.54Y-3.62 149 | X3.43Y-0.97 150 | X3.73Y-0.97 151 | X4.96Y-0.96 152 | X4.96Y-1.26 153 | X4.96Y-4.02 154 | X4.96Y-4.32 155 | X4.7816Y-2.92 156 | X4.88Y-2.92 157 | X3.43Y-0.8 158 | X3.73Y-0.8 159 | X0.5758Y-1.9085 160 | X0.8758Y-1.9085 161 | X4.07Y-1.62 162 | X4.37Y-1.62 163 | T4 164 | X1.29Y-0.62 165 | X1.39Y-0.62 166 | X0.46Y-0.63 167 | X0.56Y-0.63 168 | X2.07Y-0.63 169 | X2.17Y-0.63 170 | X2.91Y-0.62 171 | X3.01Y-0.62 172 | T5 173 | X0.4031Y-2.84 174 | X0.5016Y-2.84 175 | X0.6Y-2.84 176 | X2.0331Y-2.84 177 | X2.1316Y-2.84 178 | X2.23Y-2.84 179 | X2.8831Y-2.83 180 | X2.9816Y-2.83 181 | X3.08Y-2.83 182 | X5.16Y-2.41 183 | X5.16Y-2.51 184 | X5.45Y-2.25 185 | X5.45Y-2.35 186 | X5.45Y-2.45 187 | X5.45Y-2.55 188 | X5.45Y-2.65 189 | X5.55Y-2.25 190 | X5.55Y-2.35 191 | X5.55Y-2.45 192 | X5.55Y-2.55 193 | X5.55Y-2.65 194 | X5.1705Y-3.2041 195 | X5.2705Y-3.2041 196 | X5.3705Y-3.2041 197 | X5.4705Y-3.2041 198 | X5.5705Y-3.2041 199 | X5.6705Y-3.2041 200 | X5.7Y-3.46 201 | X5.7Y-3.56 202 | X5.7Y-3.66 203 | X5.7Y-3.76 204 | X5.7Y-3.86 205 | X5.7Y-3.96 206 | X5.7Y-4.06 207 | X5.7Y-4.16 208 | X5.7Y-4.26 209 | X1.2431Y-2.84 210 | X1.3416Y-2.84 211 | X1.44Y-2.84 212 | X5.2005Y-0.6341 213 | X5.3005Y-0.6341 214 | X5.4005Y-0.6341 215 | X5.5005Y-0.6341 216 | X5.6005Y-0.6341 217 | X5.7005Y-0.6341 218 | X5.73Y-0.89 219 | X5.73Y-0.99 220 | X5.73Y-1.09 221 | X5.73Y-1.19 222 | X5.73Y-1.29 223 | X5.73Y-1.39 224 | X5.73Y-1.49 225 | X5.73Y-1.59 226 | X5.73Y-1.69 227 | T6 228 | X0.915Y-1.1142 229 | X0.915Y-2.1142 230 | X1.015Y-1.1142 231 | X1.015Y-2.1142 232 | X1.115Y-1.1142 233 | X1.115Y-2.1142 234 | X1.215Y-1.1142 235 | X1.215Y-2.1142 236 | X1.315Y-1.1142 237 | X1.315Y-2.1142 238 | X1.415Y-1.1142 239 | X1.415Y-2.1142 240 | X1.515Y-1.1142 241 | X1.515Y-2.1142 242 | X1.615Y-1.1142 243 | X1.615Y-2.1142 244 | X1.715Y-1.1142 245 | X1.715Y-2.1142 246 | X1.815Y-1.1142 247 | X1.815Y-2.1142 248 | X1.915Y-1.1142 249 | X1.915Y-2.1142 250 | X2.015Y-1.1142 251 | X2.015Y-2.1142 252 | X2.115Y-1.1142 253 | X2.115Y-2.1142 254 | X2.215Y-1.1142 255 | X2.215Y-2.1142 256 | X2.315Y-1.1142 257 | X2.315Y-2.1142 258 | X2.415Y-1.1142 259 | X2.415Y-2.1142 260 | X2.515Y-1.1142 261 | X2.515Y-2.1142 262 | X2.615Y-1.1142 263 | X2.615Y-2.1142 264 | X2.715Y-1.1142 265 | X2.715Y-2.1142 266 | T7 267 | X5.4Y-2.97 268 | X5.5Y-2.97 269 | X5.6Y-2.97 270 | T8 271 | X2.71Y-1.46 272 | X2.71Y-1.6569 273 | X3.2021Y-1.46 274 | X3.2021Y-1.6569 275 | X1.06Y-1.45 276 | X1.06Y-1.6469 277 | X1.5521Y-1.45 278 | X1.5521Y-1.6469 279 | X0.2656Y-1.4361 280 | X0.2656Y-1.6329 281 | X0.7577Y-1.4361 282 | X0.7577Y-1.6329 283 | X1.86Y-1.45 284 | X1.86Y-1.6469 285 | X2.3521Y-1.45 286 | X2.3521Y-1.6469 287 | T9 288 | X2.49Y-3.2463 289 | X2.49Y-3.5731 290 | X2.49Y-3.6951 291 | X1.51Y-3.9632 292 | X1.51Y-4.29 293 | X1.51Y-4.412 294 | X2.49Y-3.9632 295 | X2.49Y-4.29 296 | X2.49Y-4.412 297 | X1.99Y-3.2432 298 | X1.99Y-3.57 299 | X1.99Y-3.692 300 | X1.5Y-3.2432 301 | X1.5Y-3.57 302 | X1.5Y-3.692 303 | X1.01Y-3.2432 304 | X1.01Y-3.57 305 | X1.01Y-3.692 306 | X1.0Y-3.9632 307 | X1.0Y-4.29 308 | X1.0Y-4.412 309 | X1.99Y-3.9632 310 | X1.99Y-4.29 311 | X1.99Y-4.412 312 | T10 313 | X1.1683Y-2.5644 314 | X1.5148Y-2.5644 315 | X0.3283Y-2.5644 316 | X0.6748Y-2.5644 317 | X1.9583Y-2.5644 318 | X2.3048Y-2.5644 319 | X2.8083Y-2.5544 320 | X3.1548Y-2.5544 321 | T11 322 | X5.26Y-4.88 323 | X2.86Y-4.88 324 | X5.26Y-0.12 325 | X0.6Y-0.12 326 | X0.61Y-4.88 327 | X2.86Y-0.12 328 | T0 329 | M30 330 | -------------------------------------------------------------------------------- /main/heavy/HvSignalTabwrite.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_SIGNAL_TABWRITE_H_ 18 | #define _HEAVY_SIGNAL_TABWRITE_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #define HV_TABWRITE_STOPPED -1 // ~0x0 27 | 28 | typedef struct SignalTabwrite { 29 | HvTable *table; 30 | hv_uint32_t head; // local write head. Where this object has most recently written to the table. 31 | } SignalTabwrite; 32 | 33 | hv_size_t sTabwrite_init(SignalTabwrite *o, HvTable *table); 34 | 35 | void sTabwrite_onMessage(HeavyContextInterface *_c, SignalTabwrite *o, int letIn, const HvMessage *m, 36 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)); 37 | 38 | // linear write to table 39 | static inline void __hv_tabwrite_f(SignalTabwrite *o, hv_bInf_t bIn) { 40 | hv_assert((o->head + HV_N_SIMD) <= hTable_getSize(o->table)); // assert that the table bounds are respected 41 | hv_uint32_t head = o->head; 42 | #if HV_SIMD_AVX 43 | _mm256_store_ps(hTable_getBuffer(o->table) + head, bIn); 44 | #elif HV_SIMD_SSE 45 | _mm_store_ps(hTable_getBuffer(o->table) + head, bIn); 46 | #elif HV_SIMD_NEON 47 | vst1q_f32(hTable_getBuffer(o->table) + head, bIn); 48 | #else // HV_SIMD_NONE 49 | *(hTable_getBuffer(o->table) + head) = bIn; 50 | #endif 51 | head += HV_N_SIMD; 52 | o->head = head; // update local write head 53 | hTable_setHead(o->table, head); // update the remote write head (e.g. for use by vd~) 54 | } 55 | 56 | // linear unaligned write to table 57 | static inline void __hv_tabwriteu_f(SignalTabwrite *o, hv_bInf_t bIn) { 58 | hv_uint32_t head = o->head; 59 | #if HV_SIMD_AVX 60 | _mm256_storeu_ps(hTable_getBuffer(o->table) + head, bIn); 61 | #elif HV_SIMD_SSE 62 | _mm_storeu_ps(hTable_getBuffer(o->table) + head, bIn); 63 | #elif HV_SIMD_NEON 64 | vst1q_f32(hTable_getBuffer(o->table) + head, bIn); 65 | #else // HV_SIMD_NONE 66 | *(hTable_getBuffer(o->table) + head) = bIn; 67 | #endif 68 | head += HV_N_SIMD; 69 | o->head = head; // update local write head 70 | hTable_setHead(o->table, head); // update remote write head 71 | } 72 | 73 | // this tabread can be instructed to stop. It is mainly intended for linear reads that only process a portion of a buffer. 74 | // Stores are unaligned, which can be slow but allows any indicies to be written to. 75 | // TODO(mhroth): this is not stopping! 76 | static inline void __hv_tabwrite_stoppable_f(SignalTabwrite *o, hv_bInf_t bIn) { 77 | if (o->head != HV_TABWRITE_STOPPED) { 78 | #if HV_SIMD_AVX 79 | _mm256_storeu_ps(hTable_getBuffer(o->table) + o->head, bIn); 80 | #elif HV_SIMD_SSE 81 | _mm_storeu_ps(hTable_getBuffer(o->table) + o->head, bIn); 82 | #elif HV_SIMD_NEON 83 | vst1q_f32(hTable_getBuffer(o->table) + o->head, bIn); 84 | #else // HV_SIMD_NONE 85 | *(hTable_getBuffer(o->table) + o->head) = bIn; 86 | #endif 87 | o->head += HV_N_SIMD; 88 | } 89 | } 90 | 91 | // random write to table 92 | static inline void __hv_tabwrite_if(SignalTabwrite *o, hv_bIni_t bIn0, hv_bInf_t bIn1) { 93 | float *const b = hTable_getBuffer(o->table); 94 | #if HV_SIMD_AVX 95 | const hv_int32_t *const i = (hv_int32_t *) &bIn0; 96 | const float *const f = (float *) &bIn1; 97 | 98 | hv_assert(i[0] >= 0 && i[0] < hTable_getAllocated(o->table)); 99 | hv_assert(i[1] >= 0 && i[1] < hTable_getAllocated(o->table)); 100 | hv_assert(i[2] >= 0 && i[2] < hTable_getAllocated(o->table)); 101 | hv_assert(i[3] >= 0 && i[3] < hTable_getAllocated(o->table)); 102 | hv_assert(i[4] >= 0 && i[4] < hTable_getAllocated(o->table)); 103 | hv_assert(i[5] >= 0 && i[5] < hTable_getAllocated(o->table)); 104 | hv_assert(i[6] >= 0 && i[6] < hTable_getAllocated(o->table)); 105 | hv_assert(i[7] >= 0 && i[7] < hTable_getAllocated(o->table)); 106 | 107 | b[i[0]] = f[0]; 108 | b[i[1]] = f[1]; 109 | b[i[2]] = f[2]; 110 | b[i[3]] = f[3]; 111 | b[i[4]] = f[4]; 112 | b[i[5]] = f[5]; 113 | b[i[6]] = f[6]; 114 | b[i[7]] = f[7]; 115 | #elif HV_SIMD_SSE 116 | const hv_int32_t *const i = (hv_int32_t *) &bIn0; 117 | const float *const f = (float *) &bIn1; 118 | 119 | hv_assert(i[0] >= 0 && ((hv_uint32_t) i[0]) < hTable_getAllocated(o->table)); 120 | hv_assert(i[1] >= 0 && ((hv_uint32_t) i[1]) < hTable_getAllocated(o->table)); 121 | hv_assert(i[2] >= 0 && ((hv_uint32_t) i[2]) < hTable_getAllocated(o->table)); 122 | hv_assert(i[3] >= 0 && ((hv_uint32_t) i[3]) < hTable_getAllocated(o->table)); 123 | 124 | b[i[0]] = f[0]; 125 | b[i[1]] = f[1]; 126 | b[i[2]] = f[2]; 127 | b[i[3]] = f[3]; 128 | #elif HV_SIMD_NEON 129 | hv_assert((vgetq_lane_s32(bIn0,0) >= 0) && (vgetq_lane_s32(bIn0,0) < hTable_getSize(o->table))); 130 | hv_assert((vgetq_lane_s32(bIn0,1) >= 0) && (vgetq_lane_s32(bIn0,1) < hTable_getSize(o->table))); 131 | hv_assert((vgetq_lane_s32(bIn0,2) >= 0) && (vgetq_lane_s32(bIn0,2) < hTable_getSize(o->table))); 132 | hv_assert((vgetq_lane_s32(bIn0,3) >= 0) && (vgetq_lane_s32(bIn0,3) < hTable_getSize(o->table))); 133 | 134 | vst1q_lane_f32(b + vgetq_lane_s32(bIn0, 0), bIn1, 0); 135 | vst1q_lane_f32(b + vgetq_lane_s32(bIn0, 1), bIn1, 1); 136 | vst1q_lane_f32(b + vgetq_lane_s32(bIn0, 2), bIn1, 2); 137 | vst1q_lane_f32(b + vgetq_lane_s32(bIn0, 3), bIn1, 3); 138 | #else // HV_SIMD_NONE 139 | b[bIn0] = bIn1; 140 | #endif 141 | } 142 | 143 | #ifdef __cplusplus 144 | } // extern "C" 145 | #endif 146 | 147 | #endif // _HEAVY_SIGNAL_TABWRITE_H_ 148 | -------------------------------------------------------------------------------- /main/heavy/HvSignalPhasor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _HEAVY_SIGNAL_PHASOR_H_ 18 | #define _HEAVY_SIGNAL_PHASOR_H_ 19 | 20 | #include "HvHeavyInternal.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct SignalPhasor { 27 | #if HV_SIMD_AVX 28 | __m256 phase; // current phase 29 | __m256 inc; // phase increment 30 | #elif HV_SIMD_SSE 31 | __m128i phase; 32 | __m128i inc; 33 | #elif HV_SIMD_NEON 34 | uint32x4_t phase; 35 | int32x4_t inc; 36 | #else // HV_SIMD_NONE 37 | hv_uint32_t phase; 38 | hv_int32_t inc; 39 | #endif 40 | union { 41 | float f2sc; // float to step conversion (used for __phasor~f) 42 | hv_int32_t s; // step value (used for __phasor_k~f) 43 | } step; 44 | } SignalPhasor; 45 | 46 | hv_size_t sPhasor_init(SignalPhasor *o, double samplerate); 47 | 48 | hv_size_t sPhasor_k_init(SignalPhasor *o, float frequency, double samplerate); 49 | 50 | void sPhasor_k_onMessage(HeavyContextInterface *_c, SignalPhasor *o, int letIn, const HvMessage *m); 51 | 52 | void sPhasor_onMessage(HeavyContextInterface *_c, SignalPhasor *o, int letIn, const HvMessage *m); 53 | 54 | static inline void __hv_phasor_f(SignalPhasor *o, hv_bInf_t bIn, hv_bOutf_t bOut) { 55 | #if HV_SIMD_AVX 56 | __m256 p = _mm256_mul_ps(bIn, _mm256_set1_ps(o->step.f2sc)); // a b c d e f g h 57 | 58 | __m256 z = _mm256_setzero_ps(); 59 | 60 | // http://stackoverflow.com/questions/11906814/how-to-rotate-an-sse-avx-vector 61 | __m256 a = _mm256_permute_ps(p, _MM_SHUFFLE(2,1,0,3)); // d a b c h e f g 62 | __m256 b = _mm256_permute2f128_ps(a, a, 0x01); // h e f g d a b c 63 | __m256 c = _mm256_blend_ps(a, b, 0x10); // d a b c d e f g 64 | __m256 d = _mm256_blend_ps(c, z, 0x01); // 0 a b c d e f g 65 | __m256 e = _mm256_add_ps(p, d); // a (a+b) (b+c) (c+d) (d+e) (e+f) (f+g) (g+h) 66 | 67 | __m256 f = _mm256_permute_ps(e, _MM_SHUFFLE(1,0,3,2)); // (b+c) (c+d) a (a+b) (f+g) (g+h) (d+e) (e+f) 68 | __m256 g = _mm256_permute2f128_ps(f, f, 0x01); // (f+g) (g+h) (d+e) (e+f) (b+c) (c+d) a (a+b) 69 | __m256 h = _mm256_blend_ps(f, g, 0x33); // (b+c) (c+d) a (a+b) (b+c) (c+d) (d+e) (e+f) 70 | __m256 i = _mm256_blend_ps(h, z, 0x03); // 0 0 a (a+b) (b+c) (c+d) (d+e) (e+f) 71 | __m256 j = _mm256_add_ps(e, i); // a (a+b) (a+b+c) (a+b+c+d) (b+c+d+e) (c+d+e+f) (d+e+f+g) (e+f+g+h) 72 | 73 | __m256 k = _mm256_permute2f128_ps(j, z, 0x02); // 0 0 0 0 a (a+b) (a+b+c) (a+b+c+d) (b+c+d+e) 74 | __m256 m = _mm256_add_ps(j, k); // a (a+b) (a+b+c) (a+b+c+d) (a+b+c+d+e) (a+b+c+d+e+f) (a+b+c+d+e+f+g) (a+b+c+d+e+f+g+h) 75 | 76 | __m256 n = _mm256_or_ps(_mm256_andnot_ps( 77 | _mm256_set1_ps(-INFINITY), 78 | _mm256_add_ps(o->phase, m)), 79 | _mm256_set1_ps(1.0f)); 80 | 81 | *bOut = _mm256_sub_ps(n, _mm256_set1_ps(1.0f)); 82 | 83 | __m256 x = _mm256_permute_ps(n, _MM_SHUFFLE(3,3,3,3)); 84 | o->phase = _mm256_permute2f128_ps(x, x, 0x11); 85 | #elif HV_SIMD_SSE 86 | __m128i p = _mm_cvtps_epi32(_mm_mul_ps(bIn, _mm_set1_ps(o->step.f2sc))); // convert frequency to step 87 | p = _mm_add_epi32(p, _mm_slli_si128(p, 4)); // add incremental steps to phase (prefix sum) 88 | p = _mm_add_epi32(p, _mm_slli_si128(p, 8)); // http://stackoverflow.com/questions/10587598/simd-prefix-sum-on-intel-cpu?rq=1 89 | p = _mm_add_epi32(o->phase, p); 90 | *bOut = _mm_sub_ps(_mm_castsi128_ps( 91 | _mm_or_si128(_mm_srli_epi32(p, 9), 92 | _mm_set_epi32(0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000))), 93 | _mm_set1_ps(1.0f)); 94 | o->phase = _mm_shuffle_epi32(p, _MM_SHUFFLE(3,3,3,3)); 95 | #elif HV_SIMD_NEON 96 | int32x4_t p = vcvtq_s32_f32(vmulq_n_f32(bIn, o->step.f2sc)); 97 | p = vaddq_s32(p, vextq_s32(vdupq_n_s32(0), p, 3)); // http://stackoverflow.com/questions/11259596/arm-neon-intrinsics-rotation 98 | p = vaddq_s32(p, vextq_s32(vdupq_n_s32(0), p, 2)); 99 | uint32x4_t pp = vaddq_u32(o->phase, vreinterpretq_u32_s32(p)); 100 | *bOut = vsubq_f32(vreinterpretq_f32_u32(vorrq_u32(vshrq_n_u32(pp, 9), vdupq_n_u32(0x3F800000))), vdupq_n_f32(1.0f)); 101 | o->phase = vdupq_n_u32(pp[3]); 102 | #else // HV_SIMD_NONE 103 | const hv_uint32_t p = (o->phase >> 9) | 0x3F800000; 104 | *bOut = *((float *) (&p)) - 1.0f; 105 | o->phase += ((int) (bIn * o->step.f2sc)); 106 | #endif 107 | } 108 | 109 | static inline void __hv_phasor_k_f(SignalPhasor *o, hv_bOutf_t bOut) { 110 | #if HV_SIMD_AVX 111 | *bOut = _mm256_sub_ps(o->phase, _mm256_set1_ps(1.0f)); 112 | o->phase = _mm256_or_ps(_mm256_andnot_ps( 113 | _mm256_set1_ps(-INFINITY), 114 | _mm256_add_ps(o->phase, o->inc)), 115 | _mm256_set1_ps(1.0f)); 116 | #elif HV_SIMD_SSE 117 | *bOut = _mm_sub_ps(_mm_castsi128_ps( 118 | _mm_or_si128(_mm_srli_epi32(o->phase, 9), 119 | _mm_set_epi32(0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000))), 120 | _mm_set1_ps(1.0f)); 121 | o->phase = _mm_add_epi32(o->phase, o->inc); 122 | #elif HV_SIMD_NEON 123 | *bOut = vsubq_f32(vreinterpretq_f32_u32( 124 | vorrq_u32(vshrq_n_u32(o->phase, 9), 125 | vdupq_n_u32(0x3F800000))), 126 | vdupq_n_f32(1.0f)); 127 | o->phase = vaddq_u32(o->phase, vreinterpretq_u32_s32(o->inc)); 128 | #else // HV_SIMD_NONE 129 | const hv_uint32_t p = (o->phase >> 9) | 0x3F800000; 130 | *bOut = *((float *) (&p)) - 1.0f; 131 | o->phase += o->inc; 132 | #endif 133 | } 134 | 135 | #ifdef __cplusplus 136 | } // extern "C" 137 | #endif 138 | 139 | #endif // _HEAVY_SIGNAL_PHASOR_H_ 140 | -------------------------------------------------------------------------------- /main/heavy/HvSignalEnvelope.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-2018 Enzien Audio Ltd. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "HvSignalEnvelope.h" 18 | 19 | #ifndef M_PI 20 | #define M_PI 3.14159265358979323846 // in case math.h doesn't include this defintion 21 | #endif 22 | 23 | static int ceilToNearestBlock(int x, int n) { 24 | return (int) (ceilf(((float) x) / ((float) n)) * n); 25 | } 26 | 27 | hv_size_t sEnv_init(SignalEnvelope *o, int windowSize, int period) { 28 | // 0 < BLOCK_SIZE <= period <= windowSize 29 | // NOTE(mhroth): this is an artificial limit, but it greatly simplifies development 30 | o->windowSize = (windowSize <= HV_N_SIMD) ? HV_N_SIMD : ceilToNearestBlock(windowSize, HV_N_SIMD); 31 | o->period = (period <= HV_N_SIMD) ? HV_N_SIMD : (period > o->windowSize) ? o->windowSize : ceilToNearestBlock(period, HV_N_SIMD); 32 | o->numSamplesInBuffer = 0; 33 | hv_size_t numBytes = 0; 34 | 35 | // allocate the signal buffer 36 | // the buffer is overdimensioned in this way (up to double), but not by much and so what 37 | const int bufferLength = 2 * o->windowSize; 38 | o->buffer = (float *) hv_malloc(bufferLength*sizeof(float)); 39 | hv_assert(o->buffer != NULL); 40 | numBytes += bufferLength*sizeof(float); 41 | 42 | // allocate and calculate the hanning weights 43 | o->hanningWeights = (float *) hv_malloc(o->windowSize*sizeof(float)); 44 | hv_assert(o->hanningWeights != NULL); 45 | numBytes += o->windowSize*sizeof(float); 46 | float hanningSum = 0.0f; 47 | for (int i = 0; i < o->windowSize; i++) { 48 | const float w = 0.5f * (1.0f - cosf(((float) (2.0 * M_PI * i)) / ((float) (o->windowSize - 1)))); 49 | o->hanningWeights[i] = w; 50 | hanningSum += w; 51 | } 52 | for (int i = 0; i < o->windowSize; i++) { 53 | // normalise the hanning coefficients such that they represent a normalised weighted averaging 54 | o->hanningWeights[i] /= hanningSum; 55 | } 56 | 57 | return numBytes; 58 | } 59 | 60 | void sEnv_free(SignalEnvelope *o) { 61 | hv_free(o->hanningWeights); 62 | hv_free(o->buffer); 63 | } 64 | 65 | static void sEnv_sendMessage(HeavyContextInterface *_c, SignalEnvelope *o, float rms, 66 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 67 | // finish RMS calculation. sqrt is removed as it can be combined with the log operation. 68 | // result is normalised such that 1 RMS == 100 dB 69 | rms = (4.342944819032518f * hv_log_f(rms)) + 100.0f; 70 | 71 | // prepare the outgoing message. Schedule it at the beginning of the next block. 72 | HvMessage *const m = HV_MESSAGE_ON_STACK(1); 73 | 74 | msg_initWithFloat(m, hv_getCurrentSample(_c) + HV_N_SIMD, (rms < 0.0f) ? 0.0f : rms); 75 | hv_scheduleMessageForObject(_c, m, sendMessage, 0); 76 | 77 | hv_memcpy(o->buffer, o->buffer+o->period, sizeof(float)*(o->numSamplesInBuffer - o->period)); 78 | o->numSamplesInBuffer -= o->period; 79 | } 80 | 81 | void sEnv_process(HeavyContextInterface *_c, SignalEnvelope *o, hv_bInf_t bIn, 82 | void (*sendMessage)(HeavyContextInterface *, int, const HvMessage *)) { 83 | #if HV_SIMD_AVX 84 | _mm256_stream_ps(o->buffer+o->numSamplesInBuffer, _mm256_mul_ps(bIn,bIn)); // store bIn^2, no need to cache block 85 | o->numSamplesInBuffer += HV_N_SIMD; 86 | 87 | if (o->numSamplesInBuffer >= o->windowSize) { 88 | int n4 = o->windowSize & ~HV_N_SIMD_MASK; 89 | __m256 sum = _mm256_setzero_ps(); 90 | while (n4) { 91 | __m256 x = _mm256_load_ps(o->buffer + n4 - HV_N_SIMD); 92 | __m256 h = _mm256_load_ps(o->hanningWeights + n4 - HV_N_SIMD); 93 | x = _mm256_mul_ps(x, h); 94 | sum = _mm256_add_ps(sum, x); 95 | n4 -= HV_N_SIMD; 96 | } 97 | sum = _mm256_hadd_ps(sum,sum); // horizontal sum 98 | sum = _mm256_hadd_ps(sum,sum); 99 | sEnv_sendMessage(_c, o, sum[0]+sum[4], sendMessage); // updates numSamplesInBuffer 100 | } 101 | #elif HV_SIMD_SSE 102 | _mm_stream_ps(o->buffer+o->numSamplesInBuffer, _mm_mul_ps(bIn,bIn)); // store bIn^2, no need to cache block 103 | o->numSamplesInBuffer += HV_N_SIMD; 104 | 105 | if (o->numSamplesInBuffer >= o->windowSize) { 106 | int n4 = o->windowSize & ~HV_N_SIMD_MASK; 107 | __m128 sum = _mm_setzero_ps(); 108 | while (n4) { 109 | __m128 x = _mm_load_ps(o->buffer + n4 - HV_N_SIMD); 110 | __m128 h = _mm_load_ps(o->hanningWeights + n4 - HV_N_SIMD); 111 | x = _mm_mul_ps(x, h); 112 | sum = _mm_add_ps(sum, x); 113 | n4 -= HV_N_SIMD; 114 | } 115 | sum = _mm_hadd_ps(sum,sum); // horizontal sum 116 | sum = _mm_hadd_ps(sum,sum); 117 | float f; 118 | _mm_store_ss(&f, sum); 119 | sEnv_sendMessage(_c, o, f, sendMessage); 120 | } 121 | #elif HV_SIMD_NEON 122 | vst1q_f32(o->buffer+o->numSamplesInBuffer, vmulq_f32(bIn,bIn)); // store bIn^2, no need to cache block 123 | o->numSamplesInBuffer += HV_N_SIMD; 124 | 125 | if (o->numSamplesInBuffer >= o->windowSize) { 126 | int n4 = o->windowSize & ~HV_N_SIMD_MASK; 127 | float32x4_t sum = vdupq_n_f32(0.0f); 128 | while (n4) { 129 | float32x4_t x = vld1q_f32(o->buffer + n4 - HV_N_SIMD); 130 | float32x4_t h = vld1q_f32(o->hanningWeights + n4 - HV_N_SIMD); 131 | x = vmulq_f32(x, h); 132 | sum = vaddq_f32(sum, x); 133 | n4 -= HV_N_SIMD; 134 | } 135 | sEnv_sendMessage(_c, o, sum[0]+sum[1]+sum[2]+sum[3], sendMessage); 136 | } 137 | #else // HV_SIMD_NONE 138 | o->buffer[o->numSamplesInBuffer] = (bIn*bIn); 139 | o->numSamplesInBuffer += HV_N_SIMD; 140 | 141 | if (o->numSamplesInBuffer >= o->windowSize) { 142 | float sum = 0.0f; 143 | for (int i = 0; i < o->windowSize; ++i) { 144 | sum += (o->hanningWeights[i] * o->buffer[i]); 145 | } 146 | sEnv_sendMessage(_c, o, sum, sendMessage); 147 | } 148 | #endif 149 | } 150 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/footprints.pretty/MPU6050.kicad_mod: -------------------------------------------------------------------------------- 1 | (module MPU6050 (layer F.Cu) (tedit 5ABC1B75) 2 | (fp_text reference IC1 (at 16.1036 2.54) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value "MPU6050 Gyro + Accelerometer" (at -8.64 -3.84) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start 14.55 -7.8) (end 14.55 -9.3) (layer F.SilkS) (width 0.15)) 9 | (fp_line (start 14.55 -9.3) (end 15.3 -9.3) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start 15.3 -9.3) (end 15.3 -7.8) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start 15.3 -7.8) (end 14.55 -7.8) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start 12.55 -7.8) (end 12.55 -9.3) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start 12.55 -9.3) (end 13.3 -9.3) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start 13.3 -9.3) (end 13.3 -7.8) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start 13.3 -7.8) (end 12.55 -7.8) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start 16.55 -5.55) (end 17.3 -5.55) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start 17.3 -5.55) (end 17.3 -3.8) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start 17.3 -3.8) (end 16.55 -3.8) (layer F.SilkS) (width 0.15)) 19 | (fp_line (start 16.55 -3.8) (end 16.55 -5.55) (layer F.SilkS) (width 0.15)) 20 | (fp_line (start 14.55 -5.55) (end 14.55 -3.8) (layer F.SilkS) (width 0.15)) 21 | (fp_line (start 14.55 -3.8) (end 15.3 -3.8) (layer F.SilkS) (width 0.15)) 22 | (fp_line (start 15.3 -3.8) (end 15.3 -5.55) (layer F.SilkS) (width 0.15)) 23 | (fp_line (start 15.3 -5.55) (end 14.55 -5.55) (layer F.SilkS) (width 0.15)) 24 | (fp_line (start 12.55 -5.55) (end 13.3 -5.55) (layer F.SilkS) (width 0.15)) 25 | (fp_line (start 13.3 -5.55) (end 13.3 -3.8) (layer F.SilkS) (width 0.15)) 26 | (fp_line (start 13.3 -3.8) (end 12.55 -3.8) (layer F.SilkS) (width 0.15)) 27 | (fp_line (start 12.55 -3.8) (end 12.55 -5.55) (layer F.SilkS) (width 0.15)) 28 | (fp_line (start -0.2 -8.3) (end -0.2 -9.3) (layer F.SilkS) (width 0.15)) 29 | (fp_line (start -0.2 -9.3) (end 2.05 -9.3) (layer F.SilkS) (width 0.15)) 30 | (fp_line (start 2.05 -9.3) (end 2.05 -8.3) (layer F.SilkS) (width 0.15)) 31 | (fp_line (start 2.05 -8.3) (end -0.2 -8.3) (layer F.SilkS) (width 0.15)) 32 | (fp_line (start 5.05 -7.8) (end 5.05 -9.3) (layer F.SilkS) (width 0.15)) 33 | (fp_line (start 5.05 -9.3) (end 4.3 -9.3) (layer F.SilkS) (width 0.15)) 34 | (fp_line (start 4.3 -9.3) (end 4.3 -7.8) (layer F.SilkS) (width 0.15)) 35 | (fp_line (start 4.3 -7.8) (end 5.05 -7.8) (layer F.SilkS) (width 0.15)) 36 | (fp_line (start 6.3 -7.8) (end 6.3 -9.3) (layer F.SilkS) (width 0.15)) 37 | (fp_line (start 6.3 -9.3) (end 5.55 -9.3) (layer F.SilkS) (width 0.15)) 38 | (fp_line (start 5.55 -9.3) (end 5.55 -7.8) (layer F.SilkS) (width 0.15)) 39 | (fp_line (start 5.55 -7.8) (end 6.3 -7.8) (layer F.SilkS) (width 0.15)) 40 | (fp_line (start 2.3 -4.8) (end -0.45 -4.8) (layer F.SilkS) (width 0.15)) 41 | (fp_line (start -0.45 -4.8) (end -0.45 -6.8) (layer F.SilkS) (width 0.15)) 42 | (fp_line (start -0.45 -6.8) (end 2.3 -6.8) (layer F.SilkS) (width 0.15)) 43 | (fp_line (start 2.3 -6.8) (end 2.3 -4.8) (layer F.SilkS) (width 0.15)) 44 | (fp_line (start 3.8 -4.3) (end 3.8 -3.8) (layer F.SilkS) (width 0.15)) 45 | (fp_line (start 3.8 -3.8) (end 3.05 -3.8) (layer F.SilkS) (width 0.15)) 46 | (fp_line (start 3.05 -3.8) (end 3.05 -4.3) (layer F.SilkS) (width 0.15)) 47 | (fp_line (start 5.05 -4.3) (end 5.05 -3.8) (layer F.SilkS) (width 0.15)) 48 | (fp_line (start 5.05 -3.8) (end 4.3 -3.8) (layer F.SilkS) (width 0.15)) 49 | (fp_line (start 4.3 -3.8) (end 4.3 -4.3) (layer F.SilkS) (width 0.15)) 50 | (fp_line (start 6.3 -4.3) (end 6.3 -3.8) (layer F.SilkS) (width 0.15)) 51 | (fp_line (start 6.3 -3.8) (end 5.55 -3.8) (layer F.SilkS) (width 0.15)) 52 | (fp_line (start 5.55 -3.8) (end 5.55 -4.3) (layer F.SilkS) (width 0.15)) 53 | (fp_line (start 3.8 -4.3) (end 3.8 -5.55) (layer F.SilkS) (width 0.15)) 54 | (fp_line (start 3.8 -5.55) (end 3.05 -5.55) (layer F.SilkS) (width 0.15)) 55 | (fp_line (start 3.05 -5.55) (end 3.05 -4.3) (layer F.SilkS) (width 0.15)) 56 | (fp_line (start 5.05 -4.3) (end 5.05 -5.55) (layer F.SilkS) (width 0.15)) 57 | (fp_line (start 5.05 -5.55) (end 4.3 -5.55) (layer F.SilkS) (width 0.15)) 58 | (fp_line (start 4.3 -5.55) (end 4.3 -4.3) (layer F.SilkS) (width 0.15)) 59 | (fp_line (start 5.55 -4.3) (end 5.55 -5.55) (layer F.SilkS) (width 0.15)) 60 | (fp_line (start 5.55 -5.55) (end 6.05 -5.55) (layer F.SilkS) (width 0.15)) 61 | (fp_line (start 6.05 -5.55) (end 6.3 -5.55) (layer F.SilkS) (width 0.15)) 62 | (fp_line (start 6.3 -5.55) (end 6.3 -4.3) (layer F.SilkS) (width 0.15)) 63 | (fp_line (start 7.3 -8.3) (end 7.3 -4.3) (layer F.SilkS) (width 0.15)) 64 | (fp_line (start 7.3 -4.3) (end 11.3 -4.3) (layer F.SilkS) (width 0.15)) 65 | (fp_line (start 11.3 -4.3) (end 11.3 -8.3) (layer F.SilkS) (width 0.15)) 66 | (fp_line (start 11.3 -8.3) (end 7.3 -8.3) (layer F.SilkS) (width 0.15)) 67 | (fp_line (start 7.3 -11.8) (end 7.3 -10.3) (layer F.SilkS) (width 0.15)) 68 | (fp_line (start 7.3 -10.3) (end 11.3 -10.3) (layer F.SilkS) (width 0.15)) 69 | (fp_line (start 11.3 -10.3) (end 11.3 -11.8) (layer F.SilkS) (width 0.15)) 70 | (fp_line (start 11.3 -11.8) (end 7.3 -11.8) (layer F.SilkS) (width 0.15)) 71 | (fp_line (start -1.3 -14.3) (end 19.3 -14.3) (layer F.SilkS) (width 0.15)) 72 | (fp_line (start -1.3 1.3) (end -1.3 -14.3) (layer F.SilkS) (width 0.15)) 73 | (fp_line (start 19.3 1.3) (end 19.3 -14.3) (layer F.SilkS) (width 0.15)) 74 | (fp_line (start -1.3 1.3) (end 19.3 1.3) (layer F.SilkS) (width 0.15)) 75 | (fp_line (start 6.4 1.3) (end 6.3 1.3) (layer F.SilkS) (width 0.15)) 76 | (pad 1 thru_hole circle (at 0 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 77 | (pad "" np_thru_hole circle (at 1.4 -11.6) (size 3.1 3.1) (drill 3.1) (layers *.Cu *.Mask)) 78 | (pad "" np_thru_hole circle (at 16.6 -11.6) (size 3.1 3.1) (drill 3.1) (layers *.Cu *.Mask)) 79 | (pad 2 thru_hole circle (at 2.54 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 80 | (pad 3 thru_hole circle (at 5.08 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 81 | (pad 4 thru_hole circle (at 7.62 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 82 | (pad 5 thru_hole circle (at 10.16 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 83 | (pad 6 thru_hole circle (at 12.7 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 84 | (pad 7 thru_hole circle (at 15.24 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 85 | (pad 8 thru_hole circle (at 17.78 0) (size 1.75 1.75) (drill 1) (layers *.Cu *.Mask)) 86 | ) 87 | -------------------------------------------------------------------------------- /kicad/eurorack_engine/gerbers/eurorack_engine-B_SilkS.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.7)-1* 2 | G04 #@! TF.CreationDate,2020-10-22T22:29:39+02:00* 3 | G04 #@! TF.ProjectId,eurorack_engine,6575726f-7261-4636-9b5f-656e67696e65,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Legend,Bot* 6 | G04 #@! TF.FilePolarity,Positive* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW (5.1.7)-1) date 2020-10-22 22:29:39* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %ADD10C,0.150000*% 15 | %ADD11C,2.000000*% 16 | G04 #@! TA.AperFunction,Profile* 17 | %ADD12C,0.050000*% 18 | G04 #@! TD* 19 | %ADD13C,0.120000*% 20 | %ADD14C,0.127000*% 21 | %ADD15C,0.015000*% 22 | G04 APERTURE END LIST* 23 | D10* 24 | X145541904Y-61730000D02* 25 | X145637142Y-61682380D01* 26 | X145780000Y-61682380D01* 27 | X145922857Y-61730000D01* 28 | X146018095Y-61825238D01* 29 | X146065714Y-61920476D01* 30 | X146113333Y-62110952D01* 31 | X146113333Y-62253809D01* 32 | X146065714Y-62444285D01* 33 | X146018095Y-62539523D01* 34 | X145922857Y-62634761D01* 35 | X145780000Y-62682380D01* 36 | X145684761Y-62682380D01* 37 | X145541904Y-62634761D01* 38 | X145494285Y-62587142D01* 39 | X145494285Y-62253809D01* 40 | X145684761Y-62253809D01* 41 | X145065714Y-62682380D02* 42 | X145065714Y-61682380D01* 43 | X144494285Y-62682380D01* 44 | X144494285Y-61682380D01* 45 | X144018095Y-62682380D02* 46 | X144018095Y-61682380D01* 47 | X143780000Y-61682380D01* 48 | X143637142Y-61730000D01* 49 | X143541904Y-61825238D01* 50 | X143494285Y-61920476D01* 51 | X143446666Y-62110952D01* 52 | X143446666Y-62253809D01* 53 | X143494285Y-62444285D01* 54 | X143541904Y-62539523D01* 55 | X143637142Y-62634761D01* 56 | X143780000Y-62682380D01* 57 | X144018095Y-62682380D01* 58 | X147049904Y-67635428D02* 59 | X146288000Y-67635428D01* 60 | X146668952Y-68016380D02* 61 | X146668952Y-67254476D01* 62 | X145288000Y-68016380D02* 63 | X145859428Y-68016380D01* 64 | X145573714Y-68016380D02* 65 | X145573714Y-67016380D01* 66 | X145668952Y-67159238D01* 67 | X145764190Y-67254476D01* 68 | X145859428Y-67302095D01* 69 | X144907047Y-67111619D02* 70 | X144859428Y-67064000D01* 71 | X144764190Y-67016380D01* 72 | X144526095Y-67016380D01* 73 | X144430857Y-67064000D01* 74 | X144383238Y-67111619D01* 75 | X144335619Y-67206857D01* 76 | X144335619Y-67302095D01* 77 | X144383238Y-67444952D01* 78 | X144954666Y-68016380D01* 79 | X144335619Y-68016380D01* 80 | X144049904Y-67016380D02* 81 | X143716571Y-68016380D01* 82 | X143383238Y-67016380D01* 83 | X147049904Y-57221428D02* 84 | X146288000Y-57221428D01* 85 | X145288000Y-57602380D02* 86 | X145859428Y-57602380D01* 87 | X145573714Y-57602380D02* 88 | X145573714Y-56602380D01* 89 | X145668952Y-56745238D01* 90 | X145764190Y-56840476D01* 91 | X145859428Y-56888095D01* 92 | X144907047Y-56697619D02* 93 | X144859428Y-56650000D01* 94 | X144764190Y-56602380D01* 95 | X144526095Y-56602380D01* 96 | X144430857Y-56650000D01* 97 | X144383238Y-56697619D01* 98 | X144335619Y-56792857D01* 99 | X144335619Y-56888095D01* 100 | X144383238Y-57030952D01* 101 | X144954666Y-57602380D01* 102 | X144335619Y-57602380D01* 103 | X144049904Y-56602380D02* 104 | X143716571Y-57602380D01* 105 | X143383238Y-56602380D01* 106 | D11* 107 | X132358285Y-79007714D02* 108 | X137596380Y-79007714D01* 109 | X137596380Y-47579142D01* 110 | X132358285Y-47579142D01* 111 | X123977333Y-61198190D02* 112 | X107215428Y-61198190D01* 113 | X107215428Y-66436285D01* 114 | X95691619Y-58055333D02* 115 | X97786857Y-57007714D01* 116 | X98834476Y-54912476D01* 117 | X98834476Y-50722000D01* 118 | X97786857Y-48626761D01* 119 | X95691619Y-47579142D01* 120 | X93596380Y-47579142D01* 121 | X91501142Y-48626761D01* 122 | X90453523Y-50722000D01* 123 | X90453523Y-54912476D01* 124 | X91501142Y-57007714D01* 125 | X93596380Y-58055333D01* 126 | X95691619Y-58055333D01* 127 | X82072571Y-63293428D02* 128 | X65310666Y-63293428D01* 129 | X51691619Y-49674380D02* 130 | X53786857Y-50722000D01* 131 | X54834476Y-52817238D01* 132 | X53786857Y-54912476D01* 133 | X51691619Y-55960095D01* 134 | X49596380Y-54912476D01* 135 | X48548761Y-52817238D01* 136 | X49596380Y-50722000D01* 137 | X51691619Y-49674380D01* 138 | X40167809Y-79007714D02* 139 | X34929714Y-79007714D01* 140 | X34929714Y-47579142D01* 141 | X40167809Y-47579142D01* 142 | X23405904Y-61198190D02* 143 | X6643999Y-61198190D01* 144 | X6643999Y-66436285D01* 145 | D12* 146 | X0Y-127000000D02* 147 | X0Y0D01* 148 | X150500000Y-127000000D02* 149 | X0Y-127000000D01* 150 | X150500000Y0D02* 151 | X150500000Y-127000000D01* 152 | X0Y0D02* 153 | X150500000Y0D01* 154 | D13* 155 | X137100000Y-68640000D02* 156 | X138430000Y-68640000D01* 157 | X137100000Y-67310000D02* 158 | X137100000Y-68640000D01* 159 | X139700000Y-68640000D02* 160 | X142300000Y-68640000D01* 161 | X139700000Y-66040000D02* 162 | X139700000Y-68640000D01* 163 | X137100000Y-66040000D02* 164 | X139700000Y-66040000D01* 165 | X142300000Y-68640000D02* 166 | X142300000Y-55820000D01* 167 | X137100000Y-66040000D02* 168 | X137100000Y-55820000D01* 169 | X137100000Y-55820000D02* 170 | X142300000Y-55820000D01* 171 | D14* 172 | X70250000Y-27050000D02* 173 | X15850000Y-27050000D01* 174 | X15850000Y-27050000D02* 175 | X15850000Y-54950000D01* 176 | X15850000Y-54950000D02* 177 | X70250000Y-54950000D01* 178 | X70250000Y-54950000D02* 179 | X70250000Y-27050000D01* 180 | D10* 181 | X140033333Y-69092380D02* 182 | X140033333Y-69806666D01* 183 | X140080952Y-69949523D01* 184 | X140176190Y-70044761D01* 185 | X140319047Y-70092380D01* 186 | X140414285Y-70092380D01* 187 | X139509523Y-70092380D02* 188 | X139319047Y-70092380D01* 189 | X139223809Y-70044761D01* 190 | X139176190Y-69997142D01* 191 | X139080952Y-69854285D01* 192 | X139033333Y-69663809D01* 193 | X139033333Y-69282857D01* 194 | X139080952Y-69187619D01* 195 | X139128571Y-69140000D01* 196 | X139223809Y-69092380D01* 197 | X139414285Y-69092380D01* 198 | X139509523Y-69140000D01* 199 | X139557142Y-69187619D01* 200 | X139604761Y-69282857D01* 201 | X139604761Y-69520952D01* 202 | X139557142Y-69616190D01* 203 | X139509523Y-69663809D01* 204 | X139414285Y-69711428D01* 205 | X139223809Y-69711428D01* 206 | X139128571Y-69663809D01* 207 | X139080952Y-69616190D01* 208 | X139033333Y-69520952D01* 209 | D15* 210 | X14006124Y-29408626D02* 211 | X14815960Y-29408626D01* 212 | X14911235Y-29456263D01* 213 | X14958873Y-29503901D01* 214 | X15006510Y-29599175D01* 215 | X15006510Y-29789725D01* 216 | X14958873Y-29885000D01* 217 | X14911235Y-29932637D01* 218 | X14815960Y-29980275D01* 219 | X14006124Y-29980275D01* 220 | X15006510Y-30980661D02* 221 | X15006510Y-30409012D01* 222 | X15006510Y-30694836D02* 223 | X14006124Y-30694836D01* 224 | X14149036Y-30599561D01* 225 | X14244311Y-30504287D01* 226 | X14291949Y-30409012D01* 227 | M02* 228 | --------------------------------------------------------------------------------