karta dźwiękowa

Data wykonania ćwiczenia: 21.10.2014 r.

Data oddania sprawozdania: 28.10.2014 r.

Prowadzący: dr inż. Jan Nikodem Wydział Elektroniki, Informatyka

Grupa:

Termin: Wt TN 13:15

Sprawozdanie z laboratorium

Urządzenia Peryferyjne

Ćwiczenie 11

Obsługa karty muzycznej z wykorzystaniem DirectSound, API i ActiveX


Cel ćwiczenia:

Celem ćwiczenia było napisanie programu, który będzie pracował z plikami dźwiękowymi .wav czyli odtwarzał je, wyświetlał o nich informacje zaszyte w pliku oraz przechwytywał dźwięk z mikrofonu.

Nagłówek Wav:

W nagłówku pliku .wav zapisane są informacje:

Offset (przesunięcie) Nazwa pola Rozmiar w bajtach Wartość Opis
0 ID 4 'RIFF' Identyfikator pliku RIFF
4 Rozmiar danych 4 Długość pliku - 8 Liczba określająca długość danych w pliku w bajtach z pominięciem pierwszych 8 bajtów nagłówka
8 Format ID 4 'WAVE' Format pliku
12 Opis ID 4 'fmt ' Początek części opisowej pliku
16 Rozmiar opisu 4 . Rozmiar części opisowej, dla fmt wynosi zwykle 16
20 Format Audio 2 0001h Rodzaj kompresji. 1 - bez kompresji, modulacja PCM.
22 Liczba kanałów 2 0x0001, 0x0002, itd. 1 - mono, 2 - stereo
24 Częstotliwość 4 8000, 44100, itd. Częstotliwość próbkowania w Hz
28 Częstotliwość bajtów 4 . Częstotliwość * Liczba kanałów * Rodzielczość / 8
32 Rozmiar próbki 2 . Liczba kanałów * Rodzielczość / 8
34 Rozdzielczość 2 8, 16, itd. Rozdzielczość w bitach
36 Dodatkowe parametry x . Zwykle brak tego pola
36+x Dane ID 4 'data' Początek części z danymi
40+x Rozmiar danych 4 . Rozmiar bloku danych
44+x Dane . . .

Nasz program odczytuje te dane z pliku .wav od razu po uruchomieniu a także po kliknięciu na „Odczytaj Nagłówek” oraz wyświetla je w okienku.

Funkcja PlaySound():

Funkcja ta wygląda następująco:

BOOL PlaySound(

LPCTSTR pszSound,

HMODULE hmod,

DWORD fdwSound

);

Natomiast jej wywołanie w naszym programie wygląda tak:

PlaySound(TEXT("dzwiek.wav"), NULL, SND_ SND_SYNC);
gdzie dźwięk.wav to nazwa odtwarzanego przez nas pliku.

ActiveX

Komponenty ActiveX umożliwiają w bardzo łatwy sposób odtworzenie pliku dźwiękowego, jak również sterowanie jego głośnością, przewijanie itd. Z tego względu są bardziej „przyjazne” dla odbiorcy programu jak i dla programisty.

DirectSound

Jest to część pakietu DirectX umożliwiającą szybki dostęp do karty dźwiękowej i m.in. odtwarzanie i nagrywanie dźwięku. Niestety implementacja nie jest już taka łatwa jak w pozostałych sposobach.

Okno główne programu:

Okno pozwala na odtworzenie dźwięku różnymi metodami, odczytanie zawartości nagłówka pliku .wav a także nagranie 5 sekundowego nagrania z mikrofonu oraz odtworzenie go. Przy uruchomieniu programu zostaje wyświetlony komunikat informujący o tym czy w komputerze zainstalowana jest karta dzwiękowa.

Zawartość kodu (tylko napisany przez nas):

void SprawdzKarte() //Funkcja sprawdzająca obecnośćc karty dzwiękowej

{

//WAVEOUTCAPS woc;

unsigned long iNumDevs;

/* Get the number of Digital Audio Out devices in this computer */

iNumDevs = waveOutGetNumDevs();

if (iNumDevs == 0)

AfxMessageBox(_T("Brak karty dzwiekowej !"));

else

AfxMessageBox(_T("Karta dzwiekowa wykryta !"));

}

void Naglowek() //Funkcja odczytująca zawartość nagłówka

