deej

package module
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2020 License: MIT Imports: 23 Imported by: 0

README

deej

Arduino and Go project for controlling application volumes on Windows PCs with physical sliders (like a DJ!)

New: deej has been re-written as a Go application! More details | Download

New: join the deej Discord server if you need help or have any questions!

Discord

Video demonstration on YouTube

See some awesome versions built by people around the world!

Physical build

Table of contents

What's new

deej is now written in Go, and distributed as a single Windows executable (of course you can still build from source if that's your thing).

This means you no longer have to maintain a Python environment. You can even build one for your friends, give them a simple download link and they'll be good to go!

In addition, check out these features:

  • Fully backwards-compatible with your existing config.yaml and Arduino sketch
  • Faster and more lightweight, consuming around 10MB of memory
  • Runs from your system tray
  • Helpful notifications will let you know if something isn't working
  • New system flag lets you assign the "system sounds" volume level
  • Supports everything the Python version did

Migrating from the Python version? Great! You only need to keep your config.yaml file. Download the executable from the releases page, place it alongside the configuration file and you're done.

Prefer to stick with Python? That's totally fine. It will no longer be maintained, but you can always find it in the legacy-python branch.

How it works

Hardware
  • The sliders are connected to 5 (or as many as you like) analog pins on an Arduino Nano/Uno board. They're powered from the board's 5V output (see schematic)
  • The board connects via a USB cable to the PC
Schematic

Hardware schematic

Software
  • The code running on the Arduino board is a C program constantly writing current slider values over its Serial interface deej-arduino.ino
  • The PC runs a lightweight Go client cmd/main.go in the background. This client reads the serial stream and adjusts app volumes according to the given configuration file

Slider mapping (configuration)

deej uses a simple YAML-formatted configuration file named config.yaml, placed alongside the deej executable.

The config file determines which applications are mapped to which sliders, and which COM port/baud rate to use for the connection to the Arduino board.

This file auto-reloads when its contents are changed, so you can change application mappings on-the-fly without restarting deej.

It looks like this:

slider_mapping:
  0: master
  1: chrome.exe
  2: spotify.exe
  3:
    - pathofexile_x64.exe
    - rocketleague.exe
  4: discord.exe

# limits how often deej will look for new processes
process_refresh_frequency: 5

# settings for connecting to the arduino board
com_port: COM4
baud_rate: 9600
  • master is a special option for controlling master volume of the system.
  • New: system is a special option for controlling the "System sounds" volume in the Windows mixer
  • Process names aren't case-sensitive, meaning both chrome.exe and CHROME.exe will work
  • You can create groups of process names (using a list) to either:
    • control more than one app with a single slider
    • choose whichever process in the group that's currently running (i.e. to have one slider control any game you're playing)

Build your own!

Building deej is very simple. You only need a few cheap parts - it's an excellent starter project (and my first Arduino project, personally). Remember that if you need any help or have a question that's not answered here, you can always join the deej Discord server.

Build deej for yourself, or as an awesome gift for your gaming buddies!

