1

For purposes of this question, imagine my app plays an audio clip every 10 seconds. This audio plays/mixes with the iPod music player on the device (using ducking), using AVAudioPlayer. When the app is sent to the background, I schedule UILocalNotification objects with the audio file referenced (and no text), so the sounds continue to play at 10 second intervals.

What is bothering me is that the volume of the audio clips played as part of a notification on iOS 6 seem to be twice as loud as the audio when I play in my app (and I'm setting the volume to 1.0f, which the docs say is max). So every 10 seconds the app plays a sound, and when you send to the background it's now very loud compared to what it was in the app.

Relevant snippets... App startup, here's how I'm setting up the AVAudioSession to enable ducking:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (doChangeDefaultRoute), &doChangeDefaultRoute);

OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof (allowMixing),&allowMixing);

... How I create my player:

- (AVAudioPlayer *)playerWithCAFFileNamed:(NSString *)fname {
    NSURL *u = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:fname ofType:@"caf"]];
    NSData *d = [NSData dataWithContentsOfURL:u];
    AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithData:d error:nil];
    p.delegate = self;
    p.volume = 1.0; 
    [p prepareToPlay];
    return p;
}

... and then the playback:

- (void)playAudio:(AVAudioPlayer *)player {
    [self setSessionActiveWithMixing:YES];
    [player setVolume:1.0]; // should already be set, but just to be sure
    [player play];
}

... and here's how I'm creating the uber-loud notifications:

- (UILocalNotification *)notificationWithSoundNamed:(NSString *)sound atTimeInterval:(NSTimeInterval)ti {
    UILocalNotification *n = [[UILocalNotification alloc] init];
    n.soundName = sound;
    n.fireDate = [NSDate dateWithTimeIntervalSinceReferenceDate:ti];
    return n;
}
James Boutcher
  • 2,593
  • 1
  • 25
  • 37

2 Answers2

1

The bug I opened with Apple was closed as "functions as designed". Their brief explanation:

Notification sounds follow ringer volume; AVAudioPlayer follows media volume.

... I guess you can then make the assumption that ringer volume is allowed to be louder than the loudest media volume, to ensure you hear the ringer. I guess.

James Boutcher
  • 2,593
  • 1
  • 25
  • 37
0

I faced similar issue with AVAudioPlayer volume. So I divided the value I want to assign by a factor of what I want to get. Worth finding the reason though.

sridevi
  • 617
  • 1
  • 6
  • 15
  • A bit confused there - you're dividing the volume setting by some number to _lower_ the volume? 1.0 is the max, yes? I couldn't see how lowering the audio-in app would fix my issue. (My issue is the app volume is lower than the UINotification volume - which I have no control over) – James Boutcher Jan 27 '13 at 20:39
  • Assign 0.5 in place of 1.0 to volume. Similarly if you want to assign 0.5, divide by 2 and assign 0.25. This is a workaround I used. – sridevi Jan 28 '13 at 20:30
  • I understand how division works, it's not logical why setting the volume to .5 would be louder than its setting at 1.0. Thinking logic may not have played a part here, I took your suggestion - and the audio was about half as loud as what it normally was (now it's 1/4 the volume of the notifications-played volume), which is what I expected. – James Boutcher Jan 29 '13 at 00:26