2015-06-16 52 views
0

首先:我對音頻處理了解不多。我知道與核心音頻,你可以得到一個播放軌道的信息。iPhone - 獲取當前點的音頻振幅

我的目標是在SpriteKit節點與當前歌曲從iTunes是它的規模(比如,規模應在1.0在其最響亮和0.0在最安靜的)的電流幅值/響度。

我可以做節點編程(將xScaleyScale設置爲floatamp)。我的問題涉及獲得amp的價值。

這裏是我的代碼:

AVAudioPlayer *somePlayer = [AVAudioPlayer new]; 
__autoreleasing NSError* error; 
somePlayer = [somePlayer initWithContentsOfURL:[[[MPMusicPlayerController systemMusicPlayer] nowPlayingItem] valueForProperty:MPMediaItemPropertyAssetURL] error:&error]; 
somePlayer.currentTime = [[MPMusicPlayerController systemMusicPlayer] currentPlaybackTime]; 
somePlayer.volume = 0; 
[somePlayer play]; 
[somePlayer setMeteringEnabled:YES]; 
[somePlayer updateMeters]; 
NSMutableArray* amps = [NSMutableArray array]; 
if (error != nil) { 
    NSLog(@"error: %@", error.debugDescription); 
} 
for (int i = 0; i < somePlayer.numberOfChannels; i++) { 
    [amps addObject:@([somePlayer averagePowerForChannel:i]); 
    NSLog(@"Amplitude: %f db for channel %i", [somePlayer averagePowerForChannel:i], i); 
} 
float amp = 0; 
for (NSNumber *x in amps) { 
    amp += [x floatValue]; 
} 
amp /= amps.count; 
NSLog(@"amp: %f", amp); 
// set xScale and yScale to "amp" 
[somePlayer stop]; 

我得到的是-120 dB和滯後的恆定輸出(這是我的update方法)。它通常是60 fps,在我的iPhone 6上是10-11。任何想法如何解決這個問題?我在網上搜索了一個小時,但什麼也沒有。

回答

0

我不確定我是否正確解釋了你的代碼,但看起來你可能會在每一幀實例化你的播放器,並解釋緩慢。您需要提前設置您的播放器。然後在您的計時器上,在獲取averagePowerForChannel之前立即調用updateMeters。我對spiteKit並不熟悉,所以我只是將UIKit與viewDidLoad和一個displayLink用於我的計時器。

@interface ViewController(){ 
    AVAudioPlayer *somePlayer; 
    UIView *redView; 
    UIView *blueView; 
} 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    NSURL *eggman = [[NSBundle mainBundle]URLForResource:@"Eggman" withExtension:@"mp3"]; 
    somePlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:eggman error:NULL]; 
    [somePlayer setMeteringEnabled:YES]; 
    [somePlayer play]; 


    [self addViews]; 
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateViews)]; 
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 
} 


-(void)animateViews{ 

    [somePlayer updateMeters]; 
    float left_db = [somePlayer averagePowerForChannel:0]; 
    float right_db; 
    if (somePlayer.numberOfChannels > 1) { 
     right_db = [somePlayer averagePowerForChannel:1]; 
    } 
    else{ 
     right_db = left_db; 
    } 


    float blueScale = db_to_scale(left_db); 
    float redScale = db_to_scale(right_db); 
    float vert = self.view.bounds.size.height - 80; 

    blueView.center = CGPointMake(blueView.center.x, vert - (vert * blueScale)); 
    redView.center = CGPointMake(redView.center.x, vert - (vert * redScale)); 

} 
float db_to_scale(float decibles){ 
    return powf(10, (0.05 * decibles)); 
} 
-(void)addViews{ 
    blueView = [[UIView alloc]initWithFrame:CGRectMake(80, 80, 80, 80)]; 
    blueView.backgroundColor = [UIColor blueColor]; 
    [self.view addSubview:blueView]; 

    redView = [[UIView alloc]initWithFrame:CGRectMake(160, 80, 80, 80)]; 
    redView.backgroundColor = [UIColor redColor]; 
    [self.view addSubview:redView]; 
}