mirror of
https://github.com/sjlongland/atinysynth.git
synced 2025-11-03 05:51:08 +10:00
I left this out because I thought the idea of modulus and division on a
MCU that lacks a hardware multiplier would be too much for it… and
indeed it was too much with my other project.
Thinking about it this afternoon, I had an idea. If I have 2^N samples,
then the modulus can be optimised to:
```
mod = sample & ((2**n)-1)
```
and the segment can be figured out by:
```
segment = sample >> n
```
The segment is two bits. A function that returns the scaled sine value
for a given scaled angle can be given as:
```
int8_t fp_sine(uint8_t angle) {
uint8_t segment = (angle >> POLY_SINE_SZ_BITS) & 3;
uint8_t offset = angle & ((1 << POLY_SINE_SZ_BITS)-1);
switch (segment) {
case 0:
return _poly_sine[offset];
case 1:
return _poly_sine[
POLY_SINE_SZ - offset];
case 2:
return -_poly_sine[offset];
case 3:
return -_poly_sine[
POLY_SINE_SZ - offset];
}
}
```
… or something like that. If `POLY_SINE_SZ_BITS=6`, then `angle=255`
represents 360°.
53 lines
1.2 KiB
Makefile
53 lines
1.2 KiB
Makefile
# Compiler definitions
|
|
CC = $(CROSS_COMPILE)gcc
|
|
AR = $(CROSS_COMPILE)ar
|
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
|
OBJDUMP = $(CROSS_COMPILE)objdump
|
|
SIZE = $(CROSS_COMPILE)size
|
|
|
|
INCLUDES ?=
|
|
LIBS ?=
|
|
PORT ?= pc
|
|
BINDIR ?= bin/$(PORT)
|
|
PORTDIR ?= ports/$(PORT)
|
|
OBJDIR ?= obj/$(PORT)
|
|
|
|
SRCDIR ?= $(PWD)
|
|
|
|
.PHONY: setfuse all clean
|
|
|
|
-include local.mk
|
|
include $(PORTDIR)/Makefile
|
|
|
|
$(BINDIR)/synth: $(OBJDIR)/main.o $(OBJDIR)/poly.a
|
|
@[ -d $(BINDIR) ] || mkdir -p $(BINDIR)
|
|
$(CC) -g -o $@ $(LDFLAGS) $(LIBS) $^
|
|
|
|
$(OBJDIR)/poly.a: $(OBJDIR)/adsr.o $(OBJDIR)/waveform.o
|
|
$(AR) rcs $@ $^
|
|
|
|
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
|
|
$(CC) -o $@ -c $(CPPFLAGS) $(INCLUDES) $(CFLAGS) $<
|
|
$(CC) -MM $(CPPFLAGS) $(INCLUDES) $< \
|
|
| sed -e '/^[^ ]\+:/ s:^:$(OBJDIR)/:g' > $@.dep
|
|
|
|
$(OBJDIR)/%.o: $(PORTDIR)/%.c
|
|
@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
|
|
$(CC) -o $@ -c $(CPPFLAGS) $(INCLUDES) $(CFLAGS) $<
|
|
$(CC) -MM $(CPPFLAGS) $(INCLUDES) $< \
|
|
| sed -e '/^[^ ]\+:/ s:^:$(OBJDIR)/:g' > $@.dep
|
|
|
|
$(SRCDIR)/sine.c: $(SRCDIR)/gensine.py
|
|
python $^ --amplitude 127 --num-samples-bits \
|
|
--num-samples 6 --data-type int8_t \
|
|
> $@
|
|
|
|
clean:
|
|
-rm -fr $(OBJDIR) $(BINDIR)
|
|
|
|
$(BINDIR)/%.ihex: $(BINDIR)/%
|
|
$(OBJCOPY) -j .text -j .data -O ihex $^ $@
|
|
|
|
-include $(OBJDIR)/*.dep
|