2015-10-11 15 views
8

Accelerate çerçevesini kullanarak sıklığı bulmak için ses dosyasını üzerinde FFT gerçekleştirmeye çalışıyorum. Bu soru kodu (muhtemelen yanlış) uyum sağlamış: Spectrogram from AVAudioPCMBuffer using Accelerate framework in SwiftSwift FFT - Karmaşık bölünmüş sorun

rağmen

, 'spektrum' dan büyüklükleri ', 'inf' veya 'nan' ya '', ve 'gerçek' ve 'imag' 'kompleksi bölünmüş baskı bileşenleri benzer sonuçlar; Bu şekilde sorunun nedeni olduğunu belirten:. 'büyüklük = sqrt (pow (gerçek, 2) + pow (imag, 2)' i Yanılıyorsam düzelt ama ben geri kalan düşünüyorum Kodun Tamamı

Niçin bu sonuçları alıyorsunuz ve onu nasıl çözebilirim (bölme bileşenleri ne olmalı) ve ne yapıyorum? Lütfen çok yeni olduğumu unutmayın. FFT ve örnekleme ve bir ses dosyası için bu kadar ayarlamak için bir ipucu yok, bu yüzden herhangi bir yardım büyük ölçüde takdir edilecektir.Çok teşekkürler:

Kullanmakta olduğum kod:

// get audio file 
    let fileURL:NSURL = NSBundle.mainBundle().URLForResource("foo", withExtension: "mp3")! 
    let audioFile = try! AVAudioFile(forReading: fileURL) 
    let fileFormat = audioFile.processingFormat 
    let frameCount = UInt32(audioFile.length) 

    let buffer = AVAudioPCMBuffer(PCMFormat: fileFormat, frameCapacity: frameCount) 
    let audioEngine = AVAudioEngine() 
    let playerNode = AVAudioPlayerNode() 
    audioMixerNode = audioEngine.mainMixerNode 

    let bufferSize = Int(frameCount) 
    let channels: NSArray = [Int(buffer.format.channelCount)] 
    let channelCount = channels.count 
    let floats1 = [Int(buffer.frameLength)] 
    for var i=0; i<channelCount; ++i { 
     channelSamples.append([]) 
     let firstSample = buffer.format.interleaved ? i : i*bufferSize 
     for var j=firstSample; j<bufferSize; j+=buffer.stride*2 { 
      channelSamples[i].append(DSPComplex(real: buffer.floatChannelData.memory[j], imag: buffer.floatChannelData.memory[j+buffer.stride])) 
     } 
    } 

    // connect node 
    audioEngine.attachNode(playerNode) 
    audioEngine.connect(playerNode, to: audioMixerNode, format: playerNode.outputFormatForBus(0)) 

    // Set up the transform 
    let log2n = UInt(round(log2(Double(bufferSize)))) 
    let fftSetup = vDSP_create_fftsetup(log2n, Int32(kFFTRadix2)) 

    // Create the complex split value to hold the output of the transform 
    // why doesn't this work? 
    var realp = [Float](count: bufferSize/2, repeatedValue: 0) 
    var imagp = [Float](count: bufferSize/2, repeatedValue: 0) 
    var output = DSPSplitComplex(realp: &realp, imagp: &imagp) 

    vDSP_ctoz(UnsafePointer(channelSamples), 2, &output, 1, UInt(bufferSize/2)) 

    // Do the fast Fourier forward transform 
    vDSP_fft_zrip(fftSetup, &output, 1, log2n, Int32(FFT_FORWARD)) 

    // Convert the complex output to magnitude 
    var fft = [Float](count:Int(bufferSize/2), repeatedValue:0.0) 
    let bufferOver2: vDSP_Length = vDSP_Length(bufferSize/2) 
    vDSP_zvmags(&output, 1, &fft, 1, bufferOver2) 

    var spectrum = [Float]() 
    for var i=0; i<bufferSize/2; ++i { 
     let imag = output.imagp[i] 
     let real = output.realp[i] 
     let magnitude = sqrt(pow(real,2)+pow(imag,2)) 
     spectrum.append(magnitude) } 

    // Release the setup 
    vDSP_destroy_fftsetup(fftSetup) 

cevap

3

senin koduyla sorunların bir çift vardı: bittikten sonra da okuyordu

  • channelSamples yanlış
  • vDSP_fft_zrip
  • doluydu ses dosyası örneklerinde okuma değildi

    1. dizi. beklediğinin 'ın çıkış packed bağlıdır ve hesaplamalar paketlenmemiş

      let fileURL:NSURL = NSBundle.mainBundle().URLForResource("foo", withExtension: "mp3")! 
      let audioFile = try! AVAudioFile(forReading: fileURL) 
      let frameCount = UInt32(audioFile.length) 
      
      let buffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: frameCount) 
      do { 
          try audioFile.readIntoBuffer(buffer, frameCount:frameCount) 
      } catch { 
      
      } 
      let log2n = UInt(round(log2(Double(frameCount)))) 
      
      let bufferSizePOT = Int(1 << log2n) 
      
      // Set up the transform 
      let fftSetup = vDSP_create_fftsetup(log2n, Int32(kFFTRadix2)) 
      
      // create packed real input 
      var realp = [Float](count: bufferSizePOT/2, repeatedValue: 0) 
      var imagp = [Float](count: bufferSizePOT/2, repeatedValue: 0) 
      var output = DSPSplitComplex(realp: &realp, imagp: &imagp) 
      
      vDSP_ctoz(UnsafePointer<DSPComplex>(buffer.floatChannelData.memory), 2, &output, 1, UInt(bufferSizePOT/2)) 
      
      // Do the fast Fourier forward transform, packed input to packed output 
      vDSP_fft_zrip(fftSetup, &output, 1, log2n, Int32(FFT_FORWARD)) 
      
      
      // you can calculate magnitude squared here, with care 
      // as the first result is wrong! read up on packed formats 
      var fft = [Float](count:Int(bufferSizePOT/2), repeatedValue:0.0) 
      let bufferOver2: vDSP_Length = vDSP_Length(bufferSizePOT/2) 
      vDSP_zvmags(&output, 1, &fft, 1, bufferOver2) 
      
      
      // Release the setup 
      vDSP_destroy_fftsetup(fftSetup) 
      
    bekliyoruz
  • vDSP_fft_zrip 2^log2n numuneler