DZWONEK

Są tacy, którzy czytają te wiadomości przed tobą.
Subskrybuj, aby otrzymywać świeże artykuły.
Email
Imię
Nazwisko
Jak chcesz przeczytać Dzwon
Bez spamu

Motyw: Jak sprawić, by aplikacja Delphi 2 `śpiewała`.

Ta wskazówka pokazuje cztery różne sposoby na śpiewanie aplikacji Delphi 2.0, tj. Pobierz i odtwórz plik dźwiękowy:

1. Aby odtworzyć plik dźwiękowy, użyj bezpośrednio funkcji sndPlaySound ().

2. Przeczytaj plik dźwiękowy do pamięci, a następnie użyj sndPlaySound (), aby go odtworzyć.

3. Użyj sndPlaySound, aby bezpośrednio odtworzyć pliki dźwiękowe znajdujące się w plikach zasobów powiązanych z aplikacją.

4. Przeczytaj plik dźwiękowy znajdujący się w pliku zasobów połączonym z aplikacją w pamięci, a następnie użyj sndPlaySound (), aby go odtworzyć.

Aby zbudować projekt, potrzebujesz:

1. Utwórz plik dźwiękowy o nazwie „hello.wav” w katalogu projektu.

2. Utwórz plik tekstowy o nazwie „snddata.rc” w katalogu projektu.

3. Dodaj następujący wiersz do pliku „snddata.rc”:

.

4. W sesji dos przejdź do katalogu aplikacji i skompiluj plik .rc za pomocą kompilatora zasobów Borland (brcc32.exe): wprowadź ścieżkę do brcc32.exe i przekaż „snddata.rc” jako parametr.

Spowoduje to utworzenie pliku snddata.res, który Delphi prowadzi do pliku .exe aplikacji.


wykorzystujeWindows, Wiadomości, SysUtils, Klasy, Grafika, Sterowanie, Formularze, Dialogi, StdCtrls;

typTForm1 \u003d klasa(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 lub   SND_SYNC);

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

procedura   TForm1.PlaySndFromResClick (Sender: TObject);
  PlaySound („HELLO”, hInstance, SND_RESOURCE lub   SND_SYNC);

procedura   TForm1.PlaySndbyLoadResClick (Sender: TObject);
  h: \u003d FindResource (hInstance, „HELLO”, „WAVE”);
  h: \u003d LoadResource (hInstance, h);
  sndPlaySound (p, SND_MEMORY lub   snd_sync);

Utwórz nowy plik wav

Motyw: Utwórz nowy plik z rozszerzeniem .wav.

Ten dokument został stworzony na prośbę wielu użytkowników i opisuje dodatkową funkcjonalność komponentu Delphi TMediaPlayer. Nową funkcjonalnością komponentu jest możliwość utworzenia nowego pliku w formacie .wav podczas nagrywania. Procedura SaveMedia tworzy typ rekordu przekazywanego do polecenia MCISend. Istnieje wyjątek, który powoduje zamknięcie nośnika w przypadku wystąpienia błędu podczas otwierania określonego pliku. Aplikacja składa się z dwóch przycisków. Button1 wywołuje kolejno procedury OpenMedia i RecordMedia. Procedura CloseMedia jest wywoływana, gdy aplikacja zgłasza wyjątek. Button2 wywołuje StopMedia, SaveMedia i CloseMedia.


wykorzystujeWindows, Wiadomości, SysUtils, Klasy, Grafika, Sterowanie, Formularze, Dialogi, MPlayer, MMSystem, StdCtrls;

typTForm1 \u003d klasa(TForm)
procedura
procedura   Button2Click (Sender: TObject);
procedura
procedura   AppException (Sender: TObject; E: Wyjątek);
procedura   RecordMedia;
procedura   CloseMedia;


varMyError, Flags: Longint;

procedura   TForm1.OpenMedia;
  MyOpenParms: TMCI_Open_Parms;
  Flagi: \u003d mci_Wait lub   mci_Open_Element lub   mci_Open_Type;
z   MyOpenParms zaczynać
  lpstrDeviceType: \u003d PChar („WaveAudio”);
  MyError: \u003d mciSendCommand (0, mci_Open, Flags, Longint (@MyOpenParms));
jeśli   MyError \u003d 0 wtedyFDeviceID: \u003d MyOpenParms.wDeviceID;

procedura   TForm1.RecordMedia;
  MyRecordParms: TMCI_Record_Parms;
z   Myrecordparms zaczynać
  dwCallback: \u003d Uchwyt; // TForm1.Handle
  MyError: \u003d mciSendCommand (FDeviceID, mci_Record, Flags, Longint (@MyRecordParms));

procedura   TForm1.StopMedia;
var
  jeśli   Fdeviceid<> 0 potem zacznij
  MyError: \u003d mciSendCommand (FDeviceID, mci_Stop, Flags, Longint (@MyGenParms));

