MixIt

A physical volume mixer for your computer with a customizable desktop interface.

Project Images

Showing a preview

Project Overview

MixIt started as a fun side project that I worked on in my free time. It stemmed from the problem of working remotely and wanting to control the volume of my applications without having to close remote desktop and adjust the volume on my local machine. I wanted to create a physical volume mixer that would allow me to control the volume of my applications and system sounds with a physical slider, providing a tactile and intuitive way to manage audio. The desktop interface was designed to be fully customizable, allowing users to choose which applications they want to control and how they want them displayed. Overall, MixIt was a passion project that allowed me to explore new technologies and create something that I found personally useful.

Tech Stack

PCB / CAD

KiCad
Autodesk Inventor

Firmware / Desktop

C++
PlatformIO
C#
.Net

Web

Next.js
TypeScript
MySQL

Other

GitHub
Linux
Figma

Hardware & PCB Design

The first area I focused on was the hardware. I bought a small soldering station and began experimenting with different components to build a physical volume mixer. After a few iterations, I quickly realized that hand-soldering wires was not reliable enough to ensure stable, interference-free readings. That realization pushed me to start learning how to read and design electrical schematics. Once I had a very fundamental understanding, I jumped into EasyEDA and designed my first PCB, or printed circuit board. It went horribly. I chose incorrect components, mismatched footprints, and the board was completely unusable. That failure became my first major lesson in the importance of planning and research. Before designing and ordering my next revision, I spent more time learning about component footprints, electrical best practices, and design constraints. I also switched to KiCad, which proved to be far more powerful and flexible. From there, I went through several PCB iterations, each one bringing me closer to a reliable and production-ready design. With every revision, I learned something new and significantly advanced my practical knowledge of circuit board design.

CAD Design and Enclosure Iterations

In parallel with PCB development, I was designing and 3D printing enclosures and internal components. Like KiCad, this was completely new territory for me. While I had prior experience with 3D modeling in Blender, designing for functional, real-world printing is fundamentally different. I started teaching myself Autodesk Inventor using a trial version. The learning curve was steep, especially coming from Blender’s modeling approach. After many tutorials, iterations, and failed prints, I completed the first version of the MixIt enclosure. Just like the PCBs, the enclosure has gone through countless revisions. It evolved from a larger, more modular design into a smaller and more refined form factor. Getting to the version currently sitting on my desk required significant iteration, but I am genuinely proud of how far it has come.

Firmware and Embedded Development

Alongside the hardware and enclosure design, I was developing the firmware for the ESP32 throughout various stages of the project. This was another completely new challenge. I had never written firmware that operated at such a fundamental level on physical hardware. This became one of my favorite parts of the entire project. Writing code and seeing immediate, tangible physical changes in the real world is incredibly rewarding. The firmware is written in C++, and I have primarily used PlatformIO for development. The first version of MixIt included five sliders and five individual displays. However, each display required its own framebuffer, and the ESP32 did not have enough memory to support five separate framebuffers simultaneously. This was one of the first major technical roadblocks I encountered. I was also using LVGL for the display UI. While it claimed to support multiple displays, the documentation did not work as expected. I spent several weeks simply trying to get all five displays functioning independently. Looking back, the root cause seems obvious, but at the time it was incredibly frustrating. Each display worked perfectly when tested individually. I eventually implemented a shared framebuffer approach and used chip select pins to target specific displays when pushing UI updates. I successfully rendered basic UI elements, such as a colored background with a display number, using this method. However, when integrating this approach into the broader codebase, everything broke again. The displays would load unique screens, briefly flash, and then stop updating entirely. After weeks of trial and error, I realized the issue stemmed from how the UI library instantiated and managed display objects. Ultimately, I rewrote significant portions of the UI handling logic to properly support multiple displays and control load order. While I resolved those issues, I have temporarily shifted focus to a version of the device without displays to simplify development and gather feedback on the core system before reintroducing advanced visual features.

Desktop Software and System Integration

Once I had a stable hardware prototype with a working PCB and enclosure, it was time to build the desktop application. With my background in web development, my initial instinct was to use Electron, as I had in previous projects. However, given the system-level requirements such as USB device detection, audio routing across applications, and deeper operating system integration, I decided to explore the .NET ecosystem instead. Part of that decision was long-term cross-platform distribution, but a larger factor was the limitations I had previously experienced with Electron. I needed a more system-native solution. I chose Avalonia UI for the frontend, which allowed me to build a modern and cross-platform interface without implementing every UI component from scratch. Just like PCB and CAD design, I started from almost zero knowledge and learned through experimentation, documentation, and iteration. AI tools were occasionally helpful for identifying potential problem areas, but they were often incomplete or incorrect when it came to implementation details. Ultimately, solving the core architectural and technical challenges required hands-on debugging, research, and persistence.

Deployment System and Remote Updates

The newest phase of this project focuses on building a proper software and firmware deployment system through the desktop application, powered by a companion web app. The web app serves two main purposes. First, it acts as a landing page for the MixIt project. Second, and more importantly, it hosts the backend API responsible for version verification, update checks, and secure distribution of both firmware and desktop software updates. This became necessary after I sent a mixer to a friend for real-world testing. In order for him to perform firmware updates, I had to manually package the firmware into a compressed archive, send it to him, and walk him through extracting and running a script. The same issue existed for the desktop application. Every update required me to generate and send a new setup executable manually. This process quickly became a major bottleneck. File transfers take time, and our method of sharing files over Discord became unreliable and tedious. Discord frequently removes files that appear suspicious, especially unsigned executables, which added another layer of friction. To solve this, I began developing a dedicated backend API and update distribution system. On the server side, I am building an interface that allows me to upload new releases, manage version numbers, organize release channels, and control which builds are publicly available. On the desktop side, I am implementing logic to securely check for updates, download new versions, and apply them automatically. This system removes the need for manual packaging and file sharing, reduces friction for testers, and lays the foundation for scalable distribution as the project grows. So far, development has been progressing well. Once fully implemented, this deployment system will dramatically streamline updates and make the entire MixIt ecosystem far easier to manage moving forward.

Summary

In short, this project required me to learn from scratch how to design and manufacture PCBs, create functional CAD models for real-world printing, develop embedded firmware in C++, and build a cross-platform desktop application using entirely new frameworks. Today, I have a fully functional device sitting on my desk that I use countless times a day. Every time I look at it, I am reminded of the late nights, the failed revisions, the debugging sessions, and the steady progress that led to this result. MixIt has been the most challenging and rewarding experience of my technical journey so far, and it fundamentally changed how I approach engineering problems.