在 iOS 上播放多个声音会产生变压器式的噪音
Posted
技术标签:
【中文标题】在 iOS 上播放多个声音会产生变压器式的噪音【英文标题】:Playing multiple sounds on iOS produces a Transformer-esque noise 【发布时间】:2013-12-17 18:10:04 【问题描述】:我正在开发一个应用程序,当摇晃时,它会一遍又一遍地播放声音,直到摇晃停止。我正在使用多个 AVAudioPlayers 来完成此操作,并且它大部分都有效,但有时声音会失真,就像霸天虎在变形金刚中发出的声音一样。有没有人知道为什么会发生这种情况?我使用的文件格式是mp3,代码如下:
财产声明:
@property (strong, nonatomic) AVAudioPlayer *musicPlayerForRoar;
@property (strong, nonatomic) AVAudioPlayer *musicPlayerForRoar2;
@property (strong, nonatomic) AVAudioPlayer *musicPlayerForRoar3;
@property (strong, nonatomic) AVAudioPlayer *musicPlayerForRoar4;
@property (strong, nonatomic) AVAudioPlayer *musicPlayerForRoar5;
PlayRoar 方法。 PlayRoar、PlayRoar1、PlayRoar2 等在各个方面都是相同的,只是我初始化了哪个音频播放器:
- (void)playRoar
NSError *error;
self.musicPlayerForRoar = [[AVAudioPlayer alloc]initWithContentsOfURL:[self urlForRoarFile] error:&error];
self.musicPlayerForRoar.delegate = self;
[self.musicPlayerForRoar play];
/*Idea for the following two methods came from code on http://www.iosing.com/2011/12/making-a-jingle-bells-app-part-2-coding/*/
static BOOL L0AccelerationIsShaking(UIAcceleration* last, UIAcceleration* current, double threshold)
double deltaX = fabs(last.x - current.x), deltaY = fabs(last.y - current.y), deltaZ = fabs(last.z - current.z);
return (deltaX > threshold && deltaY > threshold) || (deltaX > threshold && deltaZ > threshold) || (deltaY > threshold && deltaZ > threshold);
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
if (self.lastAcceleration)
if (!histeresisExcited && L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.7))
histeresisExcited = YES;
//Use to prevent all sound files from playing at once initially. Each time the device is shaken, this is incremented. Depending on its value, the audio players are fired
shakesCounter++;
BOOL nonePlaying = (self.musicPlayerForRoar.isPlaying && self.musicPlayerForRoar2.isPlaying && self.musicPlayerForRoar3.isPlaying && self.musicPlayerForRoar4.isPlaying && self.musicPlayerForRoar5.isPlaying);
if (!nonePlaying)
[self playRoar];
NSLog(@"first playing");
if (!self.musicPlayerForRoar2.isPlaying && shakesCounter > 1)
[self playRoar2];
NSLog(@"second playing");
//
// if (!self.musicPlayerForRoar3.isPlaying && shakesCounter > 2)
// [self playRoar3];
// NSLog(@"third playing");
//
//
//
// if (!self.musicPlayerForRoar4.isPlaying && shakesCounter > 3)
// [self playRoar4];
// NSLog(@"fourth playing");
//
//
// if (!self.musicPlayerForRoar5.isPlaying && shakesCounter > 4)
// [self playRoar5];
// NSLog(@"fifth playing");
//
if (shakesCounter > 5)
shakesCounter = 0;
else if (histeresisExcited && !L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.2))
histeresisExcited = NO;
self.lastAcceleration = acceleration;
【问题讨论】:
【参考方案1】:为了实现我想要的声音,我最终使用了 C 级音频服务。下面的代码解决了我的问题,并且在摇晃设备时会发出很好的声音。由于它使用异步方法(AudioServicesPlaySystemSound()),失真消失了,声音按预期播放。
- (void)playRoar
CFBundleRef mainBundle = CFBundleGetMainBundle(); /* Define mainBundle as the current app's bundle */
CFURLRef fileURL = CFBundleCopyResourceURL(mainBundle, (CFStringRef)@"BearcatGrowl", CFSTR("mp3"), NULL); /* Set Bundle as Main Bundle, Define Sound Filename, Define Sound Filetype */
UInt32 soundID; /* define soundID as a 32Bit Unsigned Integer */
AudioServicesCreateSystemSoundID (fileURL, &soundID); /* Assign Sound to SoundID */
AudioServicesPlaySystemSound(soundID); /* Now play the sound associated with this sound ID */
我还在http://www.iosing.com/2011/12/making-a-jingle-bells-app-part-3-coding-the-sound/ 找到了这个解决方案,非常感谢他们提供的代码。我希望这可以帮助其他人在摇晃设备时尝试发出声音。
【讨论】:
既然你已经解决了你的问题,那我就随便写个评论吧。如果您采用诸如ObjectAL 之类的音频库,那么您的长期生活将会变得更加轻松。完成了一个包含大量音频的项目后,它让我的生活轻松了很多。 很好的建议。我以前从未听说过那个图书馆,但我一定会去看看。谢谢!以上是关于在 iOS 上播放多个声音会产生变压器式的噪音的主要内容,如果未能解决你的问题,请参考以下文章