Thursday, February 13, 2020

C64 touch pad to MIDI/CV controller

A while back (like 2 years?) I was browsing the racks of the late, great HSC surplus store when I stumbled across a TouchPoint graphics tablet designed to work with, yes, a C64. I've never seen one before or since, but at $10 in good shape it was an easy buy.

With a big touch surface, buttons on the side, and plenty of room inside for mods, it looked perfect to repurpose as a control surface to send a bunch of useful MIDI CCs.

Here's the finished item with some additional knobs, switches, and I/O, plus an Arduino Uno inside to handle the controls and send MIDI over USB. (Not pictured is the plastic stylus that came with the pad but I don't use -- it responds just fine to finger pressure.)


Full feature list:
  • X/Y touch pad with enable/disable switches for each axis (for MIDI learn situations)
  • LFO with:
    • Four blendable waveforms (triangle, noise, saw up, 50% square)
    • Selectable looping or one-shot mode with a reset/trigger button
    • Knobs and switches for LFO output enable/disable, waveform blend, speed range, speed, and amplitude
    • LED display of waveform and speed
  • Five momentary buttons
  • Three toggle switches
  • +5v send/return loop for an expression pedal (2x RCA jacks)
  • CV LFO output (rightmost RCA jack)
The red button at the top resets the secondary Atmel microcontroller on the Uno board so you can load firmware for MIDI I/O, when the touch pad is in operation, or communication with the Arduino Uno while programming.

This pad has been sporadically useful for MIDI control of synths, DAWs, and Audiomulch -- but it's really taken on new life since I started using VCV Rack, which makes it easy to use all the pad's physical controls as virtual control voltages. Wiring up the X/Y axes to control 5-6 parameters each and sweeping a finger around the surface is godlike! 

The actual CV output for the LFO is also super useful with my Neutron. I thought about adding CV outputs for the pad, but last time I cracked it open and saw the hash I'd made of the internal wiring, I reconsidered. Whatever -- I think the Uno is out of useful output pins anyway. :) 

Monday, December 8, 2014

Cricket part 2: Robot --> drum synth

One of my earlier posts detailed my abandonded plans for a kids' robot I called Cricket. But the brain module worked just fine and featured a bunch of pots for real-time control, so why not turn it into a drum synthesizer?? It already had a sound system (amp and speaker) and a big yellow arcade button as a trigger.


Cricket the drum synth: The Cricket brain module with more pots, no motors.

The brain module was packed full of cables, controls, and LED diffusion pods, so my first goal was not to modify any circuitry. (I added pots and switches to the front panel, but they plugged into existing headers.)


Second, I didn't want it to take forever, so I kept the feature list simple:
  • Two digital oscillators with selectable waveforms (saw/triangle/noise/50% square) and independent pitch controls
  • Two-stage (attack and release) amplitude envelope
  • Global pitch LFO with controls for speed, depth, and waveform (same choices as the oscillators)
  • Osc 2 -> Osc 1 frequency modulation, with adjustable depth and a high/low pitch range switch for Osc 2
  • Selectable AND/OR/XORing of the oscillators with each other
  • Digital wrapping/clipping distortion with adjustable depth  
(Yes, there's no filter. Deal with it. :) 



I had a switch left over, so it selects the direction the LEDs light up while Cricket is running. There's also an "in" jack that I might in future use as a footswitch or external trigger input. (The MIDI jack isn't functional.)


I'm really pleased with the sound! It's digital and raw, but also organic and surprisingly varied. You can get kicks, snares, metallic plinks, noise bursts, bass sounds, and even vocal-like screams and yawps. I got what I wanted and then some... pretty good for 8-bit waveforms pumped out of a single pin of the dsPIC using 6-bit PWM. The video below is pure multitracked Cricket -- no processing except for a bit of autopanning:

 

Here's another video with a more detailed exploration of the features and sound:



 

Thursday, June 5, 2014

