2012-06-14 13 views
7

मुझे एक ओएसएक्स ऐप मिला है जो ऑडियो यूनिट का उपयोग करके ऑडियो डेटा रिकॉर्ड करता है। ऑडियो यूनिट का इनपुट अंतर्निहित इनपुट सहित इनपुट के साथ किसी भी उपलब्ध स्रोत पर सेट किया जा सकता है। समस्या यह है कि, अंतर्निहित इनपुट से प्राप्त ऑडियो को अक्सर क्लिप किया जाता है, जबकि ऑडैसिटी (या यहां तक ​​कि क्विकटाइम) जैसे प्रोग्राम में मैं इनपुट स्तर को बंद कर सकता हूं और मुझे क्लिपिंग नहीं मिलती है।अंतर्निहित इनपुट (ओएसएक्स कोर ऑडियो/ऑडियो यूनिट) पर इनपुट स्तर (लाभ) कैसे सेट करते हैं?

निश्चित रूप से नमूना फ्रेम को गुणा करके, काम नहीं करता है, क्योंकि मुझे कम मात्रा मिलती है, लेकिन नमूने स्वयं इनपुट के समय भी फिसल जाते हैं।

क्लिपिंग समस्या से बचने के लिए मैं उस अंतर्निहित इनपुट के लिए इनपुट स्तर या लाभ कैसे सेट करूं?

उत्तर

10

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

ओह, और मैं निश्चित रूप से इंगित करूंगा कि मैं प्राप्त होने वाले पते पर मूल्यों पर भरोसा नहीं करता क्योंकि मैं यहां कर रहा हूं। ऐसा लगता है कि यह काम करता प्रतीत होता है लेकिन जब आप किसी फ़ंक्शन के संदर्भ में एक पास करते हैं तो संरचना मूल्यों पर भरोसा करना निश्चित रूप से खराब अभ्यास होता है। यह निश्चित रूप से नमूना कोड है इसलिए कृपया मेरी आलस्य क्षमा करें। ;) अपने सवाल के जवाब में

// 
// main.c 
// testInputVolumeSetter 
// 

#include <CoreFoundation/CoreFoundation.h> 
#include <CoreAudio/CoreAudio.h> 

OSStatus setDefaultInputDeviceVolume(Float32 toVolume); 

int main(int argc, const char * argv[]) { 
    OSStatus      err; 

    // Load the Sound system preference, select a default 
    // input device, set its volume to max. Now set 
    // breakpoints at each of these lines. As you step over 
    // them you'll see the input volume change in the Sound 
    // preference panel. 
    // 
    // On my MacBook Pro setting the channel[ 1 ] volume 
    // on the default microphone input device seems to do 
    // the trick. channel[ 0 ] reports that it works but 
    // seems to have no effect and the master channel is 
    // unsettable. 
    // 
    // I do not know how to tell which one will work so 
    // probably the best thing to do is write your code 
    // to call getProperty after you call setProperty to 
    // determine which channel(s) work. 
    err = setDefaultInputDeviceVolume(0.0); 
    err = setDefaultInputDeviceVolume(0.5); 
    err = setDefaultInputDeviceVolume(1.0); 
} 

// 0.0 == no volume, 1.0 == max volume 
OSStatus setDefaultInputDeviceVolume(Float32 toVolume) { 
    AudioObjectPropertyAddress  address; 
    AudioDeviceID     deviceID; 
    OSStatus      err; 
    UInt32       size; 
    UInt32       channels[ 2 ]; 
    Float32       volume; 

    // get the default input device id 
    address.mSelector = kAudioHardwarePropertyDefaultInputDevice; 
    address.mScope = kAudioObjectPropertyScopeGlobal; 
    address.mElement = kAudioObjectPropertyElementMaster; 

    size = sizeof(deviceID); 
    err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &address, 0, nil, &size, &deviceID); 

    // get the input device stereo channels 
    if (! err) { 
     address.mSelector = kAudioDevicePropertyPreferredChannelsForStereo; 
     address.mScope = kAudioDevicePropertyScopeInput; 
     address.mElement = kAudioObjectPropertyElementWildcard; 
     size = sizeof(channels); 
     err = AudioObjectGetPropertyData(deviceID, &address, 0, nil, &size, &channels); 
    } 

    // run some tests to see what channels might respond to volume changes 
    if (! err) { 
     Boolean      hasProperty; 

     address.mSelector = kAudioDevicePropertyVolumeScalar; 
     address.mScope = kAudioDevicePropertyScopeInput; 

     // On my MacBook Pro using the default microphone input: 

     address.mElement = kAudioObjectPropertyElementMaster; 
     // returns false, no VolumeScalar property for the master channel 
     hasProperty = AudioObjectHasProperty(deviceID, &address); 

     address.mElement = channels[ 0 ]; 
     // returns true, channel 0 has a VolumeScalar property 
     hasProperty = AudioObjectHasProperty(deviceID, &address); 

     address.mElement = channels[ 1 ]; 
     // returns true, channel 1 has a VolumeScalar property 
     hasProperty = AudioObjectHasProperty(deviceID, &address); 
    } 

    // try to get the input volume 
    if (! err) { 
     address.mSelector = kAudioDevicePropertyVolumeScalar; 
     address.mScope = kAudioDevicePropertyScopeInput; 

     size = sizeof(volume); 
     address.mElement = kAudioObjectPropertyElementMaster; 
     // returns an error which we expect since it reported not having the property 
     err = AudioObjectGetPropertyData(deviceID, &address, 0, nil, &size, &volume); 

     size = sizeof(volume); 
     address.mElement = channels[ 0 ]; 
     // returns noErr, but says the volume is always zero (weird) 
     err = AudioObjectGetPropertyData(deviceID, &address, 0, nil, &size, &volume); 

     size = sizeof(volume); 
     address.mElement = channels[ 1 ]; 
     // returns noErr, but returns the correct volume! 
     err = AudioObjectGetPropertyData(deviceID, &address, 0, nil, &size, &volume); 
    } 

    // try to set the input volume 
    if (! err) { 
     address.mSelector = kAudioDevicePropertyVolumeScalar; 
     address.mScope = kAudioDevicePropertyScopeInput; 

     size = sizeof(volume); 

     if (toVolume < 0.0) volume = 0.0; 
     else if (toVolume > 1.0) volume = 1.0; 
     else volume = toVolume; 

     address.mElement = kAudioObjectPropertyElementMaster; 
     // returns an error which we expect since it reported not having the property 
     err = AudioObjectSetPropertyData(deviceID, &address, 0, nil, size, &volume); 

     address.mElement = channels[ 0 ]; 
     // returns noErr, but doesn't affect my input gain 
     err = AudioObjectSetPropertyData(deviceID, &address, 0, nil, size, &volume); 

     address.mElement = channels[ 1 ]; 
     // success! correctly sets the input device volume. 
     err = AudioObjectSetPropertyData(deviceID, &address, 0, nil, size, &volume); 
    } 

    return err; 
} 

