简体   繁体   中英

Converting a Swift UnsafePointer<AudioStreamBasicDescription> to a Dictionary?

I want to know how to create a dictionary of [String:AnyObject] from an UnsafePointer<AudioStreamBasicDescription>

I guess I don't understand how to work with an UnsafePointer<T> in Swift . Here's where I'm starting from - The AVAudioFile class has a fileFormat property which is of AVAudioFormat Type. AVAudioFormat has a streamDescription property which returns an UnsafePointer<AudioStreamBasicDescription> as a read-only property.

I'd like to see what the values are in this struct and converting to a Dictionary seems like it might be reasonable goal. In fact, there already seems to be a "settings" property on the AVAudioFormat Class that does this but I'm interested in understanding the "right way" to access the values stored in the UnsafePointer myself.

From the docs Discussion: Returns the AudioStreamBasicDescription (ASBD) struct, for use with lower-level audio APIs https://developer.apple.com/library/prerelease/ios/documentation/AVFoundation/Reference/AVAudioFormat_Class/index.html

Is there a way to do an unsafe conversion after checking if the struct is not nil? Would I use an unsafeBitCast here? I'm hesitant to jump into this too much as I've read that it's "extremely dangerous"...

I realize I can access the underlying memory with the following:

let audioFileURL:NSURL = NSBundle.mainBundle().URLForResource("FILENAME", with Extension: "mp3")
var file:AVAudioFile?
do {
  file = try AVAudioFile(forReading: audioFileURL)
  guard let file = file else {
    fatalError("file must not be nil")
  }
}catch {
  print(error)
}

let format = file.processingFormat
let asbd:AudioStreamBasicDescription = format.streamDescription.memory

Is that dangerous and would I need to dealloc for some reason after creating the asbd constant?

I've tried to follow along with the post here http://sitepoint.com/using-legacy-c-apis-swift but I'm just not getting it... Looking for any direction on best practices here.

Update:

Doing a bit more research, it seems that it might be possible to create the dictionary using reflect based off this post: http://freecake.angelodipaolo.org/simple-reflection-in-swift/

Here's what I have so far:

let asbdMirror = reflect(asbd)
var asbdDict = [String: Any]()
for i in 0..<asbdMirror.count {
  let (propertyName, childMirror) = asbdMirror[i]
  asbdDict[propertyName] = childMirror.value
} 

Any reason this is a bad idea?

You are doing everything correctly, you can access all the values in the description with asbd.mSampleRate and such. It wouldn't make sense to convert it to a dictionary because that's just not what it is, there are no keys for the values.

You also don't have to dealloc anything when working with pointers like this unless you allocate one yourself (when using malloc or alloc )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM