I was looking at a large collection of Import/Export user suggestions the other day and it dawned on me that we finally have MIDI import in Mathematica 9, which is rather interesting since MIDI supports karaoke text events, which can be run in Mathematica with scheduled tasks.

So I wrote a simple code for a Karaoke machine function, which plays a given MIDI karaoke file and highlights the text that needs to be sung at the same time.

$DisplayEvents = {
 {0.0, {Red, FontSize -> 18}}, 
 {0.5, {Orange, FontSize -> 18}}, 
 {1.0, {Gray, FontSize -> 18}}};

TextEvents[file_] := Module[{events},
 events = Cases[Import[file, "Metadata"], {time_, "TextEvent" -> text_}, 2];
 events = Select[events, Not[StringMatchQ[#[[2, 2]], "\\@*"]] &];
 Map[{#[[1]], StringReplace[#[[2, 2]], {"\\" -> "\n\n", "/" -> "\n"}]} &, 

ScheduleTextEvents[events_] := Module[{},
 Outer[With[{e = #1, d = #2},
   Unevaluated[displayEvent[e] = Last[d]], {Max[0.0, First[e] + First[d]]}]] &, 
 events, $DisplayEvents, 1]]

Cleanup[] := { Cell[MakeBoxes@Row[{
 Button["Stop Music", Sound`StopMIDI[]; RemoveScheduledTask /@ ScheduledTasks[]], 
 Button["Close Notebook", NotebookClose[EvaluationNotebook[]]]}]]}

KaraokeMachine[file_] := Module[{lyrics, song, events},
 song = Import[file];
 events = TextEvents[file];
 Map[(displayEvent[#] = {White, FontSize -> 18}) &, events];
 CreateDocument[ ExpressionCell[
  With[{t = events}, 
  Dynamic[Row[With[{x = #}, Style[x[[2]], displayEvent[x]]] & /@ t]]], 
  "Output", ShowCellBracket -> False], Background -> Black, 
  WindowElements -> {"VerticalScrollBar"}, 
  Deployed -> True, DockedCells->Cleanup[]];

Which can then be called by giving it a karaoke file (for example this song by Frank Sinatra):

KaraokeMachine[ "myway.kar"]

My question mostly revolves about ideas on how I can improve on this (code improvements as well as suggestions on how to implement features, like fading in/out text).

(Note: Mathematica uses the Jlink/Java MIDI implementation on MacOSX, which means that you may run into this issue on newer versions of MacOSX. I haven't been able to find a solution for this yet).

  • 3
    $\begingroup$ I tried to play this file, which is purportedly a midi karaoke file. It gave me a few errors, after which I got a black fullscreen with a single scrollbar to the left, and the music playing uninterruptably. So, my recommendations would be better error handling, the ability to stop the song and killing the window after having played it. A NotebookClose on the document you create seems to be an essential step. You could also add a close button. My main problem is the player window blocking all access to the other mma windows. $\endgroup$ – Sjoerd C. de Vries Jan 30 '13 at 22:13
  • 1
    $\begingroup$ @SjoerdC.deVries - I think that file has no text track associated with it. I will add a error check on that, that's a good suggestion, thanks! This is the file I used for personal testing. I added the notebook close button and a stop sound button in the code above. I also took out the maximized window setting (I didn't realize this would be confusing; I was able to close it with the usual Ctrl-W). $\endgroup$ – Arnoud Buzing Jan 30 '13 at 22:39
  • 3
    $\begingroup$ Regarding the OS X problem: I don't know much about Java, but it seemed that on my system when running Java from the command line, it was running version 1.6. I had installed the 1.7 version but that was only used for the browser plugin. So I did InstallJava[ CommandLine -> "/Library/Internet\\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"] in Mathematica to force it to use 1.7, and the problems you mentioned went away. BTW do you know how to check the Java version from within Mma? SystemInformation says "info unavailable". $\endgroup$ – Szabolcs Feb 4 '13 at 16:44
  • $\begingroup$ @Szabolcs - thanks for that idea. After upgrading my machine, I can install Java 7 now with InstallJava[CommandLine->"/usr/bin/java"] which seems to fix the Mac sound issues. $\endgroup$ – Arnoud Buzing Feb 4 '13 at 17:53
  • $\begingroup$ Hadn't seen this one, the bounty did it's job. To test it with the kar file I had to explicitly set midi as format and change Import[file, "MIDI"] and Import[file, {"MIDI", "Metadata"}]. If I have time in the week and no superb answers appear it sounds fun to give it a shot $\endgroup$ – Rojo Feb 4 '13 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.