2

I am trying to perform fft on Spotify's audio stream using EZAudio.

Following this suggestion, I have subclassed SPTCoreAudioController, overrode attemptToDeliverAudioFrames:ofCount:streamDescription:, and initialized my SPTAudioStreamingController with my new class successfully.

Spotify does not say if the pointer, which is passed into the overridden function, points to a float, double, integer, etc.. I have interpreted it as many different data types, which all failed, leaving me confused if my fft is wrong or if my audio buffer is wrong. Here is spotify's documentation on SPTCoreAudioController.

Assuming the audio buffer is a buffer of floats, here is one of my attempts at FFT:

class GetAudioPCM : SPTCoreAudioController, EZAudioFFTDelegate{
    let ViewControllerFFTWindowSize: vDSP_Length = 128
    
   
    var fft: EZAudioFFTRolling?
    //var fft: EZAudioFFT?

   override func attempt(toDeliverAudioFrames audioFrames: UnsafeRawPointer!, ofCount frameCount: Int, streamDescription audioDescription: AudioStreamBasicDescription) -> Int {
    
        if let fft = fft{
            
        let newPointer = (UnsafeMutableRawPointer(mutating: audioFrames)!.assumingMemoryBound(to: Float.self))
            let resultBuffer : UnsafeMutablePointer<Float> = (fft.computeFFT(withBuffer: newPointer, withBufferSize: 128))
            print("results: \(resultBuffer.pointee)")
        }else{
            fft = EZAudioFFTRolling(windowSize: ViewControllerFFTWindowSize, sampleRate: Float(audioDescription.mSampleRate), delegate: self)
            //fft = EZAudioFFT(maximumBufferSize: 128, sampleRate: Float(audioDescription.mSampleRate))
        }
    

    return super.attempt(toDeliverAudioFrames: audioFrames, ofCount: frameCount, streamDescription: audioDescription)
    }
    
    
    
    func fft(_ fft: EZAudioFFT!, updatedWithFFTData fftData: UnsafeMutablePointer<Float>, bufferSize: vDSP_Length) {
       
        print("\n \n DATA ---------------------")
     
        print(bufferSize)
        
        if (fft?.fftData) != nil {
        
            print("First: \(fftData.pointee)")
            
        for i : Int in 0..<Int(bufferSize) {
           
            print(fftData[i], terminator: " :: ")
        }
        }
    }
}

I make my custom class the EZAudioFFTDelegate, I initialize an EZAudioFFTRolling (have also tried plain EZAudioFFT) object, and tell it to perform an fft with the buffer. I chose a small size of 128 just for initial testing.

I have tried different data types for the buffer and different methods of fft. I decided using a well known library that has fft should give me the correct results. Yet, my output from this and similar FFT's produced 'nan' for almost every single float in the new buffer.

Is the way I access spotify's audio buffer wrong, or is my FFT process at fault?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Braden Bagby
  • 273
  • 1
  • 8
  • I am quite possibly wrong, but it seems as though `attemptToDeliverAudioFrames` sets a pointer to an array of audio frames and returns the number of frames in the array. I think one issue is that you may be using the frames incorrectly. Usually audio frames contain one sample for each channel, and most music has at least two channels (left and right) – Cobalt Aug 02 '17 at 19:27
  • 1
    Have you tried computing the FFT of audio coming from the microphone? – Cobalt Aug 02 '17 at 19:42
  • I’m reading [attemptToDeliverAudioFrames docs](https://developer.spotify.com/ios-sdk-docs/Documents/Classes/SPTCoreAudioController.html#//api/name/attemptToDeliverAudioFrames:ofCount:streamDescription:), and `audioDescription` is a `AudioStreamBasicDescription`, which [Apple docs](https://developer.apple.com/documentation/coreaudio/audiostreambasicdescription) say could be PCM audio *OR* a CBR codec—maybe your FFT is garbage because the data is packed or encoded? – Ahmed Fasih Aug 07 '17 at 00:11
  • I have verified that the EZAudio FFT does work correctly with the microphone. The two channels suggestion does make sense and is something I did not consider or think about. I will look into this more. Thank you!!! @Cobalt – Braden Bagby Aug 07 '17 at 13:50
  • Thank you @AhmedFasih!! Im not sure that the data would be encoded as a Spotify developer is the person who suggested to override this function to get the audio data, but I may be wrong. I will look at the audioDescription more as it tells me how many channels and other information. Thanks again! – Braden Bagby Aug 07 '17 at 13:55

0 Answers0