6 Replies
      Latest reply on Oct 17, 2016 2:00 PM by OOPer
      hotpaw2 Level 2 Level 2 (85 points)

        The AVAudioBuffer documentatin is a bit unclear, but it looks like the floatChannelData method on an AVAudioPCMBuffer can return an unsafe pointer to an array of pointers which point to arrays of Floats (with strides, etc.)


        In any case, how does one read/write float sample data through an unsafe pointer to a pointer to a Float array in Swift 3?

        • Re: Pointer to a pointer to data in Swift 3?
          OOPer Level 7 Level 7 (4,515 points)

          The type of the `floatChannelData` is `UnsafePointer<UnsafeMutablePointer<Float>>?`, pointer to mutable pointer to Float.

          As you know C-language uses pointer to the first element when passing an array, this porperty is directly converted from C-world.

           

          floatChannelData[0] -> a mutable pointer to Float, representing channel 0

          floatChannelData[1] -> a mutable pointer to Float, representing channel 1

          ...

           

          And Float data pointed by each "mutable pointer to Float" is arranged with stride.

          For example, assume `stride` == 2:

           

          floatChannelData[0][0] -> sample0, channel 0

          floatChannelData[0][2] -> sample1, channel 0

          floatChannelData[0][4] -> sample2, channel 0

          ...

          floatChannelData[1][0] -> sample0, channel 1

          floatChannelData[1][2] -> sample1, channel 1

          floatChannelData[1][4] -> sample2, channel 1

          ...

           

          So, you can write something like this:

          func PCMBufferToFloatArray(_ pcmBuffer: AVAudioPCMBuffer) -> [[Float]]? {
              if let floatChannelData = pcmBuffer.floatChannelData {
                  let channelCount = Int(pcmBuffer.format.channelCount)
                  let frameLength = Int(pcmBuffer.frameLength)
                  let stride = pcmBuffer.stride
                  var result: [[Float]] = Array(repeating: Array(repeating: 0.0, count: frameLength), count: channelCount)
                  for channel in 0..<channelCount {
                      for sampleIndex in 0..<frameLength {
                          result[channel][sampleIndex] = floatChannelData[channel][sampleIndex * stride]
                      }
                  }
                  return result
              } else {
                  print("format not in Float")
                  return nil
              }
          }