{

int* liczba;

short* liczba_krotka;

char bufor[4];

fstream plik;

ostringstream ss,ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8,ss9,ss10;

plik.open("dzwiek.wav", std::ios::in | std::ios::out | std::ios::binary);

plik.read(bufor, 4);

ss<< bufor[0];

ss << bufor[1];

ss << bufor[2];

ss << bufor[3];

tekst= (string)ss.str();

plik.read(bufor, 4);

liczba = (int*)&bufor;

ss1 << *liczba;

tekst2=(string) ss1.str();

plik.read(bufor, 4);

ss2 << bufor[0];

ss2 << bufor[1];

ss2 << bufor[2];

ss2 << bufor[3];

tekst3 = (string)ss2.str();

plik.read(bufor, 4);

ss3 << bufor[0];

ss3 << bufor[1];

ss3 << bufor[2];

ss3 << bufor[3];

tekst4 = (string)ss3.str();

plik.read(bufor, 4);

liczba = (int*)&bufor;

ss4<< *liczba;

tekst5 = (string)ss4.str();

plik.read(bufor, 2);

liczba_krotka = (short*)&bufor;

ss5<<*liczba_krotka;

tekst6 = (string)ss5.str();

plik.read(bufor, 2);

liczba_krotka = (short*)&bufor;

ss6<< *liczba_krotka;

tekst7 = (string)ss6.str();

plik.read(bufor, 4);

liczba = (int*)&bufor;

ss7 <<*liczba << endl;

tekst8 = (string)ss7.str();

plik.read(bufor, 4);

liczba = (int*)&bufor;

ss8 << *liczba << endl;

tekst9 = (string)ss8.str();

plik.read(bufor, 2);

liczba_krotka = (short*)&bufor;

ss9<< *liczba_krotka;

tekst10 = (string)ss9.str();

plik.read(bufor, 2);

liczba_krotka = (short*)&bufor;

ss10<< *liczba_krotka;

tekst11 = (string)ss10.str();

plik.close();

}

void Cperyferyjne_dzwiek_MFCDlg::OnBnClickedPlaysoundbutton()

{ //Odtwarzanie dzwięku przez PlaySound()

PlaySound(TEXT("dzwiek.wav"), NULL, SND_SYNC);

}

void Cperyferyjne_dzwiek_MFCDlg::OnBnClickedOdczytajnaglowekbutt()

{

Naglowek(); //funkcja wypisująca dane //odczytane z nagłówka

CString ss;

ss.Format(_T("%S"), tekst.c_str());

SetDlgItemText(IDC_EDIT1, ss);

ss.Format(_T("%S"), tekst2.c_str());

SetDlgItemText(IDC_EDIT4, ss);

ss.Format(_T("%S"), tekst3.c_str());

SetDlgItemText(IDC_EDIT5, ss);

ss.Format(_T("%S"), tekst4.c_str());

SetDlgItemText(IDC_EDIT6, ss);

ss.Format(_T("%S"), tekst5.c_str());

SetDlgItemText(IDC_EDIT7, ss);

ss.Format(_T("%S"), tekst6.c_str());

SetDlgItemText(IDC_EDIT8, ss);

ss.Format(_T("%S"), tekst7.c_str());

SetDlgItemText(IDC_EDIT9, ss);

ss.Format(_T("%S"), tekst8.c_str());

SetDlgItemText(IDC_EDIT10, ss);

ss.Format(_T("%S"), tekst9.c_str());

SetDlgItemText(IDC_EDIT11, ss);

ss.Format(_T("%S"), tekst10.c_str());

SetDlgItemText(IDC_EDIT12, ss);

ss.Format(_T("%S"), tekst11.c_str());

SetDlgItemText(IDC_EDIT13, ss);

}

void Cperyferyjne_dzwiek_MFCDlg::OnBnClickedButton1()

