6 Replies
      Latest reply: Oct 17, 2016 2:00 PM by OOPer RSS
      hotpaw2 Level 2 Level 2 (80 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 (3,325 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
              }
          }
          
            • Re: Pointer to a pointer to data in Swift 3?
              hotpaw2 Level 2 Level 2 (80 points)

              So basically, you are saying that an UnsafePointer and an UnsafeMutablePointer can be indexed through memory, with a stride indicated the type <T>, using the exact same array access syntax as regular Swift arrays, e.g. "foo[index]".

               

              Where in the Swift documentation is this specified?  Are there any initialization, bounds, or alignment restrictions to UnsafeMutablePointers, or are they partially or completely "unsafe".