Я сделал приложение для iPhone, которое будет использоваться во время тренировок. Он воспроизводит тональный сигнал, указывающий на то, что вы (пользователь) должны переключаться с одного шага упражнения на следующий. Я разработал приложение, чтобы вы могли слушать музыку на iPod во время использования приложения, и я хочу, чтобы звук звучал достаточно хорошо над музыкой. Я получил это на работу ... вроде ...
Когда музыка громкая, звук не слышен. Мое идеальное решение - это то, что приложение iPod обрабатывает входящие текстовые сообщения или электронную почту. Громкость музыки снижается, воспроизводится звук, затем громкость музыки возвращается.
Я использовал AudioServicesPlaySystemSound
для воспроизведения звука.
Я инициализировал звук так:
CFBundleRef mainBundle = CFBundleGetMainBundle();
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, CFSTR ("bell"), CFSTR ("wav"), NULL);
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundFileID);
И я играю звук в нужное время, используя:
AudioServicesPlaySystemSound (self.soundFileID);
Звучит нормально, но слишком громко слышно. Попытка 2 ...
Я попытался уменьшить громкость iPod, воспроизвести звук, а затем вернуть громкость на прежний уровень.
Если на текущем шаге осталась 1 секунда, начните уменьшать громкость:
if ([self.intervalSet currentStepTimeRemainingInSeconds] == 1) {
self.volumeIncrement = originalVolume/5.0f;
[NSTimer scheduledTimerWithTimeInterval:0.5f
target:self
selector:@selector(fadeVolumeOut:)
userInfo:[NSNumber numberWithInt:1]
repeats:NO];
}
Вот метод fadeVolumeOut:
:
- (void) fadeVolumeOut:(NSTimer *)timer {
if (!TARGET_IPHONE_SIMULATOR) {
NSNumber *volumeStep = (NSNumber *)[timer userInfo];
int vStep = [(NSNumber *)volumeStep intValue];
float volume = [[MPMusicPlayerController iPodMusicPlayer] volume];
volume = volume - self.volumeIncrement;
if (volume < 0.0f) {
volume = 0.0f;
}
[[MPMusicPlayerController iPodMusicPlayer] setVolume:volume];
if (vStep < 5) {
vStep = vStep + 1;
[NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:@selector(fadeVolumeOut:)
userInfo:[NSNumber numberWithInt:vStep]
repeats:NO];
}
}
}
Затем, когда шаг завершится, включите звуковой сигнал и снова уменьшите громкость:
[NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:@selector(alertAndFadeVolumeIn)
userInfo:nil
repeats:NO];
Вот метод alertAndFadeVolumeIn
:
- (void) alertAndFadeVolumeIn {
[self alert];
[NSTimer scheduledTimerWithTimeInterval:0.25f
target:self
selector:@selector(fadeVolumeIn:)
userInfo:[NSNumber numberWithInt:1]
repeats:NO];
}
И fadeVolumeIn:
в основном противоположно fadeVolumeOut:
выше.
Это работает, громкость затухает, звук воспроизводится, а громкость возвращается обратно. Проблема в том, что громкость звука снижается на ту же величину, что и iPod, поэтому ее легче слышать. над музыкой.
Я переключился на AVAudioSession
, чтобы воспроизвести звук, и настроил сеанс так, чтобы музыка iPod продолжала воспроизводиться во время использования приложения. Вот как я инициализирую сессию:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (allowMixing),
&allowMixing
);
NSError *activationError = nil;
[session setActive:YES error:&activationError];
NSString *audioFile = [[NSBundle mainBundle] pathForResource:@"bell"
ofType:@"wav"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:audioFile] error:NULL];
Чтобы воспроизвести звук, я звоню [self.player play]
в соответствующее время. Опять же, громкость звука снижается вместе с громкостью iPod, и звук не становится легче слышать.
Я пытался поставить [[MPMusicPlayerController applicationMusicPlayer] setVolume:1.0f];
прямо перед звуком оповещения. Это имело смешанные результаты. В первый раз звук воспроизводится на полной громкости, как я и надеялся, но в последующие времена громкость намного ниже. Кроме того, музыка не исчезает гладко. Похоже, что iPodMusicPlayer
и applicationMusicPlayer
имеют одинаковую громкость. Это результат использования [AVAudioSession sharedInstance];
? Есть ли другой способ инициализации AVAudioSession
?
Далее я попытался использовать AVAudioSession
"ducking":
OSStatus propertySetError = 0;
UInt32 allowDucking = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OtherMixableAudioShouldDuck,
sizeof (allowDucking),
&allowDucking
);
К сожалению, музыка iPod «приглушается», когда аудио-сеанс активирован, то есть, как только viewController загружается так, как у меня было.
Наконец, я изменил свой код, так что аудио-сеанс активируется за одну секунду до окончания шага, звук воспроизводится после его завершения, а через одну секунду сеанс деактивируется. На этом этапе я удалил весь свой код для появления и исчезновения. Вот соответствующие фрагменты кода:
if ([self.intervalSet currentStepTimeRemainingInSeconds] == 1) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
}
...
if (self.shouldRing) {
[self.player play];
[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(stopSound)
userInfo:nil
repeats:NO];
}
...
- (void) stopSound {
[self.player stop];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:nil];
}
Это подводит меня к тому, что я действительно застрял. Это прекрасно работает после окончания первого шага. Громкость звука iPod снижается, звук воспроизводится громко, а уровень громкости iPod снижается через секунду. Однако во второй раз, когда шаг завершается, звук воспроизводится чуть менее громко, в третий раз он едва слышен, а в четвертый раз тише. Затем, в пятый раз, он снова играет громко, и цикл повторяется.
Кроме того, активация и деактивация кажутся довольно тяжелыми операциями, и они приводят к небольшому заиканию таймера.
Кто-нибудь пытался сделать что-то подобное? Есть ли предпочтительный подход к воспроизведению звука поверх музыки iPod?