W tym artykule postaram się przedstawić multimedia. Pominiemy jednak wspaniały komponent MediaPlayer, gdyż tym razem zajmiemy się bardziej nie VCL-owym podejściem do tego zagadnienia. Napoczątku zapoznamy się z formatem MIDI.
MIDI
MIDI, czyli w skrócie Musical Instrument Digital Interface, jest protokołem i zbiorem instrukcji do przechowywania i transmitowania informacji o muzyce. Urządzenia MIDI interpretują te informacje, żeby odegrać muzykę. Delphi udostępnia wiele funkcji MIDI do odgrywania i nagrywania muzyki, my na razie zapoznamy się z podstawowymi. Pierwsze dwie funkcje, najbardziej fundamentalne, to funkcje midiInGetNumDevs i midiOutGetNumDevs. Informują one odpowiednio o ilości urządzeń wejściowych i wyjściowych w komputerze. Działają one tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{$APPTYPE CONSOLE} uses mmsystem; begin writeln('Urzadzenia wejsciowe: ',midiInGetNumDevs); writeln('Urzadzenia wyjsciowe: ',midiOutGetNumDevs); readln; end. |
Przydałoby się również pobrać informacje o możliwościach każdego z nich. Służy do tego funkcje midiInGetDevCaps i midiOutGetDevCaps. Poniższy kod sprawdza ilość urządzeń w systemie i wyświetla ich krótki opis:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
{$APPTYPE CONSOLE} uses mmsystem,windows; var in_c,out_c:integer; i:integer; in_caps:MidiInCaps; out_caps:MidiOutCaps; begin in_c:=midiInGetNumDevs; out_c:=midiOutGetNumDevs; writeln('Urzadzenia wejsciowe: ',in_c); writeln('Urzadzenia wyjsciowe: ',out_c); writeln; for i:=0 to in_c-1 do begin writeln('Urzadzenie wejsciowe[',i,']'); midiInGetDevCaps(i,@in_caps,sizeof(in_caps)); writeln('Nazwa: ',in_caps.szpnamE); writeln('Wersja: ',HIBYTE(in_caps.vDriverVersion),'.',LOBYTE(in_caps.vDriverVersion)); end; for i:=0 to out_c-1 do begin writeln('Urzadzenie wyjsciowe[',i,']'); midiOutGetDevCaps(i,@out_caps,sizeof(out_caps)); writeln('Nazwa: ',out_caps.szPName); writeln('Wersja: ',HIBYTE(out_caps.vDriverVersion),'.',LOBYTE(out_caps.vDriverVersion)); write('Typ: '); if (out_caps.wTechnology=MOD_MIDIPORT) then writeln('MIDI hardware port') else if (out_caps.wTechnology=MOD_SYNTH) then writeln('Synthesizer') else if (out_caps.wTechnology=MOD_SQSYNTH) then writeln('Squarewave synthesizer') else if (out_caps.wTechnology=MOD_FMSYNTH) then writeln('FM synthesizer') else if (out_caps.wTechnology=MOD_MAPPER) then writeln('Microsoft MIDI mapper') else if (out_caps.wTechnology=6) then writeln('Hardware wavetable synthesizer') else if (out_caps.wTechnology=7) then writeln('Software synthesizer'); writeln('Liczba glosow: ',out_caps.wVoices); writeln('Maksymalna liczba nut granych jednoczesnie: ',out_caps.wNotes); writeln; end; readln; end. |
Gdy już wiemy co i jak, możemy przejść do sedna sprawy, czyli odgrywania plików MIDI. Poniższa procedura play odgrywa plik podany jako filename. Może teraz krótkie omówienie co po kolei. Najpierw deklarujemy wykorzystywane zmienne: wDeviceID to identyfikator otworzonego urządzenia, kolejne dwie zmienne to struktury potrzebne do otworzenia urządzenia i odegrania muzyki. Kolejna sprawa do odpowiednie wypełnienie struktury MCI_OPEN_PARMS: pole lpstrDeviceType to typ urządzenia a lpstrElementName to nasz plik. Wywołujemy funkcję mciSendCommand z odpowiednimi parametrami i mamy już urządzenie otwarte, a w polu wDeviceID identyfikator urządzenia. Nie zostało już nic, tylko wywołać funkcję mciSendCommand i cieszyć się wspaniałą muzyką 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
procedure play(filename:pchar); var wDeviceID:integer; openparms:MCI_OPEN_PARMS; playparms:MCI_PLAY_PARMS; begin openparms.lpstrDeviceType:='sequencer'; openparms.lpstrElementName:=filename; mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE or MCI_OPEN_ELEMENT,DWORD(@openparms)); wDeviceID:=openparms.wDeviceID; mciSendCommand(wDeviceID,MCI_PLAY,0,DWORD(@playparms)); end; |
JOYSTICK
Teraz zabawimy się JOYSTICKEM. Podobnie jak przy urządzeniach MIDI, do pobrania liczby urządzeń użyjemy funkcji joyGetNumDevs, a do pobrania informacji o każdym z nich funkcji joyGetDevCaps.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
{$APPTYPE CONSOLE} uses mmsystem; var joy_c:word; jcaps:JOYCAPSA; i:word; begin writeln('JOYSTICK'); joy_c:=joyGetNumDevs; writeln('Ilosc urzadzen: ',joy_c); for i:=0 to joy_c-1 do begin writeln('Urzadzenie[',i,']'); joyGetDevCaps(i,@jcaps,sizeof(jcaps)); writeln('Nazwa: ',jcaps.szPName); writeln('Ilosc przyciskow: ',jcaps.wNumButtons); writeln('Rejestr: ',jcaps.szRegKey); end; readln; end. |
Do pobrania informacji o aktualnej pozycji joysticka służy funkcja joyGetPos.
1 2 3 4 5 6 7 8 9 |
var joypos:JOYINFO; begin joyGetPos(numerurzadzenia,@joypos); end; |
Teraz pola wXpos, wYpos, wZpos będą zawierały informacje o położeniu joysticka, a pole wButtons o stanie przycisków. Ostatnie pole, może przyjmować jedną lub więcej wartości:
JOY_BUTTON1 – jeżeli przycisk pierwszy jest wciśnięty
JOY_BUTTON2 – jeżeli przycisk drugi jest wciśnięty
JOY_BUTTON3 – jeżeli przycisk trzeci jest wciśnięty
JOY_BUTTON4 – jeżeli przycisk czwarty jest wciśnięty
WAVE
No końcu zajmiemy się formatem WAVE. Do odgrywania plików wav służą następujące funkcje:
1 2 3 |
PlaySound('nazwa pliku.wav',0,SND_FILENAME); sndPlaySound('nazwa pliku.wav',SND_FILENAME); |
Jest jeszcze jeden sposób na odegraniu pliku wav, a mianowicie użycie funkcji mciSendString:
1 2 3 4 5 |
mciSendString('open nazwaplikuwav type waveaudio alias foo',nil,0,0); mciSendString('set foo time format miliseconds',nil,0,0); mciSendString('play foo from od[ms] to do[ms]',nil,0,0); |
Parametry od[ms] i do[ms] służą do ustalenia od której do której milisekundy będzie odgrywany plik. A teraz nie lada gratka dla tych co doczytali do końca, gdyż nauczymy się nagrywać pliki wav. Napiszemy procedurę, która zapisze dźwięk o określonej długości do zadanego pliku wav.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
procedure recordfile(filename:pchar;milisec:dword); var wDeviceID:integer; openp:MCI_OPEN_PARMS; recordp:MCI_RECORD_PARMS; savep:MCI_SAVE_PARMS; begin // ustawiamy typ urządzenia openp.lpstrDeviceType:='waveaudio'; openp.lpstrElementName:=''; // otwieramy urządzenie mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT or MCI_OPEN_TYPE,DWORD(@openp)); // pobieramy identyfikator urządzenia wDeviceID:=openp.wDeviceID; // długość pliku recordp.dwTo:=milisec; // zaczynamy nagrywanie mciSendCommand(wDeviceID,MCI_RECORD,MCI_TO or MCI_WAIT,DWORD(@recordp)); // zapisujemy plik savep.lpFileName:=filename; mciSendCommand(wDeviceID,MCI_SAVE,MCI_SAVE_FILE or MCI_WAIT,DWORD(@savep)); end; |
Jest jeszcze bardzo, bardzo, bardzo wiele różnych funkcji, struktur, typów i tak dalej, ja tylko przytoczyłem niektóre z nich, o reszcie można poczytać na stronce Microsoftu i w Platform SDK.
Autor: krajew4