Skip to content

Commit

Permalink
Feature/adding euphonium (#32)
Browse files Browse the repository at this point in the history
* adding euphonium as a submodule

* adding euphonium as a submodule

* adding checkout guide

* testing makefile for building with customized config

* adding initial voicing DSP setup

* adding support for macos

* making root makefile
  • Loading branch information
TooDissing authored Aug 7, 2022
1 parent 4e3f7f8 commit a82683c
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "software/euphonium"]
path = software/euphonium
url = https://github.com/feelfreelinux/euphonium.git
25 changes: 6 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
# Minimal makefile for Sphinx documentation
#
all:
@$(MAKE) -C docs html
@$(MAKE) -C software esp32

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = docs/source
BUILDDIR = docs/build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
clean:
@$(MAKE) -C docs clean
@$(MAKE) -C software clean
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ This project and all it's work are licensed under the [Creative Commons Attribut
![BY SA License!](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg "The license")
[![Documentation Status](https://readthedocs.org/projects/stroem/badge/?version=latest)](https://stroem.readthedocs.io/en/latest/?badge=latest)

## Getting started

### Checking out the repository
As this project uses the git `submodule` feature to fetch all the needed source files, one would need to have this in mind when performing the checkout.

To checkout everything - including all submodules - the following snippet are handy:
```
git clone --recurse-submodules -j$(nproc) https://github.com/LydByDissing/stroem.git
```

## Project description and Design Goals
As mentioned above, this project aims at designing a **wifi speaker**, capable of streaming audio using **Bluetooth** and **Spotify Connect**.

Expand Down
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
1 change: 1 addition & 0 deletions docs/source/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ sphinxemoji>=0.2.0
sphinx-last-updated-by-git>=0.3.2
schemdraw>=0.14
sphinx-github-changelog>=1.2.0
myst-parser>=0.18.0
1 change: 1 addition & 0 deletions software/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config/euphonium/scripts/configuration/wifi.config.json
26 changes: 26 additions & 0 deletions software/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.DEFAULT_GOAL := esp32
JTAG_PORT ?= "/dev/ttyUSB0"
COPY_FLAGS := -v -R
ifeq ($(OS),Windows_NT)
#??
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
COPY_FLAGS += -u
endif
ifeq ($(UNAME_S),Darwin)
#COPY_FLAGS += -u
endif
endif

copy-config:
@echo "Copying local cofig"
cp ${COPY_FLAGS} config/* euphonium/

esp32: copy-config
cd euphonium/targets/esp32; sh generate_full_build.sh;


flash-all: esp32
@echo "flashing using this port '${JTAG_PORT}'"
cd euphonium/targets/esp32; sh flash_all.sh ${JTAG_PORT};
154 changes: 154 additions & 0 deletions software/config/euphonium/scripts/esp32/dacs/ma12070p_driver.be
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
volume_strip = nil
class MA12070P : DACDriver
var volume_table
def init()
# define a volume table, saves up on log10
#self.volume_table = [255,160,120,100,90,85,80, 75, 70, 65, 61, 57, 53, 50, 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 12, 10, 8, 6, 4, 2, 0]

#self.volume_table = [255, 160, 100, 90, 80, 70, 65, 60, 57, 54, 51, 48, 46, 44, 42, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24]

self.volume_table = [255, 160, 100, 90, 80, 70, 65, 60, 57, 54, 51, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 18, 17, 16, 15, 14]

self.name = "MA12070P"
self.hardware_volume_control = true
self.datasheet_link = "https://www.infineon.com/dgdl/Infineon-MA12070P-DS-v01_00-EN.pdf?fileId=5546d46264a8de7e0164b761f2f261e4"
end

def init_i2s()
# PINOUT: SDA: 23, SCL: 22, SDATA: 26, LRCLK: 25, BCLK: 5
# All of I2S init logic goes here

var ADDR = 0x20

var config = I2SConfig()
config.sample_rate = 44100
config.bits_per_sample = 32

# MCLK: 22.58MHz @ 44.1KHz - sufficient for running the dedicated dsp!
config.mclk = 512
config.comm_format = I2S_CHANNEL_FMT_RIGHT_LEFT
config.channel_format = I2S_COMM_FORMAT_I2S

i2s.install(config)
i2s.set_pins(self.get_i2s_pins())

# Ensures we expand from 16 to 32 bit, to match MA12070P Clock system.
i2s.expand(16, 32)

# Start I2C Driver
i2c.install(int(self.get_gpio('sda')), int(self.get_gpio('scl')))

# Mute Amplifier before i2c comm & enable. Mute pin: 21
gpio.pin_mode(8, gpio.OUTPUT)
gpio.digital_write(8, gpio.LOW)

# Enable Amplifier. Enable pin: 19
gpio.pin_mode(19, gpio.OUTPUT)
gpio.digital_write(19, gpio.LOW)

# Set Amp to Left-justified format
i2c.write(ADDR, 53, 8)

## Setting power profile 2 as active
# i2c.write(ADDR, 0x1D, 0x02)

# Set Volume to a safe level..
i2c.write(ADDR, 64, 0x50)

# Clear static error register.
i2c.write(ADDR, 45, 0x34)
i2c.write(ADDR, 45, 0x30)

# Init done.

# Unmute Amplifier
gpio.digital_write(8, gpio.HIGH)
sleep_ms(300)
volume_strip = LEDStrip(0, 4, 12, 0, 10)
end

def unload_i2s()
i2s.disable_expand()
i2s.uninstall()
i2c.delete()
end

def set_volume(volume)
# Volume is in range from 1 to 100
# Volume register is flipped in MA12070P.. Hence 100 - realvol.
var volume_step = volume / 100.0
var actual_volume = int(volume_step * 32)

var ADDR = 0x20

# Write it..
i2c.write(ADDR, 64, self.volume_table[actual_volume])

end

def make_config_form(ctx, state)
ctx.create_group('MA12070P_pins', { 'label': 'DAC binary pins' })

ctx.number_field('enablePin', {
'label': "Enable Pin",
'default': "0",
'group': 'MA12070P_pins',
})

ctx.number_field('mutePin', {
'label': "Mute Pin",
'default': "0",
'group': 'MA12070P_pins',
})
super(self).make_config_form(ctx, state)
end

end

hardware.register_driver(MA12070P())

def show_led_volume(led_volume)
if (volume_strip != nil)
leds_to_show = int((real(led_volume) /100) * 12)
step = ((real(led_volume) /100) * 12) - leds_to_show
for led_index : 0..(leds_to_show-1)
volume_strip[led_index] = [255, 255, 255]
end

for led_index : leds_to_show..11
volume_strip[led_index] = [0, 0, 0]
end

volume_strip[leds_to_show] = [int(255 * step), int(255 * step), int(255 * step)]

volume_strip.show()
end
end

local_volume = 0
gpio.register_encoder(20, 2, def (interaction)
if interaction == gpio.ENCODER_CW
if (local_volume < 100)
local_volume += (100 / 20)
end

if (local_volume > 100)
local_volume = 100
end
else
if (local_volume > 0)
local_volume -= (100 / 20)
end

if (local_volume < 0)
local_volume = 0
end
end
show_led_volume(local_volume)
euphonium.apply_volume(local_volume)
end)

euphonium.on_event(EVENT_VOLUME_UPDATED, def (volume)
local_volume = volume
show_led_volume(volume)
end)
58 changes: 58 additions & 0 deletions software/config/euphonium/scripts/extensions.be
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# # Here add your own initialiaization files

dsp.set_gain_db(-9)

dsp.add_mono_downmix()

# Crossover
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_LOWPASS, { 'f': real(0.079365079365079), 'q': 0.7 })

# Protection filter
## Not sure about the Q for a 8th order filter, so adding several 2nd ones instead
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
#dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
#dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
#dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })
#dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHPASS, { 'f': real(0.001179138321995), 'q': 0.7 })

# Vocing
#HS_1_negative
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.002267573696145), 'g': -10, 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.002267573696145), 'g': -10, 'q': 0.7 })
#HS_2_positive
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.040816326530612), 'g': 9, 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.040816326530612), 'g': 9, 'q': 0.7 })
#HS_2_negative
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.073242630385488), 'g': -4, 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.073242630385488), 'g': -4, 'q': 0.7 })
#HS_3_negative
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.007936507936508), 'g': -0.9, 'q': 0.7 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_HIGHSHELF, { 'f': real(0.007936507936508), 'g': -0.9, 'q': 0.7 })

#peak_1
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.001768707482993), 'g': 10, 'q': 3 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.001768707482993), 'g': 10, 'q': 3 })
#peak_2
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.004195011337868), 'g': -3.8, 'q': 2 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.004195011337868), 'g': -3.8, 'q': 2 })
#peak_3
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.014739229024943), 'g': 4, 'q': 6 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.014739229024943), 'g': 4, 'q': 6 })
#peak_4
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.011995464852608), 'g': -3.5, 'q': 6 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.011995464852608), 'g': -3.5, 'q': 6 })
#peak_5
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.032086167800454), 'g': -2, 'q': 2.5 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.032086167800454), 'g': -2, 'q': 2.5 })
#peak_6
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.001360544217687), 'g': 6, 'q': 5 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.001360544217687), 'g': 6, 'q': 5 })
#peak_7
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.072562358276644), 'g': 3, 'q': 5 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.072562358276644), 'g': 3, 'q': 5 })
#peak_8
dsp.add_biquad(dsp.CHANNEL_RIGHT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.149659863945578), 'g': 3, 'q': 3 })
dsp.add_biquad(dsp.CHANNEL_LEFT, dsp.BIQUAD_TYPE_PEAKING_EQ, { 'f': real(0.149659863945578), 'g': 3, 'q': 3 })
1 change: 1 addition & 0 deletions software/euphonium
Submodule euphonium added at f747ce

0 comments on commit a82683c

Please sign in to comment.