Bill of Materials
  • An Arduino Nano or Uno board
    • I officially recommend using a Nano as it offers a smaller form-factor, a friendlier USB connector and more analog pins. Plus it's cheaper
  • A few slider potentiometers, up to your number of free analog pins (they're around 1-2 USD each, and come with a standard 10K Ohm variable resistor)
    • Important: make sure to get linear sliders, not logarithmic ones! Check the product description
    • You can also use circular knobs if you like
  • Some wires
  • Any kind of box to hold everything together
Build procedure
  • Connect everything according to the schematic
  • Test with a multimeter to be sure your sliders are hooked up correctly
  • Flash the Arduino chip with the sketch in arduino\deej-5-sliders-vanilla
    • If you have more or less than 5 sliders, you can edit the sketch to match what you have
  • After flashing, check the serial monitor. You should see a constant stream of values separated by a pipe (|) character, e.g. 0|240|1023|0|483
    • When you move a slider, its corresponding value should move between 0 and 1023
  • Congratulations, you're now ready to run the deej executable!

How to run

Requirements
  • Windows. That's it
Download and installation
  • Head over to the releases page and download the latest version's executable and configuration file (deej.exe and config.yaml)
  • Place them in the same directory anywhere on your machine
  • (Optional) Create a shortcut to deej.exe and copy it to %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup to have deej run on boot
Building from source

If you'd rather not download a compiled executable, or want to extend deej or modify it to your needs, feel free to clone the repository and build it yourself. All you need is a somewhat recent (v1.12-ish+) Go environment on your machine.

Like other Go packages, you can also use the go get tool: go get -u github.com/omriharel/deej.

If you need any help with this, please join our Discord server.

Community

Discord

While deej is still a very new project, a vibrant community has already started to grow around it. Come hang out with us in the deej Discord server, or check out awesome builds made by our members in the community showcase.

Long-ish term roadmap

  • Serial communications rework to support two-way data flows for better extensibility
  • Mic input support
  • Basic GUI to replace manual configuration editing
  • Feel free to open an issue if you feel like something else is missing

License

deej is released under the MIT license.

Documentation

Overview

Package deej provides a machine-side client that pairs with an Arduino chip to form a tactile, physical volume control system/

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewLogger

func NewLogger(buildType string) (*zap.SugaredLogger, error)

NewLogger provides a logger instance for the whole program

Types

type CanonicalConfig

type CanonicalConfig struct {
	SliderMapping *sliderMap

	// renamed from ProcessRefreshFrequency, key left as is in yaml-config for backwards compatibility
	SessionRefreshThreshold time.Duration

	ConnectionInfo struct {
		COMPort  string
		BaudRate int
	}
	// contains filtered or unexported fields
}

CanonicalConfig provides application-wide access to configuration fields, as well as loading/file watching logic for deej's configuration file

func NewConfig

func NewConfig(logger *zap.SugaredLogger, notifier Notifier) (*CanonicalConfig, error)

NewConfig creates a config instance for the deej object

func (*CanonicalConfig) Load

func (cc *CanonicalConfig) Load() error

Load reads a config file from disk and tries to parse it

func (*CanonicalConfig) StopWatchingConfigFile

func (cc *CanonicalConfig) StopWatchingConfigFile()

StopWatchingConfigFile signals our filesystem watcher to stop

func (*CanonicalConfig) SubscribeToChanges

func (cc *CanonicalConfig) SubscribeToChanges() chan bool

SubscribeToChanges allows external components to receive updates when the config is reloaded

func (*CanonicalConfig) WatchConfigFileChanges

func (cc *CanonicalConfig) WatchConfigFileChanges()

WatchConfigFileChanges starts watching for configuration file changes and attempts reloading the config when they happen

type Deej

type Deej struct {
	// contains filtered or unexported fields
}

Deej is the main entity managing access to all sub-components

func NewDeej

func NewDeej(logger *zap.SugaredLogger) (*Deej, error)

NewDeej creates a Deej instance

func (*Deej) Initialize

func (d *Deej) Initialize() error

Initialize sets up components and starts to run in the background

func (*Deej) SetVersion

func (d *Deej) SetVersion(version string)

SetVersion causes deej to add a version string to its tray menu if called before Initialize

type Notifier

type Notifier interface {
	Notify(title string, message string)
}

Notifier provides generic notification sending

type SerialIO

type SerialIO struct {
	// contains filtered or unexported fields
}

SerialIO provides a deej-aware abstraction layer to managing serial I/O

func NewSerialIO

func NewSerialIO(deej *Deej, logger *zap.SugaredLogger) (*SerialIO, error)

NewSerialIO creates a SerialIO instance that uses the provided deej instance's connection info to establish communications with the arduino chip

func (*SerialIO) Start

func (sio *SerialIO) Start() error

Start attempts to connect to our arduino chip

func (*SerialIO) Stop

func (sio *SerialIO) Stop()

Stop signals us to shut down our serial connection, if one is active

func (*SerialIO) SubscribeToSliderMoveEvents

func (sio *SerialIO) SubscribeToSliderMoveEvents() chan SliderMoveEvent

SubscribeToSliderMoveEvents returns an unbuffered channel that receives a sliderMoveEvent struct every time a slider moves

type Session

type Session interface {
	GetVolume() float32
	SetVolume(v float32) error

	Key() string
	Release()
}

Session represents a single addressable audio session

type SessionFinder added in v0.9.2

type SessionFinder interface {
	GetAllSessions() ([]Session, error)
}

SessionFinder represents an entity that can find all current audio sessions

type SliderMoveEvent

type SliderMoveEvent struct {
	SliderID     int
	PercentValue float32
}

SliderMoveEvent represents a single slider move captured by deej

type ToastNotifier

type ToastNotifier struct {
	// contains filtered or unexported fields
}

ToastNotifier provides toast notifications for Windows

func NewToastNotifier

func NewToastNotifier(logger *zap.SugaredLogger) (*ToastNotifier, error)

NewToastNotifier creates a new ToastNotifier

func (*ToastNotifier) Notify

func (tn *ToastNotifier) Notify(title string, message string)

Notify sends a toast notification (or falls back to other types of notification for older Windows versions)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL