Newsgroup: it.comp.lang.pascal
Titolo: COme eseguire dei .wav?

Qualcuno sa come eseguire dei file .wav con il Turbo Pascal?
Chiunque abbia documentazione, sorgenti o links interessanti a proposito epr
favore si faccia vivo in e-mail al 
cia...@tiscalinet.it
 . Grazie mille.

 wrote in message
Q5ko4.100992$C3.10...@news.infostrada.it...

Ciao, io ho la documentazione di come funziona il driver CT-VOICE.DRV della
SBLaster e compatibili, cioè funzioni e sistema di come caricare il driver,
caricare il file .voc e riprodurre il suono.
Il file *.voc sono molto simili ai file *.wav, esistono dei
convertitori(WAV2VOC.exe) per dos; oppure li converti con qualche programma
di editing di file audio.
Ovviamente funziona solo con la SB e compatibili(io ho una SB16). Il file
CT-VOICE.DRV è contenuto nel cd della SB o lo trovi nel sito della sb
(credo...); comunque è liberamente distribuibile con i giochi o programmi
che sviluppi. Se non lo trovi te lo invio via mail.
Questo programma funzia solo con file .voc di piccole dimensioni (minori di
64kb); io l'ho usato per far dire al computer un numero inserito
dall'utente; prima avevo registrato tutti i numeri da 0 a 9 su dei file
.wav, e li ho convertiti in *.voc.
-----------------------------------------------
Innanzitutto devi caricare il driver:crea un puntatore ad un array di char
grande quanto il file CT-VOICE.drv (che è più piccolo di 64kb per fortuna).
carichi il file CT-VOICE.drv nel puntatore(l'ho chiamato Driver_buf);
(*per ogni chiamata al driver devi inserire nei registri:
in BX                la funzione che ti interessa
in AX, ES, DI    alcuni parametri (es AL=0 oppure  ES:DI l'indirizzo del
file .voc )
e poi           CALL Driver_buf;     (* per chiamare il driver *)
*)
Ti informi sulla versione del driver con la funzione BX=0   (il mio indica
0.22)
Prima imposti i parametri (1:porta e 2:DMA) con le funzioni BX=1 e 2
(risposta tutto ok in AX)
Inizializzi il driver con la funzione BX=3
Imposti la parola di stato(per sapere se la sb sta lavorando) con BX=5 e
ES:DI = seg():offset() della word
Accendi gli altoparlanti con la funzione BX=4 e AL=1
  Carichi il file .voc il un buffer temporaneo
LOOP:
  controlli se la parola di stato è diversa da -1
  muovi il buffer temporaneo in un buffer che hai dedicato alla sb;
  Riproduci il suono chiamando la funzione BX=6 con ES=segmento e DI=offset
(risposta in AX)
  mentre sta riproducendo carichi il file successivo nel buffer temporaneo
vai LOOP:   ( ovviamente questo ciclo è diverso a seconda del programma che
si deve sviluppare)
                (ad esempio si potrebbe aspettare la fine del file e
riprodurlo continuamente senza altri caricamenti)
Spegni gli altoparlanti con la funzione BX=4 e AL=0
Interrompi l'output con la funzione BX=8
Chiudi il driver con la funzione BX=9
(* nota la funzione BX=4 funzia solo con SB modello base (penso sia solo
SB16) per altre non ha effetto(?) *)
(* in alternativa si può usare BX=10 (senza nessun altro parametro) indica
una PAUSE; mentre per riprendere usare BX=11 (senza altri parametri)  oppure
BX=6 (che ricomincia) *)
-----------------------------------------------
(* nota che il programma non è ottimizzato ma va' bene come inizio...*)
Program SBLaster;
uses Crt;
type driverb=array [0..40000]of char;  (* array di char per il driver *)
var Driver_buf:^driverb;    (* deve essere globale cioè non dentro ad una
procedure o function *)
const Max=20000;            (* massima dimensione in byte del file .voc *)
type datab=array [0..Max]of char;   (* array per il file .voc *)
var Driver_buf:^driverb;
    File_buf,temp_buf:^datab;
    ctstatus:integer;
Function CaricaDriver:integer;
var ark:file;versione:integer; status:integer;
begin
New(Driver_buf);
if ofs(Driver_buf^)<>0 then Writeln('Errore nell''offset del driver!!!');
Assign(ark,'CT-VOICE.DRV');
reset(ark,1);
blockread(ark,driver_buf^,filesize(ark));  (* carica dal disco tutto il
driver *)
close(ark);
 asm
  mov bx,1                      (* funzione 1 impostazione PORTA SB*)
  mov ax,$220                (* porta 220h *)
  call driver_buf
  mov bx,2                      (* funzione 2 impostazione canale DMA *)
  mov ax,5                      (* canale DMA #5 oppure DMA basso #1 *)
  call driver_buf
  mov bx,0                     (* funzione 0  richiesta versione driver*)
  call driver_buf
  mov versione,ax          (* risposta in ax *)
 end;
 Writeln('Versione driver: ',HI(versione),'.',versione AND $00FF);
(* INIZIALIZZA IL DRIVER *)
 asm
  mov bx,3                      (* funzione 3 inizializzazione *)
  call driver_buf
  mov status,ax                (* Imposta la parola(word) di stato per
sapere come funziona la SB*)
  mov bx,5                      (* funzione 5 impostazione del segmento ed
offset della parola di stato *)
  mov ax,seg(ctstatus)
  mov es,ax                       (* es:di   :=  seg(ctstatus):ofs(ctstatus)
*)
  mov di,offset(ctstatus)
  call driver_buf
  mov bx,4                       (* funzione 4 attiva/disattiva
l'altoparlante; è necessario(?)*)
  mov al,1                        (* AL:=1 altoparlanti attivati
AL:=0 altoparlanti disattivati*)
  call driver_buf
 end;
 Writeln('Driver SuondBlaster CT-VOICE caricato ed inizializzato!!!');
CaricaDriver:=status;
end;
Procedure DoneDriver;  (* scarica il driver dalla memoria e spegne la
sblaster *)
begin
 asm
  mov bx,4        (* funzione 4 attiva/disattiva l'altoparlante *)
  mov al,0         (* AL:=1 altoparlanti attivati          AL:=0
altoparlanti disattivati *)
  call driver_buf
  mov bx,8        (* funzione 8 interrompe qualsiasi output *)
  call driver_buf
  mov bx,9        (* funzione 9 chiude il driver IMPORTANTE *)
  call driver_buf
 end;
end;
Procedure CaricaOnda(f:string);
var ark:file; K:INTEGER;
begin
(*if ofs(temp_buf^)<>0 then Writeln('Errore nell''offset del file!!!');
non so se sia necessario... l'ho tolto perché non succede mai*)
fillchar(temp_buf^,max+1,0);  (* riempie il buffer di 0; il file caricato
precedentemente potrebbe essere stato
                                                più grande di questo *)
Assign(ark,f);
reset(ark,1);
blockread(ark,temp_buf^,filesize(ark));
close(ark);
(* verifica che sia un file voc;  non è necessario questo controllo (se si
sa quello che si sta facendo...)*)
(*IF (temp_BUF^[0]<>'C') or (temp_BUF^[1]<>'r')    then Writeln('Non è un
file voc.');*)
(* Nota: i file .voc hanno come intestazione(primi caratteri del file) la
parola Creative *)
end;
Procedure StopSuono;
begin
 asm
  mov bx,8          (* funzione 8 interrompe l'output *)
  call driver_buf
 end;
end;
Function RiproduciSuono:integer;
var offs,segs:word;status:integer;
begin
segs:=seg(file_buf^);          (* bisogna indicare alla SB segmento ed
offset del .voc *)
offs:=ord(file_buf^[20]);
 asm
  mov bx,6        (* funzione 6 riproduce il suono:    BX=6    ES=segmento
DI=offset  *)
  mov ax,segs    (* per caricare in ES bisogna prima passare per AX
ax:=segs*)
  mov es,ax       (* es:=ax *)
  mov di,offs
  call driver_buf   (* chiamata al driver che esegue il comando BX*)
  mov status,ax     (* la risposta se è stato eseguito correttamente è data
in AX *)
 end;
RiproduciSuono:=status;
end;
var ch:char;numero:string;k:integer;
(* programma principale *)
begin
clrscr;
Writeln(CaricaDriver);
New(file_buf);
file_buf:=ptr(seg(file_buf^)+1,0);
New(temp_buf);
repeat
 Write('Inserire il numero da leggere:');readln(numero);
 for k:=1 to length(numero) do
 begin
   ch:=numero[k];
   if (ch in ['1'..'9']) or (ch='0') then
   begin
     CaricaOnda(ch+'.VOC');    (* per ogni numero carica il file .voc
corrispondente *)
     while (ctstatus=-1) do   (* IMPORTANTE: non si può sovrascrivere il
buffer mentre la sb sta leggendo e *)
          begin                      (* riproducendo il file *)
          end;
     Move(temp_buf^,file_buf^,max);   (* siccome ctstatus indica che sb ha
finito si può copiare il file nel *)
     RiproduciSuono;                          (* buffer per riprodurre il
suono *)
   end;
 end;
until CH='0';    (* finche non viene inserito come numero 0 il programma non
termina*)
while (ctstatus=-1) do      (* evita di uscire la programma mentre la sb sta
riproducendo *)
 begin
 end;
StopSuono;
Dispose(file_buf);
DoneDriver;                    (* chiude il driver altrimenti rimane in
memoria e bisogna riavviare il pc *)
Dispose(driver_buf);        (* per poter eseguire nuovamente il programma o
altri programmi che usano la sb; *)
end.
C'è un piccolo problema se vuoi riprodurre continuamente un file d'onda:
devi impostare il buffer grande esattamente come il file .voc altrimenti si
sente un silenzio dovuto al fillchar che riempie di 0 il buffer.
Il programma funziona solo sotto Dos e non dentro ad una finestra. Inoltre
la SBlaster deve essere configurata e funzionante, con i driver
DEVICE=C:\SB16\DRV\CTSB16.SYS /UNIT=0 /BLASTER=A:220 I:5 D:1 H:1
DEVICE=C:\SB16\DRV\CTMMSYS.SYS
caricati nel config.sys e impostati
SET BLASTER=A220 I5 D1 H1 P330 T6        (dove A=porta i/o, I=irq, D=dma,
H=dma alto, P=midi, T=?)
nell'autoexec.bat (questi ovviamente valgono per SB16).
Spero di essere stato abbastanza chiaro e di aver commentato il programma in
modo che si capisca.
Se vuoi la documentazione completa anche del driver SBFDRV.drv per la musica
MIDI te la invio per mail, oppure scrivi nel ng (anche se è la prima volta
che rispondo in un newsgroup, spero sia di interesse anche per altri
programmatori).
mo.da...@MONDOlibero.it
 togli MONDO per l'email.

Mi sono dimenticato di chiederti se percaso il programma doveva funzionare
in windows o in dos!
Perché quello funzia solo sotto dos.
?