procedura   TForm1.SaveMedia;
typ   // nie zaimplementowane w Delphi
  PMCI_Save_Parms \u003d ^ TMCI_Save_Parms;
  TMCI_Save_Parms \u003d nagrywać
  lpstrFileName: PAnsiChar; // nazwa pliku do zapisania
varMySaveParms: TMCI_Save_Parms;
  jeśli   Fdeviceid<> 0 potem zacznij
  // zapisz plik ...
  Flagi: \u003d mci_Save_File lub   mci_Wait;
z   MySaveParms zaczynać
  lpstrFileName: \u003d PChar („c: \\ message.wav”);
  MyError: \u003d mciSendCommand (FDeviceID, mci_Save, Flags, Longint (@MySaveParms));

procedura   TForm1.CloseMedia;
varMyGenParms: TMCI_Generic_Parms;
  jeśli   Fdeviceid<> 0 potem zacznij
  MyGenParms.dwCallback: \u003d Uchwyt; // TForm1.Handle
  MyError: \u003d mciSendCommand (FDeviceID, mci_Close, Flags, Longint (@MyGenParms));
jeśli   MyError \u003d 0 wtedyFDeviceID: \u003d 0;

procedura

procedura   TForm1.Button2Click (Sender: TObject);

procedura
  Application.OnException: \u003d AppException;

procedura   TForm1.AppException (Sender: TObject; E: Wyjątek);

Jak wdrożyć regulację głośności?

Nomadic radzi:

Tak, wszystko jest proste. Nawet, powiedziałbym, pisz. :-)

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) return 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) return 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);
  jeśli (MMSYSERR_NOERROR! \u003d mmr) zwraca FALSE;

Przepisanie do Delphi, jak sądzę, na cokolwiek. Trzeba tylko pamiętać, aby dodać używa MMSystem; Głośność poszczególnych kanałów można bardzo łatwo ustawić za pomocą auxSetVolume i tym podobnych.

Jak korzystać z interfejsów API DirectSound i DirectSound3D w moim programie?


Nomadic radzi:

Przykład 1

Przedstawiam wam praktyczny przykład użycia DirectSound na Delphi + z kilkoma przydatnymi procedurami. Ten przykład tworzy jeden podstawowy SoundBuffer i 2 statyczne, dodatkowe; ładują 2 pliki WAV. Bufor podstawowy jest tworzony przez procedurę AppCreateWritePrimaryBuffer, a każdy bufor dodatkowy jest tworzony przez AppCreateWritePrimaryBuffer. Ponieważ bufor dodatkowy jest powiązany z plikiem WAV, podczas tworzenia bufora należy określić jego parametry zgodnie z plikiem dźwiękowym, dlatego te cechy (Próbki, Bity, IsStereo) są ustawiane w postaci parametrów procedury. Czas - czas pliku WAV w sekundach (zaokrąglanie w górę). Po naciśnięciu przycisku następuje mieszanie buforów pomocniczych z buforami pierwotnymi AppWriteDataToBuffer umożliwia zapisanie sygnału do bufora PCM. Procedura CopyWAVToBuffer otwiera plik WAV, oddziela nagłówek, odczytuje fragment danych i kopiuje go do bufora (w tym samym czasie najpierw odczytywany jest rozmiar danych, ponieważ w niektórych plikach WAV jest dołączany tekst, a jeśli nie zostanie usunięty, możliwe jest pękanie w głośnikach).

PS. Jeśli będą jakieś pytania, postaram się na nie odpowiedzieć.



wykorzystuje

typTForm1 \u003d klasa(TForm)
procedura   FormCreate (Sender: TObject);
procedura
procedura   Button1Click (Sender: TObject);
  SecondarySoundBuffer: tablica z   IDirectSoundBuffer;
procedura
procedura   AppCreateWriteSecondaryBuffer ( var
procedura var
procedura   CopyWAVToBuffer (nazwa: PChar;
var


procedura   TForm1.FormCreate (Sender: TObject);
  jeśliDirectSoundCreate ( zero, DirectSound, zero) <>   DS_OK następnie podnieś
AppCreateWriteSecondaryBuffer (SecondarySoundBuffer, 22050, 8, False, 10);
  AppCreateWriteSecondaryBuffer (SecondarySoundBuffer, 22050, 16, True, 1);

procedura
  jeśliPrzypisany (DirectSoundBuffer) wtedy   DirectSoundBuffer.Release;
dla   i: \u003d 0 do 1 zrobić jeśli   Assigned (SecondarySoundBuffer [i]) wtedy   SecondarySoundBuffer [i] .Release;
jeśli   Przypisany (DirectSound) wtedy   DirectSound.Release;

procedura
  H: \u003d;
jeśli   H \u003d DSERR_BUFFERLOST potem zacznij
jeśli   Buffer.Lock (OffSet, SoundBytes, AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2, 0)<>   DS_OK następnie podnieś
  inaczej jeśli   H.<>   DS_OK następnie podnieś   Exception.Create („Nie można zablokować bufora dźwięku”);
jeśli   AudioPtr2<> zero wtedy zacznij
jeśli <>   DS_OK następnie podnieś

procedura
z   Bufferdesk zaczynać
jeśli <>   DS_OK następnie podnieś
jeśli zero) <>   DS_OK następnie podnieś
jeśli <>   DS_OK następnie podnieś
jeśli   DirectSound.SetCooperativeLevel (uchwyt, DSSCL_NORMAL)<>   DS_OK następnie podnieś   Exception.Create („Nie można ustawić poziomu współpracy”);

procedura   TForm1.AppCreateWriteSecondaryBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
z   Bufferdesk zaczynać
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
jeśli   isStereo wtedy   PCM.n Kanały: \u003d 2
jeszcze   PCM.nChannels: \u003d 1;
  PCM.nBlockAlign: \u003d (Bity div   8) * PCM.nKanały;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  jeśli zero) <>   DS_OK następnie podnieś   Exception.Create („Utworzenie bufora dźwięku nie powiodło się”);

procedura   TForm1.CopyWAVToBuffer;
do   Chunk \u003d „data”;

procedura   TForm1.Button1Click (Sender: TObject);
  CopyWAVToBuffer („1.wav”, SecondarySoundBuffer);
  CopyWAVToBuffer („flip.wav”, SecondarySoundBuffer);
  jeśli <>   DS_OK wtedy
  jeśli   SecondarySoundBuffer.Play (0, 0, 0)<>   DS_OK wtedy   ShowMessage („Can” „t play the Sound”);
Przykład 2

Przedstawiam państwu kolejny przykład pracy z DirectSound na Delphi. Ten przykład pokazuje, jak pracować z buforem 3D. Tak więc pozostawiłem procedury AppCreateWritePrimaryBuffer, AppWriteDataToBuffer, CopyWAVToBuffer bez zmian (patrz litery wcześniej). Procedura AppCreateWriteSecondary3DBuffer jest kompletnym analogiem procedury AppCreateWriteSecondaryBuffer, z wyjątkiem flagi DSBCAPS_CTRL3D, która wskazuje, że inny bufor zostanie powiązany ze statycznym buforem wtórnym - SecondarySound3DBuffer. Aby go zainicjować, a także ustawić niektóre wartości początkowe (pozycja w przestrzeni, prędkość itp.), Wywoływana jest procedura AppSetSecondary3DBuffer, której parametrami są SecondarySoundBuffer i powiązany SecondarySound3DBuffer. W tej procedurze SecondarySound3DBuffer jest inicjowany przy użyciu metody QueryInterface z odpowiednią flagą. Ponadto tutaj ustawia się także pozycję źródła dźwięku w przestrzeni: SetPosition (Pos, 1 (X), 1 (Y), 0 (Z)).

Zatem w początkowym momencie źródło znajduje się na wysokości 1 m (oś Y jest skierowana pionowo w górę, a oś Z „skierowana jest w stronę ekranu”). Widziane z góry:

Punkt O (właściwie ty) ma współrzędne (0,0), źródło dźwięku A (-25,1). Oczywiście pojęcie „miernika” jest bardzo arbitralne.

Po naciśnięciu przycisku dźwięk „xhe4.wav” jest ładowany do bufora SecondarySoundBuffer. Jest to dźwięk działającego wirnika śmigłowca, jego długość (dźwięk) wynosi dokładnie 3,99 s (a rozmiar bufora dokładnie 4 s). Następnie następuje mieszanie z bufora dodatkowego do podstawowego z flagą DSBPLAY_LOOPING, co pozwala na powtarzanie powtarzanego dźwięku; czas ucha 0,01 praktycznie nie jest rejestrowany i uzyskuje się ciągły dźwięk latającego helikoptera. Następnie uruchamia się licznik czasu (pole INTERWAŁ w Inspektorze obiektów jest ustawione na 1). Oczywiście nie musisz tego robić, to tylko przykład. W procedurze Timer1Timer współrzędna X zmienia się po prostu o 0,1.

W rezultacie otrzymujemy latający helikopter od lewej do prawej. Jednocześnie możesz sprawdzić, czy głośniki są prawidłowo ustawione.

PS. Jeśli masz pytania, postaram się na nie odpowiedzieć.



wykorzystujeWindows, Wiadomości, SysUtils, Klasy, Grafika, Sterowanie, Formularze, Dialogi, DSound, MMSystem, StdCtrls, ExtCtrls;

typTForm1 \u003d klasa(TForm)
procedura   FormCreate (Sender: TObject);
procedura   FormDestroy (Sender: TObject);
procedura   Button1Click (Sender: TObject);
procedura   Timer1Timer (Sender: TObject);
  DirectSoundBuffer: IDirectSoundBuffer;
  SecondarySoundBuffer: IDirectSoundBuffer;
  SecondarySound3DBuffer: IDirectSound3DBuffer;
  procedura   AppCreateWritePrimaryBuffer;
procedura   AppCreateWriteSecondary3DBuffer ( var   Bufor: IDirectSoundBuffer; SamplesPerSec: Integer; Bity: Word; isStereo: Boolean; Czas: liczba całkowita);
procedura   AppSetSecondary3DBuffer ( var   Bufor: IDirectSoundBuffer; var   _3DBuffer: IDirectSound3DBuffer);
procedura   AppWriteDataToBuffer (Buffer: IDirectSoundBuffer; OffSet: DWord; var   SoundData SoundBytes: DWord);
procedura   CopyWAVToBuffer (nazwa: PChar; var   Bufor: IDirectSoundBuffer);


procedura   TForm1.FormCreate (Sender: TObject);
  jeśliDirectSoundCreate ( zero, DirectSound, zero) <>   DS_OK następnie podnieś   Exception.Create („Nie udało się utworzyć obiektu IDirectSound”);
  AppCreateWriteSecondary3DBuffer (SecondarySoundBuffer, 22050, 8, False, 4);
  AppSetSecondary3DBuffer (SecondarySoundBuffer, SecondarySound3DBuffer); Timer1.Enabled: \u003d False;

procedura   TForm1.FormDestroy (Sender: TObject);
  jeśliPrzypisany (DirectSoundBuffer) wtedy   DirectSoundBuffer.Release;
jeśli   Przypisany (SecondarySound3DBuffer) wtedy   SecondarySound3DBuffer.Release;
jeśli   Assigned (SecondarySoundBuffer) wtedy   SecondarySoundBuffer.Release;
jeśli   Przypisany (DirectSound) wtedy   DirectSound.Release;

procedura   TForm1.AppCreateWritePrimaryBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
z   Bufferdesk zaczynać
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  dwFlags: \u003d DSBCAPS_PRIMARYBUFFER;
jeśli   DirectSound.SetCooperativeLevel (uchwyt, DSSCL_WRITEPRIMARY)<>   DS_OK następnie podnieś
jeśli   DirectSound.CreateSoundBuffer (BufferDesc, DirectSoundBuffer, zero) <>   DS_OK następnie podnieś   Exception.Create („Utworzenie bufora dźwięku nie powiodło się”);
jeśli DirectSoundBuffer.SetFormat (PCM)<>   DS_OK następnie podnieś   Exception.Create („Nie można ustawić formatu”);
jeśli   DirectSound.SetCooperativeLevel (uchwyt, DSSCL_NORMAL)<>   DS_OK następnie podnieś   Exception.Create („Nie można ustawić poziomu współpracy”);

procedura   TForm1.AppCreateWriteSecondary3DBuffer;
  FillChar (BufferDesc, SizeOf (DSBUFFERDESC), 0);
  FillChar (PCM, SizeOf (TWaveFormatEx), 0);
z   Bufferdesk zaczynać
  PCM.wFormatTag: \u003d WAVE_FORMAT_PCM;
jeśli   isStereo, a następnie PCM.n Kanały: \u003d 2
jeszcze   PCM.nChannels: \u003d 1;
  PCM.nSamplesPerSec: \u003d SamplesPerSec;
  PCM.nBlockAlign: \u003d (Bity div   8) * PCM.nKanały;
  PCM.nAvgBytesPerSec: \u003d PCM.nSamplesPerSec * PCM.nBlockAlign;
  dwSize: \u003d SizeOf (DSBUFFERDESC);
  dwFlags: \u003d DSBCAPS_STATIC lub   DSBCAPS_CTRL3D;
  dwBufferBytes: \u003d Czas * PCM.nAvgBytesPerSec;
jeśli   DirectSound.CreateSoundBuffer (BufferDesc, Buffer, zero) <>   DS_OK następnie podnieś   Exception.Create („Utworzenie bufora dźwięku nie powiodło się”);

procedura   TForm1.AppWriteDataToBuffer;
  AudioPtr1, AudioPtr2: Wskaźnik;
  AudioBytes1, AudioBytes2: DWord;
jeśli   H \u003d DSERR_BUFFERLOST potem zacznij
jeśli   Buffer.Lock (OffSet, SoundBytes, AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2, 0)<>   DS_OK następnie podnieś   Exception.Create („Nie można zablokować bufora dźwięku”);
  inaczej jeśli   H.<>   DS_OK następnie podnieś   Exception.Create („Nie można zablokować bufora dźwięku”);
  Przenieś (Temp ^, AudioPtr1 ^, AudioBytes1);
jeśli   AudioPtr2<> zero wtedy zacznij
  Inc (liczba całkowita (temperatura), AudioBytes1);
  Przenieś (Temp ^, AudioPtr2 ^, AudioBytes2);
jeśli   Buffer.UnLock (AudioPtr1, AudioBytes1, AudioPtr2, AudioBytes2)<>   DS_OK następnie podnieś   Exception.Create („Nie można odblokować bufora dźwięku”);

