#!/usr/bin/perl
# 
# Convert RIFF WAVE format sound files to Akai S3000 samples.
# Copyright (c) 1997, Hiroyuki Ohsaki.
# All rights reserved.
# 
# $Id: wav2akai,v 1.2 1998/06/30 01:35:40 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::AkaiSample;
use Synth::WaveSample;
use File::Basename;
use Getopt::Std;
use strict;

sub convert_wave {
    my($wave, $akai, %wave) = @_;

    my $dataref = $wave->read_wave_data;
    my $tune = log($wave{rate} / 44100) / log(1.0595);

    (name       => $::opt_n ? $::opt_n: $wave{name},
     size       => $wave{size} >> 1,
     rate       => $wave{rate},
     key        => 60,
     tune       => $tune,
     start      => 0,
     end        => $wave{size} >> 1,
     play_mode  => 0,
     loop_start => $wave{size} >> 1,
     loop_len   => 0,
     loop_times => 0,
     data       => $dataref,
     );
}

sub usage {
    my $prog = basename($0);
    die <<EOF;
usage: $prog [-v] [-d dir] [-n name] file...
 -v       verbose mode
 -d dir   crate S3000 samples in dir      
 -n name  specify sample name
EOF
}

getopts('vd:n:') || usage;
@ARGV || usage;

my $dir = $::opt_d || '.';

my $file;
for $file (@ARGV) {
    # load WAVE file
    my $wave = new Synth::WaveSample;
    $wave->load($file) || warn "$file: $!\n";

    my $akai = new Synth::AkaiSample;
    
    # extract wave data
    my %wave = $wave->read_wave_header;
    $wave->dump_wave(%wave) if $::opt_v;
    if ($wave{tag} != 1 or $wave{bits} != 16) {
	warn "$file: only 16 bit PCM is supported.\n";
	next;
    }

    my $chan = $wave{chan};
    %wave = convert_wave($wave, $akai, %wave);

    if ($chan == 2) {
	# seperate left and right channel since data for left and
	# right are interleaved.
	my $dataref = $wave{data};
	my $data_l = '';
	my $data_r = '';
	# this operation is quite slow, and consumes a fair amount of 
	# memory.
 	for ($_ = 0; $_ < ($wave{size} << 1); $_ += 4) {
 	    $data_l .= substr($$dataref, $_, 2);
 	    $data_r .= substr($$dataref, $_ + 2, 2);
 	}
 	$$dataref = '';
        my $name = $wave{name};
	my $size = $wave{size} >> 1;
	$wave{size} = $wave{end} = $wave{loop_start} = $size;

	# write left channel
	$wave{name} = sprintf "%-10s-L", $name;
	$wave{data} = \$data_l;
	$akai->save_sample($dir, %wave);
	$data_l = '';

	# write right channel
	$wave{name} = sprintf "%-10s-R", $name;
	$wave{data} = \$data_r;
	$akai->save_sample($dir, %wave);
	$data_r = '';
    } else {
	$akai->save_sample($dir, %wave);
    }
}

__END__

=head1 NAME

wav2akai - convert RIFF WAVE files to Akai S3000 samples

=head1 SYNOPSIS

  wav2akai [-v] [-d dir] [-n name] file...

=head1 DESCRIPTION

This manual page documents B<wav2akai>.  This program converts
mono/stereo Microsoft RIFF WAVE files to Akai S3000 samples.  Note
that B<wav2akai> only supports RIFF WAVE in I<16 bit PCM format>.  For
other types of formats, use B<any2akai> that invokes B<sox>
internally.  If I<file> is stereo, B<wav2akai> creates two sample
files for each channel.

=head1 OPTIONS

=over 4

=item C<-v>

Verbose mode.  Print much information for debugging.

=item C<-d> directory

Specify the directory in which all sample files will be written.  By
default, the current directory is used.

=item C<-n> name

Converted Akai sample files will be named as I<name>.  

=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

