LA CAMPANA

C'è chi legge queste notizie prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
cognome
Come vuoi leggere The Bell
No spam

tema: Come far cantare l'app Delphi 2.

Questo suggerimento mostra quattro modi diversi per far "cantare" l'applicazione Delphi 2.0, ad es. Scarica e riproduci file audio:

1. Per riprodurre il file audio, utilizzare direttamente la funzione sndPlaySound ().

2. Leggere il file audio in memoria, quindi utilizzare sndPlaySound () per riprodurlo.

3. Utilizzare sndPlaySound per riprodurre direttamente i file audio che si trovano nei file di risorse collegati all'applicazione.

4. Leggere il file audio che si trova nel file di risorse collegato all'applicazione in memoria, quindi utilizzare sndPlaySound () per riprodurlo.

Per costruire un progetto avrai bisogno di:

1. Creare un file audio denominato "hello.wav" nella directory del progetto.

2. Creare un file di testo chiamato "snddata.rc" nella directory del progetto.

3. Aggiungere la seguente riga al file "snddata.rc":

.

4. Nella sessione dos, vai alla directory dell'applicazione e compila il file .rc usando il compilatore di risorse Borland (brcc32.exe): inserisci il percorso a brcc32.exe e passa "snddata.rc" come parametro.

Questo creerà il file snddata.res, che Delphi collega al file .exe dell'applicazione.


usiWindows, Messaggi, SysUtils, Classi, Grafica, Controlli, Moduli, Finestre di dialogo, StdCtrls;

tipoTForm1 \u003d classe(TForm)
procedura   PlaySndFromFileClick (Sender: TObject);
procedura   PlaySndFromMemoryClick (Sender: TObject);
procedura   PlaySndFromResClick (Sender: TObject);
procedura   PlaySndbyLoadResClick (Sender: TObject);



procedura   TForm1.PlaySndFromFileClick (Sender: TObject);
  sndPlaySound ("hello.wav", SND_FILENAME o   SND_SYNC);

procedura   TForm1.PlaySndFromMemoryClick (Sender: TObject);
  sndPlaySound (p, SND_MEMORY o   SND_SYNC);

procedura   TForm1.PlaySndFromResClick (Sender: TObject);
  PlaySound ("HELLO", hInstance, SND_RESOURCE o   SND_SYNC);

procedura   TForm1.PlaySndbyLoadResClick (Mittente: TObject);
  h: \u003d FindResource (hInstance, "HELLO", "WAVE");
  h: \u003d LoadResource (hInstance, h);
  sndPlaySound (p, SND_MEMORY o   snd_sync);

Crea un nuovo file wav

tema: Crea un nuovo file con estensione .wav.

Questo documento è stato creato su richiesta di molti utenti e descrive le funzionalità aggiuntive del componente Delphi TMediaPlayer. La nuova funzionalità del componente è la possibilità di creare un nuovo file in formato .wav durante la registrazione. La procedura SaveMedia crea un tipo di record che viene passato al comando MCISend. Esiste un'eccezione che causa la chiusura del supporto quando si verificano errori durante l'apertura di un file specifico. L'applicazione è composta da due pulsanti. Button1 chiama le procedure OpenMedia e RecordMedia in ordine. La procedura CloseMedia viene chiamata quando un'applicazione genera un'eccezione. Button2 chiama StopMedia, SaveMedia e CloseMedia.


usiWindows, Messaggi, SysUtils, Classi, Grafica, Controlli, Moduli, Finestre di dialogo, MPlayer, MMSystem, StdCtrls;

tipoTForm1 \u003d classe(TForm)
procedura
procedura   Button2Click (Mittente: TObject);
procedura
procedura   AppException (mittente: TObject; E: eccezione);
procedura   RecordMedia;
procedura   CloseMedia;


varMyError, Flags: Longint;

procedura   TForm1.OpenMedia;
  MyOpenParms: TMCI_Open_Parms;
  Bandiere: \u003d mci_Wait o   mci_Open_Element o   mci_Open_Type;
con   MyOpenParms iniziare
  lpstrDeviceType: \u003d PChar ("WaveAudio");
  MyError: \u003d mciSendCommand (0, mci_Open, Flags, Longint (@MyOpenParms));
se   MyError \u003d 0 poiFDeviceID: \u003d MyOpenParms.wDeviceID;

procedura   TForm1.RecordMedia;
  MyRecordParms: TMCI_Record_Parms;
con   MyRecordParms iniziare
  dwCallback: \u003d Handle; // TForm1.Handle
  MyError: \u003d mciSendCommand (FDeviceID, mci_Record, Flags, Longint (@MyRecordParms));

procedura   TForm1.StopMedia;
var
  se   FDeviceID<> 0 quindi iniziare
  MyError: \u003d mciSendCommand (FDeviceID, mci_Stop, Flags, Longint (@MyGenParms));

procedura   TForm1.SaveMedia;
tipo   // non implementato in Delphi
  PMCI_Save_Parms \u003d ^ TMCI_Save_Parms;
  TMCI_Save_Parms \u003d record
  lpstrFileName: PAnsiChar; // nome del file da salvare
