Tuesday, September 26, 2017

Arduino-Midi for Sim City Music Playback...




Roland Sound Canvas SC-55, hooked up through a hacked cable to an Arduino Uno,
which is connected to... NOT THE MACBOOK because I FORGOT
THE STUPID USB-C ADAPTER AT HOME. GEEZ.

Was thinking in the car on the way to Interlock of a way to make the Sim City 2000 music thing better.

The project I'm talking about is to play the weird Sim City 2000 midi files at random intervals throughout the day, so that life feels more like Sim City. ;)

I have a python script that will play the songs on my laptop... (see below) but I want something more physical..


Roland MT-90. It plays midi files off of floppy disks to a builtin Sound Canvas.
Yes. I think it's a weird thing as well, but at least it sounds nice!

Was thinking of putting an Arduino inside of the MT-90, which would press the button sequence to: (switch on shuffle mode), (switch on random play), then (wait) then (play the next track)... (The arduino would press the buttons via relays, the way I did it inside the Yamaha Tape deck..

I was thinking that it might be nice to not have to hack the device, and have just a midi thing i could plug in to any midi device... I'd have it do the above with the MT-90, but it doesn't have any midi control sequences to control playback... just midi notes/tone generation stuff.

Then I took a step back and thought that if i just stored the midi files on a sd card, and just had the arduino play them itself out to a sound canvas, that'd do the trick! I found a 5 pin din cable, hacked in connections.... but I forgot my USB-C to USB adapter at home. Dang!

So it's not really a failure of a project *YET*, but it was a definite lack of success...

Here's the python script. It expects to be run on a Mac, with timidity installed, which will play the music. Also it expects the midi files to be in a "SC2000/" subdirectory. It's not the most elegant thing, but I hacked it together in a couple days...



#!/usr/bin/python
#
#  an attempt to make real life more like playing SimCity
#
#  It picks a random amount of time from 15-90 seconds
#  if there's silence for the entire thing, it will pick a random 
#  track in the SC2000 directory and play it.
#  then it repeats... until you ctrl-c out of it
#
#  v2 2017-07-28 - made more configurable, quieter output, class
#  v1 2017-07-27 yorgle@gmail.com
#
# Requires: - timidity to be installed (brew install timidity)
#   - OS X (10.12 tested)


import sys
import os
import time
import random
import subprocess
sys.dont_write_bytecode = True


class SimMusic:

# defaults
midicmd = "/usr/local/bin/timidity --no-loop {} 2> /dev/null" 
mididir = "SC2000/"
silenceTimer = 0
timerMin = 15
timerMax = 90
disabled = 999999
timeout = disabled

# constructor
def __init__( self, tmin = None, tmax = None ):
if( tmin != None ):
self.timerMin = tmin

if( tmax != None ):
self.timerMax = tmax

self.setupTimer()

def setupTimer( self ):
self.silenceTimer = 0
self.timeout = random.randint( self.timerMin,  self.timerMax )

def resetTimer( self ):
self.silenceTimer = 0

def stopTimer( self ):
self.silenceTimer = 0
self.timeout = self.disabled

def systemIsPlayingAudio( self ):
process = os.popen('/usr/bin/pmset -g' );
text = process.read()
process.close()
if( "coreaudio" not in text ):
return False
return True


def playRandomMIDI( self ):
self.stopTimer()

files = os.listdir( self.mididir )
fname = self.mididir + random.choice( files )

print( "Timidity: {}".format( fname ))
process = subprocess.Popen( self.midicmd.format( fname ), shell=True )
process.wait()

self.setupTimer()


def run( self ):
playingTimer = 0
print( "scanning..." );

self.setupTimer()
while True:
if( self.systemIsPlayingAudio() ):
if( playingTimer == 0 ):
print( "\n" )
sys.stdout.write( '\033[2K' )
sys.stdout.write( "\rAudio is playing... Waiting. ({})".format( playingTimer ))
sys.stdout.flush()

time.sleep( 1 )
playingTimer = playingTimer + 1
self.resetTimer()
else:
playingTimer = 0
if( self.silenceTimer == 0 ):
self.setupTimer()

self.silenceTimer = self.silenceTimer+1

if( self.silenceTimer > 0 ):
if( self.silenceTimer == 1 ):
print( "\n" )
sys.stdout.write( '\033[2K' )
sys.stdout.write( "\rShhh! {} of {} seconds has passed".format( self.silenceTimer, self.timeout ))
sys.stdout.flush()
if( self.silenceTimer >= self.timeout ):
self.playRandomMIDI()
self.setupTimer()
self.silenceTimer = 0
else:
time.sleep( 1 )

################################################################################

# put this in your main app as well.
if __name__ == "__main__":
simMusic = SimMusic( )
simMusic.run()