2017-04-03 33 views
7

Próbuję nagrać dźwięk za pomocą AVAudioRecorder. Muszę stworzyć prosty przebieg tak:iOS: Utwórz prostą animację fali dźwiękowej

enter image description here

Gdy użytkownik mówi do mikrofonu okrąg wskazuje poziom głosu użytkownika. Próbowałem zmierzyć się głos z tego kodu, ale kod nie wykrywa żadnego bufora i nie działa:

func levelTimerCallback(timer:Timer) { 

    //we have to update meters before we can get the metering values 
    audioRecorder.updateMeters() 

    //print to the console if we are beyond a threshold value. Here I've used -7 
    if audioRecorder.averagePower(forChannel: 1) > -7 { 

     print(" level I'm hearin' you in dat mic ") 
     print(audioRecorder.averagePower(forChannel: 0)) 
    } 
}  

nagrywania audio:

func startRecording() { 

     let audioSession = AVAudioSession.sharedInstance() 
     do { 

     // Audio Settings 
      settings = [ 
       AVFormatIDKey: Int(kAudioFormatMPEG4AAC), 
       AVSampleRateKey: 12000, 
       AVNumberOfChannelsKey: 1, 
       AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue 
      ] 


      audioRecorder = try AVAudioRecorder(url: self.directoryURL(), settings: settings) 
      audioRecorder.delegate = self 
      audioRecorder.prepareToRecord() 
      audioRecorder.isMeteringEnabled = true 


     } catch { 

      finishRecording(success: false) 
     } 

     do { 

      try audioSession.setActive(true) 
      audioRecorder.record() 

      TIMERRRRR = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(ViewController.levelTimerCallback), userInfo: nil, repeats: true) 

     } catch { 

     } 

    } 

Odpowiedz

5

dwa problemy, które mogę zobaczyć.

Po pierwsze, testujesz z nieprawidłowym numerem kanału w swojej funkcji levelTimerCallback. Twój test powinien dotyczyć kanału 0.

Drugą wartością jest to, że wartość -7 jest bardzo głośna. averagePower zwraca wartości z zakresu od -160 do 0. Spróbuj przetestować od -160, aby zwiększyć i zmniejszyć czułość.

To zmienia swój test:

if audioRecorder.averagePower(forChannel: 1) > -160 { 
    ... 
} 

Jest tylko jeden kanał dla wejścia i liczenie zaczyna się od 0. Trzeba to prawo później na wezwanie do audioRecorder.averagePower.

Aby uzyskać skalę liniową, musisz interpolować. Zmień wartość scale, aby zmienić zakres. proportion będzie między 0 a scale.

let lowerLimit: Float = -100.0 

func levelTimerCallback(timer:Timer) { 

    audioRecorder.updateMeters() 

    let power = audioRecorder.averagePower(forChannel: 0) 
    if power > lowerLimit { 
     // proportion will have a value between 0 and scale 
     let scale: Float = 10.0 
     let proportion = -scale * (power - lowerLimit)/lowerLimit 
    } 
} 

Edit: fixed obliczenia proporcji

+0

dodałem coś do odpowiedzi, które myślę, że jest blisko do prawej. –

+0

ale jeden problem można sprawdzić edytowany kod? –

+0

Jeśli proporcje mieszczą się w przedziale od 0 do 1, wygląda to dla mnie dobrze. –