#!/usr/bin/perl -w

### make-pitch.pl: generate single-pitch midi data on stdout.
###
### Run this script with no arguments to see a usage message.
###
### Read the MIDI::Simple perldoc page to understand how this works.

use strict;
use MIDI::Simple;

my $usage =
    "Usage: playpitch.pl PITCH DURATION INSTRUMENT\n"
    . "\n"
    . "PITCH is a string of the form NOTE[MODIFIER]NUMBER.  The\n"
    . "letter is the name of the note, the optional modifier is \"s\" for\n"
    . "sharp, \"f\" for flat, and the number is the octave.\n"
    . "\n"
    . "DURATION is a number of seconds; it may be fractional.\n"
    . "\n"
    . "INSTRUMENT is an instrument name.\n"
    . "\n"
    . "Output: midi data to stdout.\n"
    . "\n";

### Read the arguments
my $pitch      = shift || die ($usage);
my $duration   = shift || die ($usage);
my $instrument = shift || die ($usage);

### Convert to the format MIDI expects.
### Note: all instrument names are listed at the end of this script.
$pitch = ucfirst ($pitch);
$instrument = ucfirst ($instrument);
my $midi_instrument = $MIDI::patch2number{$instrument};

### Following code taken from the MIDI::Simple perldoc page:

&new_score ();
&text_event ("A pitch: $pitch, $duration seconds, $instrument.\n");
&set_tempo (1000000);  # 1 qn => 1 seconds (1,000,000 microseconds)
&patch_change (1, $midi_instrument);  # See list after "__END__".

# Setup.  This is a bit mysterious to me now, although I think I
# understood it when I wrote it.
&noop ("c1", "v64", "ff", "d${duration}");

# Set quarter note to $duration seconds.
&set_tempo ($duration * 1_000_000);

# Then generate that quarter note.
&n ("qn", "$pitch");

# And play it to stdout.
&write_score ("-");

__END__

### List of instrument names: ###

# Sitar
# Oboe
# Xylophone
# Acoustic Grand
# Fiddle
# Banjo
# Tango Accordion
# Electric Guitar(clean)
# Tuba
# Melodic Tom
# Synth Drum
# Voice Oohs
# Pad 2 (warm)
# Pad 3 (polysynth)
# Breath Noise
# Telephone Ring
# Reverse Cymbal
# Acoustic Guitar(steel)
# Bagpipe
# Applause
# Lead 4 (chiff)
# Viola
# Alto Sax
# Ocarina
# FX 5 (brightness)
# FX 7 (echoes)
# Baritone Sax
# Pad 7 (halo)
# SynthBrass 1
# SynthBrass 2
# Woodblock
# Lead 8 (bass+lead)
# Bird Tweet
# Blown Bottle
# Electric Bass(pick)
# Agogo
# Vibraphone
# Lead 5 (charang)
# Trumpet
# Tubular Bells
# Choir Aahs
# Lead 6 (voice)
# String Ensemble 1
# String Ensemble 2
# Shanai
# Bassoon
# Dulcimer
# Shamisen
# Seashore
# Drawbar Organ
# FX 4 (atmosphere)
# Skakuhachi
# FX 2 (soundtrack)
# Flute
# Whistle
# Electric Bass(finger)
# Celesta
# Lead 7 (fifths)
# FX 8 (sci-fi)
# Clav
# Electric Guitar(muted)
# Electric Guitar(jazz)
# Pad 6 (metallic)
# Gunshot
# Piccolo
# FX 1 (rain)
# Synth Voice
# Tremolo Strings
# French Horn
# Helicopter
# Cello
# Pad 4 (choir)
# Muted Trumpet
# Brass Section
# Contrabass
# Taiko Drum
# Synth Bass 1
# Overdriven Guitar
# Synth Bass 2
# Fretless Bass
# Lead 2 (sawtooth)
# Electric Piano 1
# Electric Piano 2
# Electric Grand
# Reed Organ
# Bright Acoustic
# Distortion Guitar
# Pan Flute
# Glockenspiel
# Percussive Organ
# English Horn
# Orchestral Strings
# Pad 8 (sweep)
# Lead 3 (calliope)
# Acoustic Bass
# FX 3 (crystal)
# Trombone
# Tinkle Bell
# Rock Organ
# Steel Drums
# Acoustic Guitar(nylon)
# Lead 1 (square)
# Music Box
# Slap Bass 1
# Slap Bass 2
# Pad 5 (bowed)
# Soprano Sax
# Pad 1 (new age)
# Orchestra Hit
# Guitar Harmonics
# SynthStrings 1
# Kalimba
# Violin
# SynthStrings 2
# Honky-Tonk
# Clarinet
# Timpani
# Harmonica
# Accordion
# FX 6 (goblins)
# Tenor Sax
# Church Organ
# Recorder
# Harpsichord
# Marimba
# Guitar Fret Noise
# Koto
