Bagaimana saya harus melepaskan ikatan dan menghapus buffer OpenAL?


12

Saya menggunakan OpenAL untuk memutar suara. Saya mencoba menerapkan fungsi putar api dan lupa yang mengambil ID penyangga dan menetapkannya ke sumber dari kumpulan yang sebelumnya saya alokasikan, dan memutarnya. Namun, ada masalah dengan masa hidup objek.

Di OpenGL, hapus fungsi baik secara otomatis melepaskan ikatan hal-hal (misalnya tekstur), atau secara otomatis menghapus hal ketika akhirnya tidak terikat (mis. Shader) dan biasanya mudah untuk mengelola penghapusan. Namun alDeleteBuffersjustru gagal dengan AL_INVALID_OPERATIONjika buffer masih terikat ke sumber.

Apakah ada cara idiomatis untuk "menghapus" buffer OpenAL yang memungkinkan mereka untuk selesai bermain, dan kemudian secara otomatis melepaskan ikatan dan benar-benar mereka? Apakah saya perlu mengikat manajemen buffer lebih dalam ke dalam kumpulan sumber (misalnya menghapus buffer memerlukan memeriksa semua sumber yang dialokasikan juga)?

Demikian pula, adakah cara idiomatis untuk melepaskan ikatan (tetapi tidak menghapus) buffer ketika mereka selesai bermain? Akan lebih baik jika, ketika saya sedang mencari sumber gratis, saya hanya perlu melihat apakah buffer terpasang sama sekali dan tidak repot-repot memeriksa status sumber.

(Saya menggunakan C ++, meskipun pendekatan untuk C juga baik-baik saja. Pendekatan dengan asumsi bahasa GCd dan menggunakan finalizer mungkin tidak berlaku.)

openal 

Jika Anda masih membutuhkan jawaban, saya menggunakan metode pengumpulan sampah di mesin Gorgon: sf.net/p/gorgon-ge
Cem Kalyoncu

Jawaban:


8

Sebelum menghapus buffer, Anda harus melepaskannya dari setiap sumber yang menggunakannya (mis: alSourcei(mSourceId, AL_BUFFER, NULL);atau menghapus semua sumber yang terikat ke buffer.

Anda harus melacak panjang setiap suara Anda untuk melepaskannya setelah selesai. Anda dapat melakukan ini menggunakan struktur untuk setiap sumber untuk menjaga panjang suara dan waktu bermain (diperbarui setiap centang game). Ex:

struct AudioVoice
{
    ALuint          mSourceId;
    ALuint          mMsDuration;
    ALuint          mMsPlayed;
};

Jika Anda menggunakan sistem berbasis komponen, Anda dapat secara berkala memeriksa semua sumber yang sedang berjalan untuk menyelesaikan dan menghapus / mengikat sumber di sana.

Jika Anda tidak melacak perubahan play / pause dalam kode Anda, Anda juga akan ingin memeriksa apakah sumber diputar sebelum menambah waktu bermain.

ALint sourceState;
alGetSourcei(mSourceId, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_PLAYING) { /* increase played time */  }

Jika Anda ingin melacak sumber terikat ke buffer, Anda dapat menggunakan struktur dengan id buffer Anda dan vektor yang menghubungkan ke struktur sumber dengan cara ini Anda bahkan dapat mengganggu semua sumber yang terikat ke buffer yang Anda perlu lepaskan SECEPAT MUNGKIN. Ex:

struct AudioData
{
    RKuint                      mMsDuration;
    ALuint                      mSourceId;
    std::vector<AudioVoice*>    mVoices;
};

Ini seharusnya cukup untuk membuat Anda berada di jalur yang benar. Saya tidak bisa memberikan kode yang lebih rinci dari proyek saya karena sangat bergantung pada makro dan mekanisme RTTI buatan tangan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.