vadymmarkov / Beethoven

:guitar: A maestro of pitch detection.
https://github.com/vadymmarkov
Other
827 stars 146 forks source link

Can not read audio from file. #57

Open ChiefGodMan opened 6 years ago

ChiefGodMan commented 6 years ago

When I specify the url variable to Config object, it will call OutputSignalTracker.start()function, but it can not enter this function and exit the program: audioEngine.outputNode.installTap(onBus: bus, bufferSize: bufferSize, format: nil) { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in DispatchQueue.main.async { self.delegate?.signalTracker(self, didReceiveBuffer: buffer, atTime: time) }}

kocharyanvahe commented 6 years ago

Also, I have the same problem.

hepiyellow commented 5 years ago

Yeah, Can you give an example of how to analyze an audio file and get the Pitch array or something? And, how would I know the timing info (offset in milliseconds) of each Pitch sample?

jhristov commented 2 years ago

What I found is a couple of issues in OutputSignalTracker which prevent the pitch output. First, installTap() has no effect on audioEngine - one has to substitute with audioPlayer. Second, the delegate in the closure was always nil so self.delegate?.signalTracker() was never called. Here is my replacement code which should give you an idea how to get some readings. It goes in the start() method of OutputSignalTracker. One must import Pitchy too.

      let factory = EstimationFactory()
      let estimator = factory.create(.yin) // Choose pitch method here!
      let queue = DispatchQueue(label: "BeethovenQueue", attributes: [])

      self.audioPlayer.installTap(onBus: 0, bufferSize: self.bufferSize, format: nil) { (buffer, time) in

          queue.async { [weak self] in
            guard let `self` = self else { return }

            do {
              let transformedBuffer = try estimator.transformer.transform(buffer: buffer)
              let frequency = try estimator.estimateFrequency(
                sampleRate: Float(time.sampleRate),
                buffer: transformedBuffer)
              let pitch = try Pitch(frequency: Double(frequency))
            print(time,pitch)

              DispatchQueue.main.async { [weak self] in
                guard let `self` = self else { return }
                //self.delegate?.pitchEngine(self, didReceivePitch: pitch)
              }
            } catch {
              DispatchQueue.main.async { [weak self] in
                guard let `self` = self else { return }
                //self.delegate?.pitchEngine(self, didReceiveError: error)
              }
            }
        }

    }

One would then start the tracking with:

        let config = Config(
          bufferSize: 4096,
          estimationStrategy: .yin, // has no effect, has to be set in the estimator, see above
          audioUrl: Bundle.main.url(forResource: "sound_file", withExtension: "wav")!
        )

        let pitchEngine = PitchEngine(config: config)
        pitchEngine.start()
mannyvw commented 1 year ago

@jhristov perfect. Yep i replaced the following line in OutputSignalTracker::start

audioEngine.outputNode.installTap(onBus: bus, bufferSize: bufferSize, format: nil)

With

audioPlayer.installTap(onBus: bus, bufferSize: bufferSize, format: nil)

and everything else works. Good work