home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sound Sensations!
/
sound_sensations.iso
/
voice
/
tan_snd
/
noiz.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-07-28
|
12KB
|
497 lines
unit noiz; { NOIZ.PAS Copyright (c) 1990 DSoft Specialties }
interface { Sound routines for the Tandy 1000 and/or PCJr. See NOIZ.SIM }
{ All I ask is if you use any of these routines in your program
please mention DSoft in the docs or in a copyright message }
const
inturbo: boolean = true;
type
voices = 0..3;
attenuations = 0..15;
styles = 1..4;
const
A1 = 27; A2 = 55; A3 = 110; A4 = 220; A5 = 440; A6 = 880; A7 = 1760;
B1 = 31; B2 = 62; B3 = 123; B4 = 247; B5 = 494; B6 = 988; B7 = 1976;
C1 = 33; C2 = 65; C3 = 131; C4 = 262; C5 = 523; C6 = 1047; C7 = 2093;
D1 = 37; D2 = 74; D3 = 147; D4 = 294; D5 = 588; D6 = 1175; D7 = 2349;
E1 = 41; E2 = 83; E3 = 165; E4 = 330; E5 = 660; E6 = 1320; E7 = 2640;
F1 = 44; F2 = 88; F3 = 175; F4 = 350; F5 = 700; F6 = 1400; F7 = 2800;
G1 = 49; G2 = 98; G3 = 196; G4 = 392; G5 = 784; G6 = 1568; G7 = 3136;
A8 = 3520; A9 = 7040; A10 = 14080;
B8 = 3952; B9 = 7904; B10 = 15808;
C8 = 4160; C9 = 8320; C10 = 16640;
D8 = 4704; D9 = 9408; D10 = 18816;
E8 = 5280; E9 = 10560;
F8 = 5600; F9 = 11200;
G8 = 6272; G9 = 12544;
AS1 = 29; AS2 = 58; AS3 = 116; AS4 = 231; AS5 = 466; AS6 = 928; AS7 = 1856;
CS1 = 34; CS2 = 69; CS3 = 139; CS4 = 277; CS5 = 554; CS6 = 1108;CS7 = 2240;
DS1 = 39; DS2 = 78; DS3 = 156; DS4 = 311; DS5 = 622; DS6 = 1244;DS7 = 2496;
FS1 = 46; FS2 = 93; FS3 = 185; FS4 = 370; FS5 = 740; FS6 = 1480;FS7 = 2960;
GS1 = 26; GS2 = 52; GS3 = 208; GS4 = 415; GS5 = 830; GS6 = 1660;GS7 = 3320;
AS8 = 3712; AS9 = 7424; AS10 = 14848;
CS8 = 4480; CS9 = 8960; CS10 = 17920;
DS8 = 4992; DS9 = 9984; DS10 = 19968;
FS8 = 5920; FS9 = 11840;
GS8 = 6640; GS9 = 13280;
const
stacatto: boolean = false; legato: boolean = false;
zetto: boolean = false; xetto: boolean = false;
dtime: integer = 80;
procedure wait(dt: longint);
procedure delay(dt: longint);
procedure sound(freq: word);
procedure nosound;
procedure sound_level(voice: voices;atten: attenuations);
procedure sound_period(voice: voices;period: integer);
procedure sound_pitch(voice: voices;freq: real);
procedure sound_off;
procedure extsound(freq,dur: integer;level: attenuations;voice: voices);
procedure plays(freq,dur: word;attack,decay: integer;voice: voices);
procedure chord(freq1,freq2,freq3,dur,level: integer);
procedure play(freq,dur: integer;v: voices;style: styles);
procedure noise(ch: char;sr,atten,dur: word);
procedure note1(freq,dura: word);
procedure note4(note,dura: integer);
procedure dubend(freq1,freq2,dt: integer);
procedure bend(tone,tone1,tonedur,dur,reps: integer);
procedure scale(freq1,freq2,freq3: integer;a,b,c,d,e,f,g,aa: integer);
procedure scale2(a,b,c,d,e,f,g,z: integer;dtime,attack,decay: integer;
v: voices);
procedure snd(freq: integer);
procedure snd2(freq: integer);
procedure nosnd;
procedure nosnd2;
procedure quiet;
function fkey: char;
function keyhit: boolean;
implementation
uses dos;
procedure wait(dt: longint);
const
inturb = 32;
indos = 60;
var tt,ir,tr: longint;
begin
if inturbo then
tt:=inturb
else
tt:=indos;
for ir:=1 to dt do
for tr:=1 to tt do
end;
procedure delay(dt: longint);
begin
wait(dt);
end;
{$F+}
procedure sound(freq: word);
begin
inline(
$8B/$5E/$06/$B8/$DD/$34/
$BA/$12/$00/$39/$DA/
$73/$1A/$F7/$F3/$89/$C3/
$E4/$61/$A8/$03/$75/$08/
$0C/$03/$E6/$61/$B0/$B6/
$E6/$43/$88/$D8/$E6/$42/
$88/$F8/$E6/$42);
end;
{$F-}
procedure nosound;
begin
inline($E4/$61/$24/$FC/$E6/$61);
end;
procedure sound_level(voice: voices;atten: attenuations);
{ change the level (atten) of a voice }
begin
if (atten < 0) then
atten:=0
else
if (atten > 15) then atten:=15;
port[$C0]:=($90 + (voice shl 5) + (atten and $0F));
end;
procedure sound_period(voice: voices;period: integer);
{ change the sound divider (period) of a voice }
begin
port[$C0]:=($80 + (voice shl 5) + (period and $0F)); { lo 4 bits }
port[$C0]:=((period shr 4) and $3F); { hi 6 bits }
end;
procedure sound_pitch(voice: voices;freq: real);
{ change the pitch (freq) of a voice }
var period: real;
function chip_freq(freq: real): word;
begin
chip_freq:=round(((3.579 * 1000000) / (freq * 32)));
end;
begin
if (freq = 0.0) then
period:=0
else
period:=chip_freq(freq);
if (period <= 1) or (period > $3FF) then period:=1;
sound_period(voice,round(period));
end;
procedure sound_off;
var v: voices;
begin
for v:=0 to 3 do
begin
sound_level(v,15);
sound_pitch(v,0);
end;
end;
procedure extsound(freq,dur: integer;level: attenuations;voice: voices);
begin
sound_level(voice,level div 4);
if ((freq < A3) or (voice = 3)) then
sound(freq)
else
sound_pitch(voice,freq);
wait(dur);
end;
procedure plays(freq,dur: word;attack,decay: integer;voice: voices);
var i,j,k: integer;
begin
if (dur < 4) then dur:=4;
if (freq < A3) then
begin
sound(freq);
wait(dur);
end else
begin
sound_pitch(voice,freq);
for i:=attack downto 0 do
begin
sound_level(voice,i);
wait(2);
end;
wait(dur-(attack-decay)-4);
for i:=0 to decay do
begin
sound_level(voice,i);
wait(2);
end;
end;
end;
procedure chord(freq1,freq2,freq3,dur,level: integer);
var i,j,k: integer;
begin
if (level > 15) then
begin
for i:=15 downto (level - 15) do
begin
extsound(freq1,dur div 2,i,0);
extsound(freq2,dur div 2,i,1);
extsound(freq3,dur div 2,i,2);
end;
extsound(freq1,dur,level,0);
extsound(freq2,dur,level,1);
extsound(freq3,dur,level,2);
wait(dur);
exit;
end else
for i:=1 to level do
begin
extsound(freq1,dur div 2,i,0);
extsound(freq2,dur div 2,i,1);
extsound(freq3,dur div 2,i,2);
end;
extsound(freq1,dur,level,0);
extsound(freq2,dur,level,1);
extsound(freq3,dur,level,2);
wait(dur);
end;
procedure play(freq,dur: integer;v: voices;style: styles);
var zz,z,x,xx,i: integer;
begin
x:=dur div 3;
xx:=dur div 2;
z:=xx-x;
zz:=x div 2;
case style of
1: begin
extsound(freq,z,3,v);
for i:=15 downto 1 do extsound(freq,zz,i,v);
for i:=1 to 13 do extsound(freq,zz,i,v);
extsound(freq,xx,2,v);
exit;
end;
2: begin
extsound(freq,xx+z,4,v);
for i:=1 to 15 do
begin
extsound(freq,zz,5 xor i,v);
if (v >= 2) then
extsound(freq,zz,i,v-1)
else
extsound(freq,zz,i,v+1);
end;
exit;
end;
3: begin
for i:=15 downto 1 do
begin
extsound(freq*2,1,i,v);
if (v >=2) then
extsound(freq,zz,i,v-1)
else
extsound(freq,zz,i,v+1);
end;
extsound(freq,zz,10,v);
for i:=15 downto 7 do extsound(freq,zz,i,v);
extsound(freq,xx,2,v);
exit;
end;
4: begin
for i:=0 to 15 do extsound(freq,1,i,v);
for i:=15 downto 0 do
begin
if (v >= 2) then
extsound(freq*2,zz,i,v-1)
else
extsound(freq*2,zz,i,v+1);
end;
for i:=7 to 15 do extsound(freq,zz,i,v);
extsound(freq,xx,10,v);
exit;
end;
end;
end;
procedure noise(ch: char;sr,atten,dur: word);
var portpass1: integer;
begin
portpass1:=224;
if (ch in ['W','w']) then portpass1:=portpass1 + 4;
case sr of
10: portpass1:=portpass1 + 1;
20: portpass1:=portpass1 + 2;
end;
port[$C0]:=240+atten;
port[$C0]:=portpass1;
wait(dur);
end;
procedure note1(freq,dura: word);
var x: integer;
begin
if keyhit then
begin
quiet;
exit;
end;
if (legato=true) then
begin
sound(freq); wait(dura-7); sound(freq); wait(7);
end else
if (stacatto=true) then
begin
sound(freq); wait(dura-11);
nosound; wait(11);
end else
if (zetto=true) then
begin
x:=dura div 3;
sound(freq); wait(x);
nosound; wait(x*2);
end else
if (xetto=true) then
begin
x:=dura div 5;
sound(freq); wait(x);
nosound; wait(x*4);
end else
begin
sound(freq); wait(dura);
nosound;
end;
end;
procedure note4(note,dura: integer);
var x: integer;
begin
if keyhit then
begin
quiet; exit;
end;
if (legato=true) then
begin
extsound(note,dura-7,0,0);
extsound(note,7,0,0);
end else
if (stacatto=true) then
begin
extsound(note,dura-11,0,0);
sound_level(1,15);
wait(11);
end else
if (zetto=true) then
begin
x:=dura div 3;
extsound(note,x,0,0);
sound_level(1,15); wait(x*2);
end else
if (xetto=true) then
begin
x:=dura div 5;
extsound(note,x,0,0);
sound_level(1,15); wait(x*4);
end else
begin
extsound(note,dura,0,0);
sound_level(1,15);
end;
end;
procedure dubend(freq1,freq2,dt: integer);
var i: integer;
begin
for i:=freq1 to freq2 do extsound(i,dt,1,0);
sound_level(0,15);
end;
procedure bend(tone,tone1,tonedur,dur,reps: integer);
var i,j: integer;
begin
if (tone1 > tone) then
begin
for i:=1 to reps do
begin
extsound(tone1,tonedur,1,0);
dubend(tone,tone1,dur);
sound_level(0,15); wait(10);
end;
end else
if (tone > tone1) then
begin
for i:=1 to reps do
begin
for j:=tone downto tone1 do extsound(j,dur,1,0);
extsound(tone1,tonedur,1,0);
end;
sound_level(0,15);
end;
end;
procedure scale(freq1,freq2,freq3: integer;a,b,c,d,e,f,g,aa: integer);
begin
chord(freq1,freq2,freq3,1,5);
if (freq1 >= A3) then
begin
note1(a,dtime); note1(b,dtime); note1(c,dtime); note1(d,dtime);
note1(e,dtime); note1(f,dtime); note1(g,dtime); note1(aa,dtime);
end else
if (freq1 < A3) then
begin
note4(a,dtime); note4(b,dtime); note4(c,dtime); note4(d,dtime);
note4(e,dtime); note4(f,dtime); note4(g,dtime); note4(aa,dtime);
end;
quiet;
end;
procedure scale2(a,b,c,d,e,f,g,z: integer;dtime,attack,decay: integer;
v: voices);
begin
plays(a,dtime,attack,decay,v);
plays(b,dtime,attack,decay,v);
plays(c,dtime,attack,decay,v);
plays(d,dtime,attack,decay,v);
plays(e,dtime,attack,decay,v);
plays(f,dtime,attack,decay,v);
plays(g,dtime,attack,decay,v);
plays(z,dtime,attack,decay,v);
end;
procedure snd(Freq: integer);
var Count: integer;
begin
Count:=$1B1AAA div Freq;
Port[$C0]:=$A5;
port[$C0]:=$15;
port[$C0]:=$A0;
port[$C0]:=$A5;
port[$C0]:=hi(count);
port[$C0]:=$A0;
end;
procedure snd2(Freq: integer);
var Count: integer;
begin
Count:=$1B1AAA div Freq;
Port[$C0]:=$C5;
port[$C0]:=$15;
port[$C0]:=$C0;
port[$C0]:=$C5;
port[$C0]:=hi(count);
port[$C0]:=$C0;
end;
procedure Nosnd;
var sport: Byte;
begin
SPort:=Port[$C0];
port[$C0]:=$BF;
end;
procedure Nosnd2;
var sport: Byte;
begin
SPort:=Port[$C0];
port[$C0]:=$DF;
port[$C0]:=$BF;
end;
procedure quiet;
begin
nosound;
nosnd; nosnd2;
sound_off;
port[$C0]:=$9F;
end;
function fkey: char;
var regs: registers;
begin
regs.AH:=0;
intr($16,regs);
if regs.AL=0 then
fkey:=chr(regs.AH+128)
else
fkey:=chr(regs.AL)
end;
function keyhit: boolean;
var regs: registers;
begin
regs.AH:=1;
intr($16,regs);
keyhit:=(regs.flags and 64)=0;
end;
end.