Taken pretty much from the MIDI:Event documentation:
use MIDI; # which "use"s MIDI::Event;
my @lyrics;
MIDI::Opus->new( {
"from_file" => $ARGV[0],
"exclusive_event_callback" => sub{push @lyrics, $_[2],$_[1]\n"},
"include" => \@MIDI::Event::Text_events
} );
so now @lyrics contains elements looking like this:
"Happy,300"
"Birthday,400"
"To,80"
"You,500"
I think the numbers represent the length of time to wait before adding the next bit of text, though I'm not sure what the units are - presumably not absolute times, because the file may get played at different tempos, so maybe they're "midi ticks" or similar.
I've noticed that when playing a karaoke file in Timidity from the command line, it actually prints the lyric events (presumably to STDOUT) so another idea might be to just capture this and print it, letting Timitidy take care of the syncronisation.
Thanks for all your suggestions.
mj
| [reply] [d/l] [select] |
I usually use the "drvmidi" utlity to play midis and karaoke. It is an old sound blaster awedrv package. It plays kar files pretty good. I tried to capture the output of it, but there is some problem because the apps output actually goes to the soundcard so it is full of binary data. It would be neat if the lyrics were printed to stderr to avoid that complication. I'll try timidity and the MIDI::Event code above and post my results( whether success or not :-) )As a last resort, I have been able to run drvmidi in a window in a tk canvas, and I'm sure timidity would work too. So this isn't much better than the command line, but it could be made better by using bigger fonts in the xterm and going full screen and changing the solid color to a photo.
#!/usr/bin/perl -w
use strict;
use Tk;
my $mw = MainWindow->new();
my $canv = $mw->Canvas(-bg => 'lightsteelblue',
-relief => 'sunken',
-width => 550,
-height => 350)->pack(-expand => 1, -fill => 'both');
my $xtermWidth = 400;
my $xtermHeight = 300;
## this Frame is needed for including the xterm in Tk::Canvas
my $xtermContainer = $canv->Frame(-container => 1);
my $xtid = $xtermContainer->id();
# converting the id from HEX to decimal as xterm requires a decimal Id
+
my ($xtId) = sprintf hex $xtid;
my $dcontitem = $canv->createWindow(275,175,
-window => $xtermContainer,
-width => $xtermWidth+100,
-height => $xtermHeight,
-state => 'normal');
my $label = $canv->createText( 275,10,
-text => "Hide xterm",
);
$canv->Tk::bind("<Button-1>", \&hideShow);
my $width = $xtermWidth;
my $height = $xtermHeight;
$mw->Button(-text => "Exit", -command => [sub{Tk::exit}] )->pack( );
my $tl; #used to mask xterm
system("xterm -into $xtId -e timidity z.kar &");
MainLoop();
sub hideShow {
if ($canv->itemcget($label, -text) =~ /Hide/) {
$canv->itemconfigure($label,
-fill => 'white',
-text => "Show xterm");
$tl = $mw->Toplevel(-use=>$xtId );
} else {
$canv->itemconfigure($label,
-fill => 'black',
-text => "Hide xterm");
$tl->withdraw;
}
}
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |