2013-12-17 105 views
0

我正在研究一個應用程序,當它動搖時,會一直播放聲音,直到抖動停止。我使用多個AVAudioPlayers來完成這個任務,它主要工作,但有時聲音會變形,就像霸天虎在變形金剛中所做的聲音一樣。有沒有人有一個想法,爲什麼會發生這種情況?我使用的文件格式爲MP3,代碼如下:在iOS上播放多個聲音會產生變壓器式的噪音

屬性聲明:

@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/,所以非常感謝你對他們爲他們提供的代碼。我希望這可以幫助別人試圖在設備震動時發出聲音。

+1

既然你已經解決了你的問題,我只是在評論中折騰。如果您採用諸如[ObjectAL]之類的音頻庫(http://kstenerud.github.io/ObjectAL-for-iPhone/),您將使您的生活更加輕鬆。做了一個音量相當大的項目後,它讓我的生活變得更加輕鬆。 – Travis

+0

很棒的建議。我從來沒有聽說過那個圖書館,但我一定會檢查出來。謝謝! – mike