यह मेरे मैकबुक प्रो (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 पर दस्तावेज़ीकरण अपर्याप्त होने के लिए मिलेगा। आखिरकार आपको ऑनलाइन प्राप्त करना होगा और स्रोत कोड, या तो अन्य लोगों की परियोजनाओं या ओएस एक्स स्रोत या दोनों के माध्यम से खोदना होगा, और जल्द ही आप निष्कर्ष निकालेंगे क्योंकि मेरे पास यह है कि स्रोत वास्तव में उत्तर के लिए सबसे अच्छी जगह है (भले ही स्टैक ओवरव्लो बहुत बढ़िया है)।
आपकी परियोजना के साथ अंक और शुभकामनाएं के लिए धन्यवाद :)
महान उत्तर के लिए धन्यवाद। जिज्ञासा से बाहर, और संभावित भावी उपयोगिता, यह कैसे है कि आप या तो इस समाधान में आए थे या कोड लिखने के लिए ज्ञान था? –
एक उचित उत्तर बदलता है एक टिप्पणी में फिट नहीं होगा इसलिए मैंने अपना जवाब संपादित किया। बक्षीस के लिए फिर से धन्यवाद! – par
महान विवरण - समय लेने के लिए धन्यवाद! –