{ //Odtwarzanie dzwięku przez WaveOut

FILE *fd;

WAVEFORMATEX wav;

fopen_s(&fd, "dzwiek.wav", "rb");

fseek(fd, 20, SEEK_SET);

fread(&(wav.wFormatTag), 2, 1, fd);

fread(&(wav.nChannels), 2, 1, fd);

fread(&(wav.nSamplesPerSec), 4, 1, fd);

fread(&(wav.nAvgBytesPerSec), 4, 1, fd);

fread(&(wav.nBlockAlign), 2, 1, fd);

fread(&(wav.wBitsPerSample), 2, 1, fd);

wav.cbSize = 0;

if (waveOutOpen(&hwaveout, WAVE_MAPPER, &wav, NULL, NULL, CALLBACK_NULL) != MMSYSERR_NOERROR) {

fclose(fd);

MessageBox(L"Blad otwierania urzadzenia WaveOut");

return;

}

fseek(fd, 40, SEEK_SET);

fread(&(wavhdr.dwBufferLength), 4, 1, fd);

wavhdr.lpData = (LPSTR)malloc(wavhdr.dwBufferLength);

if (wavhdr.lpData == NULL) {

fclose(fd);

return;

}

if (fread(wavhdr.lpData, wavhdr.dwBufferLength, 1, fd) != 1) {

fclose(fd);

MessageBox(L"Blad kopiowania danych do bufora");

}

wavhdr.dwFlags = 0;

wavhdr.dwLoops = 0;

if (waveOutPrepareHeader(hwaveout, &wavhdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {

MessageBox(L"Blad przygotowywania do odtwarzania");

return;

}

if (waveOutWrite(hwaveout, &wavhdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {

MessageBox(L"Blad zapisywania do karty dzwiekowej");

return;

}

fclose(fd);

}

LPWAVEFORMATEX wczytajPlik(LPCSTR nazwa, HANDLE &bufor) {

FILE *plik;

plik = fopen(nazwa, "rb");

LPWAVEFORMATEX wav = new WAVEFORMATEX;

if (plik) {

BYTE id[5];

id[4] = 0;

DWORD size;

fread(id, sizeof(BYTE), 4, plik);

if (!strcmp((char *)id, "RIFF")) {

cout << "ChunkID: " << (char*)id << endl;

fread(&size, sizeof(DWORD), 1, plik);

fseek(plik, 20, SEEK_SET);

fread(&(wav->wFormatTag), 2, 1, plik);

fread(&(wav->nChannels), 2, 1, plik);

fread(&(wav->nSamplesPerSec), 4, 1, plik);

fread(&(wav->nAvgBytesPerSec), 4, 1, plik);

fread(&(wav->nBlockAlign), 2, 1, plik);

fread(&(wav->wBitsPerSample), 2, 1, plik);

wav->cbSize = 0;

fseek(plik, 40, SEEK_SET);

fread(&(wavhdr.dwBufferLength), 4, 1, plik);

if (fread(bufor, wavhdr.dwBufferLength, 1, plik) != 1) {

fclose(plik);

return NULL;

}

}

else

fclose(plik);

}

else

fclose(plik);

return wav;

}

//funkcja nagrywajacą z mikrofonu

void Cperyferyjne_dzwiek_MFCDlg::OnBnClickedButton3()

{

unsigned short Channels = 1;

unsigned long SamplesPerSecond = 44100;

unsigned short BitsPerSample = 8;

unsigned long RecordSeconds = 5;

WaveFormat.wFormatTag = WAVE_FORMAT_PCM;

WaveFormat.nChannels = Channels;

WaveFormat.nSamplesPerSec = SamplesPerSecond;

WaveFormat.wBitsPerSample = BitsPerSample;

WaveFormat.nAvgBytesPerSec = SamplesPerSecond * Channels;

WaveFormat.nBlockAlign = (Channels*BitsPerSample) / 8;

WaveFormat.cbSize = 0;

int Res = waveInOpen(&WaveHandle, WAVE_MAPPER, &WaveFormat, 0, 0, WAVE_FORMAT_QUERY);

if (Res == WAVERR_BADFORMAT) return;

Res = waveInOpen(&WaveHandle, WAVE_MAPPER, &WaveFormat, 0, 0, CALLBACK_WINDOW);

BufferSize = RecordSeconds * (BitsPerSample / 8) * SamplesPerSecond * Channels;

Buffer = new char[BufferSize];

WaveHeader.dwBufferLength = BufferSize;

WaveHeader.dwFlags = 0;

WaveHeader.lpData = Buffer;

Res = waveInPrepareHeader(WaveHandle, &WaveHeader, sizeof(WAVEHDR));

if (Res) {

cout << "Blad przygotowania naglowka" << endl;

if (Buffer)

delete Buffer;

return;

}

Res = waveInAddBuffer(WaveHandle, &WaveHeader, sizeof(WAVEHDR));

Res = waveInStart(WaveHandle);

if (Res != MMSYSERR_NOERROR){

cout << "Blad nagrywania dzwieku" << endl;

if (Buffer)

delete Buffer;

return;

}

}

//funkcja oddwarzająca nagrany przez //mikrofon dzwięk

void Cperyferyjne_dzwiek_MFCDlg::OnBnClickedButton4()

{

int Res = waveOutOpen(&WaveOUTHandle, WAVE_MAPPER, &WaveFormat, 0, 0, WAVE_FORMAT_QUERY);

if (Res == WAVERR_BADFORMAT)

return;

Res = waveOutOpen(&WaveOUTHandle, WAVE_MAPPER, &WaveFormat, 0, 0, CALLBACK_WINDOW);

waveOutPrepareHeader(WaveOUTHandle, &WaveHeader, sizeof(WAVEHDR));

waveOutWrite(WaveOUTHandle, &WaveHeader, sizeof(WAVEHDR));

}

Podsumowanie

Dzięki temu ćwiczeniu dowiedzieliśmy się jak łatwo zaimplementować odtwarzanie i nagrywanie plików dźwiękowych w C++. Polega to w dużej mierze na operacjach na gotowych już funkcjach ( np. PlaySound() ).

Źródła:

http://www.kartydzwiekowe.republika.pl/pliki/wave1/wave2.htm

http://msdn.microsoft.com/en-us/library/windows/desktop/dd743680(v=vs.85).aspx


Wyszukiwarka

Podobne podstrony:
Rozwiązywanie problemów z kartą dźwiękową, windows XP i vista help
karta dzwiekowa
utk cw 3 4 karta dzwiekowa teoria
karta dźwiękowa
Karta dźwiękowa
Karta dźwiękowa
Karta dzwiękowa USB Schemat
Karta Dzwiękowa, S
Karta dźwiękowa
karta dźwiękowa
Karta dzwiękowa USB, Schemat
Karta dzwiękowa USB, PCM2705 płytka
Karta Dżwiękowa, Studia, Informatyka, Informatyka, Informatyka
Karta dzwiekowa
karta dźwiękowa 2
utk cw 3 4 karta dzwiekowa teoria
karta dzwiekowa
karta dzwiekowa
karta dźwiękowa schemat

więcej podobnych podstron