2010-04-07 18 views
11

पर पीसीएम डेटा चलाने के लिए ऑडियो कतार सेवाओं का उपयोग करना मैं आईफोन के लिए एक दूरस्थ डेस्कटॉप क्लाइंट लिख रहा हूं और मैं ऑडियो पुनर्निर्देशन को लागू करने की कोशिश कर रहा हूं।
क्लाइंट सॉकेट कनेक्शन पर सर्वर से कनेक्ट है, और सर्वर एक समय में पीसीएम डेटा के 32K भाग भेजता है।सॉकेट कनेक्शन

मैं डेटा खेलने के लिए एक्यूएस का उपयोग करने की कोशिश कर रहा हूं और यह पहले दो सेकंड (1 बफर लायक) खेलता है। हालांकि, चूंकि डेटा का अगला हिस्सा अभी तक सॉकेट में नहीं आया है, तो अगला ऑडियो क्यूई बफर खाली है। जब डेटा आता है, तो मैं डेटा के साथ अगले उपलब्ध बफर भरता हूं और इसे ऑडियो क्यूईएन्यूक्यूफफर के साथ संलग्न करता हूं। हालांकि, यह कभी भी इन बफर को नहीं चलाता है।

क्या कतार में कोई बफर नहीं होने पर कतार खेलना बंद कर देता है, भले ही आप बाद में बफर जोड़ते हैं?

यहाँ कोड के प्रासंगिक हिस्सा है:

void 
wave_out_write(STREAM s, uint16 tick, uint8 index) 
{ 

    if(items_in_queue == NUM_BUFFERS){ 
     return; 
    } 
    if(!playState.busy){ 
     OSStatus status; 
     status = AudioQueueNewOutput(&playState.dataFormat, AudioOutputCallback, &playState, CFRunLoopGetCurrent(), NULL, 0, &playState.queue); 

     if(status == 0){ 
      for(int i=0; i<NUM_BUFFERS; i++){ 
       AudioQueueAllocateBuffer(playState.queue, 40000, &playState.buffers[i]); 

      } 
      AudioQueueAddPropertyListener(playState.queue, kAudioQueueProperty_IsRunning, MyAudioQueuePropertyListenerProc, &playState); 

      status = AudioQueueStart(playState.queue, NULL); 
      if(status ==0){ 
       playState.busy = True; 
      } 
      else{ 
       return; 
      } 
     } 
     else{ 
      return; 
     } 
    } 
    playState.buffers[queue_hi]->mAudioDataByteSize = s->size; 

    memcpy(playState.buffers[queue_hi]->mAudioData, s->data, s->size); 

    AudioQueueEnqueueBuffer(playState.queue, playState.buffers[queue_hi], 0, 0); 
    queue_hi++; 
    queue_hi = queue_hi % NUM_BUFFERS; 
    items_in_queue++; 
} 


void AudioOutputCallback(void* inUserData, AudioQueueRef outAQ, AudioQueueBufferRef outBuffer) 
{ 
    PlayState *playState = (PlayState *)inUserData; 
    items_in_queue--; 
} 

धन्यवाद!

उत्तर

0

आम तौर पर, जब परिपत्र ऑडियो बफ़र्स उपयोग कर, आप बफ़र्स underrunning से रोकने चाहिए। यदि आपके पास आवश्यक डेटा (उदा। नेटवर्क की भीड़ के कारण) की कमी है, तो अपने ऑडियो डेटा को चुप्पी के साथ पैड करने या ऑडियो प्लेबैक को रोकने का प्रयास करें।

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

+3

आपको चुप्पी के साथ कुछ भी पैड नहीं करना है। यदि आपके कॉलबैक को कॉल करते समय कतार में वापस रखने के लिए आपके पास कोई डेटा नहीं है, तो बस वहां कोई डेटा न डालें। यदि आपकी कतार डेटा से बाहर हो जाती है, तो यह तब तक मौन बजाएगी जब तक कि आप डेटा को फिर से न दबाएं। यदि सभी बफर कतार से बाहर हैं, तो आपके कॉलबैक को फिर से नहीं कहा जाता है, लेकिन आप अभी भी किसी अन्य फ़ंक्शन से कतार में डेटा को एनक्यू कर सकते हैं जो कॉलबैक नहीं है (जैसे ही डेटा फिर से आ गया है)। यह पोस्टर की समस्या नहीं है। उनकी समस्या यह है कि उनके साथ शुरू करने के लिए कतार में केवल एक बफर है। आपको कम से कम 2. – Mecki

+0

धन्यवाद मेकी, मेरे पास एक समान समस्या है, और भले ही समाधान अभी तक लिखा नहीं गया है, कम से कम यह बिंदु सही दिशा में है ... – Nick

1

CoreAudio की ऑडियो क्यूइंग सेवाओं का उपयोग करके यह सुनिश्चित करके बहुत सरलता से यह सुनिश्चित किया जाता है कि जब भी प्लेबैक समाप्त हो जाता है तो कॉलबैक में ऐसा करने से आप प्रत्येक बफर को फिर से कतारबद्ध कर सकते हैं। ऑडियो डेटा को एक अलग सर्कुलर बफर में बैठना चाहिए क्योंकि यह नेटवर्क से प्राप्त होता है ताकि नेटवर्क और ऑडियो कोड सीधे युग्मित न हों।

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

0

मुझे यह बेवकूफ लगता है कि मैं जवाब पोस्ट कर सकता हूं लेकिन यहां पर्याप्त टिप्पणियां नहीं हैं, तो यहां टिप्पणियां नहीं हैं। मैं सिर्फ निम्नलिखित जवाब देने के लिए जोड़ना चाहते थे:

"यह हो सकता है कि एक बार अपने बफर श्रृंखला underruns, आप प्लेबैक फिर से शुरू करनी मैं वास्तव में AudioQueue बफर कभी नहीं underrunned है, लेकिन मैं Win32 प्रोग्रामिंग से याद रखें कि यह किया गया था। मामला, तो अगर मैं गलत हूं तो कृपया मुझे सही करने के लिए स्वतंत्र महसूस करें। "

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

यह सिर्फ मेरा अवलोकन है, और मैंने अभी तक बहुत कुछ नहीं सोचा है कि मैं इस व्यवहार को क्यों देख रहा हूं। हो सकता है कि यह नमूना गिनती से मेल खाने के लिए नमूनों को फेंक देता है ऑडियोक्यूयू सोचता है कि इस समय यह खेलना चाहिए - यह भूख के दौरान खो गया है? मेरा ऑडियो प्लेयर गाना बजाने लगता है जब तक वह उस बिंदु तक पहुंच न जाए जो वह फिर से खेलना चाहता है।

संपादित करें: जब तक आप प्रत्येक कॉलबैक के लिए एक नया बफर पोस्ट करते हैं, आपको कभी भी खेल या कुछ भी पुनरारंभ करने की आवश्यकता नहीं होगी। मेरे खिलाड़ी में, यदि मैं बफर को संसाधित नहीं कर रहा हूं, तो अगला बफर 'वापस बुलाया जाता है', उस बफर के लिए थ्रेड को तब तक अवरुद्ध कर दिया जाएगा जब तक कि पहला बफर भर नहीं जाता है। यह एनएसएलॉक के साथ किया जाता है। जब मेरा प्लेयर अभी तक 24 बिट एफएलएसी नहीं समझता है तो सिंक खोने पर ऑडियोक्यूज़ गंभीर रूप से भूखा होता है। एनएसएलॉक भी किसी भी दौड़ की स्थिति को रोकता है जब ऑडियोक्यूयू आपको भरने के लिए अधिक बफर देता है। मैं कम विलंबता के साथ 3 बफर का उपयोग करता हूं। बहुत कम विलंबता पूर्ण चुप्पी देता है, इसलिए आपको अपने सिस्टम के लिए 'अच्छा आकार' ढूंढना होगा।