varMySaveParms: TMCI_Save_Parms;
  se   FDeviceID<> 0 quindi iniziare
  // salva il file ...
  Flag: \u003d mci_Save_File o   mci_Wait;
con   MySaveParms iniziare
  lpstrFileName: \u003d PChar ("c: \\ message.wav");
  MyError: \u003d mciSendCommand (FDeviceID, mci_Save, Flags, Longint (@MySaveParms));

procedura   TForm1.CloseMedia;
varMyGenParms: TMCI_Generic_Parms;
  se   FDeviceID<> 0 quindi iniziare
  MyGenParms.dwCallback: \u003d Handle; // TForm1.Handle
  MyError: \u003d mciSendCommand (FDeviceID, mci_Close, Flags, Longint (@MyGenParms));
se   MyError \u003d 0 poiFDeviceID: \u003d 0;

procedura

procedura   TForm1.Button2Click (Mittente: TObject);

procedura
  Application.OnException: \u003d AppException;

procedura   TForm1.AppException (Mittente: TObject; E: eccezione);

Come implementare un controllo del volume?

Nomadic consiglia:

Sì, è tutto semplice. Anche, direi, digitare. :-)

INT GetMasterVolumeControlID () (
  mxl.cbStruct \u003d sizeof (MIXERLINE);
mxl.dwComponentType \u003d MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
  if (:: mixerGetLineInfo ((HMIXEROBJ) ghmx, & mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE)! \u003d MMSYSERR_NOERROR) restituisce 34;
  mxlc.cbStruct \u003d sizeof (MIXERLINECONTROLS);
  mxlc.dwLineID \u003d mxl.dwLineID;
  mxlc.dwControlType \u003d MIXERCONTROL_CONTROLTYPE_VOLUME;
  mxlc.cbmxctrl \u003d sizeof (MIXERCONTROL);
  if (:: mixerGetLineControls ((HMIXEROBJ) ghmx, & mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE)! \u003d MMSYSERR_NOERROR) restituisce 34;

BOOL SetMasterVolume (DWORD dwVolume) (
  MIXERCONTROLDETAILS_UNSIGNED mxcd_u;
  mxcd.cbStruct \u003d sizeof (mxcd);
  mxcd.dwControlID \u003d MasterVolumeControlID;
  mmr \u003d mixerGetControlDetails ((HMIXEROBJ) ghmx, & mxcd, 0L);
  mmr \u003d mixerSetControlDetails ((HMIXEROBJ) ghmx, & mxcd, 0L);
  if (MMSYSERR_NOERROR! \u003d mmr) restituisce FALSE;

Riscrivere a Delphi, penso, a qualsiasi cosa. Devi solo ricordare di aggiungere usa MMSystem; Il volume dei singoli canali è facilmente impostabile tramite auxSetVolume e simili.

Come utilizzare le API DirectSound e DirectSound3D nel mio programma?


Nomadic consiglia:

Esempio 1

Vi presento un esempio funzionante dell'utilizzo di DirectSound su Delphi + con diverse procedure utili. In questo esempio viene creato un SoundBuffer primario e 2 secondari statici; caricano 2 file WAV. Il buffer primario viene creato dalla procedura AppCreateWritePrimaryBuffer e qualsiasi buffer secondario viene creato da AppCreateWritePrimaryBuffer. Poiché il buffer secondario è associato al file WAV, quando si crea un buffer, è necessario determinarne i parametri in base al file audio, queste caratteristiche (Samples, Bits, IsStereo) vengono impostate sotto forma di parametri di procedura. Tempo - tempo del file WAV in secondi (arrotondamento per eccesso) Quando si preme il pulsante, viene eseguita la miscelazione dai buffer secondari a quello primario. AppWriteDataToBuffer consente di scrivere un segnale nel buffer PCM. La procedura CopyWAVToBuffer apre il file WAV, separa l'intestazione, legge il blocco di dati e lo copia nel buffer (allo stesso tempo, la dimensione dei dati viene letta per prima, poiché in alcuni file WAV è presente un'appendice di testo e, se non viene rimossa, è possibile eseguire il cracking negli altoparlanti).

PS. Se ci sono domande, proverò a rispondere.



usi

tipoTForm1 \u003d classe(TForm)
procedura   FormCreate (Mittente: TObject);
procedura
procedura   Button1Click (Mittente: TObject);
  SecondarySoundBuffer: schieramento di   IDirectSoundBuffer;
procedura
procedura   AppCreateWriteSecondaryBuffer ( var
procedura var
procedura   CopyWAVToBuffer (Nome: PChar;
var


procedura   TForm1.FormCreate (Mittente: TObject);
  seDirectSoundCreate ( zero, DirectSound, zero) <>   DS_OK poi rilancia
AppCreateWriteSecondaryBuffer (SecondarySoundBuffer, 22050, 8, False, 10);
  AppCreateWriteSecondaryBuffer (SecondarySoundBuffer, 22050, 16, True, 1);

procedura
  seAssegnato (DirectSoundBuffer) poi   DirectSoundBuffer.Release;
per   i: \u003d 0 a 1 fare se   Assegnato (SecondarySoundBuffer [i]) poi   SecondarySoundBuffer [i]. Rilascio;
se   Assegnato (DirectSound) poi   DirectSound.Release;

procedura
  H: \u003d;
se   H \u003d DSERR_BUFFERLOST quindi iniziare
se   Buffer.Lock (OffSet, SoundBytes, AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2, 0)<>   DS_OK poi rilancia
  altro se   H<>   DS_OK poi rilancia   Exception.Create ("Impossibile bloccare il buffer audio");
se   AudioPtr2<> zero quindi iniziare
se <>   DS_OK poi rilancia

procedura
con   BufferDesc iniziare
se <>   DS_OK poi rilancia
se zero) <>   DS_OK poi rilancia
se <>   DS_OK poi rilancia
se   DirectSound.SetCooperativeLevel (Handle, DSSCL_NORMAL)<>   DS_OK poi rilancia   Exception.Create ("Impossibile impostare il livello cooperativo");

procedura   TForm1.AppCreateWriteSecondaryBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
con   BufferDesc iniziare
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
se   isStereo poi   PCM.nChannels: \u003d 2
altro   PCM.nChannels: \u003d 1;
  PCM.nBlockAlign: \u003d (Bit div   8) * PCM.nChannels;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  se zero) <>   DS_OK poi rilancia   Exception.Create ("Creazione buffer audio non riuscita");

procedura   TForm1.CopyWAVToBuffer;
fino a quando   Chunk \u003d "data";

procedura   TForm1.Button1Click (Mittente: TObject);
  CopyWAVToBuffer ("1.wav", SecondarySoundBuffer);
  CopyWAVToBuffer ("flip.wav", SecondarySoundBuffer);
  se <>   DS_OK poi
  se   SecondarySoundBuffer.Play (0, 0, 0)<>   DS_OK poi   ShowMessage ("Impossibile" riprodurre l'audio ");
Esempio 2

Vi presento alla vostra attenzione un altro esempio di come lavorare con DirectSound su Delphi. Questo esempio mostra come lavorare con un buffer 3D. Quindi, ho lasciato invariate le procedure AppCreateWritePrimaryBuffer, AppWriteDataToBuffer, CopyWAVToBuffer (vedi lettere precedenti). La procedura AppCreateWriteSecondary3DBuffer è un analogo completo della procedura AppCreateWriteSecondaryBuffer, ad eccezione del flag DSBCAPS_CTRL3D, che indica che un altro buffer sarà associato al buffer secondario statico - SecondarySound3DBuffer. Per inizializzarlo, nonché per impostare alcuni valori iniziali (posizione nello spazio, velocità, ecc.), Viene chiamata la procedura AppSetSecondary3DBuffer, i cui parametri sono SecondarySoundBuffer e il SecondarySound3DBuffer associato. In questa procedura, SecondarySound3DBuffer viene inizializzato utilizzando il metodo QueryInterface con il flag appropriato. Inoltre, qui viene impostata anche la posizione della sorgente sonora nello spazio: SetPosition (Pos, 1 (X), 1 (Y), 0 (Z)).

Pertanto, nel momento iniziale del tempo, la sorgente si trova ad un'altezza di 1 m (l'asse Y è diretto verticalmente verso l'alto e l'asse Z è "rivolto verso lo schermo"). Visto dall'alto:

Il punto O (in realtà tu) ha coordinate (0,0), sorgente sonora A (-25,1). Naturalmente, il concetto di "metro" è molto arbitrario.

Quando viene premuto un pulsante, il suono "xhe4.wav" viene caricato nel buffer SecondarySoundBuffer. Questo è il suono di un rotore di elicottero funzionante, la sua lunghezza (suono) è esattamente 3,99 s (e la dimensione del buffer è esattamente 4 s). Successivamente, si verifica il missaggio dal buffer secondario a quello primario con il flag DSBPLAY_LOOPING, che consente di emettere suoni ripetutamente ripetuti; un tempo di 0,01 con l'orecchio non viene praticamente catturato e si ottiene un suono continuo di un elicottero volante. Successivamente, il timer si avvia (il campo INTERVALLO nella finestra di ispezione oggetti è impostato su 1). Certo, non devi fare proprio questo, è solo un esempio. Nella procedura Timer1Timer, la coordinata X cambia semplicemente con incrementi di 0,1.

Di conseguenza, otteniamo un elicottero volante da sinistra a destra. Allo stesso tempo, puoi verificare se i tuoi altoparlanti sono posizionati correttamente.

PS. Se hai domande, cercherò di rispondere.



usiWindows, Messaggi, SysUtils, Classi, Grafica, Controlli, Moduli, Finestre, DSound, MMSystem, StdCtrls, ExtCtrls;

tipoTForm1 \u003d classe(TForm)
procedura   FormCreate (Mittente: TObject);
procedura   FormDestroy (Mittente: TObject);
procedura   Button1Click (Mittente: TObject);
procedura   Timer1Timer (Mittente: TObject);
  DirectSoundBuffer: IDirectSoundBuffer;
  SecondarySoundBuffer: IDirectSoundBuffer;
  SecondarySound3DBuffer: IDirectSound3DBuffer;
  procedura   AppCreateWritePrimaryBuffer;
procedura   AppCreateWriteSecondary3DBuffer ( var   Buffer: IDirectSoundBuffer; SamplesPerSec: intero; Bit: Word; isStereo: Boolean; Tempo: intero);
procedura   AppSetSecondary3DBuffer ( var   Buffer: IDirectSoundBuffer; var   _3DBuffer: IDirectSound3DBuffer);
procedura   AppWriteDataToBuffer (Buffer: IDirectSoundBuffer; OffSet: DWord; var   SoundData; SoundBytes: DWord);
procedura   CopyWAVToBuffer (Nome: PChar; var   Buffer: IDirectSoundBuffer);


procedura   TForm1.FormCreate (Mittente: TObject);
  seDirectSoundCreate ( zero, DirectSound, zero) <>   DS_OK poi rilancia   Exception.Create ("Impossibile creare l'oggetto IDirectSound");
  AppCreateWriteSecondary3DBuffer (SecondarySoundBuffer, 22050, 8, False, 4);
  AppSetSecondary3DBuffer (SecondarySoundBuffer, SecondarySound3DBuffer); Timer1.Enabled: \u003d False;

procedura   TForm1.FormDestroy (Mittente: TObject);
  seAssegnato (DirectSoundBuffer) poi   DirectSoundBuffer.Release;
se   Assegnato (SecondarySound3DBuffer) poi   SecondarySound3DBuffer.Release;
se   Assegnato (SecondarySoundBuffer) poi   SecondarySoundBuffer.Release;
se   Assegnato (DirectSound) poi   DirectSound.Release;

procedura   TForm1.AppCreateWritePrimaryBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
con   BufferDesc iniziare
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  dwFlags: \u003d DSBCAPS_PRIMARYBUFFER;
se   DirectSound.SetCooperativeLevel (handle, DSSCL_WRITEPRIMARY)<>   DS_OK poi rilancia
se   DirectSound.CreateSoundBuffer (BufferDesc, DirectSoundBuffer, zero) <>   DS_OK poi rilancia   Exception.Create ("Creazione buffer audio non riuscita");
se DirectSoundBuffer.SetFormat (PCM)<>   DS_OK poi rilancia   Exception.Create ("Impossibile impostare il formato");
se   DirectSound.SetCooperativeLevel (Handle, DSSCL_NORMAL)<>   DS_OK poi rilancia   Exception.Create ("Impossibile impostare il livello cooperativo");

procedura   TForm1.AppCreateWriteSecondary3DBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
con   BufferDesc iniziare
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
se   isStereo quindi PCM.nChannels: \u003d 2
altro   PCM.nChannels: \u003d 1;
  PCM.nSamplesPerSec: \u003d SamplesPerSec;
  PCM.nBlockAlign: \u003d (Bit div   8) * PCM.nChannels;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  dwFlags: \u003d DSBCAPS_STATIC o   DSBCAPS_CTRL3D;
  dwBufferBytes: \u003d Time * PCM.nAvgBytesPerSec;
se   DirectSound.CreateSoundBuffer (BufferDesc, Buffer, zero) <>   DS_OK poi rilancia   Exception.Create ("Creazione buffer audio non riuscita");

procedura   TForm1.AppWriteDataToBuffer;
  AudioPtr1, AudioPtr2: puntatore;
  AudioBytes1, AudioBytes2: DWord;
se   H \u003d DSERR_BUFFERLOST quindi iniziare
se   Buffer.Lock (OffSet, SoundBytes, AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2, 0)<>   DS_OK poi rilancia   Exception.Create ("Impossibile bloccare il buffer audio");
  altro se   H<>   DS_OK poi rilancia   Exception.Create ("Impossibile bloccare il buffer audio");
  Sposta (Temp ^, AudioPtr1 ^, AudioBytes1);
se   AudioPtr2<> zero quindi iniziare
  Inc (Integer (Temp), AudioBytes1);
  Sposta (Temp ^, AudioPtr2 ^, AudioBytes2);
se   Buffer.UnLock (AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2)<>   DS_OK poi rilancia   Exception.Create ("Impossibile sbloccare il buffer audio");

procedura   TForm1.CopyWAVToBuffer;
  FName: \u003d TFileStream.Create (Name, fmOpenRead);
  FName.Seek (Pos, soFromBeginning);
fino a quando   Chunk \u003d "data";
  FName.Seek (Pos + 3, soFromBeginning);
  FName.Read (DataSize, SizeOf (DWord));
  AppWriteDataToBuffer (Buffer, 0, Data ^, DataSize);

var   Pos: Singolo \u003d -25;

procedura   TForm1.AppSetSecondary3DBuffer;
  seBuffer.QueryInterface (IID_IDirectSound3DBuffer, _3DBuffer)<>   DS_OK poi rilancia   Exception.Create ("Impossibile creare l'oggetto IDirectSound3D");
se   _3DBuffer.SetPosition (Pos, 1, 1, 0)<>   DS_OK poi rilancia   Exception.Create ("Impossibile impostare la posizione IDirectSound3D");

procedura   TForm1.Button1Click (Mittente: TObject);
  CopyWAVToBuffer ("xhe4.wav", SecondarySoundBuffer);
  se   SecondarySoundBuffer.Play (0, 0, DSBPLAY_LOOPING)<>   DS_OK poi   ShowMessage ("Impossibile" riprodurre l'audio ");

procedura   TForm1.Timer1Timer (Mittente: TObject);
  SecondarySound3DBuffer.SetPosition (Pos, 1,1,0);

In questo articolo proverò a prendere in considerazione tre procedure per riprodurre l'audio. L'uso di queste procedure al posto del componente TMediaPlayer consente di risparmiare significativamente risorse di sistema. Utilizzando queste procedure, è possibile risolvere una vasta gamma di attività. Quindi, inizieremo la considerazione di queste procedure con la più semplice.

Procedura del segnale acustico

Questa procedura non ha parametri. La sua pubblicità sembra piuttosto semplice:

L'essenza di questa procedura è riprodurre il segnale audio standard installato in Windows, se è presente una scheda audio e se il suono standard è configurato, in caso contrario, l'audio verrà trasmesso attraverso l'altoparlante del computer sotto forma di un breve clic. Può essere utilizzato, ad esempio, quando l'utente immette dati errati o quando chiude il modulo:

procedura TForm1.FormClose (mittente: TObject; var Azione: TCloseAction);
  iniziare
  Beep;
  fine;

Abbiamo capito la prima procedura. Ora vediamo il secondo ...

Funzione MessageBeep

Questa funzione è più seria, è definita come:

funzione MessageBeep (uType: word): boolean;

Il parametro uType consente di specificare il suono riprodotto, come identificatore della chiave di registro in cui vengono registrati i suoni che accompagnano questi o altri eventi di Windows. Il parametro uType può assumere i seguenti valori:

  • MB_ICONASTERISK - riproduce il suono "Asterisk" (SystemAsterisk)
  • MB_ICONEXCLAMATION - riproduce il suono "Exclamation" (SystemExclamation)
  • MB_ICONHAND - riproduce il suono "Errore critico" (SystemHand)
  • MB_ICONQUESTION - riproduce il suono "Domanda" (SystemQuestion)
  • MB_OK - riproduce il suono "Standard Sound" (SystemDefault)

Va notato che questa funzione riproduce il suono in modo asincrono, ad es. durante la riproduzione del suono, l'applicazione continua a funzionare. Dopo una richiesta audio, MessageBeep trasferisce il controllo alla funzione che lo ha chiamato.

Se non è possibile riprodurre il suono specificato, la funzione proverà a riprodurre il suono di sistema standard impostato di default, se ciò non è possibile, il segnale standard verrà riprodotto attraverso l'altoparlante.

Infine, rimane la funzione di riproduzione audio più interessante e utile, ne parliamo ora.

Funzione PlaySound

Questa funzione può riprodurre qualsiasi suono wave, non solo suoni di eventi Windows. Una funzione API di Windows i cui parametri sono descritti nel modulo mmsystem. Pertanto, per utilizzare questa funzione nei programmi, è necessario includere il modulo mmsystem nella sezione degli usi. La funzione PlaySound è definita come segue:

funzione PlaySound (pszSound: PChar; hmod: HINST; fdwSound: Cardinal): booleano;

Il parametro pszSound è una stringa con terminazione null (l'ultimo carattere della stringa ha un codice null), determina il suono riprodotto. Il parametro hmod viene utilizzato quando il suono viene prelevato dalla risorsa, poiché non lo faremo, è possibile impostare questo parametro su 0 o zero.

L'ultimo parametro, fdwSound, è il set che determina come verrà riprodotto il suono (modalità di riproduzione). Darò i valori più importanti di questo set per la riproduzione di flag wave arbitrari.

  • SND_ASYNC - Il suono viene riprodotto in modo asincrono e la funzione ritorna immediatamente dopo l'inizio della riproduzione. Per interrompere la riproduzione, è necessario chiamare la funzione PlaySound con il parametro pszSound uguale a 0.
  • SND_LOOP - la ripetizione del suono viene ripetuta costantemente; allo stesso tempo, è necessario impostare il flag SND_ASYNC.
  • SND_NOSTOP - Se il suono specificato non può essere riprodotto a causa di risorse occupate, la funzione restituirà immediatamente falso (e il suono non verrà riprodotto). Se questo flag non viene specificato, la funzione proverà a interrompere la riproduzione di un altro suono per liberare risorse.
  • SND_PURGE - Interrompe la riproduzione di qualsiasi suono causato in questa attività.
  • SND_SYNC - Riproduzione sincrona del suono di un evento. La funzione PlaySound ritorna solo al termine della riproduzione.

Importante: i flag possono essere combinati con o.

Il suono specificato dal parametro pszSound dovrebbe essere adatto al driver installato per il dispositivo di riproduzione dei file wave e dovrebbe anche essere inserito nella memoria disponibile.

È possibile interrompere il suono eseguendo la dichiarazione

PlaySound (0, 0, SND_PURGE);

o impostando un nuovo suono.

Ad esempio, per riprodurre ripetutamente e in modo asincrono alcuni suoni selezionati usando OpenDialog, è possibile scrivere il seguente codice:

procedura TForm1.Button1Click (Mittente: TObject);
  var PCh: PChar;
  iniziare
  se OpenDialog1.Execute allora
  iniziare
  StrPCopy (PCh, OpenDialog1.FileName);
  PlaySound (Pch, 0, SND_ASYNC o SND_LOOP);
  fine;
  fine;

Spero sia tutto chiaro! La prossima volta ci sarà qualcosa di più complicato e più interessante!

Dopo aver configurato i componenti, è necessario impostare le dimensioni del modulo in base alle dimensioni del componente Image1 in modo che i componenti MediaPlayer1, SpeedButton5 e SpeedButton6 siano al di fuori dei limiti del modulo. Di conseguenza, la forma dovrebbe apparire come quella mostrata in fig. 10.17.

Fig. 10.17. La forma finale della forma del "lettore MP3"

Controllo del volume

È possibile impostare il volume di riproduzione desiderato per un file MP3 utilizzando la funzione API waveOutSetVolume. Affinché questa funzione diventi disponibile, è necessario inserire un collegamento al modulo MMSystem nel testo del programma (specificare il nome del modulo nella direttiva usi).

L'istruzione di chiamata della funzione in generale è simile alla seguente:

r \u003d waveOutSetVolume (identificatore dispositivo, volume)

parametro ID dispositivoimposta il dispositivo di riproduzione (più precisamente, il canale audio) il cui volume deve essere impostato. Quando si regola il volume di riproduzione di un file MP3, il valore di questo parametro deve essere uguale

WAVE_MAPPER (la costante WAVE_MAPPER è definita nel modulo MMSystem).

Il parametro Volume (doppia parola) imposta il volume di riproduzione: la parola inferiore determina il volume del canale sinistro, la parola più alta determina il volume del canale destro. Il volume audio massimo del canale corrisponde al valore esadecimale di FFFF, il minimo - 0000. Pertanto, per impostare il volume massimo di riproduzione in entrambi i canali, il valore del parametro Volume dovrebbe essere $ FFFFFFFF (in Delphi, il prefisso $ viene utilizzato quando si scrivono costanti esadecimali). Un livello di volume del 50% corrisponde alla costante $ 7FFF7FFF.

Si noti che la funzione waveOutSetVolume regola il volume di riproduzione canale sonoropiuttosto che il livello sonoro complessivo.

Modificare il volume utilizzando il componente TrackBar1. Si noti che quando il componente è posizionato verticalmente, la posizione superiore del cursore corrisponde al valore zero della proprietà Posizione e quella inferiore corrisponde al valore specificato dalla proprietà Max. Pertanto, il livello del volume corrispondente alla posizione del motore viene calcolato come differenza tra la corrente e il max

il valore più basso possibile della proprietà Position (questo valore imposta la proprietà Max), moltiplicato per $ FFFF.

Una modifica diretta del volume viene eseguita dalla procedura per l'elaborazione dell'evento Change (Listato 10.14), il controllo del volume (componente TrackBar1), che si verifica a seguito dello spostamento del cursore con il mouse o i tasti cursore. Innanzitutto, calcola il valore del volume per il canale sinistro, quindi aggiunge lo stesso valore spostato di 16 bit al valore ricevuto (di conseguenza, gli stessi valori più alti si trovano nelle parole alta e bassa) e il valore così ottenuto viene passato come parametro alla funzione

waveOutSetVolume.

Listato 10.14. Gestire l'evento Change del componente TrackBar1

iniziare

volume: \u003d $ FFFF * (TrackBar1.Max - TrackBar1.Position); volume: \u003d volume + (volume shl 16); waveOutSetVolume (WAVE_MAPPER, volume);

fine;

Spostamento della finestra

Il valore della proprietà BorderStyle del modulo è bsNone, pertanto il titolo non viene visualizzato nella finestra del programma (vedere la Figura 10.5) e pertanto, a prima vista, l'utente sembra privato della possibilità di spostare la finestra sullo schermo nel solito modo. Tuttavia, la finestra del programma può ancora essere spostata. Per fare ciò, imposta il puntatore del mouse su un punto della finestra libero (non occupato dai componenti), premi il pulsante sinistro del mouse e tienilo premuto, trascina la finestra sul punto desiderato sullo schermo (questo metodo è molto comune). Il metodo descritto per spostare la finestra è fornito dalla procedura per l'elaborazione dell'evento MouseDown nel campo del componente Image1 (elenco 10.15). La procedura "inganna" il sistema operativo, lo informa (inviando un messaggio corrispondente) che l'utente ha fatto clic sul pulsante del mouse nel titolo della finestra, ovvero ha eseguito un'azione che richiede lo spostamento della finestra.

Listato 10.15. Gestire l'evento MouseDown nel campo del componente Image1

// In questo caso, l'utente può spostare la finestra come di consueto

SendMessage (Form1.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0) fine;

Testo del programma

Il testo completo del programma del lettore MP3 è mostrato nel Listato 10.16.

Listato 10.16. Lettore mp3

(Lettore MP3 con controllo del volume.

(c) Kultin N.B., 2003-2010)

unità MainForm;

Windows, Messaggi, SysUtils, Varianti, Classi, Grafica, Controlli, Moduli, Finestre, StdCtrls, Pulsanti, ExtCtrls, MPlayer, ComCtrls, MMSYSTEM, FileCtrl, Menu; // questi collegamenti vengono inseriti manualmente

TForm1 \u003d class (TForm) MediaPlayer1: TMediaPlayer;

SpeedButton1: TSpeedButton; // composizione precedenteSpeedButton2: TSpeedButton; // Play / Stop SpeedButton3: TSpeedButton; // prossima composizioneSpeedButton4: TSpeedButton; // seleziona la cartella

// i pulsanti invisibili SpeedButton5 e SpeedButton6 forniscono

// memorizzazione di immagini Play e Stop

SpeedButton5: TSpeedButton;

SpeedButton6: TSpeedButton;

ListBox1: TListBox; // elenco di brani

Parte II Workshop di programmazione

Etichetta 1: TLabel; // composizione giocabile

Etichetta2: TLabel; // tempo di gioco

Immagine 1: TImage; // sfondo

PopupMenu1: TPopupMenu; // menu contestuale

N1: TMenuItem; // "Chiudi"

N2: TMenuItem; // "Riduci a icona"

// controllo del volume

Panel1: TPanel; // Pannello TrackBar1: TTrackBar;

procedura Image1MouseDown (mittente: TObject; pulsante: TMouseButton; Maiusc: TShiftState; X, Y: intero);

procedura N2Click (Mittente: TObject); procedura N1Clicca (Mittente: TObject);

procedura FormCreate (mittente: TObject); procedura ListBox1Click (Mittente: TObject); procedura SpeedButton2Click (Mittente: TObject); procedura SpeedButton1Click (Mittente: TObject); procedura SpeedButton3Click (Mittente: TObject); procedura TrackBar1Change (Sender: TObject); procedura Timer1Timer (mittente: TObject); procedura SpeedButton4Click (Mittente: TObject);

// queste dichiarazioni sono inserite qui manualmente procedura Play; // gioca

procedura PlayList (Path: string); // forma un elenco di file MP3

(Dichiarazioni private) pubblico

(Dichiarazioni pubbliche) fine;

($ R * .dfm) var

SoundPath: stringa; // directory in cui si trovano i file MP3

min, sec: intero; // tempo di gioco

volume: LongWord; // volume di riproduzione:

// la parola più alta è il canale giusto,

// la parola bassa è rimasta

procedura TForm1.FormCreate (mittente: TObject); iniziare

PlayList (""); // crea un elenco di file MP3

ListBox1.ItemIndex: \u003d 0; Label1.Caption: \u003d ListBox1.Items;

// imposta il livello del volume

TrackBar1.Position: \u003d 7;

// la parola più alta del volume variabile è il canale giusto,

// in basso a sinistra

volume: \u003d (TrackBar1.Position - TrackBar1.Max + 1) * $ FFFF; volume: \u003d volume + (volume shl 16); waveOutSetVolume (WAVE_MAPPER, volume); // livello del volume

fine;

// forma un elenco di procedure per file MP3 TForm1.PlayList (Path: string); var

SearchRec: TSearchRec; // La struttura di SearchRec contiene informazioni // sul file che soddisfa la condizione di ricerca

// crea un elenco di file MP3

se FindFirst (Path + "* .mp3", faAnyFile, SearchRec) \u003d 0, quindi inizia

// La directory ha un file con l'estensione mp3.

// Aggiungi il nome di questo file all'elenco.

ListBox1.Items.Add (SearchRec.Name);

Parte II Workshop di programmazione

// Altri MP3?

while (FindNext (SearchRec) \u003d 0) fa ListBox1.Items.Add (SearchRec.Name);

fine; ListBox1.ItemIndex: \u003d 0;

fine;

// fai clic sul titolo dell'opera

procedura TForm1.ListBox1Click (Mittente: TObject); iniziare

se SpeedButton2.Tag \u003d 0 allora

// visualizza il nome del file selezionato nel campo etichetta Etichetta1

Label1.Caption: \u003d ListBox1.Items else

Form1.Play; // attiva il processo di riproduzione

fine;

// fai clic sul pulsante "Riproduci"

procedura TForm1.SpeedButton2Click (Mittente: TObject); iniziare

// la proprietà Tag memorizza le informazioni sullo stato.

// giocatore: 0 - stop; 1 - gioca

se SpeedButton2.Tag \u003d 0, quindi iniziare // avvia la riproduzione

Form1.Play; fine

// se si preme il pulsante di riproduzione,

// quindi premere di nuovo per interrompere la riproduzioneiniziare

SpeedButton2.Tag: \u003d 0; MediaPlayer1.Stop;

SpeedButton2.Glyph: \u003d SpeedButton5.Glyph; Timer1.Enabled: \u003d False; SPeedButton2.Hint: \u003d "Riproduci"; Label2.Caption: \u003d "0:00";

fine;

fine;

// pulsante "Traccia precedente"

procedura TForm1.SpeedButton1Click (Mittente: TObject);

se ListBox1.ItemIndex\u003e 0 allora

ListBox1.ItemIndex: \u003d ListBox1.ItemIndex - 1; se SpeedButton2.Tag \u003d 1 allora

fine;

// Pulsante "Traccia successiva"

procedura TForm1.SpeedButton3Click (Mittente: TObject); iniziare

se ListBox1.ItemIndex< ListBox1.Count then ListBox1.ItemIndex:= ListBox1.ItemIndex + 1;

se SpeedButton2.Tag \u003d 1 quindi Riproduci;

fine;

// l'utente ha modificato la posizione della procedura di controllo del volume TForm1.TrackBar1Change (Mittente: TObject);iniziare

volume: \u003d $ FFFF * (TrackBar1.Max - TrackBar1.Position); volume: \u003d volume + (volume shl 16); waveOutSetVolume (WAVE_MAPPER, volume);

fine;

// suona il brano, il cui nome è evidenziato nell'elenco Procedura ListBox1 TForm1.Play;

Timer1.Enabled: \u003d False; Label1.Caption: \u003d ListBox1.Items; MediaPlayer1.FileName: \u003d SoundPath + ListBox1.Items;

Mediaplayer1.Open; tranne

su EMCIDeviceError ha inizio

ShowMessage ("Errore durante l'accesso al file" + ListBox1.Items);

uscire; fine;

fine;

Parte II Workshop di programmazione

MediaPlayer1.Play; min: \u003d 0;

sec: \u003d 0; Timer1.Enabled: \u003d True;

SpeedButton2.Hint: \u003d "Stop"; SpeedButton2.Tag: \u003d 1;

fine;

// segnale del timer

procedura TForm1.Timer1Timer (mittente: TObject); iniziare

// cambia il contatore del tempose sec< 59

quindi inc (sec) altrimenti inizia

sec: \u003d 0; inc (min);

fine;

// visualizzare il tempo di riproduzione

Label2.Caption: \u003d IntToStr (min) + ":"; se sec< 10

quindi Label2.Caption: \u003d Label2.Caption + "0" + IntToStr (sec) else Label2.Caption: \u003d Label2.Caption + IntToStr (sec);

// se la riproduzione del brano corrente non è completata

se MediaPlayer1.Position< MediaPlayer1.Length then exit;

// la riproduzione del brano corrente è terminata

Timer1.Enabled: \u003d False; // ferma il timerMediaPlayer1.Stop; // ferma il giocatore

se ListBox1.ItemIndex< ListBox1.Count // list non è esauritoquindi iniziare

ListBox1.ItemIndex: \u003d ListBox1.ItemIndex + 1; Play; // attiva la riproduzioneFile di fine MP3

fine;

// Fare clic sul pulsante "Cartella".

// Selezionare la cartella in cui si trovano i file MP3 procedura TForm1.SpeedButton4Click (Mittente: TObject);var

Root: string; // directory root pwRoot: PWideChar;

Dir: string; iniziare

Root: \u003d ""; // directory root - Cartella desktop

GetMem (pwRoot, (Lunghezza (Root) +1) * 2);

pwRoot: \u003d StringToWideChar (Root, pwRoot, MAX_PATH * 2);

se non SelectDirectory ("Seleziona la cartella in cui si trovano i file MP3", pwRoot, Dir)

quindi Dir: \u003d ""

altrimenti Dir: \u003d Dir + "\\";

// è selezionata la directory in cui si trovano i file MP3

SoundPath: \u003d Dir; PlayList (SoundPath);

fine;

// clic del mouse nel campo del componente Image1

procedura TForm1.Image1MouseDown (Mittente: TObject; Pulsante: TMouseButton; Maiusc: TShiftState; X, Y: Integer);

// Non c'è il titolo della finestra. Trucchi su Windows. Lascia che OC pensi

// che il pulsante viene premuto e mantenuto nel titolo della finestra.

// In questo caso, l'utente può spostare la finestra nel solito modo.

SendMessage (Form1.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0)

fine;

// seleziona il comando "Chiudi" nella procedura del menu contestuale TForm1.N1Fare clic su (Mittente: TObject);iniziare

Form1.Close; fine;

finire.

LA CAMPANA

C'è chi legge queste notizie prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
cognome
Come vuoi leggere The Bell
No spam