home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
music
/
krecord1.arc
/
KRECORD1.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1987-04-23
|
10KB
|
354 lines
Program Krecord1; { Written by Kenneth Manos 04/14/87 - Cambridge, Ma. }
{$C+} { Play a 3 octave keyboard and record the notes. }
{ Replay forward or reversed. }
{ Save to a file. Load/Replay from a file. }
{ Generate random notes. }
Type
noterec = record
nroctave,nrduration,nrsub: integer;
nrnotetbl: array[1..500] of integer;
nrintvtbl: array[1..500] of integer;
end;
Var
notefile: file of noterec;
nrec: noterec;
lim1,lim2,hh,mm,ss,ff,svhh,svmm,svss,svff: real;
notex: char;
note,octave,duration,sub1,sub2,sub3,lnth: integer;
notetbl: array[1..500] of integer;
intvtbl: array[1..500] of integer;
filnam1,filnam2: string[30];
Const
chartbl: string[36] = 'ASDFGHJKL;''/QWERTYUIOP[]1234567890-=';
Label
ExitMainLine;
Procedure DisplayMenu;
{ Display the menu }
begin
Writeln('Enter Note: (Top Three Rows On Keyboard)');
Writeln(' (Enter "x" To Exit Program)');
Writeln(' (Enter ">" To Replay - Forward)');
Writeln(' (Enter "<" To Replay - Reverse)');
Writeln(' (Enter "?" To Display This Menu)');
Writeln(' (Enter "c" To Generate Random Notes)');
Writeln(' (Enter "z" To Reset Options/Clear Memory)');
Writeln(' (Enter "v" To Save Recording To A Disk File)');
Writeln(' (Enter "b" To Play Recording From A Disk File)');
Writeln(' (Enter "n" To Load Recording From A Disk File Into Memory)');
end;
Procedure PlayNote(octave,note,duration: integer);
{ Play note in octave for duration (in ms). }
{ Frequency computed by first computing C in }
{ octave and then increasing it by note-1 }
{ times the twelfth root of 2. (1.059463994). }
Var
frequency: real;
begin
frequency := 32.625;
for sub3 := 1 to octave do { Compute C in octave }
frequency := frequency * 2;
for sub3 := 1 to (note - 1) do { Increase frequency note-1 times }
frequency := frequency * 1.059463094;
Sound(Round(frequency));
Delay(duration);
NoSound;
end;
Procedure GetTime;
{ Get the system time from DOS }
Type
regpack = record
ax,bx,cx,dx,bp,si,di,ds,es,flags: integer;
end;
Var
regs: regpack;
begin
svhh := hh; svmm := mm; svss := ss; svff := ff;
with regs do
begin
ax := $2C00;
MsDos(regs); { Get system time from DOS }
hh := Int(Hi(cx)); { Hour }
mm := Int(Lo(cx)); { Minute }
ss := Int(Hi(dx)); { Second }
ff := Int(Lo(dx)); { Fraction of second }
end;
end;
Function Interval: integer;
{ Return the time interval between two notes }
Var
tt: real;
begin
GetTime;
if (sub1 > 0) then
begin
tt := (hh - svhh)*3600 + (mm - svmm)*60 + (ss - svss) + (ff - svff)/100;
tt := Abs(tt * 1000 - 100);
if (tt > 30000) then { Protect against fixed point overflow }
tt := 1000;
Interval := Round(tt);
end;
end;
Function Rand(var testlim: real): integer;
{ Return a random number between 1 and testlim based on system time }
Var
rr: real;
begin
GetTime;
rr := (hh + 1) * (mm + 1) * (ss + 1) * (ff + 1) * pi;
rr := Frac(rr / (testlim + 1)) * (testlim +1);
Rand := Round(rr + 0.5);
end;
Procedure Siren;
{ Sound a siren }
Var
frequency: integer;
begin
for frequency := 300 to 3000 do
begin
Delay(1);
Sound(frequency);
end;
Delay(1000);
for frequency := 3000 downto 300 do
begin
Delay(1);
Sound(frequency);
end;
NoSound;
end;
Procedure GetFileName;
{ Get a file name from the console. }
{ Default file name is in filnam2. }
{ Default file extension is "NOT". }
begin
Readln(filnam1);
lnth := Length(filnam1);
if (lnth = 0) then
begin
filnam1 := filnam2;
exit;
end;
for sub2 := 1 to lnth do
filnam1[sub2] := UpCase(filnam1[sub2]);
if (Pos('.',filnam1) = 0) then
filnam1 := Concat(filnam1,'.NOT');
filnam2 := filnam1;
end;
Procedure SaveToFile;
{ Save this recording to a disk file. }
begin
Writeln('Enter File Name Of Recording To Be Saved (',filnam2,')');
GetFileName;
with nrec do
begin
Assign(notefile,filnam1);
Rewrite(notefile);
Flush(notefile);
nrsub := sub1;
nroctave := octave;
nrduration := duration;
for sub2 := 1 to nrsub do
begin
nrnotetbl[sub2] := notetbl[sub2];
nrintvtbl[sub2] := intvtbl[sub2];
end;
Write(notefile,nrec);
Close(notefile);
end;
end;
Procedure PlayFromFile;
{ Play a recording from a disk file. }
begin
Writeln('Enter File Name Of Recording To Be Played (',filnam2,')');
GetFileName;
with nrec do
begin
Assign(notefile,filnam1);
{$I-}
Reset(notefile);
{$I+}
if (IOresult <> 0) then
begin
Writeln(' ** Note File Not Found **');
exit;
end;
Read(notefile,nrec);
Writeln('** ',filnam2,': Octave=',nroctave,' Duration=',nrduration,
' #Notes=',nrsub);
for sub2 := 1 to nrsub do
begin
Delay(nrintvtbl[sub2]);
PlayNote(nroctave,nrnotetbl[sub2],nrduration);
end;
Flush(notefile);
Close(notefile);
end;
end;
Procedure LoadFromFile;
{ Load a recording from a disk file into memory. }
begin
Writeln('Enter File Name Of Recording To Be Loaded (',filnam2,')');
GetFileName;
with nrec do
begin
Assign(notefile,filnam1);
{$I-}
Reset(notefile);
{$I+}
if (IOresult <> 0) then
begin
Writeln(' ** Note File Not Found **');
exit;
end;
Read(notefile,nrec);
Writeln('** ',filnam2,': Octave=',nroctave,' Duration=',nrduration,
' #Notes=',nrsub);
for sub1 := 1 to nrsub do
begin
notetbl[sub1] := nrnotetbl[sub1];
intvtbl[sub1] := nrintvtbl[sub1];
end;
Flush(notefile);
Close(notefile);
end;
end;
Procedure PlayRandom;
{ Play Random notes }
begin
lim1 := 5;
lim2 := 222;
Writeln(' Enter High Octave (1-8) And High Note Duration (ms)');
Readln(lim1,lim2);
lim1 := (lim1 - octave + 1) * 12;
Writeln(' Hit Any Note To Stop');
while (not KeyPressed)
begin
note := Rand(lim1);
duration := Rand(lim2);
Delay(Rand(lim2));
PlayNote(octave,note,duration);
end;
end;
Procedure ResetOptions;
{ Reset options/clear memory }
begin
sub1 := 0;
Writeln('Enter Octave (1-8) And Note Duration (ms)');
Readln(octave,duration);
if (octave < 1) or (octave > 8) then
begin
Writeln('** Invalid Octave: ',octave);
octave := 3;
Siren;
end;
DisplayMenu; { Display menu }
end;
Begin { Mainline logic }
filnam2 := 'K1.NOT';
octave := 3;
duration := 100;
notex := 'Z';
while (notex <> 'X')
begin
if (notex = 'Z') then
begin { Reset options/clear memory }
ResetOptions;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = 'V') then
begin { Save recording to disk file }
SaveToFile;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = 'B') then
begin { Play recording from disk file }
PlayFromFile;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = 'N') then
begin { Load recording from disk file into memory }
LoadFromFile;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = '?') then
begin { Display menu }
DisplayMenu;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = 'C') then
begin { Generate random notes }
PlayRandom;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = '>') then
begin { Replay from memory - forward }
for sub2 := 1 to sub1 do
begin
Delay(intvtbl[sub2]);
PlayNote(octave,notetbl[sub2],duration);
end;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
if (notex = '<') then
begin { Replay from memory - reverse }
for sub2 := sub1 downto 1 do
begin
PlayNote(octave,notetbl[sub2],duration);
Delay(intvtbl[sub2]);
end;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
note := 0;
for sub2 := 1 to 36 do
begin { Determine numeric value of note }
if chartbl[sub2] = notex then
note := sub2;
end;
if (note = 0) then
begin
Writeln('** Invalid Note: ',notex);
Siren;
GetTime; { Reset interval timer }
goto ExitMainLine;
end;
sub1 := sub1 + 1; { Increment note subscript }
notetbl[sub1] := note; { Save this note }
intvtbl[sub1] := Interval; { Save time interval from last note }
PlayNote(octave,note,duration); { Play this note }
ExitMainLine:
Read(kbd,notex); { Get next note }
notex := UpCase(notex); { Convert to upper case }
end;
End.