मुझे OpenAL बफ़र्स को कैसे हटाना और हटाना चाहिए?


12

मैं साउंड्स खेलने के लिए OpenAL का उपयोग कर रहा हूँ। मैं एक आग-और-भूल खेलने के कार्य को लागू करने की कोशिश कर रहा हूं जो एक बफर आईडी लेता है और इसे एक स्रोत से आवंटित करता है जिसे मैंने पहले आवंटित किया है, और इसे खेलता है। हालांकि, वस्तु जीवनकाल के साथ एक समस्या है।

ओपनजीएल में, फ़ंक्शंस को या तो स्वचालित रूप से चीजों को अनबाइंड (जैसे बनावट) हटा दें, या स्वचालित रूप से उस चीज़ को हटा देता है जब वह अंततः अनबाउंड (जैसे शेड्स) होता है और इसलिए आमतौर पर डिलीट को प्रबंधित करना आसान होता है। हालांकि alDeleteBuffersइसके बजाय बस के साथ विफल रहता है AL_INVALID_OPERATIONअगर बफर अभी भी एक स्रोत के लिए बाध्य है।

क्या OpenAL बफ़र्स को "हटाने" का एक मुहावरेदार तरीका है जो उन्हें खेल खत्म करने की अनुमति देता है, और फिर स्वचालित रूप से उन्हें अंधा कर देता है और वास्तव में उन्हें? क्या मुझे बफर प्रबंधन को स्रोत पूल में अधिक गहराई से बाँधने की आवश्यकता है (उदाहरण के लिए एक बफर को हटाने के लिए सभी आवंटित स्रोतों की भी जाँच की आवश्यकता होती है)?

इसी तरह, बफ़र्स को अनबाइंड (लेकिन डिलीट नहीं) करने का एक मुहावरेदार तरीका है जब वे खेल खत्म कर रहे हैं? यह अच्छा होगा यदि, जब मैं एक मुक्त स्रोत की तलाश में था, तो मुझे केवल यह देखने की ज़रूरत थी कि क्या कोई बफर बिल्कुल जुड़ा हुआ है और स्रोत राज्य की जांच करने से परेशान नहीं है।

(मैं सी ++ का उपयोग कर रहा हूं, हालांकि सी के लिए दृष्टिकोण भी ठीक हैं। जीसीडी भाषा को मानने वाले दृष्टिकोण और फाइनल का उपयोग करना संभवतः लागू नहीं होता है।)

openal 

यदि आपको अभी भी उत्तर की आवश्यकता है, तो मैंने Gorgon इंजन में कचरा संग्रहण विधि का उपयोग किया: sf.net/p/gorgon-ge
Cem Kalyoncu

जवाबों:


8

बफ़र को हटाने से पहले आपको इसे उपयोग करने वाले प्रत्येक स्रोत से इसे अनबाइंड करना होगा (उदा: alSourcei(mSourceId, AL_BUFFER, NULL);या बफ़र से बंधे सभी स्रोतों को हटा दें।

पूर्णता पर उन्हें जारी करने के लिए आपको अपनी प्रत्येक आवाज़ की लंबाई पर नज़र रखने की आवश्यकता है। आप ध्वनि की लंबाई और खेले जाने वाले समय (प्रत्येक खेल को अपडेट करते हुए) को बनाए रखने के लिए प्रत्येक स्रोत के लिए एक संरचना का उपयोग करके ऐसा कर सकते हैं। उदाहरण के लिए:

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

यदि आप एक घटक आधारित प्रणाली का उपयोग करते हैं, तो आप समय-समय पर सभी चल रहे स्रोतों को पूरा करने के लिए जाँच कर सकते हैं और वहां अनबाइंड / स्रोत हटा सकते हैं।

यदि आप अपने कोड में खेलने / ठहराव परिवर्तन का ट्रैक नहीं रखते हैं, तो आप यह भी जांचना चाहेंगे कि खेले गए समय को बढ़ाने से पहले स्रोत खेल रहे हैं या नहीं।

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

यदि आप किसी बफ़र से बंधे स्रोतों का ट्रैक रखना चाहते हैं, तो आप अपने बफ़र की आईडी के साथ एक संरचना का उपयोग कर सकते हैं और एक सदिश को सोर्स स्ट्रक्चर्स से जोड़ सकते हैं, इस तरह से आप उन सभी स्रोतों को भी बाधित कर सकते हैं, जो आपको बफ़र के लिए बाध्य हैं। यथाशीघ्र। उदाहरण के लिए:

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

यह आपको सही रास्ते पर लाने के लिए पर्याप्त होना चाहिए। मैं आपको अपनी परियोजनाओं से अधिक विस्तृत कोड नहीं दे सकता क्योंकि वे मैक्रोज़ और हाथ से बनाए गए आरटीटीआई तंत्र पर बहुत अधिक भरोसा करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.