Download raw (2.3 KB)
#!/usr/bin/perl # # eCantorix - singing speech synthesis using eSpeak # Copyright (C) 2012 Rudolf Polzer # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. use FindBin; use lib $FindBin::Bin; use strict; use warnings; use MIDI; use Getopt::Long; use eCantorix::Util; use Config::Tiny; my $UTAU_TICKS = 480; sub mapnote($$$$) { my ($start, $ev, $channel, $options) = @_; my @events = (); my $len = $ev->{'Length'}; my $note = $ev->{'NoteNum'}; my $velocity = $ev->{'Intensity'}; my $text = $ev->{'Lyric'}; if($text ne "R") { push @events, ['lyric', $start, $text]; push @events, ['note_on', $start, $channel, $note, $velocity]; push @events, ['note_off', $start + $len, $channel, $note, $velocity]; } return @events; } sub mapusthash($$$) { my ($ini, $channel, $options) = @_; my @events = (); die "Multitrack UST not supported yet" if $ini->{"#SETTING"}->{Tracks} != 1; my $tick = 0; for my $k(sort { $a <=> $b } map { /^#(\d+)$/ ? ($1) : () } keys %$ini) { my $ev = $ini->{"#$k"}; push @events, mapnote $tick, $ev, $channel, $options; $tick += $ev->{Length}; } return @events; } my $infile = "-"; my $outfile = "-"; my $options = { }; Getopt::Long::Configure("gnu_getopt", "auto_help", "auto_version"); GetOptions( 'input|i=s' => \$infile, 'output|o=s' => \$outfile, ); my $ini = Config::Tiny->read($infile); my $utautempo = $ini->{"#SETTING"}->{Tempo}; my $miditempo = int(60000000 / $utautempo + 0.5); my $ttrack = MIDI::Track->new(); $ttrack->events(['set_tempo', 0, $miditempo]); my $ntrack = MIDI::Track->new(); $ntrack->events(reltime mapusthash $ini, 1, $options); my $opus = MIDI::Opus->new({ format => 1, ticks => $UTAU_TICKS, tracks => [$ttrack, $ntrack] }); $opus->write_to_file($outfile);