2011-01-31 18 views
19

के साथ एक रेखा खींचने के लिए कुशल विधि मैं ज़ूम विकल्पों की विस्तृत श्रृंखला के साथ कोको में एक ऑडियो वेवफ़ॉर्म संपादक लिख रहा हूं। इसकी व्यापकता में, यह एक संपूर्ण गीत (~ 10 मिलियन नमूने देखने के लिए) के लिए एक तरंग दिखाता है। इसकी सबसे कम दूरी पर, यह ध्वनि तरंग (एक दृश्य में ~ 1 हजार नमूने) का एक पिक्सेल सटीक प्रतिनिधित्व दिखाता है। मैं इन ज़ूम स्तरों के बीच आसानी से संक्रमण करने में सक्षम होना चाहता हूं। ऐसा लगता है कि एबलेटन लाइव जैसे कुछ वाणिज्यिक संपादक इसे एक बहुत ही सस्ती फैशन में करते हैं।लाखों अंक

मेरा वर्तमान कार्यान्वयन मेरी वांछित ज़ूम रेंज को संतुष्ट करता है, लेकिन अक्षम और चंचल है। डिजाइन काफी हद तक क्वार्ट्ज साथ waveforms ड्राइंग पर इस उत्कृष्ट लेख से प्रेरित:

http://supermegaultragroovy.com/blog/2009/10/06/drawing-waveforms/

मैं कई CGMutablePathRef कमी के विभिन्न स्तरों पर ऑडियो फ़ाइल के लिए के पैदा करते हैं। जब मैं सभी तरह से ज़ूम आउट करता हूं, तो मैं उस पथ का उपयोग करता हूं जो प्रति x-हजार नमूने एक बिंदु तक कम हो गया है। जब मैं सभी तरह से ज़ूम किया जाता हूं, तो मैं उस पथ का उपयोग करता हूं जिसमें प्रत्येक नमूने के लिए एक बिंदु होता है। जब मैं कमी स्तर के बीच में हूं तो मैं क्षैतिज पथ को स्केल करता हूं। यह कार्यात्मक हो जाता है, लेकिन अभी भी काफी महंगा है और कलाकृतियों में कमी आती है जब कमी स्तर के बीच संक्रमण होता है।

एक विचार यह है कि मैं इसे कम महंगा कैसे बना सकता हूं एंटी-एलियासिंग करना है। मेरे संपादक में तरंग एंटी-एलाइज्ड है जबकि एबलेटन में कोई नहीं है (नीचे तुलना देखें)। enter image description here enter image description here

मैं एक तरह से CGMutablePathRef के लिए विरोधी aliasing बंद करने के लिए नहीं दिख रहा। क्या कोको की दुनिया में CGMutablePathRef के लिए एक गैर-एंटी-एलाइज्ड विकल्प है? यदि नहीं, तो क्या किसी को कुछ ओपनजीएल कक्षाओं या नमूना कोड के बारे में पता है जो मुझे मेरी विशाल रेखा को और अधिक कुशलता से आकर्षित करने के लिए निश्चित रूप से सेट कर सकता है?

अद्यतन 2014/01/21: अब है कि वास्तव में करता है एक महान पुस्तकालय मैं के लिए क्या देख रहा था: https://github.com/syedhali/EZAudio

उत्तर

6

मैं अपने अनुप्रयोग में CGContextMoveToPoint + CGContextAddLineToPoint + CGContextStrokePath का उपयोग करें। ओवरव्यू के लिए पूर्व-गणना बैकिंग बफर का उपयोग करके ड्रॉ करने के लिए एक बिंदु प्रति ऑनस्क्रीन पॉइंट। बफर में ड्रॉ करने के लिए सटीक बिंदु होते हैं, और संकेत के एक इंटरप्लाटेड प्रतिनिधित्व (ज़ूम/स्केल के आधार पर) का उपयोग करते हैं। हालांकि यह तेजी से हो सकता है और अगर मैं एक छवि बफर को प्रस्तुत करता हूं तो बेहतर दिखता हूं, मुझे कभी शिकायत नहीं हुई है। यदि आप इसे सही तरीके से सेट करते हैं, तो आप इसे माध्यमिक थ्रेड से कैल्क और प्रस्तुत कर सकते हैं।

एंटी-एलियासिंग ग्राफिक्स संदर्भ से संबंधित है।

CGFloat (CGPaths के लिए मूल इनपुट) एक ओवरव्यू के लिए ओवरकिल है, एक मध्यवर्ती प्रतिनिधित्व के रूप में, और तरंगों के अवलोकन की गणना के लिए। 16 बिट पर्याप्त होना चाहिए। बेशक, सीजी कॉल में जाने पर आपको CGFloat में कनवर्ट करना होगा।

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

