home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Intermedia 1998 January
/
inter1_98.iso
/
www
/
rozi
/
POLI_SMP.ZIP
/
POLY.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-11-25
|
7KB
|
318 lines
program PolyPlayer;
{ Polifoniczne odtwarzanie próbek d½wi⌐kowych }
{$G+} { Instrukcje 286 }
uses Dos;
const
{Tablica cz⌐stotliwoÿci d½wi⌐ków poszczególnych klawiszy}
keyboard : array[1..50] of word =
( 0, 0, 9441,10597, 0,
12602,14145,15877, 0,18881,
21193, 0, 0, 0, 0,
8911,10002,11227,11894,13351,
14986,16821,17821,20004,22453,
0, 0, 0, 0, 0,
4720, 5298, 0, 6301, 7072,
7939, 0, 0, 0, 0,
0, 0, 0, 4455, 5001,
5613, 5947, 6675, 7493, 8411);
type
smp = array[1..65535] of byte;
var
f : file;
basefrq : word;
c1pos,c2pos,c3pos,c4pos : longint;
cmax : longint;
c1frq,c2frq,c3frq,c4frq : longint;
c1val,c2val,c3val,c4val : byte;
sample : ^smp;
old8 : pointer;
p60,akey : byte;
procedure EnableIrq0; assembler;
{ WêÑczenie przerwania IRQ0 }
asm
in al,21h
and al,254
out 21h,al
end;
procedure DisableIrq0; assembler;
{ WyêÑczenie przerwania IRQ0 }
asm
in al,21h
or al,1
out 21h,al
end;
procedure EnableIrq1; assembler;
{ WêÑczenie przerwania IRQ1 }
asm
in al,21h
and al,253
out 21h,al
end;
procedure DisableIrq1; assembler;
{ WyêÑczenie przerwania IRQ1 }
asm
in al,21h
or al,2
out 21h,al
end;
procedure TimerInit; assembler;
{ Inicjacja timera }
asm
mov al,34h
out 43h,al
end;
procedure InitFreq(frq : word); assembler;
{ Ustalenie cz⌐stotliwoÿci }
asm
mov ax,[frq]
out 40h,al
mov al,ah
out 40h,al
end;
{$F+}
procedure Play; interrupt;
begin
asm
cli
les ax,sample { adres sampla do ES:DI }
mov bx,es
mov dx,ax
and ax,15
mov di,ax
shr dx,4
add bx,dx
mov es,bx
mov ax,word ptr c1pos+2 { C1POS<C1MAX ? }
cmp ax,word ptr cmax+2
ja @ToBig1 { tak - za du╛y }
jne @Ok1
mov ax,word ptr c1pos
cmp ax,word ptr cmax
ja @ToBig1 { tak - za du╛y }
@Ok1: { ok }
mov ax,word ptr c1pos { obliczamy pozycj⌐ }
mov dx,word ptr c1pos+2 { C1POS => DX:AX }
shr ax,14 { DX:AX / 16384 }
shl dx,2
add ax,dx
mov si,di
add si,ax
mov al,[es:si] { pobieramy próbk⌐ }
mov [c1val],al
mov ax,word ptr c1frq { C1POS := C1POS + C1FRQ }
add word ptr c1pos,ax
adc word ptr c1pos+2,0
@ToBig1:
mov ax,word ptr c2pos+2 { i tak samo dla
dalszych 3 kanaêów }
cmp ax,word ptr cmax+2
ja @ToBig2
jne @Ok2
mov ax,word ptr c2pos
cmp ax,word ptr cmax
ja @ToBig2
@Ok2:
mov ax,word ptr c2pos
mov dx,word ptr c2pos+2
shr ax,14
shl dx,2
add ax,dx
mov si,di
add si,ax
mov al,[es:si]
mov [c2val],al
mov ax,word ptr c2frq
add word ptr c2pos,ax
adc word ptr c2pos+2,0
@ToBig2:
mov ax,word ptr c3pos+2
cmp ax,word ptr cmax+2
ja @ToBig3
jne @Ok3
mov ax,word ptr c3pos
cmp ax,word ptr cmax
ja @ToBig3
@Ok3:
mov ax,word ptr c3pos
mov dx,word ptr c3pos+2
shr ax,14
shl dx,2
add ax,dx
mov si,di
add si,ax
mov al,[es:si]
mov [c3val],al
mov ax,word ptr c3frq
add word ptr c3pos,ax
adc word ptr c3pos+2,0
@ToBig3:
mov ax,word ptr c4pos+2
cmp ax,word ptr cmax+2
ja @ToBig4
jne @Ok4
mov ax,word ptr c4pos
cmp ax,word ptr cmax
ja @ToBig4
@Ok4:
mov ax,word ptr c4pos
mov dx,word ptr c4pos+2
shr ax,14
shl dx,2
add ax,dx
mov si,di
add si,ax
mov al,[es:si]
mov [c4val],al
mov ax,word ptr c4frq
add word ptr c4pos,ax
adc word ptr c4pos+2,0
@ToBig4:
xor bh,bh
mov ax,0 { sumujemy wartoÿci
z czerech kanaêów }
mov bl,c1val
add ax,bx
mov bl,c2val
add ax,bx
mov bl,c3val
add ax,bx
mov bl,c4val
add ax,bx
shr ax,2 { i dzielimy przez 4 }
{ tu mo╛e byå umieszczona procedura do obsêugi }
{ urzÑdzenia wyjÿciowego }
mov dx,378h
out dx,al { do portu LPT1 ("Covox") }
mov al,20h { zakoΣczenie obsêugi przerwania }
out 20h,al
sti
end;
end;
{$F-}
begin
new(sample);
writeln('Polifoniczne odtwarzanie sampli.');
if paramstr(1)='' then
begin
writeln('U╛ycie: POLYPLAY <nazwa_sampla>'); halt;
end;
basefrq := 16384;
assign(f,paramstr(1));
{$I-}
reset(f,1);
{$I+}
if ioresult<>0 then
begin
writeln('U╛ycie: POLYPLAY <nazwa_sampla>'); halt;
end;
if filesize(f)>65535 then
begin
writeln('Maksymalna dêugoÿå próbki 65535 bajtów.');
halt;
end;
cmax := filesize(f)*basefrq;
{$I-}
blockread(f,sample^,filesize(f));
close(f);
{$I+}
if ioresult<>0 then
begin
writeln('BêÑd odczytu !'); halt;
end;
c1pos := 1; c2pos := 1;
c3pos := 1; c4pos := 1;
c1frq := 0; c2frq := 0;
c3frq := 0; c4frq := 0;
akey := 0;
write('Escape - przerwanie odtwarzania.');
DisableIrq1; { wyêÑczamy klawiatur⌐ }
GetIntVec(8,old8); { pobieramy wektor IRQ0 }
DisableIrq0; { wyêÑczamy IRQ 0 }
SetIntVec(8,@Play); { ustawiamy wektor na Play }
TimerInit; { inicjujemy licznik }
InitFreq(trunc(1193180/basefrq));
{ ustalamy cz⌐stotliwoÿå }
EnableIrq0; { wêÑczamy IRQ0 }
repeat
p60 := port[$60]; { pobierz waroÿå bezpoÿr.
z portu klawiatury }
while port[$60]=p60 do; { czekaj na zmian⌐ warotÿci }
p60 := port[$60]; { pobierz jÑ }
if (p60>1)and(p60<50)and(keyboard[p60]<>0) then
{ czy któryÿ }
begin { z wêaÿciwych klawiszy ? }
inc(akey); { akey - numer kanaêu,
zmieniany cyklicznie }
if akey=5 then akey := 1;
case akey of
1 : begin
c1frq := keyboard[p60];
{ ustalamy cz⌐stotliwoÿå }
c1pos := longint(c1frq);
{ i poczÑtkowÑ pozycj⌐ }
end;
2 : begin
c2frq := keyboard[p60];
c2pos := longint(c2frq);
end;
3 : begin
c3frq := keyboard[p60];
c3pos := longint(c3frq);
end;
4 : begin
c4frq := keyboard[p60];
c4pos := longint(c4frq);
end;
end;
end;
until p60=1; { Escape (kod 1) - koniec }
asm cli end;
DisableIrq0; { odtworzenie poczÑtkowych wartoÿci IRQ0 }
asm sti end;
TimerInit;
InitFreq(0);
SetIntVec(8,old8);
EnableIrq0;
EnableIrq1;
dispose(sample);
writeln;
end.