Odtwarzacz plików dźwiękowych.
W tym kursie programowania pokażę jak stworzyć w pełni funkcjonalny odtwarzacz plików dźwiękowych w formatach: *.wav, *.mp3, *.midi. Odtwarzcz nie będzie ani lepszy, ani pięknieszy od dostępnych już wszędzie tego typu odtwarzaczy, będzie raczej prosty i funkcjonalny, i będzie zawierał to wszystko co powinien zawierać tego typu program, czyli listę plików, regulator głośności, pasek postępu, pasek stanu, regulatory i inne mniej istone elementy. Po przejściu wszystkich "kroków", każdy będzie już na tyle zorientowany na czym polega programowanie by sobie dowolnie zmodyfikować, ulepszyć i upiększyć program. Więc zaczynamy.
krok 1. - tworzymy nowy projekt
Najpierw należy utworzyć na dysku nowy katalog w który będziemy przchowywać projekt. Następnie uruchamiamy BCB. W chwili uruchomienia program automatycznie tworzy nowy projekt. Przchodzimy do menu File i wybieramy Save All. Plik źródłowy zapisujemy pod nazwą Unit1.cpp, plik nagłówkowy zostanie utworzony automatycznie i zapisany pod nazwą Unit1.h. Program będzie się nazywał Empeg więc pod taką nazwą zapisujemy projekt.
krok 2. - rozmieszczamy komponenty i ustawiamy ich właściwości
Najpierw umieszczamy na formularzu komponent 'MediaPlayer1' który znajduje się na zakładce System, potem umieszczamy komponenty 'ListBox1', 'Label1', 'OpenDialog1', 'Edit1', 'TrackBar1', 'ProgressBar1', 'Timer1' oraz siedem kopmonentów
'SpeedButton'. Właściwości wszystkich komponentów ustawiamy według wzoru podanego w tabeli:
|
|
|
|
|
|
Ważna uwaga. W niektórych przypadkach (prawdopodobnie w BCB poniżej wersji 4) w właściwości Max i Position obiektu TrackBar1 nie można wprowadzić wartości MaxWord, dlatego należy przypisać tym właściwościom wartość
65535.W 'OpenDialog1' wprowadzamy tylko filtry do edytora filtrów według wzoru:
Pliki WAV | *.wav
Pliki MP3 | *.mp3
Pliki MIDI | *.midi
Wszystkie formaty | *.wav;*.mp3;*.midi
Jeśli chodzi o przyciski 'SpeedButton' to jako właściwość Glyph należy wprowadzić pliki graficzne, a konkretnie bitmapy. Można zastosować tutej pliki które są dołączane w czasie instalacji BCB i powinny znajdować się w lokalizacji np. "C:\Program Files\Common Files\Borland Shared\Images\Buttons\", lecz można równie dobrze posłużyć się własnymi bitmapami. Jako właściwość Glyph będę podawał nazwy plików które znajdują się w podanej lokalizacji.
|
|
|
|
|
|
|
|
|
|
krok 3. - wczytywanie plików do listy
Teraz dołączymy procedury wczytywania plików i umieszczania ich na liście - 'ListBox1'. W tym celu przechodzimy do pliku nagłówkowego Unit1.h i w sekcji private definiujemy listę typu string, która będzie przechowywała ścieżki dostępu do nazw plików ładowanych do listy 'ListBox1'. Definiujemy również funkcję LoadFiles, która będzie obsługiwała wczytywanie plików.
Przykład:
// Plik nagłówkowy np. Unit1.h. //-------------------------------- private: void __fastcall LoadFiles(void); TStringList *Lista; //-------------------------------- |
Następnie przechodzimy do pliku źródłowego Unit1.cpp i w zdarzeniu formularza 'OnCreate' inicjujemy listę Lista, natomiast w zdarzeniu 'OnClose' usuwamy listę z pamięci, a następnie tworzymy procedurę obsługi funkcji 'LoadFiles' po czym w zdarzeniu 'OnClick' przycisku 'Open1' wywołujemy zdefiniowaną funkcję. Potem również w zdarzeniu 'OnClick' lecz przycisku 'Clear1' wywołujemy funkcję kasującą zawartość obiektów 'Lista' i 'ListBox1'.
Przykład:
// Plik źródłowy np. Unit1.cpp //-------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { Lista = new TStringList; } //-------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { Lista->Free(); } //-------------------------------- void __fastcall TForm1::LoadFiles(void) { if(OpenDialog1->Execute()){ for(int i = 0; i < Lista->Count; i++){ if(OpenDialog1->FileName == Lista->Strings[i]) return; } Lista->Add(OpenDialog1->FileName); ListBox1->Items->Add(ExtractFileName(OpenDialog1->FileName)); } } //-------------------------------- void __fastcall TForm1::Open1Click(TObject *Sender) { LoadFiles(); } //-------------------------------- void __fastcall TForm1::Clear1Click(TObject *Sender) { ListBox1->Items->Clear(); Lista->Clear(); } //-------------------------------- |
krok 4. - odtwarzanie plików
Teraz zajmiemy się obsługą plików znajdujących się na liście oraz obsługą paska postępu 'ProgressBar1', który będzie informował nas o tym jak długo plik jest odtwarzany oraz ile jeszcze pozostało do końca. Natomiast obiekt 'Edit1' będzie wyświetlał tytuł utworu oraz jego czas całkowity dlatego stworzymy również funkcję obliczającą całkowitą długość utworu - 'FullTime'. Wszystko to zostanie zawarte w jednej funkcji 'PlayFile'. W tym celu przechodzimy do pliku nagłówkowego Unit1.h i w sekcji private definiujemy funkcję.
Przykład:
// Plik nagłówkowy np. Unit1.h. //-------------------------------- private: void __fastcall LoadFiles(void); void __fastcall PlayFile(int index); // nowo tworzona funkcja PlayFile AnsiString FullTime(void); // nowo tworzona funkcja FullTime TStringList *Lista; //-------------------------------- |
Następnie przechodzimy do pliku źródłowego i tworzymy obsługę funkcji 'PlayFile', a nastęnie w zdarzeniu przycisku 'Play1' - 'OnClick' wywołujemy funkcję i uruchamiamy odtwarzanie pliku wskazanego na liście - 'ListBox1'.
Przykład:
// Plik źródłowy np. Unit1.cpp |
krok 5.- wykańczanie programu, dołączanie obsługi pozostałych obiektów
Teraz w zdarzeniu 'OnChange' obiektu 'Volume'1 dołączymy obsługę regulacji głośności, a następnie dołączymy obsługę pozostałych przycisków.
Przykład:
// Plik źródłowy np. Unit1.cpp //-------------------------------- void __fastcall TForm1::Volume1Change(TObject *Sender) { waveOutSetVolume (0, (Volume1->Position * 65536) + Volume1->Position); } //-------------------------------- void __fastcall TForm1::Pause1Click(TObject *Sender) { MediaPlayer1->Pause(); } //-------------------------------- void __fastcall TForm1::Stop1Click(TObject *Sender) { Timer1->Enabled = false; MediaPlayer1->Close(); } //-------------------------------- void __fastcall TForm1::Rewind1Click(TObject *Sender) { if(ListBox1->ItemIndex > 0) ListBox1->ItemIndex--; PlayFile(ListBox1->ItemIndex); } //-------------------------------- void __fastcall TForm1::Forward1Click(TObject *Sender) { if(ListBox1->ItemIndex < ListBox1->Items->Count) ListBox1->ItemIndex++; PlayFile(ListBox1->ItemIndex); } //-------------------------------- |
Program jest już gotowy i jeśli wszystko zrobiliście dobrze, tak jak to opisałem to będzie działał. Można by go jeszcze usprawnić, ale to by uczyniło kod i cały kurs mało czytelnym. Tak jak obiecywałem program nie jest piękny, nie obfituje również w opcje, ale co to by była za frajda tworzyć programy poprzez przpisywanie lub kopiowanie kodu, dlatego resztę możecie rozwinąć, zmodyfikować, poprawić według własnego uznania.
Program nie został dokładnie przetestowany, tak więc jeśli znajdziecie jakieś błędy to uwagi proszę mi przesłać e-mail'em.
Przygotował: Cyfrowy Baron