ฉันจะยกเลิกการผูกและลบบัฟเฟอร์ OpenAL ได้อย่างไร


12

ฉันใช้ OpenAL เพื่อเล่นเสียง ฉันพยายามที่จะใช้ฟังก์ชั่นการเล่นแบบไฟและลืมที่ใช้บัฟเฟอร์ ID และกำหนดให้กับแหล่งที่มาจากพูลที่ฉันได้จัดสรรไว้ก่อนหน้านี้และเล่นมัน อย่างไรก็ตามมีปัญหาเกี่ยวกับอายุการใช้งานของวัตถุ

ใน OpenGL ให้ลบฟังก์ชั่นทั้งยกเลิกการผูกสิ่งต่าง ๆ โดยอัตโนมัติ (เช่นพื้นผิว) หรือลบสิ่งโดยอัตโนมัติเมื่อในที่สุดมันก็ไม่ได้ถูกผูก (เช่นตัวแปลง) และดังนั้นจึงเป็นเรื่องง่ายที่จะจัดการการลบ อย่างไรก็ตามalDeleteBuffersแทนที่จะล้มเหลวAL_INVALID_OPERATIONหากบัฟเฟอร์ยังคงถูกผูกไว้กับแหล่งที่มา

มีวิธีการ "ลบ" บัฟเฟอร์แบบเปิดที่ทำให้พวกเขาเล่นจนจบแล้วยกเลิกการผูกและโดยอัตโนมัติหรือไม่? ฉันจำเป็นต้องผูกการจัดการบัฟเฟอร์อย่างลึกซึ้งยิ่งขึ้นลงในพูลแหล่งที่มาหรือไม่ (เช่นการลบบัฟเฟอร์จำเป็นต้องตรวจสอบแหล่งที่ปันส่วนทั้งหมดด้วย)

ในทำนองเดียวกันมีวิธีใช้สำนวนเพื่อแยกบัฟเฟอร์ (แต่ไม่ลบ) เมื่อเล่นเสร็จหรือไม่ มันจะดีถ้าเมื่อฉันกำลังมองหาแหล่งฟรีฉันเพียงต้องการดูว่าบัฟเฟอร์ถูกแนบเลยและไม่ต้องตรวจสอบสถานะของแหล่งที่มา

(ฉันใช้ C ++ แม้ว่าวิธีการสำหรับ C ก็ใช้ได้เช่นกันวิธีคิดว่าเป็นภาษา GCd และการใช้ finalizers อาจไม่สามารถใช้ได้)

openal 

หากคุณยังต้องการคำตอบฉันใช้วิธีการรวบรวมขยะในเครื่องมือกอร์กอน: sf.net/p/gorgon-ge
Cem Kalyoncu

คำตอบ:


8

ก่อนที่จะลบบัฟเฟอร์คุณต้องยกเลิกการผูกจากแต่ละแหล่งที่ใช้ (เช่น: alSourcei(mSourceId, AL_BUFFER, NULL);หรือลบแหล่งที่มาทั้งหมดซึ่งผูกไว้กับบัฟเฟอร์

คุณจำเป็นต้องติดตามความยาวของแต่ละเสียงของคุณเพื่อปล่อยพวกเขาเมื่อเสร็จสมบูรณ์ คุณสามารถทำได้โดยใช้โครงสร้างสำหรับแต่ละแหล่งที่มาเพื่อรักษาความยาวของเสียงและเวลาที่เล่น (อัปเดตแต่ละเกมติ๊ก) Ex:

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

หากคุณใช้ระบบที่ใช้องค์ประกอบคุณสามารถตรวจสอบแหล่งที่ทำงานอยู่ทั้งหมดเป็นระยะเพื่อให้เสร็จสมบูรณ์และทำการถอนการผูก / แหล่งที่มาที่นั่น

หากคุณไม่ติดตามการเปลี่ยนแปลงการเล่น / หยุดชั่วคราวในรหัสของคุณคุณจะต้องตรวจสอบว่าแหล่งที่มานั้นเล่นอยู่หรือไม่ก่อนที่จะเพิ่มเวลาเล่น

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

หากคุณต้องการติดตามแหล่งที่มาที่ผูกไว้กับบัฟเฟอร์คุณสามารถใช้โครงสร้างที่มี ID ของบัฟเฟอร์ของคุณและเวกเตอร์ที่เชื่อมโยงไปยังโครงสร้างแหล่งที่มาด้วยวิธีนี้คุณสามารถขัดขวางแหล่งที่มาทั้งหมดซึ่งผูกไว้กับบัฟเฟอร์ที่คุณต้องการ โดยเร็วที่สุด Ex:

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

นี่น่าจะเพียงพอแล้วที่จะพาคุณไปในเส้นทางที่ถูกต้อง ฉันไม่สามารถให้รหัสรายละเอียดเพิ่มเติมจากโครงการของฉันได้เพราะพวกเขาพึ่งพามาโครอย่างมากและกลไก RTTI ที่ทำด้วยมือ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.