The magic of speech synthesis: linear predictive coding

Growing up in the '80s and '90s, I had a pretty decent idea how a lot of tech around me worked. Maybe I couldn't actually fix a TV with a blown tube or swap out a dead (soldered) CPU on a motherboard yet, but I knew how the big pieces fit together, what they were supposed to do, and what might happen if a given piece went kaput.

Speech synthesizers were not in that category.

When I first encountered a Speak 'N' Spell, it seemed like magic. The voice was so crude and inhuman it was obviously computer-generated (i.e., not recorded). It was halting and seemingly stitched together from scraps of speech, but I'd never even heard of phonemes, let alone a process by which a chip like the one I found inside could spit out words and phrases.

For a long time, I had an inordinate fascination with the SnS, the General Instruments SP0256-AL2, and the speech synthesis cartridges for the TI-99/4A and TRS-80. (Wasn't there a C64 speech cartridge too?) I never did find out much about how they worked, though, or get my hands on hardware to experiment.

Linear Predictive Coding: Speech Analysis, Synthesis, Compression

Fast-forward 20 years or so to DSP class... and it turns out that most of those devices, along with a healthy amount of speech synthesis today, is based on variants of the linear predictive coding (LPC) technique. For my class project, I worked up an LPC example in Matlab to peek under the hood.

LPC models the human vocal tract as a medium-order time-varying filter (typically 10th-order) excited by pitched and unpitched (noise) impulses created by the diaphragm and vocal cords. A speech sequence (e.g., a word) is created from a train of impulses filtered with changing filter coefficients and gain.

LPC discretizes speech into overlapping frames of 10-20 ms, where the filter coefficients, gain, and impulse type and pitch are constant for a given  frame.

LPC is most commonly used as a compression scheme: speech is analyzed to estimate frame parameters, the frame parameters are transmitted using far fewer bits than the original speech, and the parameters are applied to a filter and impulse train in the receiver to synthesize output speech.

The figure shows data from the whole process. From the top, there's the filtered input audio, the detected pitch period in samples for each frame, the resulting excitation signals (pulse trains in green, noise in blue) and gains, and the final synthesized output.

 
Conclusions

Basic LPC turned out to be easier and more interesting to implement than I expected... considering that I didn't write custom code for everything and that I did leave out quite a bit of work that would normally be required to tune up the sound quality, optimize computing time, and/or achieve compression specs. (Here's a great writeup on all the work that went into the Speak 'N' Spell.)

A few samples of the output:


It's pretty cool to be able to pull speech apart, in a sense, and put it back together any way you like. I'm interested in experimenting with my code to create interesting musical textures, including vocoding by replacing the impulse train with audio from a musical instrument.

Code is here!

Friday, January 24, 2014

Lego Segway with minimal-order observer control

Self-balancing Lego robots are nothing new, but everyone uses PID controllers. I wanted to implement an observer controller to do something new and flex my controls muscles. 

I built a Mindstorms robot that uses a light sensor to measure light reflected off the floor and thereby the robot's tilt. This turned out to be finicky since I had to set the zero point manually, and ambient light variations screwed things up fairly often. It worked well enough in the end though.


Controller Design
A full-order observer controller uses a model of the system in the control loop, which allows us to observe state information that would otherwise be hidden in the actual system. We can then use that state info in the feedback to reduce the error, which now incorporates both the system and model outputs. This can be a robust way to control high-dimensional systems while also being able to inspect the (estimated) states for useful insights.

However, we may not actually need all the state information. A minimal-order observer (aka functional observer) still uses a model, but requires fewer poles to be chosen than a full-order controller. That simplifies design and eliminates the need to calculate and compute state-space transformation matrices.

The figure shows the minimal-order observer, with the controller elements labeled as psi 0 and psi 1. In the lower diagram, psi 0 is algebraically combined with the summation block to simplify coding. As noted, each psi function is a ratio of (simple) Z-domain transfer polynomials.

Minimal-order diagram in Simulink. In the actual system, the real robot takes the place of the "Linearized Model".
Results
I coded the observer controller in RobotC with the help of a couple of Matlab scripts to choose poles and calculate the coefficients of the transfer polynomials. I could have put more work into accurately modeling the robot (weighing it properly, etc.), but as you can see, it works well enough.


The video's a bit long, to show the balancing stability - skip to 1:30 to see me driving the robot with a joystick over Bluetooth. Driving could use some smoothing, but it's fun.

Code is here.
            

Sunday, June 16, 2013

Tunes are go!

Holy Roland, I can't believe it's taken me until 2013 to move my music hosting off MySpace! The only thing more embarrassing is that people have invested money in MySpace in the interim... good luck Justin.

Anyway, I've got three albums up: Singlestar (the latest) along with collections of tracks for both film music and older stuff. The site is here, but I've also embedded players below. Enjoy!

Krylenko (Bandcamp)

Singlestar


Composed - Music for Film


Collected 1999-2009

Wednesday, June 12, 2013

Remixing a mixer

Is there a recording musician who hasn't owned a Behringer mixer? They're cheap as chips and do what they say on the tin.

I'm surprised my current model is only the second I've owned in 15 years of mucking about with music gear. It's a tiny thing, but just about perfect for the space I have and inputs I need. That said, it didn't come with an aux send. Those are super-useful, especially with my new spring reverb, so I decided to add one.

A bit of parts diving, soldering, and gluing later and I've got a mono out, stereo return aux bus. Had to scrap the tape I/O but don't think I'll be missing it. Here's a pic of this truly classic Junkbox Raider mod:

I could have made it uglier, but I ran out of time.

 

Monday, January 28, 2013

I broke a what?!?!

I've busted a lot of stuff over the years - mostly the poorly constructed and therefore delicate projects I'd built, but also plenty of electronic components, hardware, circuit boards, etc. I've even broken and bent a few small tools.

But until yesterday I'd never snapped off half a pair of needlenose pliers so cleanly it looked like they'd been sawed apart. How's that even possible? (Sure, my finger strength is unparalleled, but I wield it gently. :)

I'd post a picture, but I can't be bothered to dig 'em out from under the pile of Robosapien discards clogging up the trash. Trust this random guy on the Internet, though - it really happened.

Maximum information, minimum post

I've been planning for a while to write up some research I worked on in 2011 involving intrinsic "motivation" for robots. We got a workshop paper out of it, and I presented the results to the ECE department last year. I also planned to extend it into my thesis project.

But... the lab went through some advisor round-robin and the project fell apart, and I just don't feel like writing it up into a full post anymore.

In a nutshell, our robot learned a policy for a partially observable Markov decision process (POMDP) to learn about objects in a space by manipulating them with its arm, then assigning object classification probabilities, with Shannon information gain across all objects as the learning reward.

Here's the AAAI workshop abstract, with a link to the full PDF:
http://www.aaai.org/ocs/index.php/WS/AAAIW11/paper/view/3960

Here's a fun picture of the robot!

Sunday, December 18, 2011

Cricket, the toy robot that never was

I decided earlier this year to build a robot as a gift for a young relative. I've always found Braitenberg vehicles interesting and wanted to create a mobile robot with simple sensors and the ability to switch among several Braitenberg-type "personalities" (light-following, sound-avoiding, etc.).

Thus Cricket was born.

Cricket with, well, some things working.

Turns out I underestimated the chaos of the target environment, with multiple even younger siblings running around. Only a totally bombproof gift would work - which Cricket is not.

That, plus some irritating bugs I don't feel like ironing out, means Cricket is now abandonware. But not forgotten!


Testing the light pods.

Full details and more pics after the jump.


Friday, December 9, 2011

Hot glue FTW!