संपादित करें, "कैसे [मैं] आंकड़ा इस बाहर?"

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

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

प्रक्रिया के लिहाज से हो सकता है आप इस उपयोगी मानते हैं:

एक बार मुझे पता था कि यह एक सीधा जवाब मैं के बारे में कैसे समस्या को हल करने में सोचना शुरू नहीं था। मुझे पता था कि ध्वनि प्रणाली पसंद आप इनपुट लाभ सेट तो मैं otool साथ यह वियोजन द्वारा शुरू किया देखने के लिए कि एप्पल पुराने या नए ऑडियो उपकरण बॉक्स दिनचर्या के उपयोग (नई के रूप में यह होता है) कर रहा था कर सकते हैं:

उपयोग करके देखें:

otool -tV /System/Library/PreferencePanes/Sound.prefPane/Contents/MacOS/Sound | bbedit

तो Audio के लिए खोज को देखने के लिए क्या पद्धतियों को बुलाया जाता है (यदि आप bbedit की जरूरत नहीं है, जो हर मैक डेवलपर चाहिए IMO, यह एक फ़ाइल और कुछ अन्य पाठ संपादक में खुला करने के लिए डंप)।

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

एक बार जब मैं उस बिंदु पर पहुंच गया तो मैं कोशिश की गई और सत्य पर वापस गिर गया: उन कीवर्ड के लिए गुगलिंग शुरू करें जो शामिल होने की संभावना थी (उदा। AudioObjectSetPropertyData, kAudioDevicePropertyVolumeScalar, आदि) उदाहरण के उपयोग की तलाश में।

एक दिलचस्प बात यह है कि मैं CoreAudio के बारे में मिल गया है और सामान्य रूप में एप्पल उपकरण बॉक्स का उपयोग कर लिया है मुक्त स्रोत कोड की एक बहुत बाहर वहाँ है जहाँ लोगों को विभिन्न चीजों (pastebins की टन और GoogleCode परियोजनाओं आदि) की कोशिश है कि वहाँ है । यदि आप इस कोड के समूह के माध्यम से खोदने के इच्छुक हैं, तो आप आम तौर पर या तो जवाब सीधे प्राप्त करेंगे या कुछ अच्छे विचार प्राप्त करेंगे।

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

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

जब आप ऐप्पल की अत्याधुनिक तकनीकों से निपटना शुरू करते हैं तो यह लगातार होता है। आप अपने टूलबॉक्स के साथ अद्भुत चीजें कर सकते हैं और यह पानी से बाहर काम करने वाले हर दूसरे ओएस को उड़ाता है लेकिन उनके दस्तावेज से आगे निकलने में बहुत लंबा समय नहीं लगता है, खासकर यदि आप कुछ भी परिष्कृत करने की कोशिश कर रहे हैं।

यदि आप कभी भी कर्नेल ड्राइवर लिखने का निर्णय लेते हैं तो उदाहरण के लिए आपको IOKit पर दस्तावेज़ीकरण अपर्याप्त होने के लिए मिलेगा। आखिरकार आपको ऑनलाइन प्राप्त करना होगा और स्रोत कोड, या तो अन्य लोगों की परियोजनाओं या ओएस एक्स स्रोत या दोनों के माध्यम से खोदना होगा, और जल्द ही आप निष्कर्ष निकालेंगे क्योंकि मेरे पास यह है कि स्रोत वास्तव में उत्तर के लिए सबसे अच्छी जगह है (भले ही स्टैक ओवरव्लो बहुत बढ़िया है)।

आपकी परियोजना के साथ अंक और शुभकामनाएं के लिए धन्यवाद :)

+0

महान उत्तर के लिए धन्यवाद। जिज्ञासा से बाहर, और संभावित भावी उपयोगिता, यह कैसे है कि आप या तो इस समाधान में आए थे या कोड लिखने के लिए ज्ञान था? –

+0

एक उचित उत्तर बदलता है एक टिप्पणी में फिट नहीं होगा इसलिए मैंने अपना जवाब संपादित किया। बक्षीस के लिए फिर से धन्यवाद! – par

+0

महान विवरण - समय लेने के लिए धन्यवाद! –

संबंधित मुद्दे