Skip to content

Instantly share code, notes, and snippets.

@mhungerford
Last active April 13, 2024 19:32
Show Gist options
  • Save mhungerford/0af269ee46c0d44a813c to your computer and use it in GitHub Desktop.
Save mhungerford/0af269ee46c0d44a813c to your computer and use it in GitHub Desktop.
SparkFM for Pebble
var UI = require('ui');
//Replaced # with _, to support urlEncoding for POST
//Max RTTTL length is 512 (buffer on spark hard-coded).
var song_list = [
{song: "Back to the Future",
rtttl: "d=4,o=5,b=100:c_4,g_.4,8c_,b.4,16a_4,16g_4,8a_.4,8g_.4,8f_4,g_.4,16g_4,16g_4,2g_.4,c_,g_.,8c_6,b.,16a_,16g_,8a_.,8g_.,8f_,1g_,g_.,c_.,2g.,32g_.,32a_.,8g_,8f,8c_,g,32g_.,32a_.,8g_.,8d_.,8g_.,8d_.6,d_.6,d6,32c.6,32d.6,2d_.6,16d_,16g_,16d_,16g_,16c_6,16a_,16d_6,16g_6,c_.6,f_.,2c.6,32c_.6,32d_.6,8c_6,8a_,8f_,c6,32c_.6,32d_.6,8c_.6,8g_.,8c_.6,8g_.6,g_.6,g6,32f.6,32g.6,2g_.6"},
{song: "Barbie Girl",
rtttl: "d=4,o=5,b=125:8g_,8e,8g_,8c_6,a,p,8f_,8d_,8f_,8b,g_,8f_,8e,p,8e,8c_,f_,c_,p,8f_,8e,g_,f_,8g_,8e,8g_,8c_6,a,p,8f_,8d_,8f_,8b,g_,8f_,8e,p,8e,8c_,f_,c_,p,8f_,8e,g_,f_,8g_,8e,8g_,8c_6,a,p,8f_,8d_,8f_,8b,g_,8f_,8e,p,8e,8c_,f_,c_,p,8f_,8e,g_,f_"},
{song: "Butterfly",
rtttl: "d=4,o=5,b=125:8g_4,8g_4,8c_.,16b4,8c_,8d_,e,p,8e.,16d_,8e,8f_,g_,p,f_,8f_,8d_,b4,d_,8e,8f_,8e,8d_,c_,p,8c_.,16c_,8c_,8d_,8e.,16p,8e.,16p,8e.,16d_,8e,8f_,g_,p,f_,8f_,8d_,b4,d_,8e,8f_,8e,8d_,c_,p,g_,8g_,8b,c_6,8g_,8b,8c_6,8e6,8c_6,8b,g_,p,f_,8f_,8g_,b,8g_,8e,8f_,8g_,8f_,8e,c_,p,g_,8g_,8b,c_6,8g_,8b,8c_6,8e6,8c_6,8b,g_,p,f_,8f_,8g_,b,8g_,8e,8f_,8g_,8f_,8e,c_"},
{song: "Never Gonna Give You Up",
rtttl: "d=4,o=5,b=200:8g,8a,8c6,8a,e6,8p,e6,8p,d6.,p,8p,8g,8a,8c6,8a,d6,8p,d6,8p,c6,8b,a.,8g,8a,8c6,8a,2c6,d6,b,a,g.,8p,g,2d6,2c6.,p,8g,8a,8c6,8a,e6,8p,e6,8p,d6.,p,8p,8g,8a,8c6,8a,2g6,b,c6.,8b,a,8g,8a,8c6,8a,2c6,d6,b,a,g.,8p,g,2d6,2c6."},
{song: "Take On Me",
rtttl: "d=4,o=4,b=160:8f_5,8f_5,8f_5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g_5,8g_5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f_5,8p,8f_5,8p,8f_5,8e5,8e5,8f_5,8e5,8f_5,8f_5,8f_5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g_5,8g_5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f_5,8p,8f_5,8p,8f_5,8e5,8e5"},
{song: "Mahna Mahna",
rtttl: "d=16,o=6,b=125:c_,c.,b5,8a_.5,8f.,4g_,a_,g.,4d_,8p,c_,c.,b5,8a_.5,8f.,g_.,8a_.,4g,8p,c_,c.,b5,8a_.5,8f.,4g_,f,g.,8d_.,f,g.,8d_.,f,8g,8d_.,f,8g,d_,8c,a_5,8d_.,8d_.,4d_,8d_."},
{song: "Indiana Jones",
rtttl: "d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6"},
{song: "Super Mario Brothers",
rtttl: "d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a_,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a_,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f_6,16f6,16d_6,16p,16e6,16p,16g_,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f_6,16f6,16d_6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f_6,16f6,16d_6,16p,16e6,16p,16g_,16a,16c6,16p,16a,16c6,16d6,8p,16d_6,8p,16d6,8p,16c6"},
{song: "The Simpsons",
rtttl: "d=4,o=5,b=168:c.6,e6,f_6,8a6,g.6,e6,c6,8a,8f_,8f_,8f_,2g,8p,8p,8f_,8f_,8f_,8g,a_.,8c6,8c6,8c6,c6"},
{song: "The Muppets",
rtttl: "d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c"},
{song: "Tetris",
rtttl: "d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a"},
{song: "Mission Impossible",
rtttl: "d=16,o=6,b=95:32d,32d_,32d,32d_,32d,32d_,32d,32d_,32d,32d,32d_,32e,32f,32f_,32g,g,8p,g,8p,a_,p,c7,p,g,8p,g,8p,f,p,f_,p,g,8p,g,8p,a_,p,c7,p,g,8p,g,8p,f,p,f_,p,a_,g,2d,32p,a_,g,2c_,32p,a_,g,2c,a_5,8c,2p,32p,a_5,g5,2f_,32p,a_5,g5,2f,32p,a_5,g5,2e,d_,8d"},
{song: "Sorcerers Apprentice",
rtttl: "d=18,o=6,b=125:4c,4g,g.5,a.5,b.5,c.,12p,d_.,c.,12p,d_.,d.,c.,b.5,c.,12p,d_.,c.,12p,d_.,d.,c.,b.5,c.,12p,d_.,c.,d_.,d.,c.,d.,d_.,d.,f.,d_.,d.,12p,f_.,c.,12p,d_.,d.,f.,d_.,d.,12p,f_.,c.,12p,d_.,d.,d_.,f.,g.,g.,g.,g.,g.,g.,2g."},
{song: "Pink Dinosaur",
rtttl: "d=4,o=5,b=140:f_6,b,g6,e6,8a6,16p,16b6,8a6,8g6,f_6,8d6,8e6,f_6,8f_6,8b,e6,8f_6,f_6,2e6,p,f_6,b,g6,e6,8a6,16p,16b6,8a6,8g6,f_6,8d6,8e6,f_6,8f_6,8d6,g6,8a6,b6,2a6"},
{song: "Dam Dariram",
rtttl: "d=4,o=5,b=160:8b,8e6,8f_6,g6,8g6,8f_6,g6,8g6,8f_6,g6,8g6,8f_6,8g6,8a6,8g6,8f_6,g6,8g6,8f_6,8g6,f_6,e6,8b,8g6,8f_6,8e6,f_6,16g6,16f_6,e6"},
{song: "Dub I Dub",
rtttl: "d=4,o=5,b=125:8g,16g,8g,8g,16a,8f_,8f_,8f_,8p,8e,16e,8e,8e,16d,8f_.,16d,8b4,8d,8g,16g,8g,8g,16a,8f_,8f_,8f_,8p,8e,8e,8e,d,f_"},
{song: "Samba De Amigo",
rtttl: "d=4,o=5,b=140:d,8c,8d,e.,8c,8a4,8p,a4,c,e,a,8g,8a,b.,8g,8e,8p,e,a,e,d,8c,8d,e,c,8a4,8p,a,c6,a,a,8g,8a,b,g,1a"},
{song: "StarWars",
rtttl: "d=4,o=5,b=45:32p,32f_,32f_,32f_,8b.,8f_.6,32e6,32d_6,32c_6,8b.6,16f_.6,32e6,32d_6,32c_6,8b.6,16f_.6,32e6,32d_6,32e6,8c_.6,32f_,32f_,32f_,8b.,8f_.6,32e6,32d_6,32c_6,8b.6,16f_.6,32e6,32d_6,32c_6,8b.6,16f_.6,32e6,32d_6,32e6,8c_6"},
{song: "Transformers",
rtttl: "d=16,o=6,b=285:e7,f7,e7,d_7,4d7,4p,d,d,d,d,d,d,d,d,e,e,e,e,f,f,f,f,f,f,f,f,8a7,8a_7,8a7,8p,4d7,2p,d,d7,d,d7,d,d7,d,d7,e,e7,e,e7,f,f7,f,f7,f,f7,f,f7,a5,a5,a5,a5,a_5,a_,a_5,a_,a_5,a_,a_5,a_,a_5,a_,a_5,a_,4p,8d,8p,4e,4f,4p,4f,4p,2g,4a,4a_,4p,g,g7,g,g7,g,g7,g,g7,4e,4g,4a,4p,f,f7,f,f7,f,f7,f,f7,4e,4f,4g,4p,e,e7,e,e7,e,e7,e,e7,e,e7,e,e7,4p,4d,4c_,8e,8p,4d,2d,d,d7,d,d7,d,d7,d,d7"},
{song: "No Surprises - Radiohead",
rtttl: "d=4,o=5,b=63:4a6,4c6,4f6,4c6,4a6,4c6,4f6,4c6,4a6,4c6,4f6,4c6,4a_5,4c_6,4f6,4g6,4a6,4c6,4f6,4c6,4a6,4c6,4f6,4c6,4a6,4c6,4f6,4c6,4a_5,4c_6,4f6,4g6"},
{song: "Stairway To Heaven",
rtttl: "d=4,o=5,b=50:32p,16a_,16c6,8c_6,16c6,16a_,8c.6,32a_,32c6,8c_6,16d_6,16c_6,16c6,16a_,16c_6,16d_6,8f6,16d_6,16c_6,16c6,16a_,16a_,32g_,16g_,16a_,a_,16c_6,16f6,d_6,8d_6,16c_6,16c6,16c_6,16a_,16a_,16c6,16c_6,16d_6,16f6,16d_6,16d_6,16c_6,16c6,16g_,16g_,16a_,8a_"},
{song: "Goldeneye",
rtttl: "d=4,o=5,b=125:8e,16f_,16f_,8f_,f_,8e,8e,8e,8e,16g,16g,8g,g,8f_,8f_,8f_,8e,16f_,16f_,8f_,f_,8e,8e,8e,8e,16g,16g,8g,g,8f_,8f_,8f_,8e,16f_,16f_,8f_,f_,8e,8e,8e,8e,16g,16g,8g,g,8f_,8f,8e,8e6,2d6,8p,8b,8a,2b"},
{song: "YMCA",
rtttl: "d=4,o=5,b=160:8c_6,8a_,2p,8a_,8g_,8f_,8g_,8a_,c_6,8a_,c_6,8d_6,8a_,2p,8a_,8g_,8f_,8g_,8a_,c_6,8a_,c_6,8d_6,8b,2p,8b,8a_,8g_,8a_,8b,d_6,8f_6,d_6,f.6,d_.6,c_.6,b.,a_,g_"}
];
//POST the setSong command to spark.io device with the song index
//Requires the spark.io device_id & access_token
function sendRTTTLChunk(chunk) {
var device_id = "123456789afde"; // Spark Core Device ID
var access_token = "123456789"; // Spark.io account token
var spark_url = "https://api.spark.io/v1/devices/";
var params = "";
if(chunk.length > 0) {
params = "access_token=" + access_token + "&args=" + chunk;
} else {
params = "access_token=" + access_token;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", spark_url + device_id + "/rtttlChunk", false); // synchronous
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader("Content-length", params.length);
xhr.setRequestHeader("Connection", "close");
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.send(params);
console.log("sendRTTTLChunk:" + chunk);
}
var playing = false;
function playSong(songTitle) {
playing = true;
function findSong(song) {
for (var i = 0; i < song_list.length; i++) {
if (song_list[i].song == song) {
return i;
}
}
return; // Song not found, returns undefined
}
var rtttl = song_list[findSong(songTitle)].rtttl;
for (var i = 0; i < rtttl.length; i+=63) {
sendRTTTLChunk(rtttl.substring(i, i+63));
}
// Send a empty chunk to finalize the rtttl message
sendRTTTLChunk("");
playing = false;
}
var main = new UI.Card({
title: 'SparkFM',
icon: 'images/menu_icon.png',
subtitle: 'Spark Core RTTL Player!',
body: 'Press any button.'
});
main.show();
main.on('click', 'select', function(e) {
// Create menu list from song_list
var menu_items = [];
song_list.forEach(function(entry) {
menu_items.push({title: entry.song});
});
var menu = new UI.Menu({
sections: [{
title: 'SparkFM Songs',
items: menu_items
}]
});
menu.on('select', function(e) {
if (!playing) {
console.log('Selected item #' + e.itemIndex + ' of section #' + e.sectionIndex);
console.log('Playing song "' + e.item.title + '"');
playSong(e.item.title);
}
});
menu.show();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment