alaingilbert / Turntable-API

Allows you to create bots for turntable.fm
http://alaingilbert.github.com/Turntable-API/
MIT License
317 stars 97 forks source link

Making the bot sing #195

Closed ghost closed 11 years ago

ghost commented 11 years ago

How do you make the bot sing the lyrics to the song that is currently playing on the DJ Stage.

technobly commented 11 years ago

You grab it by the lugnuts and squeeze ;-)

technobly commented 11 years ago

Basically you have to set up timers to make the bot speak lyrics at the right times.

So a nice way would be to create a sing(songid) function that is called on 'newsong' event. You'd pass it the songid, and if that matched something on your list, it would set up all of the timers with lyrics for it. You could daisy-chain the timers (when one goes off you set the next one) or set them all up at once (at the beginning of the song). Either way you are probably going to get some minor timing errors. Have fun!

ghost commented 11 years ago

ok, can I get a example of what the code should look like.

technobly commented 11 years ago

This is the hard part. I'll leave the easy part up to you.

var songs = {
  "123456789012345678901234": [{
      "time": 1000,
      "lyrics": "Na je nun ta sa ro un in gan jo gin yo ja"
    }, {
      "time": 2000,
      "lyrics": "Ko pi han ja ne yo yu rul a neun pum gyo gi nun yo ja"
    }
  ],
  "123456789012345678901235": [{
      "time": 1000,
      "lyrics": "What you wanna hear, what you wanna do is me"
    }, {
      "time": 2000,
      "lyrics": "Damn! Girl! You so freakin sexy!"
    }
  ]
};

function sing(songid) {
  var _id = "";
  var _lyricscount = 0;
  var _lyric = 0;
  for (id in songs) {
    //console.log("ID "+id);
    if (songid === id) {
      _id = id;
      _lyricscount = songs[id].length;
      _lyric = _lyricscount;
      //console.log("SONGID "+songid);
      //console.log("LENGTH "+_lyricscount);
      for (lyrics in songs[id]) {
        //console.log("LYRICSID "+lyrics);
        //console.log("LYRICS "+songs[_id][lyrics].lyrics);
        //console.log("TIME "+songs[_id][lyrics].time);
        setTimeout(function () {
          bot.speak(":musical_note: " + songs[_id][_lyricscount - _lyric--].lyrics + " :musical_note:");
          console.log(":musical_note: " + songs[_id][_lyricscount - _lyric--].lyrics + " :musical_note:");
        }, songs[_id][lyrics].time);
      }
      return; // ditch the for loop after song found
    }
  }
}

sing("123456789012345678901234");
ghost commented 11 years ago

ok, what should i do for the easy part.

technobly commented 11 years ago

Re-read all comments.

ghost commented 11 years ago

ok, thanks for the help

MikeWills commented 11 years ago

Sparkle already has a singing function to get you started.

ghost commented 11 years ago

yeah, but sparkle's coding is a bit confusing

MikeWills commented 11 years ago

I have been meaning to start a project for singing bots. So we could all work together to make a song list. I'd be willing to follow through if everyone would submit their songs to the database. Cause let's face it. It isn't easy to get the timing right. Thoughts?

Mike Wills mike@mikewills.me http://mikewills.me 507-933-0880 On May 10, 2013 6:26 PM, "Turntablelover" notifications@github.com wrote:

yeah, but sparkle's coding is a bit confusing

— Reply to this email directly or view it on GitHubhttps://github.com/alaingilbert/Turntable-API/issues/195#issuecomment-17749593 .

ghost commented 11 years ago

good idea, it helps new bot makers.

technobly commented 11 years ago

Hmm I typed a whole bunch and it got deleted... sigh.

alaingilbert commented 11 years ago

:(

ghost commented 11 years ago

:(, that is disappointing

technobly commented 11 years ago

Ok, I guess I have a moment to retype this...

Despite always wanting to code up a function to make the bot sing, I've always thought it would be a pretty spammy feature that would get old fast which is probably why I never did it.

That said, I'll probably set this up on my bot anyway for two songs that I'm partial to... because it's already done.. might as well :trollface:

As far as getting the data for songs... I'm thinking of two ways: 1) Some way to snag data from Karaoke CDs since they are already sync'd with lyrics... have no idea how though. 2) Create a script for a bookmarklet that contains your JSON song database organized like above. As the song plays your script highlights the first line of your lyrics. You then press a button on the keyboard (right ALT maybe) to capture the current time in your JSON database. The lyrics would advance waiting for you to hit the key again. Of course you might be off on some of the lyrics, but you could manually tweak these later. The majority of the work would be done automatically. Once done you can just copy/paste the data from your chrome console to your song JSON file. I'll probably try this way at some point once I clear my plate.

gizmotronic commented 11 years ago

I coded singing up quite some time ago and originally had it auto-activate whenever one of the recognized songs was played. That changed within a couple of days because it actually affected song choices for folks who wanted the bot to sing, and also greatly increased aggravation for the people who disliked the spam. In addition to making it a manual trigger, I decided that I was going to severely limit any further additions until I had a way to throttle it so that it didn't happen too often.

MikeWills commented 11 years ago

Good point. I'll work that into how I do this. I might takle this tonight.

ghost commented 11 years ago

ok cool

technobly commented 11 years ago

Way to throttle... if the song matches and a random number generated is 1 out of 10, it will on avg sing 10% of the time for that song. Or whatever percentage you want.

Speaking of Math.rand though, it would generate 10 of the same number in a row... it's possible. So if you really want a truly dead set "sings once every 10 tries" then you have to create a virtual deck of cards that you shuffle, and draw and discard cards (i.e. numbers). Pretty sure that's self explanatory.

@gizmotronic How did your manual trigger work?

gizmotronic commented 11 years ago

The probability-based throttle you describe is a simple solution but I decided that I'd strongly prefer one that was time-based, instead. That is, I wanted to limit it to N times per day, regardless of how many songs were played in total. I just never got around to implementing it, mostly because it's hard to get too excited to hear people complain about the spam.

The manual trigger is just a command to tell the bot to sing. If the song isn't in the database, it reports that fact. It's smart enough to be able to pick up mid-song, so timing isn't really an issue (within the tolerances you would expect). There's a corresponding command to hush the bot, too, of course. :)

In short, fun to think about, even more fun to code, but not terribly exciting for most people after the novelty wears off.

ghost commented 11 years ago

ok, cool