15

Currently, I'm setting the volume to max, and then checking if the volume is at max, or a lower value. If it's at a lower value, then the user must have a Volume Lock on their system.

This works fine, but I'm wondering if there is some method to call, or property to check which tells me this in code for free? I've been looking online as to how to do this, but I can't seem to find anything. Thanks in advance!

Edit: It turns out that my previous method of setting the max volume and then checking if it's lower to see if there is a Volume lock does not work on the device. It seems as though the volume is scaled with the Volume lock, instead of just being cut off.

Now I'm completely stuck on this. Is there even any private methods or properties that I can use in order to detect this?

msgambel
  • 7,320
  • 4
  • 46
  • 62
  • 10
    Isn't that fairly rude to change the user's volume settings? – Dietrich Epp Aug 02 '11 at 20:14
  • I need to make sure the volume is constant. Otherwise, the sound I am outputting will be different for each user depending on their system volume. I should have mentioned that! – msgambel Aug 02 '11 at 20:17
  • Have the user configure the volume themselves -- and in the process warn about the Volume Lock? Assuming that the hardware is identical, just the ambient environment will greatly change the *perceived* sound volume. (Library vs. crowded subway as a more extreme case...) –  Aug 02 '11 at 20:19
  • 4
    (It's possible that the volume is locked at max, too :-) –  Aug 02 '11 at 20:21
  • If I detect a difference in the volume max, I post an AlertView which asks the user to remove the lock. What I'm asking about more is to actually DETECT that the volume is locked. True, it could be locked at max. I didn't think of that. But I guess I'd like to be able to find the value the lock is at. – msgambel Aug 02 '11 at 20:23
  • 6
    It's not a volume lock, it's a limit. So you can't "lock to max", that'd be the same as not having a limit on at all. If you play with the settings, you'll see that the limit is marked as "off" if you turn the limit slider all the way to max. – Christina Nov 09 '11 at 18:36
  • Check out this answer http://stackoverflow.com/questions/833304/how-to-detect-iphone-is-on-silent-mode – Trenskow Nov 11 '11 at 15:35
  • I can imagine a couple of tasks that might genuinely require this (e.g. sonic ruler) but in the vast majority of cases what you're claiming you need is both against Apple guidelines (you are not allowed to programmatically change volume without user input) and considered downright rude by users. If there is a good justification for this, it'd be helpful to have that at least partially explained in your question, even if you don't want to share everything about what you're doing. – Duncan Babbage Nov 15 '11 at 17:57
  • Unfortunately, I am under NDA, and cannot divulge too much information. From what I can say though, is that the exact volume needs to be known so that the application can make an approximation of the dBHL that is being output by the device. Without knowing this value, the application's functionality is severely limited. – msgambel Nov 15 '11 at 18:04

3 Answers3

1

I think what you are asking for is to find out if the iphone has a cap on the volume limit. I have looked for the answer but could not find one. Here is a way just to check the volume level, hope this helps.

In your XIB you can add a slider to check what the volume level is at, so basically you can tell if it is silent, and know the level of the volume. For more understanding of this class, here's the link http://blog.stormyprods.com/2008/09/proper-usage-of-mpvolumeview-class.html but try this first:

The following code will create something like a volume bar.

  - (void)viewDidLoad {
            // create a frame for MPVolumeView image
     CGRect frame = volumeViewHolder.bounds; // CGRectMake(0, 5, 180, 0);
     volumeView = [[[MPVolumeView alloc] initWithFrame:frame] autorelease];
     [volumeView sizeToFit];
     [volumeViewHolder addSubview:volumeView];

     for (UIView *view in [volumeView subviews]){
      if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) {
       volumeViewSlider = view;
      }
     }
     [[NSNotificationCenter defaultCenter] addObserver:self 
          selector:@selector(volumeChanged:) 
          name:@"AVSystemController_SystemVolumeDidChangeNotification" 
          object:nil];
    }
    - (void) volumeChanged:(NSNotification *)notify
    {
    [volumeViewSlider setValue:[[[notify userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue]];
    }

I heard that for some reason apple doesn't allow you to sell an app if you use a certain class (the one in my example) but I'm not too sure about this, I would double-check and make sure that you are 'allowed' to use it. But the code should work.

Gabriel
  • 3,039
  • 6
  • 34
  • 44
  • I think that this will only show what the current volume setting is. The problem with that is that the volume seems to be scaled, as opposed to limited, and therefore the volumeChanged method will still report a value of 1, even if the system volume has been limited to 0.5. I will try this out and get back to you. Thanks for the suggestion! – msgambel Nov 15 '11 at 17:33
  • Unfortunately, I cannot get your above code to work either. It also seems that according to your provided link, this code is no longer relevant to the current SDK, and should not be used. Thanks for the help though, this is a difficult problem! – msgambel Nov 15 '11 at 18:00
1

There are many answers to this problem but they all seem to have fallen foul of Apple's guidelines or App Store curators at some point as Apple don't provide an official way to do this.

However one feature you can utilise to find this out is that when a device is muted then the OS will not play the sound at all - so if you play a 800ms sound file and you time how long it takes to play if it is less than 800ms then you can infer that the mute switch is on.

I would recommend to use a silent 800ms sound file to use this trick so that the user is not suddenly confronted with an unexpected sound.

See here for the article that inspired me: http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

In addition you might want to use the Audio Toolbox to do this simply and guarantee that the mute switch is being used.

Grouchal
  • 9,756
  • 6
  • 34
  • 46
  • Even if they don't follow Apple's guidelines, could you post a way of finding out what the volume cap is? – msgambel Nov 15 '11 at 17:30
  • This question has a couple of tricks that are no longer working: http://stackoverflow.com/questions/287543/how-to-programmatically-sense-the-iphone-mute-switch – Grouchal Nov 16 '11 at 19:45
  • These questions deal with detecting if the app is muted or not. They do not deal with finding out if the user has a volume limit or not in the settings. Do you know any way of detecting that? – msgambel Nov 16 '11 at 22:12
  • Yes sorry for that I had misunderstood the question. – Grouchal Nov 17 '11 at 14:09
  • No problem. This is not a question with an obvious solution. Thanks for trying to help! – msgambel Nov 17 '11 at 15:40
  • 1
    I would be interested to know about this too. Volume "limit" not if it is muted or not. Not knowing what it is you are trying to achieve I would suggest prompting the user that "for best results volume must be set to...." At the launch of your app. Sorry for such a lame work around, but I am not sure if there is a way to do what you want with the whole sandboxing thing. Also I think you can ask an Apple engineer two questions a year for free with your paid developer membership. I have never done so but it might be right for you. – I00I Jan 13 '12 at 16:28
1

Consider setting the volume to max, then recording the output channel, and playing a short tone - then compare the peak of that recorded sample to a known sample where the volume limiter is not present. This will work if the iPad scales the output volume before recording gets access to it.

I wish I had more info on how to record the output, but I don't have much personal experience with it. Somebody who is versed in recording input should be able to point you the right way.

Tim
  • 14,447
  • 6
  • 40
  • 63