सेमी-ओटी: एस + एच मानों का उपयोग करने में सक्षम है यह थोड़ा तेज हो सकता है लेकिन ... मैं इसे एक विकल्प के रूप में पसंद करता हूं। यदि आपका कार्यान्वयन रैखिक इंटरपोलेशन (जो इसकी उपस्थिति के आधार पर हो सकता है) का उपयोग करता है, तो अधिक सहज दृष्टिकोण पर विचार करें। रैखिक इंटरपोलेशन एक धोखाधड़ी का एक सा है, और वास्तव में नहीं, यदि उपयोगकर्ता एक प्रो ऐप विकसित कर रहे हैं तो उपयोगकर्ता अपेक्षा करेगा।

+0

विस्तृत प्रतिक्रिया के लिए धन्यवाद! लगता है जैसे आप यहां भी रहे हैं। दरअसल मैं तरंगों को अधिक बार खींच रहा हूं जितना मुझे चाहिए। मैं ओवरले के साथ एक पूर्ण पुनः ड्रॉ को प्रतिस्थापित करने पर विचार करूंगा। एस + एच मूल्यों का उपयोग करते हुए एबलेटन के बारे में, वे क्या हैं? आप यह मानने के लिए सही हैं कि मेरा कार्यान्वयन रैखिक इंटरपोलेशन का उपयोग करता है। ऐसा लगता है कि एबलेटन की स्क्वायर लाइनें आकर्षित करने के लिए और अधिक कुशल हो सकती हैं, लेकिन यह सुनिश्चित नहीं है कि मैं ऐसा करने के बारे में कैसे जाऊंगा। – tassock

+0

@ टासॉक आपका स्वागत है। 'एस + एच' से, मेरा मतलब सिग्नल के 'नमूना और पकड़' मान था। यह केवल वेवफ़ॉर्म चरणों को खींचता है जैसा कि वे समय डोमेन में दर्शाए जाते हैं। सिग्नल के प्रतिनिधित्व को इंटरपोलेट और निर्माण करने के लिए यह बेहतर है (आईएमओ)। एस + एच ठीक है, लेकिन यह एक विकल्प होना चाहिए, एक इंटरपोलेटेड प्रतिनिधित्व डिफ़ॉल्ट के रूप में। जब मैं इंटरपोलेशन कहता हूं, तो मैं ऐसे दृष्टिकोण का जिक्र कर रहा हूं जो एस + एच या रैखिक इंटरपोलेशन की तुलना में एनालॉग सिग्नल का अधिक प्रतिनिधि है। इसके लिए, शायद यह आवश्यक है कि आप सटीकता के साथ प्रदर्शन को संतुलित करें। एक sinc अच्छा होगा, (cont) – justin

+0

लेकिन आप शायद उच्च ऑर्डर स्पलीन (एक उदाहरण के रूप में) से दूर हो सकते हैं। वेवफॉर्म को इंटरपोलेटिंग/पुनर्निर्माण सही ढंग से आपके वर्तमान कार्यान्वयन में बहुत सी सीपीयू जोड़ सकता है। – justin

2

विरोधी aliasing की खास सवाल के संबंध में। क्वार्ट्ज में एंटी-एलाइजिंग ड्राइंग के पल में संदर्भ पर लागू होती है। CGPathRef ड्राइंग संदर्भ के लिए अज्ञेयवादी है। इस प्रकार, एक ही CGPathRef को एंटीअलाइज्ड संदर्भ में या गैर-एंटीअलाइज्ड संदर्भ में प्रस्तुत किया जा सकता है। उदाहरण के लिए एनिमेशन के दौरान एंटीलायज़िंग़ निष्क्रिय करने के लिए:

CGContextRef context = UIGraphicsGetCurrentContext(); 
GMutablePathRef fill_path = CGPathCreateMutable(); 
// Fill the path with the wave 
... 

CGContextAddPath(context, fill_path); 
if ([self animating]) 
    CGContextSetAllowsAntialiasing(context, NO); 
else 
    CGContextSetAllowsAntialiasing(context, YES); 
// Do the drawing 
CGContextDrawPath(context, kCGPathStroke); 
+0

आह, संदर्भ एंटी-एलियासिंग सेटिंग को इंगित करने के लिए धन्यवाद। दुर्भाग्यवश, ऐसा लगता है कि यह एक महत्वपूर्ण प्रदर्शन वृद्धि का कारण नहीं है। स्पष्ट रूप से मेरे वर्तमान कार्यान्वयन में मेरे पास कई अन्य अक्षम प्रक्रियाएं हैं। – tassock