How did it take me so long to discover hot glue?!?!?! Everyone else smears it on their robots and projects, but somehow it never occurred to me to try it. As an inveterate epoxy user - what a revelation!

Sure, it can get messy. But the adhesive power, the (literal) flexibility, and the absolute trifle of time it takes to set up are mind-bottling.

I just built a set of contact bumpers for a small robot in about 10 minutes, including time to mount them on the robot itself. With epoxy I'd still be waiting for the bumpers to set up, then I'd have to mount them tomorrow and wait another day, and it'd still be fairly brittle.

Now I'm on the prowl for anything that needs gluing - just like way back in the day when I discovered duct tape. Thanks, hot glue gun! 

Wednesday, December 7, 2011

Neural networks part 2: Evolving a "living" robot

In my first post on neural networks, I discussed training the network using gradient descent - a pretty straightforward optimization method. This project took a completely different approach: evolving the network's weights with genetic algorithms

Our project team designed a virtual agent (robot) that learned to avoid obstacles while acting autonomously to "work" and "eat", maintaining its own internal conditions in proper balance like a living animal.

The virtual robot (green circle) navigates from the green "health" waypoint to the red "work" waypoint while avoiding the gray obstacles.

We started in simulation, planning to implement the working system on a physical robot, but ran out of time to get the hardware side functioning. C'est la vie robotique! We did make sure our virtual agent would use the same motor commands as the real robot, so the simulation wasn't completely disconnected from the real world.

Full details, including the multilevel control architecture we developed, after the jump.

Wednesday, November 9, 2011

Neural networks part 1: Teaching Canyonero to drive

Artificial neural networks (ANNs) are modeled after natural neural networks (brains and nervous systems) and though they don't work exactly alike, both a brain and an ANN can learn arbitrarily complex tasks without being told exactly how - they just need data about the task and their performance.

A generic artificial neural network.

ANNs have been applied to a lot of artificial intelligence and machine learning problems, from autonomous vehicle driving to recognizing handwritten address on envelopes to creating artificial intelligence for video game agents.
  
I won't go deep into the math behind ANNs here; there are great sites on the web (and it's not really difficult, there's just a lot of bookkeeping). 

Instead, I'll take two posts to describe a couple of neural net projects I've worked on. First up: a mobile robot called Canyonero that learned to compensate for its own mismatched wheels.

Canyonero, with a camera in the front and a netbook running an ANN.


Tuesday, October 4, 2011

PIC + pyserial + Windows

I use PIC microcontrollers fairly often since I'm familiar with them and they generally have the features I need. That's a pain when I need to program a PIC board, then talk to the code over a serial port. I need Windows to burn the firmware, but I've never bothered to learn Windows serial port programming. 

Then I realized the pyserial library for Python is cross-platform. Sweet! One download and one "import serial" later I was burning firmware and talking to the PIC over USB serial, all from inside Vista.

PIC serial comms to the left of me, Python to the right, here I am, stuck in the middle with you...
(Well, almost... there's some weird version conflict where the pyserial version I downloaded doesn't like the Python version I have. Lucky I found a sketchy-looking forum post with some random dude's replacement for a key pyserial file. Copy, paste, run, and done. Sure, I can't close the serial port without getting an error, but it opens and handles data just fine. Thanks Internet!)

   

Friday, September 30, 2011

Microchip ICD adapter -> NXT port breakout board

