Perl 小品集 ─ mplay

#!/usr/bin/perl
#
# mplay - midi/mp3 player version 0.4
# April 1, 2002 * Penguin Club

# 使いかたの説明
if ($ARGV[0] eq "-h"){
    print "\tTo Move\t-- Directory name\n";
    print "\tA\t-- play-all(default)\n";
    print "\t3 8 9\t-- play #3, #8, and #9\n";
    print "\t4-7\t-- play #4, #6, #7\n";
    print "\t5x3\t-- play #5 for 3 times\n";
    print "\tR\t-- Random(play-all)\n";
    print "\tQ\t-- Q-uit\n";
    print "\t\^C\t-- Skip\n";
    print "\t\^Z\t-- End\n";
    exit 0;
    }
elsif ($ARGV[0] eq ""){
    $music_dir = "./";
    }
else{
    $music_dir = $ARGV[0];
    }
&start;

## サブルーチン

sub start{
&path_find;
# MIDI RMID MP3 ファイルの取得
@files1 = glob("$music_dir\*.mid");
@files2 = glob("$music_dir\*.rmi");
@files3 = glob("$music_dir\*.mp3");
@files = (@files1, @files2, @files3);

# ファイルまたはディレクトリの表示
if (($sum = scalar (@files)) > 0){
    &sequence;
    &show_music;
    }else{
    &show_dir;
    }

# 演奏オプション
while(1){
    print "Options(A/#/R/Q) => ";
    $input = <STDIN>;
    chomp $input;
    # デフォルト(全曲演奏)
    if ($input eq ""){
        &play_all;
        &show_music;
        next;
        }
    # 終了
    if ($input eq 'q'){
        exit 0;
        }
    # 全曲
    elsif ($input eq 'a'){
        &play_all;
        &show_music;
        next;
        }
    # ランダム
    elsif ($input eq 'r'){
        &randamize;
        &play_all;
        $sequence;
        &show_music;
        next;
        }
    # 選曲
    elsif ($input =~ /^[\d]+/){
        &play_some ($input);
        &show_music;
        next;
        }
    # ディレクトリー移動
    else{
        $music_dir = $input;
        &start;
        }
    }
exit 0;
}

# ディレクトリーの取得
sub path_find{
local ($current_dir, $dir_tree, $upper_dir);

# パス入力を整える
if ($music_dir !~/^\//  and $music_dir !~ /^\./){
    $music_dir = "\.\/$music_dir";
    }
if ($music_dir !~ /\/$/){
    $music_dir = "$music_dir\/";
    }
# 現在のパスを取得
$current_dir = `pwd`;
chomp $current_dir;
# 上位パスを得る
if ($music_dir =~ /^\.\.\//){
    while ($music_dir =~ /^\.\.\//){
        $music_dir =~ s/^\.\.\///;
        $current_dir =~ s/\/[\w]+$//;
        }
    $music_dir = "$current_dir\/$music_dir";
    }else{
    $music_dir =~ s/^\./$current_dir/;
    }
}

# ディレクトリーの表示と撰択
sub show_dir{
local ($dir_list, $dir_data, $dir_name, $current_dir);

# ディレクトリーの取得
$dir_list = `ls`;
@dir_data = split /\n/, $dir_list;
$i = 0;
foreach $dir_name (@dir_data){
    if (-d $dir_name){
        $data[$i] = $dir_name;
        $i++;
        }
    }
$current_dir = `pwd`;
chomp $current_dir;
&show_data (" DIRECTORY LIST ($current_dir/) ", $i);
# ディレクトリーの移動
while(1){
    print "Select by name or number => ";
    $input = <STDIN>;
    chomp $input;
    # 終了
    if ($input eq 'q'){
        exit 0;
        }
    # 番号による撰択
    elsif ($input =~ /^[\d]+/){
        $music_dir = $data[$input - 1];
        &start;
        }
    # 名前による撰択
    else {
        $music_dir = $input;
        &start;
        }
    }
}

# 曲名の表示
sub show_music{
&show_data (" MUSIC LIST ($music_dir) ", $sum)
}