procedura   TForm1.CopyWAVToBuffer;
  FName: \u003d TFileStream.Create (nazwa, fmOpenRead);
  FName.Seek (Pos, soFromBeginning);
do   Chunk \u003d „data”;
  FName.Seek (Pos + 3, soFromBeginning);
  FName.Read (DataSize, SizeOf (DWord));
  AppWriteDataToBuffer (Buffer, 0, Data ^, DataSize);

var   Pos: Pojedyncze \u003d -25;

procedura   TForm1.AppSetSecondary3DBuffer;
  jeśliBuffer.QueryInterface (IID_IDirectSound3DBuffer, _3DBuffer)<>   DS_OK następnie podnieś   Exception.Create („Nie udało się utworzyć obiektu IDirectSound3D”);
jeśli   _3DBuffer.SetPosition (Pos, 1, 1, 0)<>   DS_OK następnie podnieś   Exception.Create („Nie udało się ustawić pozycji IDirectSound3D”);

procedura   TForm1.Button1Click (Sender: TObject);
  CopyWAVToBuffer („xhe4.wav”, SecondarySoundBuffer);
  jeśli   SecondarySoundBuffer.Play (0, 0, DSBPLAY_LOOPING)<>   DS_OK wtedy   ShowMessage („Can” „t play the Sound”);

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

W tym artykule postaram się rozważyć trzy procedury odtwarzania dźwięku. Zastosowanie tych procedur zamiast komponentu TMediaPlayer znacznie zaoszczędzi zasoby systemowe. Korzystając z tych procedur, możesz rozwiązać dość szeroki zakres zadań. Rozpatrzymy te procedury od najprostszej.

Procedura dźwiękowa

Ta procedura nie ma parametrów. Jej reklama wygląda dość prosto:

Istotą tej procedury jest odtworzenie standardowego sygnału dźwiękowego zainstalowanego w systemie Windows, jeśli istnieje karta dźwiękowa i skonfigurowany jest standardowy dźwięk, jeśli nie, dźwięk będzie odtwarzany przez głośnik komputera w postaci krótkiego kliknięcia. Można go użyć na przykład, gdy użytkownik wprowadzi nieprawidłowe dane lub podczas zamykania formularza:

procedura TForm1.FormClose (Sender: TObject; var Action: TCloseAction);
  zacząć
  Beep
  koniec;

Wymyśliliśmy pierwszą procedurę. Zobaczmy teraz drugi ...

Funkcja MessageBeep

Ta funkcja jest poważniejsza i jest zdefiniowana jako:

funkcja MessageBeep (uType: word): boolean;

Parametr uType określa odtwarzany dźwięk, jako identyfikator klucza rejestru, w którym rejestrowane są dźwięki towarzyszące tym lub innym zdarzeniom systemu Windows. Parametr uType może przyjmować następujące wartości:

  • MB_ICONASTERISK - odtwarza dźwięk „Asterisk” (SystemAsterisk)
  • MB_ICONEXCLAMATION - odtwarza dźwięk „Exclamation” (SystemExclamation)
  • MB_ICONHAND - odtwarza dźwięk „Critical Error” (SystemHand)
  • MB_ICONQUESTION - odtwarza dźwięk „Pytanie” (pytanie systemowe)
  • MB_OK - odtwarza dźwięk „Standard Sound” (SystemDefault)

Należy zauważyć, że ta funkcja odtwarza dźwięk asynchronicznie, tj. podczas odtwarzania dźwięku aplikacja nadal działa. Po żądaniu dźwięku MessageBeep przenosi kontrolę do funkcji, która go wywołała.

Jeśli odtworzenie określonego dźwięku nie jest możliwe, funkcja spróbuje odtworzyć domyślny zestaw dźwięków systemowych, jeśli nie jest to możliwe, standardowy dźwięk będzie odtwarzany przez głośnik.

I w końcu pozostaje najbardziej interesująca i użyteczna funkcja odtwarzania dźwięku, porozmawiamy o tym teraz.

Funkcja PlaySound

Ta funkcja może odtwarzać dowolne dźwięki fal, a nie tylko dźwięki zdarzeń systemu Windows. Funkcja Windows API, której parametry są opisane w module mmsystem. Dlatego, aby użyć tej funkcji w swoich programach, musisz uwzględnić moduł mmsystem w sekcji zastosowań. Funkcja PlaySound jest zdefiniowana w następujący sposób:

funkcja PlaySound (pszSound: PChar; hmod: HINST; fdwSound: Cardinal): boolean;

Parametr pszSound jest łańcuchem zakończonym zerem (ostatni znak łańcucha ma kod zerowy), określa odtwarzany dźwięk. Parametr hmod jest używany, gdy dźwięk jest pobierany z zasobu, ponieważ nie zrobimy tego, możesz ustawić ten parametr na 0 lub zero.

