2011-09-04 4 views
-2

안녕 난 당신이 버튼을 누른 상태에서 전화로 날려가 응용 프로그램을 가지고 그리고 여기, 소리를 만드는 코드입니다 : 나는 당신이 내가 노력하고 이해를 바랍니다정지 음악 즉시

 #import "AirInstrumentViewController.h" 

@implementation AirInstrumentViewController 
    @synthesize audiOfA; 
     - (void)didReceiveMemoryWarning 
     { 
// Releases the view if it doesn't have a superview. 
[super didReceiveMemoryWarning]; 

// Release any cached data, images, etc that aren't in use. 
} 

    #pragma mark - View lifecycle 



     - (void)viewDidLoad 
    { 
    [super viewDidLoad]; 


    NSURL *url = [NSURL fileURLWithPath:@"/dev/null"]; 

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithFloat: 44100.0],     AVSampleRateKey, 
          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey, 
          [NSNumber numberWithInt: 1],       AVNumberOfChannelsKey, 
          [NSNumber numberWithInt: AVAudioQualityMax],   AVEncoderAudioQualityKey, 
          nil]; 

NSError *error; 

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error]; 

if (recorder) { 
    [recorder prepareToRecord]; 
    recorder.meteringEnabled = YES; 
    [recorder record]; 
    levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES]; 
} else 
    NSLog([error description]); 
} 

      - (void)levelTimerCallback:(NSTimer *)timer { 
[recorder updateMeters]; 

const double ALPHA = 0.05; 
double peakPowerForChannel = pow(10, (0.05 * [recorder peakPowerForChannel:0])); 
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults; 

if (lowPassResults > 0.55) { 
    NSLog(@"Mic blow detected"); 

    if (aIsBeingTouched == YES) { 
     NSString *musicString = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"aifc"]; 
     audiOfA = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicString] error:NULL]; 
     [audiOfA play]; 

    } }else { 

     [audiOfA stop]; 
    } 


} 

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 


UITouch *touch = [[event allTouches] anyObject]; 

CGPoint touchLocation = [touch locationInView:self.view]; 
if (CGRectContainsPoint(aImage.frame, touchLocation)) { 

    aImage.image = [UIImage imageNamed:@"active.png"]; 
    aIsBeingTouched = YES; 

      } 
     } 
      -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
[audiOfA stop]; 

aImage.image = [UIImage imageNamed:@"a.png"]; 

aIsBeingTouched = NO; 

    } 

- (void)viewDidUnload 
    { 

[super viewDidUnload]; 
// Release any retained subviews of the main view. 
// e.g. self.myOutlet = nil; 
    } 



    @end 

할 것. 이상 : if (lowPassResults> 0.55) { NSLog (@ "Mic blow detected");

if (aIsBeingTouched == YES) { 
    NSString *musicString = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"aifc"]; 
    audiOfA = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicString] error:NULL]; 
    [audiOfA play]; 

} }else { 

    [audiOfA stop]; 
} 


    } 

소리가 BIT보다 오래 지속 된 다음 중지됩니다. 끝나는 접촉을 위해 동일. 그리고 내가 이미지를 누르고 있지 않을 때 을 날려 버리면 마침내 이미지를 멈추게됩니다. 불이 나지 않아도 불어 나옵니다. 왜냐하면 만약에 그것이 열리지 않았을 때 불었습니다. 그리고 그것은 그것을 기록했거나 무언가를 기록했을 것입니다! 나는이 모든 문제들을 고치는 방법을 알고있다.

답변

1

NSTimer은 매우 신뢰할 수 없습니다. Apple Documentation, 인용에 따르면

타이머의 시간 간격의 유효 해상도는 50 ~ 100 밀리 초

의 순서에 제한됩니다

그것은 당신이 그렇게 그들을 호출되기 때문에 것을 할 수있다 (0.03 초 또는 30 밀리 초가 매우 빠름) NSTimer은 정확한 간격으로 호출되지 않으므로 건너 뜁니다.

UI- 관련 모든 것이 주 스레드에서 수행되고 AVAudio 부분이 별도 스레드에서 수행되도록이 스레드를 멀티 스레딩 할 수 있습니다. ThisNSOperation을 설명하는 링크입니다.이 방법은 쉬운 방법이며 제공 한 코드가 있으면 잘 작동합니다.

희망이 도움이됩니다!

+0

그 링크가 나를 도울 수있는 방법을 모르겠다. – user918958

+0

실제로 음악이 잠시 후에 멈추는지라도 – user918958

+0

'AVAudio' 섹션에 대해'NSOperation'을 사용할 수 있기 때문에 프로세스가 별도의 스레드에서 수행되고 따라서 메인 스레드의 속도를 높이고 'NSTimer'뿐만 아니라 터치 이벤트 및 기타 UI 요소의 타이밍을 향상시킬 수 있습니다. – msgambel