我创建了一个简单的应用程序,可以根据仪器的x,y,z轴触发3种不同的声音。目前,如果我将间隔计的频率更新间隔设置得太低,它会播放很多声音,如果我将它设置得太高,它就不会有足够的响应。我是客观c和iphone开发的完全初学者,你可以通过代码告诉我们。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional
UIAccelerometer* accelerometer = [UIAccelerometer sharedAccelerometer];
[accelerometer setUpdateInterval: 25.0 / 10.0f];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
[accelerometer setDelegate:self];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
player.volume = 0.5;
player.numberOfLoops = 0;
player.delegate = self;
}
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
if (aceler.x > 0.5) {
NSString *fileName = [NSString stringWithFormat:@"snare"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.x = %+.6f greater", aceler.x);
[player play];
}
else if (aceler.y > 0.5) {
NSString *fileName = [NSString stringWithFormat:@"kick2"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.y = %+.6f greater", aceler.y);
[player play];
}
else if (aceler.z > 0.5) {
NSString *fileName = [NSString stringWithFormat:@"hat"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.y = %+.6f greater", aceler.z);
[player play];
}
else {
[player stop];
};
}
答案 0 :(得分:1)
将加速度计的更新频率设置为较低值不会对此有所帮助。想象一下以下情况:
time: ------------------------>
real world acceleration event: ___X_____X_____X_____X___
acceleration update: X_____X_____X_____X_____X
sound output started: _________________________
此草稿表示用户以与更新加速度计相同的频率摇动设备。但震动事件恰好发生在两个加速度计更新之间。因此,震动事件将不会被记录,也不会播放声音。
与先前的方法相比,考虑高加速度计更新频率:
real world acceleration event: ___X_____X_____X_____X___
acceleration update: XXXXXXXXXXXXXXXXXXXXXXXXX
sound output started: ___X_____X_____X_____X___
基本上所有真实世界的事件都会在这种情况下产生声音。
修改后的代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"viewDidLoad");
UIAccelerometer* accelerometer = [UIAccelerometer sharedAccelerometer];
//[accelerometer setUpdateInterval: 25.0 / 10.0f];
[accelerometer setUpdateInterval: 0.01f];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
[accelerometer setDelegate:self];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
//player.volume = 0.5;
//player.numberOfLoops = 0;
//player.delegate = self;
}
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
if ((aceler.x > ACC_THRESHOLD)&&((playerX == nil)||(playerX.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:@"snare"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerX = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.x = %+.6f greater", aceler.x);
playerX.delegate = self;
[playerX play];
}
if ((aceler.y > ACC_THRESHOLD)&&((playerY == nil)||(playerY.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:@"kick2"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerY = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.y = %+.6f greater", aceler.y);
playerY.delegate = self;
[playerY play];
}
if ((aceler.z > ACC_THRESHOLD)&&((playerZ== nil)||(playerZ.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:@"hat"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerZ = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(@"acceleration.z = %+.6f greater", aceler.z);
playerZ.delegate = self;
[playerZ play];
}
//else {
// [player stop];
//};
}
请注意,由于每个维度现在单独评估,因此只能通过一个事件触发多个声音播放。 #define ACC_THRESHOLD 0.5f
引入了一个常量。在上一场比赛结束后,仅启动一个维度的新声音播放。
在事件处理的这些一般更改之后,您可以使用signal filter开始优化。
此外,您可以使用AVAudioPlayer的委托方法进行更详细的声音处理:
#pragma mark -
#pragma mark AVAudioPlayerDelegate methods
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@"audioPlayerDidFinishPlaying: %i", flag);
}
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
NSLog(@"audioPlayerDecodeErrorDidOccur: %@", error.description);
}