Ostatni parametr, fdwSound, to zestaw, który określa sposób odtwarzania dźwięku (tryb odtwarzania). Podam najważniejsze wartości tego zestawu do odtwarzania flag o dowolnej fali.

  • SND_ASYNC - Dźwięk jest odtwarzany asynchronicznie, a funkcja powraca natychmiast po rozpoczęciu odtwarzania. Aby zatrzymać odtwarzanie, musisz wywołać funkcję PlaySound z parametrem pszSound równym 0.
  • SND_LOOP - powtarzanie dźwięku jest ciągle powtarzane; jednocześnie należy ustawić flagę SND_ASYNC.
  • SND_NOSTOP - Jeśli określonego dźwięku nie można odtworzyć z powodu zajętych zasobów, funkcja natychmiast zwróci false (i dźwięk nie zostanie odtworzony). Jeśli ta flaga nie zostanie określona, \u200b\u200bfunkcja spróbuje przerwać odtwarzanie innego dźwięku w celu zwolnienia zasobów.
  • SND_PURGE - Zatrzymuje odtwarzanie dźwięków spowodowanych w tym zadaniu.
  • SND_SYNC - Synchroniczne odtwarzanie dźwięku zdarzenia. Funkcja PlaySound powraca dopiero po zakończeniu odtwarzania.

Ważne: flagi można łączyć z lub.

Dźwięk określony w parametrze pszSound powinien być odpowiedni dla zainstalowanego sterownika urządzenia do odtwarzania plików wave, a także powinien znajdować się w dostępnej pamięci.

Możesz przerwać dźwięk, wykonując instrukcję

PlaySound (0, 0, SND_PURGE);

lub ustawiając nowy dźwięk.

Na przykład, aby wielokrotnie i asynchronicznie odtwarzać niektóre dźwięki wybrane za pomocą OpenDialog, możesz napisać następujący kod:

procedura TForm1.Button1Click (Sender: TObject);
  var PCh: PChar;
  zacząć
  jeśli OpenDialog1.Execute, to
  zacząć
  StrPCopy (PCh, OpenDialog1.FileName);
  PlaySound (Pch, 0, SND_ASYNC lub SND_LOOP);
  koniec;
  koniec;

Mam nadzieję, że wszystko jest jasne! Następnym razem będzie coś bardziej skomplikowanego i ciekawszego!

Po skonfigurowaniu komponentów należy ustawić rozmiar formularza zgodnie z rozmiarem komponentu Image1, tak aby komponenty MediaPlayer1, SpeedButton5 i SpeedButton6 znajdowały się poza granicą formy. W rezultacie kształt powinien wyglądać tak, jak pokazano na rys. 10.17

Ryc. 10.17 Ostateczna forma „odtwarzacza MP3”

Regulacja głośności

Możesz ustawić żądaną głośność odtwarzania pliku MP3 za pomocą funkcji API waveOutSetVolume. Aby ta funkcja stała się dostępna, należy umieścić łącze do modułu MMSystem w tekście programu (podaj nazwę modułu w dyrektywie uses).

Instrukcja wywołania funkcji wygląda następująco:

r \u003d waveOutSetVolume (identyfikator urządzenia, głośność)

Parametr ID urządzeniaustawia urządzenie odtwarzające (a dokładniej kanał dźwiękowy), którego głośność musi być ustawiona. Podczas regulacji głośności odtwarzania pliku MP3 wartość tego parametru powinna być równa

WAVE_MAPPER (stała WAVE_MAPPER jest zdefiniowana w module MMSystem).

Parametr Głośność (podwójne słowo) ustawia głośność odtwarzania: dolne słowo określa głośność lewego kanału, najwyższe słowo określa głośność prawego kanału. Maksymalna głośność kanału odpowiada wartości szesnastkowej FFFF, minimalna - 0000. Tak więc, aby ustawić maksymalną głośność odtwarzania w obu kanałach, wartość parametru Volume powinna wynosić $ FFFFFFFF (w Delphi prefiks $ jest używany podczas pisania stałych szesnastkowych). Poziom głośności 50% odpowiada stałej wartości 7FFF7FFF.

Należy pamiętać, że funkcja waveOutSetVolume dostosowuje głośność odtwarzania kanał dźwiękowyzamiast ogólnego poziomu dźwięku.

Zmień głośność za pomocą komponentu TrackBar1. Należy zauważyć, że gdy komponent jest ustawiony pionowo, górna pozycja suwaka odpowiada zerowej wartości właściwości Position, a dolna odpowiada wartości określonej przez właściwość Max. Dlatego poziom głośności odpowiadający położeniu silnika oblicza się jako różnicę między prądem a maks

najniższa możliwa wartość właściwości Position (ta wartość ustawia właściwość Max), pomnożona przez $ FFFF.

Bezpośrednia zmiana głośności jest wykonywana przez procedurę przetwarzania zdarzenia Change (Listing 10.14), kontroli głośności (komponent TrackBar1), która występuje w wyniku przesunięcia kursora za pomocą myszy lub klawiszy kursora. Najpierw oblicza wartość głośności dla lewego kanału, a następnie dodaje tę samą wartość przesuniętą o 16 bitów do odebranej wartości (w rezultacie te same i wyższe wartości znajdują się w słowach wysokich i niskich), a tak otrzymana wartość jest przekazywana jako parametr do funkcji

