Tôi nên hủy liên kết và xóa bộ đệm OpenAL như thế nào?


12

Tôi đang sử dụng OpenAL để phát âm thanh. Tôi đang cố gắng thực hiện một chức năng chơi lửa và quên lấy ID bộ đệm và gán nó cho một nguồn từ một nhóm mà tôi đã phân bổ trước đó và chơi nó. Tuy nhiên, có một vấn đề với tuổi thọ đối tượng.

Trong OpenGL, xóa các chức năng tự động hủy liên kết mọi thứ (ví dụ như kết cấu) hoặc tự động xóa nội dung khi cuối cùng không bị ràng buộc (ví dụ: trình đổ bóng) và do đó thường dễ quản lý việc xóa. Tuy nhiên, alDeleteBuffersthay vào đó chỉ đơn giản là thất bại với AL_INVALID_OPERATIONnếu bộ đệm vẫn bị ràng buộc với một nguồn.

Có một cách thành ngữ để "xóa" bộ đệm OpenAL cho phép họ chơi xong, sau đó tự động hủy liên kết và thực sự chúng? Tôi có cần buộc quản lý bộ đệm sâu hơn vào nhóm nguồn không (ví dụ: xóa bộ đệm yêu cầu kiểm tra tất cả các nguồn được phân bổ)?

Tương tự, có một cách thành ngữ để hủy liên kết (nhưng không xóa) bộ đệm khi chúng chơi xong? Sẽ thật tuyệt nếu, khi tôi đang tìm kiếm một nguồn miễn phí, tôi chỉ cần xem liệu bộ đệm có được đính kèm hay không và không cần kiểm tra trạng thái nguồn.

(Tôi đang sử dụng C ++, mặc dù các cách tiếp cận cho C cũng tốt. Cách tiếp cận giả sử ngôn ngữ GCd và sử dụng công cụ hoàn thiện có thể không áp dụng được.)

openal 

Nếu bạn vẫn cần câu trả lời, tôi đã sử dụng phương pháp thu gom rác trong công cụ Gorgon: sf.net/p/gorgon-ge
Cem Kalyoncu

Câu trả lời:


8

Trước khi xóa bộ đệm, bạn phải hủy liên kết nó khỏi từng nguồn sử dụng nó (ví dụ: alSourcei(mSourceId, AL_BUFFER, NULL);hoặc xóa tất cả các nguồn được liên kết với bộ đệm.

Bạn cần theo dõi độ dài của từng âm thanh để phát hành chúng khi hoàn thành. Bạn có thể làm điều này bằng cách sử dụng cấu trúc cho từng nguồn để giữ độ dài âm thanh và thời gian phát (cập nhật từng dấu tích trò chơi). Ví dụ:

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

Nếu bạn sử dụng một hệ thống dựa trên thành phần, bạn có thể kiểm tra định kỳ tất cả các nguồn đang chạy để hoàn thành và xóa unbind / source ở đó.

Nếu bạn không theo dõi các thay đổi phát / tạm dừng trong mã của mình, bạn cũng sẽ muốn kiểm tra xem các nguồn đang phát trước khi tăng thời gian phát.

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

Nếu bạn muốn theo dõi các nguồn bị ràng buộc vào bộ đệm, bạn có thể sử dụng cấu trúc với id của bộ đệm và vectơ liên kết với cấu trúc nguồn theo cách này, thậm chí bạn có thể làm gián đoạn tất cả các nguồn được liên kết với bộ đệm mà bạn cần giải phóng CÀNG SỚM CÀNG TỐT. Ví dụ:

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

Điều này là đủ để giúp bạn đi đúng hướng. Tôi không thể cung cấp cho bạn mã chi tiết hơn từ các dự án của tôi vì chúng chủ yếu dựa vào các macro và các cơ chế RTTI được làm bằng tay.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.