sub show_data{
local ($line, $i, $row, $number, $file, $music, $name);
local($title, $sum) = @_;

# 縦二列に表示するため、左側の列の長さを得る
if($sum % 2 == 0){
    $last = $sum / 2 + 1;
    }else{
    $last = int($sum / 2) + 2;
    }

# 画面をクリヤしてタイトルを表示する
print "\033[2J\033[1;0H";
#$title = " MUSIC LIST ($music_dir) ";
# 左側のラインを引く
$line = int((80 - length ($title)) / 2);
$i = 0;
while ($i < $line){
    print '=';
    $i++;
    }
# タイトルを表示
print $title;
# 右側のラインを引く
$i = $i + length ($title);
while ($i < 80){
    print '=';
    $i++;
    }
# 左側の曲名を表示
$i = 1;
$row = 2;
$col = 0;
while ($i < $last){
    if($i < 10){
        $number = " [0$i] ";}else{
        $number = " [$i] ";
        }
    $file = $data[$i - 1];
    @music = split /\//, $file;
    $name = $music[scalar(@music)-1];
    $name =~ s/\.[\w]+//;
    print "\033[$row;$col\H$number$name";
    $row++;
    $i++;
    }
# 右側の曲名を表示
$row = 2;
$col = 40;
while ($i < $sum + 1){
    if($i < 10){
        $number = " [0$i] ";}else{
        $number = " [$i] ";
        }
    $file = $data[$i - 1];
    @music = split /\//, $file;
    $name = $music[scalar(@music)-1];
    $name =~ s/\.[\w]+//;
    print "\033[$row;$col\H$number$name";
    $row++;
    $i++;
    }
if($sum % 2 == 0){
    print "\n";}else{
    print "\n\n";}
}

# アルファベット順にならべる
sub sequence{
local ($i);

$i = 0;
for $file (@files){
    $data[$i] = $file;
    $i++;
    }
}

# ランダムにならべる
sub randamize{
local ($i, $number);

# 配列の初期化
$i = 0;
while($i < $sum){
    $data[$i] = " ";
    $i++;
    }

# ランダムにして配列に入れる
$i = 1;
for $file (@files){
    while($i <= $sum){
    # 乱数発生
    $number = int(rand(@files));
        # すでに曲目があればスキップ
        if($data[$number] eq " "){
            $data[$number] = $file;
            last;
            }
        }
    $i++;
    }
}

# 指定した曲の演奏
sub play_some{
local (@numbers, $number, $input);

($input) = @_;
@numbers = split /[ ]+/, $input;
for $number (@numbers){
    # 連続
    if ($input =~ /\-/){
        &from_to($number);
        }
    # リピート
    elsif ($input =~ /x/){
        &repeat($number);
        }else{
        &play_one ($number);
        }
    }
}

# 全曲演奏
sub play_all{
local ($i);

$i = 1;
while ($i < $sum +1 ){
    &play_one ($i);
    $i++;
    }
}

# 連続演奏の処理
sub from_to{
local (@inputs, $input, $from, $to);

($input) = @_;
@inputs = split /\-/, $input;

if ($inputs[0] == ''){
    $from = 1;
    }else{
    $from = $inputs[0];
    }
if ($inputs[1] == ''){
    $to = $sum;
    }else{
    $to = $inputs[1];
    }
while ($from < $to +1){
    play_one ($from);
    $from++;
    }
}

# リピート演奏の処理
sub repeat{
local (@inputs, $input, $number, $rep, $i);
($input) = @_;
@inputs = split /x/, $input;

if ($inputs[0] == ''){
    return;
    }else{
    $number = $inputs[0];
    }
if ($inputs[1] == ''){
    play_one ($number);
    return;
    }else{
    $rep = $inputs[1];
    }
$i = 0;
while ($i < $rep){
    play_one ($number);
    $i++;
    }
}

# 単曲演奏
sub play_one{
local ($number, $music, $words);
($number) = @_;
if ($number > 0 and $number <= $sum){
    $music = $data[$number-1];
    # 歌詞ファイルの表示
    $words = $music;
    $words =~ s/\.[\w]+$/.txt/;
    if (-e $words){
        system "cat \"$words\"";
        }
    # MP3 ファイルの場合
    if ($music =~ /\.mp3/){
        system "mpg123 \"$music\"";
    # MIDI RMIDI ファイルの場合
        }else{
        system "timidity \"$music\"";
        }
    }else{
    print "Sorry, I can't find the music!\n";
    sleep 1;
    return;
    }
}


[INDEX]