waveOutSetVolume.

Listing 10.14. Obsługa zdarzenia zmiany komponentu TrackBar1

zacząć

volume: \u003d $ FFFF * (TrackBar1.Max - TrackBar1.Position); objętość: \u003d objętość + (objętość shl 16); waveOutSetVolume (WAVE_MAPPER, wolumin);

koniec;

Okno się porusza

Wartość właściwości BorderStyle formularza to bsNone, dlatego tytuł nie jest wyświetlany w oknie programu (patrz rys. 10.5), a zatem na pierwszy rzut oka użytkownik wydaje się być pozbawiony możliwości przesuwania okna po ekranie w zwykły sposób. Niemniej jednak okno programu można nadal przenosić. Aby to zrobić, ustaw wskaźnik myszy na wolny punkt okna (nie zajmowany przez komponenty), naciśnij lewy przycisk myszy i przytrzymaj go, przeciągnij okno do żądanego punktu na ekranie (ta metoda jest bardzo powszechna). Opisana metoda przenoszenia okna jest zapewniona przez procedurę przetwarzania zdarzenia MouseDown w polu komponentu Image1 (lista 10.15). Procedura „oszukuje” system operacyjny, informuje go (wysyłając odpowiedni komunikat), że użytkownik kliknął przycisk myszy w tytule okna, czyli wykonał akcję wymagającą przeniesienia okna.

Listing 10.15. Obsługa zdarzenia MouseDown w polu komponentu Image1

// W takim przypadku użytkownik może przesunąć okno w zwykły sposób

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

Tekst programu

Pełny tekst programu odtwarzacza MP3 pokazano na Listingu 10.16.

Listing 10.16. Odtwarzacz MP3

