Skip to content

Instantly share code, notes, and snippets.

@0xDBFB7
Last active December 23, 2018 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xDBFB7/40276cf93ac9e1dfe7d01f0c533cfad8 to your computer and use it in GitHub Desktop.
Save 0xDBFB7/40276cf93ac9e1dfe7d01f0c533cfad8 to your computer and use it in GitHub Desktop.
A little ATTiny MIDI player script
from mido import MidiFile
mid = MidiFile('onmyown1.mid')
NOTE_NUMBER = 129
NOTE_DURATION_THRESHOLD = 30
freqs = []
times = []
for i, track in enumerate(mid.tracks):
print('Track {}: {}'.format(i, track.name))
if(track.name == "Harp"):
for msg in track:
if not msg.is_meta and (msg.type == 'note_on' or msg.type == 'note_off'):
if(msg.time < NOTE_DURATION_THRESHOLD):
continue
freq = (round(440.0*((2.0**(1.0/12.0))**(float(msg.note)-69.0))))
if(msg.type == 'note_off'):
freq = 0
freqs.append(int(freq))
times.append(msg.time)
print(len(freqs))
print(freqs[0:NOTE_NUMBER])
print(times[0:NOTE_NUMBER])
//Connect a length of wire to PB0 and pull to ground via a 1M resistor
//This'll act as a capacitive sensor
//Connect a piezo buzzer to PB1 - no resistor seems to be required, the output impedance is enough
//to prevent damage
//Tested with 1Mhz oscillator.
#define CAPACITANCE_SENSITIVITY 5
#define NOTE_NUMBER 129
//Paste the two arrays from generator.py here
const PROGMEM uint16_t freqs[] =
{0, 587, 659, 440, 587, 0, 440, 784, 494, 587, 740, 494, 587, 659, 0, 740, 440, 587, 659, 0, 587, 0, 440, 784, 494, 587, 740, 494, 587, 659, 0, 0, 370, 440, 659, 370, 440, 587, 440, 0, 392, 494, 740, 392, 494, 659, 494, 740, 370, 440, 659, 370, 440, 0, 440, 740, 440, 587, 659, 370, 440, 587, 440, 587, 370, 494, 554, 294, 370, 494, 370, 0, 330, 415, 554, 330, 415, 494, 415, 0, 554, 440, 0, 440, 554, 440, 0, 440, 554, 440, 0, 659, 554, 440, 330, 0, 392, 0, 440, 392, 554, 466, 330, 466, 330, 440, 330, 0, 370, 494, 554, 294, 370, 494, 370, 0, 392, 494, 740, 392, 494, 659, 494, 784, 392, 494, 659, 784, 659, 554};
const PROGMEM uint16_t times[] =
{111, 117, 115, 119, 116, 90, 120, 119, 110, 111, 106, 114, 116, 114, 114, 128, 112, 103, 119, 119, 118, 85, 117, 124, 111, 115, 110, 115, 116, 117, 115, 110, 123, 105, 112, 105, 99, 102, 111, 120, 118, 115, 114, 107, 104, 115, 120, 113, 108, 124, 106, 107, 114, 119, 108, 129, 103, 118, 111, 113, 110, 117, 112, 123, 112, 122, 112, 108, 106, 115, 98, 117, 117, 98, 108, 105, 116, 123, 110, 107, 112, 117, 108, 225, 101, 113, 115, 113, 104, 112, 36, 94, 100, 110, 104, 109, 122, 112, 127, 353, 220, 115, 115, 123, 228, 119, 116, 104, 115, 117, 110, 107, 110, 123, 105, 112, 119, 122, 119, 110, 119, 111, 110, 124, 103, 109, 116, 115, 112, 112};
void setup()
{
DDRB |= (1 << PB1);
}
void loop()
{
//Vibrato: int shift = fundamental*vibrato_intensity*sin(6*2*3.14159*t);
int capacitance_value = 0;
DDRB &= ~(1 << PB0);
PORTB &= ~(1 << PB0);
while(PINB & (1 << PB0)){
capacitance_value++;
}
if(capacitance_value > CAPACITANCE_SENSITIVITY){
for(int i = 0; i < NOTE_NUMBER; i++){
play_tone(pgm_read_word_near(freqs + i), pgm_read_word_near(times + i));
}
}
DDRB |= (1 << PB0);
PORTB |= (1 << PB0);
}
void play_tone(int frequency, int duration){
if(frequency == 0){
delayMicroseconds(duration*1000);
return;
}
int t = ((1.0/float(frequency))*1000000)/2;
//look ma, no timers!
for(int i = 0; i < float(duration)/((1.0/float(frequency))*1000.0); i++){
PORTB |= (1 << PB1);
delayMicroseconds(t);
PORTB &= ~(1 << PB1);
delayMicroseconds(t);
}
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment