वास्तविक समय में MacOS आउटपुट डिवाइस ऑडियो बफ़र्स प्राप्त करें

Dec 14 2020

मैं वर्तमान में चयनित आउटपुट ऑडियो डिवाइस को macOS पर टैप करने की कोशिश कर रहा हूं , इसलिए मेरे पास मूल रूप से श्रोता के माध्यम से एक पास है, जो वर्तमान में आउटपुट को प्रभावित किए बिना ऑडियो स्ट्रीम की निगरानी कर सकता है।

मैं इस डेटा को वास्तविक समय में रिंग बफर पर कॉपी करना चाहता हूं ताकि मैं इस पर अलग से काम कर सकूं।

Apple डॉक्स का संयोजन और (पुराना?) SO उत्तर भ्रमित करने वाले हैं कि क्या मुझे हैकी कर्नेल एक्सटेंशन लिखने की आवश्यकता है, इसके लिए CoreAudio का उपयोग कर सकते हैं, या HAL के साथ इंटरफ़ेस करने की आवश्यकता है?

अगर संभव हो तो मैं स्विफ्ट में काम करना चाहूंगा।

बहुत धन्यवाद

(पी एस। मैं इसे और यह देख रहा था )

जवाब

3 RhythmicFistman Dec 14 2020 at 23:07

मुझे कर्नेल एक्सटेंशन के बारे में नहीं पता है - उनके विशेष "कॉल यूज़" साइनिंग सर्टिफिकेट या एसआईपी बंद करने की आवश्यकता के बारे में पता चलता है।

हालाँकि आप जो चाहते हैं उसे करने के लिए CoreAudio और HAL AudioServer प्लगइन्स के संयोजन का उपयोग कर सकते हैं और आपको स्वयं प्लगइन लिखने की भी आवश्यकता नहीं है, चुनने के लिए कई खुले स्रोत संस्करण हैं।

CoreAudio आपको आउटपुट डिवाइस (या "टैप") से रिकॉर्ड करने का एक तरीका नहीं देता है - आप केवल इनपुट डिवाइस से रिकॉर्ड कर सकते हैं, इसलिए इसे प्राप्त करने का तरीका एक वर्चुअल "डिवाइस (ऑडियोसर्वरप्लगिन) से गुजरना है, न कि किसी भी हार्डवेयर से जुड़ा है, जो आउटपुट को इनपुट के माध्यम से कॉपी करता है और फिर डिवाइस के माध्यम से इस आउटपुट को डिफ़ॉल्ट आउटपुट के रूप में सेट करता है और इसके इनपुट से रिकॉर्ड करता है। मैं इस का उपयोग कर खुला स्रोत AudioServer प्लगइन्स की तरह किया है BackgroundMusic और BlackHole [: ऐड अधिक TODO]।

परिणामी डिवाइस से टैप / रिकॉर्ड करने के लिए आप बस AudioDeviceIOProcइसमें कॉलबैक जोड़ सकते हैं या डिवाइस को ए के रूप में सेट kAudioOutputUnitProperty_CurrentDeviceकर सकते हैंkAudioUnitSubType_HALOutput AudioUnit

डिवाइस के दृष्टिकोण से उपरोक्त वर्चुअल पास के साथ दो समस्याएं हैं:

  1. आप अपने श्रवण आउटपुट को अब और नहीं कर सकते, क्योंकि यह डिवाइस के माध्यम से पास द्वारा खपत किया जा रहा है
  2. डिफ़ॉल्ट आउटपुट डिवाइस को बदलने से आपके डिवाइस से दूर चला जाएगा और नल चुप हो जाएगा।

यदि 1. एक समस्या है, तो एक सरल डिवाइस के माध्यम से पास और एक वास्तविक आउटपुट डिवाइस (स्क्रीनशॉट देखें) के माध्यम से एक मल्टी-आउटपुट डिवाइस बनाना है और इसे डिफ़ॉल्ट आउटपुट डिवाइस के रूप में सेट करना है। वॉल्यूम नियंत्रण काम करना बंद कर देते हैं, लेकिन आप फिर भी वास्तविक आउटपुट डिवाइस का वॉल्यूम बदल सकते हैं Audio MIDI Setup.app

2. के लिए आप डिफ़ॉल्ट आउटपुट डिवाइस के लिए एक श्रोता को जोड़ सकते हैं और इसे बदलने पर मल्टी-आउटपुट डिवाइस को अपडेट कर सकते हैं।

आप उपर्युक्त अधिकांश स्विफ्ट में कर सकते हैं, हालाँकि बफर डिलीवरी कॉलबैक से रिंगबफ़र-स्टोविंग के लिए आपको सी या कुछ अन्य भाषा का उपयोग करना होगा जो रियलटाइम ऑडियो नियमों (कोई लॉक, कोई मेमोरी आवंटन, आदि) का सम्मान नहीं कर सकता है । आप शायद AVAudioEngineटैप करने की कोशिश कर सकते हैं , लेकिन IIRC बदलते इनपुट डिवाइस आँसू की एक घाटी है ।