การรับ kAUGraphErr_CannotDoInCurrentContext เมื่อเรียก AUGraphStart เพื่อเล่น


113

ฉันกำลังทำงานกับAUGraphและ Audio Units API เพื่อเล่นและบันทึกเสียงในแอป iOS ของฉัน ตอนนี้ฉันมีปัญหาที่หายากเมื่อAUGraphไม่สามารถเริ่มต้นด้วยข้อผิดพลาดต่อไปนี้:

ผลลัพธ์ = kAUGraphErr_CannotDoInCurrentContext (-10863)

เกิดข้อผิดพลาดที่ไม่สามารถคาดเดาได้เมื่อเราพยายามโทรAUGraphStartซึ่งตั้งค่าไว้สำหรับการเล่นเสียง:

(BOOL)startRendering
{
    if (playing) {
        return YES;
    }

    playing = YES;

    if (NO == [self setupAudioForGraph:&au_play_graph playout:YES]) {
        print_error("Failed to create play AUGraph",0);
        playing = NO;
        return NO;
    }

    //result = kAUGraphErr_CannotDoInCurrentContext (-10863)
    OSStatus result = AUGraphStart(au_play_graph);
    if (noErr != result) {
        print_error("AUGraphStart", result);
        playing = NO;
    }

    return playing;
}

สิ่งที่เราได้รับจากเอกสารประกอบมีดังนี้

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

รหัสผลลัพธ์นี้เป็นเพียงสถานะชั่วคราวซึ่งจะส่งต่อทันทีที่เธรดอื่นของคุณเรียก AUGraph (ที่มีการล็อก) เสร็จสิ้น

ในกรณีของฉันฉันเพิ่งเริ่มAUGraphมันใหม่และเพิ่งสร้างขึ้น ฉันจะแก้ไขข้อบกพร่องของเคสได้อย่างไรและอะไรคือปัญหาที่อาจเกิดขึ้นที่นี่


อะไรsetupAudioForGraphทำอย่างไร คุณ AUGraph เริ่มต้นกราฟก่อนหรือไม่?
cvu

6
ใช่ setupAudioForGraph สร้างและเริ่มต้นกราฟ เวลาส่วนใหญ่ทำงานได้ดี ปัญหาที่นี่ในการเข้าถึงแบบขนานหรืออะไรทำนองนั้น หากเพียงแค่เริ่มครั้งเดียวและหยุดเพียงครั้งเดียวทุกอย่างก็ทำงานได้อย่างสมบูรณ์แบบ
Alexey Strakh

1
ฉันจะมองหาวิธีดูว่ามีการล็อก mutex หรือไม่และถ้าเป็นเช่นนั้นให้ดำเนินการต่อในลูปของคุณหากไม่วางไข่ AUGraph
Taylor Belland

คำตอบ:


1

คุณสามารถสร้างบางสิ่งจาก CSS หรือ SQLite นี่คือเหตุผล

OSStatus result = AUGraphStart(au_play_graph);
if (noErr != result) {
    print_error("AUGraphStart", result);
    playing = NO;
}

return playing;

}

พยายามจัดการโค้ดนี้มีปัญหากับบูลีนในโค้ดของคุณ ...

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