(Odtwarzacz MP3 z regulacją głośności.

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

jednostka MainForm;

Windows, Wiadomości, SysUtils, Warianty, Klasy, Grafika, Kontrolki, Formularze, Dialogi, StdCtrls, Przyciski, ExtCtrls, MPlayer, ComCtrls, MMSYSTEM, FileCtrl, Menu; // te linki są wstawiane ręcznie

TForm1 \u003d klasa (TForm) MediaPlayer1: TMediaPlayer;

SpeedButton1: TSpeedButton; // poprzednia kompozycjaSpeedButton2: TSpeedButton; // Play / Stop SpeedButton3: TSpeedButton; // następna kompozycjaSpeedButton4: TSpeedButton; // wybierz folder

// niewidoczne przyciski SpeedButton5 i SpeedButton6 zapewniają

// przechowywanie zdjęć Play i Stop

SpeedButton5: TSpeedButton;

SpeedButton6: TSpeedButton;

ListBox1: TListBox; // lista piosenek

Część II Warsztaty programistyczne

Label1: TLabel; // grywalna kompozycja

Label2: TLabel; // czas gry

Image1: TImage; // tło

PopupMenu1: TPopupMenu; // menu kontekstowe

N1: TMenuItem; // „Zamknij”

N2: TMenuItem; // „Minimalizuj”

// regulacja głośności

Panel1: TPanel; // Panel TrackBar1: TTrackBar;

procedura Image1MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

procedura N2Click (Sender: TObject); procedura N1Click (Sender: TObject);

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

// te deklaracje są wstawiane tutaj ręcznie procedura Odtwórz; // zagraj

procedura PlayList (ścieżka: ciąg); // tworzy listę plików MP3

(Prywatne deklaracje) publiczne

(Oświadczenia publiczne) zakończone;

($ R * .dfm) var

SoundPath: string; // katalog, w którym znajdują się pliki MP3

min, sec: liczba całkowita; // czas gry

tom: LongWord; // głośność odtwarzania:

// najwyższe słowo to właściwy kanał,

// niskie słowo zostało

procedura TForm1.FormCreate (Sender: TObject); zacząć

PlayList („”); // utwórz listę plików MP3

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

// ustaw poziom głośności

TrackBar1.Position: \u003d 7;

// wysokie słowo zmiennej głośności to właściwy kanał,

// w lewym dolnym rogu

volume: \u003d (TrackBar1.Position - TrackBar1.Max + 1) * $ FFFF; objętość: \u003d objętość + (objętość shl 16); waveOutSetVolume (WAVE_MAPPER, wolumin); // poziom głośności

koniec;

// tworzy listę procedur plików MP3 TForm1.PlayList (Path: string); var

SearchRec: TSearchRec; // Struktura SearchRec zawiera informacje // o pliku, który spełnia warunek wyszukiwania

// utwórz listę plików MP3

jeśli FindFirst (ścieżka + „* .mp3”, faAnyFile, SearchRec) \u003d 0, to zacznij

// Katalog ma plik z rozszerzeniem mp3.

// Dodaj nazwę tego pliku do listy.

ListBox1.Items.Add (SearchRec.Name);

Część II Warsztaty programistyczne

// Jeszcze jakieś pliki MP3?

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

koniec; ListBox1.ItemIndex: \u003d 0;

koniec;

// kliknij tytuł pracy

procedura TForm1.ListBox1Click (Sender: TObject); zacząć

jeśli SpeedButton2.Tag \u003d 0, wtedy

// wyświetl nazwę wybranego pliku w polu etykiety Label1

Label1.Caption: \u003d ListBox1.Items else

Form1.Play; // aktywuj proces odtwarzania

koniec;

// kliknij przycisk „Odtwórz”

procedura TForm1.SpeedButton2Click (Sender: TObject); zacząć

// właściwość Tag przechowuje informacje o stanie.

// gracz: 0 - stop; 1 - zagraj

jeśli SpeedButton2.Tag \u003d 0, to zacznij // rozpocznij odtwarzanie

Form1.Play; koniec

// po naciśnięciu przycisku odtwarzania

// następnie ponowne naciśnięcie zatrzymuje odtwarzaniezacząć

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

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

koniec;

koniec;

// przycisk „Poprzedni utwór”

procedura TForm1.SpeedButton1Click (Sender: TObject);

jeśli ListBox1.ItemIndex\u003e 0, to

ListBox1.ItemIndex: \u003d ListBox1.ItemIndex - 1; jeśli SpeedButton2.Tag \u003d 1, to

koniec;

// Przycisk „Następny utwór”

procedura TForm1.SpeedButton3Click (Sender: TObject); zacząć

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

jeśli SpeedButton2.Tag \u003d 1, to Play;

koniec;

// użytkownik zmienił pozycję procedury regulacji głośności TForm1.TrackBar1Change (Sender: TObject);zacząć

volume: \u003d $ FFFF * (TrackBar1.Max - TrackBar1.Position); objętość: \u003d objętość + (objętość shl 16); waveOutSetVolume (WAVE_MAPPER, wolumin);

koniec;

// odtworzenie utworu, którego nazwa jest podświetlona na liście Procedura ListBox1 TForm1.Play;

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

Mediaplayer1.Open; oprócz

na EMCIDeviceError zaczynają się

ShowMessage („Błąd dostępu do pliku” + ListBox1.Items);

wyjście koniec;

koniec;

Część II Warsztaty programistyczne

MediaPlayer1.Play; min: \u003d 0;

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

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

koniec;

// sygnał timera

procedura TForm1.Timer1Timer (Sender: TObject); zacząć

// zmienić licznik czasujeśli sec< 59

następnie inc (sec) else rozpocząć

sec: \u003d 0; inc (min);

koniec;

// wyświetlać czas odtwarzania

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

następnie Label2.Caption: \u003d Label2.Caption + „0” + IntToStr (sec) else Label2.Caption: \u003d Label2.Caption + IntToStr (sec);

// jeśli odtwarzanie bieżącego utworu nie zostanie zakończone

if MediaPlayer1.Position< MediaPlayer1.Length then exit;

// odtwarzanie bieżącego utworu jest zakończone

Timer1.Enabled: \u003d False; // zatrzymać stoperMediaPlayer1.Stop; // zatrzymaj gracza

if ListBox1.ItemIndex< ListBox1.Count // lista nie jest wyczerpanapotem zacznij

ListBox1.ItemIndex: \u003d ListBox1.ItemIndex + 1; Graj // aktywuj odtwarzaniePlik końcowy MP3

koniec;

// Kliknij przycisk „Folder”.

// Wybierz folder, w którym znajdują się pliki MP3 TForm1.SpeedButton4Click (Sender: TObject);var

Root: string; // katalog główny pwRoot: PWideChar;

Dir: string; zacząć

Root: \u003d ""; // katalog główny - folder pulpitu

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

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

jeśli nie SelectDirectory („Wybierz folder, w którym znajdują się pliki MP3”, pwRoot, Dir)

następnie Dir: \u003d ""

else Dir: \u003d Dir + "\\";

// wybrany jest katalog, w którym znajdują się pliki MP3

SoundPath: \u003d Dir; PlayList (SoundPath);

koniec;

// kliknij myszą w polu komponentu Image1

procedura TForm1.Image1MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

// Nie ma tytułu okna. Oszukiwać w systemie Windows. Niech OC myśli

// że przycisk jest wciśnięty i przytrzymany w tytule okna.

// W takim przypadku użytkownik może przesunąć okno w zwykły sposób.

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

koniec;

// wybierz polecenie „Zamknij” w procedurze menu kontekstowego TForm1.N1Click (Sender: TObject);zacząć

Form1.Close; koniec;

koniec

DZWONEK

Są tacy, którzy czytają te wiadomości przed tobą.
Subskrybuj, aby otrzymywać świeże artykuły.
Email
Imię
Nazwisko
Jak chcesz przeczytać Dzwon
Bez spamu