#!/usr/bin/perl
# 
# Read specified files from Ensoniq EPS disk.
# Copyright (c) 1997, Hiroyuki Ohsaki.
# All rights reserved.
# 
# $Id: epsread,v 1.2 1998/06/30 01:35:36 oosaki Exp ohsaki $
# 

# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

use Synth::EpsDisk qw(qualify_path unqualify_path join_path);
use Getopt::Std;
use File::Basename;
use integer;
use strict;

my %EXTS = (3 => 'ins');

sub read_file {
    my($dir, $disk, $path, %entry) = @_;

    my $name = unqualify_path(basename($path));
    $name = join_path($dir, $name);
    $name .= ".$EXTS{$entry{type}}" if (exists $EXTS{$entry{type}});

    print STDERR "reading $path\n  -> $name\n" if $::opt_v;
    system qq(mkdir -p $dir) unless (-d $dir);
    open(OUT, ">$name") || die "open: $name: $!\n";
    binmode(OUT);
    # print EPS instrument header
    print OUT pack('C2 A16 A16 A13 C5 n C4 @512',
		   0x0d, 0x0a, 'Eps File:', basename($path), 'Instrument',
		   0x0d, 0x0a, 0x1a, 0x03, 0x00, $entry{size},
		   0x00, 0x01, 0x00, 0x1f);
    close(OUT);
    $disk->read_file($path, $name) || die "read: $path: $!\n";
}

sub usage {
    my $prog = basename($0);
    die <<EOF;
usage: $prog [-vR] [-f file] [-d dir] path...
 -v       verbose mode
 -R       read all files recursively
 -f file  specify EPS disk image (default \$EPS_DISK)
 -d dir   all output goes to dir
EOF
}

getopts('vRf:d:') || usage;
@ARGV || usage;

my $dir = $::opt_d || '.';
my $file = $::opt_f || $ENV{EPS_DISK} || '/dev/cdrom';

my $disk = new Synth::EpsDisk($file) || die "new: $file: $!\n";

while (@ARGV) {
    # read file properties
    my $path = shift;
    $path = qualify_path($path);
    (my(%entry) = $disk->stat($path)) || die "stat: $path: $!\n";

    # if $path is a directory, get all files in it
    if ($entry{type} == 2) {
	my(%entries) = $disk->readdir($path);
	my $key;
	for $key (sort { $entries{$a}->{at} <=> $entries{$b}->{at} }
		  keys %entries) {

	    my %entry = %{$entries{$key}};

	    # traverse all subdirectories if -R is set
	    if ($::opt_R) {
		if ($entry{type} == 2) {
		    push(@ARGV, join_path($path, $key));
		}
	    }
		
	    # don't read directory itself
	    next if ($entry{type} == 2 or $entry{type} == 8);

	    read_file(join_path($dir, unqualify_path($path)), 
		      $disk, join_path($path, $key), %entry);
	}
    } else {
	read_file($dir, $disk, $path, %entry);
    }
}

__END__

=head1 NAME

epsread - Read files from Ensoniq EPS HDD/CD-ROM

=head1 SYNOPSIS

  epsread [-vR] [-f file] [-d dir] path...

=head1 DESCRIPTION

This manual page documents B<epsread>.  This program extracts files
from HDD/CD-ROM in Ensoniq EPS format.  B<epsread> is almost identical
to B<akairead> except that it works for Ensoniq EPS disks rather than
Akai S1000/S3000 disks.  See L<akairead(1)> for more information.

B<epsread> can recognize GKH format files as well as EDA format files.

=head1 OPTIONS

=over 4

=item C<-v>

Verbose mode.  Print much information for debugging.

=item C<-R>

Retrieve all files under I<path> recursively.

=item C<-f> file

Specify the regular file of EPS disk image or the block device file of
EPS HDD/CD-ROM.  Usually, this should be the block device of HDD or
CD-ROM such as F</dev/sda>.  If this option is omitted, the
environment variable I<EPS_DISK> is used as the default device.  If
I<EPS_DISK> is not defined, F</dev/cdrom> is assumed.

=item C<-d> directory

All output files goes to I<directory> instead of the current directory.

=back

=head1 SEE ALSO

akaitools(1), akaiformat(1), akailist(1), akaimkdir(1), akairead(1),
akaiwrite(1), epslist(1), epsread(1), eps2akai(1), wav2akai(1),
any2akai(1), akaiconv(1) 

=head1 AUTHOR

Hiroyuki Ohsaki <oosaki@ics.es.osaka-u.ac.jp>

=cut