Lego Mindstorms NXT kits are great for robotic prototypes and experiments. The computer brick and sensors communicate over I2C, which is great for DIY expansions. Unfortunately they also use nonstandard RJ connectors. (You can now buy the connectors, but that's no fun.)

The NXT's RJ port with offset connector lock.


I wanted to access the I2C, so I hacked up my "sound sensor" (microphone) to add a standard 0.1" header. But even as hacks go, it was ugly and only allowed access to 5 of the 6 pins.

However, a while ago the ECE department was getting rid of surplus parts, and among the reels of SMD resistors were a handful of header-to-RJ45 adapter boards that come with Microchip ICD programmers.

Microchip, on the other hand, make this handy board with a normal RJ45 port.
One day I happened to look at one and realize the RJ port on the Microchip board had the same pin spacing as the NXT ports. I cracked open my earlier hack, did a bit of soldering and desoldering, and boom - I had a small, clean NXT-port-to-header breakout board.

The connector lock may be shifted, but the footprint is the same as RJ45.
Mind you, I haven't actually coded up an I2C interface yet. But I can have a lot of lovely continuity beeps between NXT ports and a breadboard now. :)

     

Monday, September 12, 2011

ModDroid, we hardly knew ye

One of the projects I worked on at the Robotics and Neural Systems Lab was a modular robot we were going to design and build for a conference. Each module would be about 8" x 8" and stackable, so you could load up on CPUs and batteries, add some arms, mobility options, different heads...

Alas, for a variety of reasons we didn't get that far - we built just enough modules to make a basic robot we named ModDroid. ModDroid's coolest feature was his adorable head, designed by two of my labmates and featuring 8x8 RGB LED matrix eyes from Sparkfun. I had a lot of fun coding up the eye animations on the PIC control board.


 

I recently saw ModDroid sitting in a heap of parts in a corner of the lab. Looks like all we have to remember him by is this video... bon voyage little buddy!



Particle filters in real time

I love class projects, because it's great to make something that works amidst the theory and pure math. For one of my robotics classes, my team decided to code up a particle filter.

Actually, our plan was to have a Lego Mindstorms NXT robot localize itself (figure out its initially unknown position in a known environment), then navigate to a sound source while avoiding obstacles. We couldn't get the physical robot to cooperate, so we did the localization piece in simulation.

We got the particle filter working, and made some nice videos of the particles in action. Those and more info after the jump.

Sunday, September 11, 2011

Little Drummer Boy: a drum machine with real drums

 
"Little Drummer Boy" was my final class project for an embedded microcontroller class. Two Futaba S3004 servos with drumsticks, controlled by a PIC18F4550, play a set of bongos. The frame was built by a teammate from scrap aluminum.

Videos and more info after the jump.

Music gear hacks: ugly but fun

Contrary to what you might think from the photos on this site, I do care about aesthetics. I get jazzed about great industrial design, I love a good clean interface, and part of me always wants to take a working project and sculpt it into a beautifully finished product that anyone would be proud to own.

The other 90% of me really likes the "junkyard whirlwind" look.

I was going through old files last week and found some photos/videos of music gear I modified, then sold when I got bored. These were all cool little hacks, some more labor-intensive than others - but they're all pretty ugly.

Circuit-Bent Casio SK-1 Keytar
By far the coolest SK-1 you'll ever see. Unfortunately since I made it around 1998, the only evidence left is this crop of a highly embarrassing snapshot.

Of course I'm not making a "rocking with my keytar" face.

Yes, that's the handhold from a kid's keytar bolted on an SK-1. Yes, that's a full-size guitar strap. Yes, the yellow buttons are wired up as circuit bends. And there are others you can't see - switches, pots, and body contacts - to modify the already crazy SK-1 sample magic.

I loved this thing and only sold it because I thought I could make bank at the height of the SK-1 craze. Which I did. Maybe I sold a little piece of my soul too. 

Check out the rest after the jump...

On the origin of blog

I'm not sure why anyone would be reading this post, it's pretty clear from the rest of this blog that I just wanted a place to blag on the internet about my precious wecious little projects. :)

Also I've gotten a lot of help and good ideas looking at other people's projects and code online, so maybe something here will come in handy for someone else someday.

About me... well, I'm back in school so I can build robots and finally put my scavenging skills to good use. There's really nothing better than a good long walk around the neighborhood the night before the trash gets picked up, wondering what treasures will, uh, fall into my lap.

After all, it's only junk if you don't know what to do with it.