Cara: Memuat File Data Audio di XAudio2
Catatan
Konten ini hanya berlaku untuk aplikasi desktop dan akan memerlukan revisi untuk berfungsi di aplikasi Bursa Windows. Silakan lihat dokumentasi untuk CreateFile2, CreateEventEx, WaitForSingleObjectEx, SetFilePointerEx, dan GetOverlappedResultEx. Lihat SoundFileReader.h/.cpp dalam sampel BasicSound Windows 8 dari Galeri Sampel Windows SDK.
Topik ini menjelaskan langkah-langkah untuk mengisi struktur yang diperlukan untuk memutar data audio di XAudio2. Langkah-langkah berikut memuat potongan 'fmt ' dan 'data' dari file audio, dan menggunakannya untuk mengisi struktur WAVEFORMATEXTENSIBLE dan struktur XAUDIO2_BUFFER .
Bersiap untuk mengurai file audio
File audio yang didukung oleh XAudio2 menggunakan Format File Pertukaran Sumber Daya (RIFF). RIFF dijelaskan dalam gambaran umum Resource Interchange File Format (RIFF ). Data audio dalam file RIFF dimuat dengan menemukan gugus RIFF dan kemudian mengulangi potongan untuk menemukan potongan individual yang terkandung dalam gugus RIFF. Fungsi berikut adalah contoh kode untuk menemukan gugus dan memuat data yang terkandung dalam gugus.
Untuk menemukan gugus dalam file RIFF:
#ifdef _XBOX //Big-Endian #define fourccRIFF 'RIFF' #define fourccDATA 'data' #define fourccFMT 'fmt ' #define fourccWAVE 'WAVE' #define fourccXWMA 'XWMA' #define fourccDPDS 'dpds' #endif #ifndef _XBOX //Little-Endian #define fourccRIFF 'FFIR' #define fourccDATA 'atad' #define fourccFMT ' tmf' #define fourccWAVE 'EVAW' #define fourccXWMA 'AMWX' #define fourccDPDS 'sdpd' #endif HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition) { HRESULT hr = S_OK; if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) ) return HRESULT_FROM_WIN32( GetLastError() ); DWORD dwChunkType; DWORD dwChunkDataSize; DWORD dwRIFFDataSize = 0; DWORD dwFileType; DWORD bytesRead = 0; DWORD dwOffset = 0; while (hr == S_OK) { DWORD dwRead; if( 0 == ReadFile( hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL ) ) hr = HRESULT_FROM_WIN32( GetLastError() ); if( 0 == ReadFile( hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL ) ) hr = HRESULT_FROM_WIN32( GetLastError() ); switch (dwChunkType) { case fourccRIFF: dwRIFFDataSize = dwChunkDataSize; dwChunkDataSize = 4; if( 0 == ReadFile( hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL ) ) hr = HRESULT_FROM_WIN32( GetLastError() ); break; default: if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, dwChunkDataSize, NULL, FILE_CURRENT ) ) return HRESULT_FROM_WIN32( GetLastError() ); } dwOffset += sizeof(DWORD) * 2; if (dwChunkType == fourcc) { dwChunkSize = dwChunkDataSize; dwChunkDataPosition = dwOffset; return S_OK; } dwOffset += dwChunkDataSize; if (bytesRead >= dwRIFFDataSize) return S_FALSE; } return S_OK; }
Untuk membaca data dalam gugus setelah ditemukan.
Setelah gugus yang diinginkan ditemukan, datanya dapat dibaca dengan menyesuaikan penunjuk file ke awal bagian data dari gugus. Fungsi untuk membaca data dari gugus setelah ditemukan mungkin terlihat seperti ini.
HRESULT ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset) { HRESULT hr = S_OK; if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, bufferoffset, NULL, FILE_BEGIN ) ) return HRESULT_FROM_WIN32( GetLastError() ); DWORD dwRead; if( 0 == ReadFile( hFile, buffer, buffersize, &dwRead, NULL ) ) hr = HRESULT_FROM_WIN32( GetLastError() ); return hr; }
Mengisi struktur XAudio2 dengan isi gugus RIFF
Agar XAudio2 dapat memutar audio dengan suara sumber, dibutuhkan struktur WAVEFORMATEX dan struktur XAUDIO2_BUFFER . Struktur WAVEFORMATEX mungkin merupakan struktur yang lebih besar seperti WAVEFORMATEXTENSIBLE yang berisi struktur WAVEFORMATEX sebagai anggota pertamanya. Lihat halaman referensi WAVEFORMATEX untuk informasi selengkapnya.
Dalam contoh ini , WAVEFORMATEXTENSIBLE sedang digunakan untuk memungkinkan pemuatan file audio PCM dengan lebih dari dua saluran.
Langkah-langkah berikut mengilustrasikan menggunakan fungsi yang dijelaskan di atas untuk mengisi struktur WAVEFORMATEXTENSIBLE dan struktur XAUDIO2_BUFFER . Dalam hal ini, file audio yang dimuat berisi data PCM, dan hanya akan berisi gugus 'RIFF', 'fmt ', dan 'data'. Format lain mungkin berisi jenis gugus tambahan seperti yang dijelaskan dalam Format File Pertukaran Sumber Daya (RIFF).
Deklarasikan STRUKTUR WAVEFORMATEXTENSIBLE dan XAUDIO2_BUFFER .
WAVEFORMATEXTENSIBLE wfx = {0}; XAUDIO2_BUFFER buffer = {0};
Buka file audio dengan CreateFile.
#ifdef _XBOX char * strFileName = "game:\\media\\MusicMono.wav"; #else TCHAR * strFileName = _TEXT("media\\MusicMono.wav"); #endif // Open the file HANDLE hFile = CreateFile( strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( INVALID_HANDLE_VALUE == hFile ) return HRESULT_FROM_WIN32( GetLastError() ); if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) ) return HRESULT_FROM_WIN32( GetLastError() );
Temukan gugus 'RIFF' dalam file audio, dan periksa jenis file.
DWORD dwChunkSize; DWORD dwChunkPosition; //check the file type, should be fourccWAVE or 'XWMA' FindChunk(hFile,fourccRIFF,dwChunkSize, dwChunkPosition ); DWORD filetype; ReadChunkData(hFile,&filetype,sizeof(DWORD),dwChunkPosition); if (filetype != fourccWAVE) return S_FALSE;
Temukan potongan 'fmt', dan salin isinya ke dalam struktur WAVEFORMATEXTENSIBLE .
FindChunk(hFile,fourccFMT, dwChunkSize, dwChunkPosition ); ReadChunkData(hFile, &wfx, dwChunkSize, dwChunkPosition );
Temukan gugus 'data', dan baca kontennya ke dalam buffer.
//fill out the audio data buffer with the contents of the fourccDATA chunk FindChunk(hFile,fourccDATA,dwChunkSize, dwChunkPosition ); BYTE * pDataBuffer = new BYTE[dwChunkSize]; ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);
Isi struktur XAUDIO2_BUFFER .
buffer.AudioBytes = dwChunkSize; //size of the audio buffer in bytes buffer.pAudioData = pDataBuffer; //buffer containing audio data buffer.Flags = XAUDIO2_END_OF_STREAM; // tell the source voice not to expect any data after this buffer
Topik terkait
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk