Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift3 AURenderCallback中的UnsafeMutablePointer_Swift3_Core Audio_Unsafemutablepointer - Fatal编程技术网

Swift3 AURenderCallback中的UnsafeMutablePointer

Swift3 AURenderCallback中的UnsafeMutablePointer,swift3,core-audio,unsafemutablepointer,Swift3,Core Audio,Unsafemutablepointer,我不明白,我应该如何在Swift 3中使用unsafemeutablepointer。尤其是在AURenderCallback中 我尝试以下代码: import Foundation import AudioToolbox let sineFrequency = 880.0 // MARK: User data struct struct SineWavePlayer { var outputUnit: AudioUnit? = nil var startingFrameCo

我不明白,我应该如何在Swift 3中使用
unsafemeutablepointer
。尤其是在
AURenderCallback

我尝试以下代码:

import Foundation
import AudioToolbox

let sineFrequency = 880.0

// MARK: User data struct
struct SineWavePlayer {
    var outputUnit: AudioUnit? = nil
    var startingFrameCount: Double = 0
}

// MARK: Callback function
let SineWaveRenderProc: AURenderCallback = {(inRefCon, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData) -> OSStatus in

    var player = UnsafeMutablePointer<SineWavePlayer>(inRefCon)


    var j = player.pointee.startingFrameCount
    let cycleLength = 44100 / sineFrequency

    for frame in 0..<inNumberFrames {
        var buffers = UnsafeMutableAudioBufferListPointer(ioData)

        UnsafeMutablePointer<Float32>(buffers[0].mData)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))
        UnsafeMutablePointer<Float32>(buffers[1].mData)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))

        // Or iterate through array:
//        for buffer in buffers {
//            UnsafeMutablePointer<Float32>(buffer.mData)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))
//        }

        j++
        if j > cycleLength {
            j -= cycleLength
        }
    }

    player.pointee.startingFrameCount = j
    return noErr
}

// MARK: Utility function
func CheckError(_ error: OSStatus, operation: String) {
    guard error != noErr else {
        return
    }

    var result: String = ""
    var char = Int(error.bigEndian)

    for _ in 0..<4 {
        guard isprint(Int32(char&255)) == 1 else {
            result = "\(error)"
            break
        }
        result.append(String(describing: UnicodeScalar(char&255)))
        char = char/256
    }

    print("Error: \(operation) (\(result))")

    exit(1)
}

func CreateAndConnectOutputUnit(_ player: inout SineWavePlayer) {
    // Generate a description that matches the output device (speakers)
    var outputcd = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_DefaultOutput, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)

    let comp = AudioComponentFindNext(nil, &outputcd)

    if comp == nil {
        print("Can't get output unit")
        exit(-1)
    }

    CheckError(AudioComponentInstanceNew(comp!, &player.outputUnit),
        operation: "Couldn't open component for outputUnit")

    // Register the render callback
    var input = AURenderCallbackStruct(inputProc: SineWaveRenderProc, inputProcRefCon: &player)

    CheckError(AudioUnitSetProperty(player.outputUnit!, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, UInt32(MemoryLayout<AURenderCallbackStruct>.size)),
        operation: "AudioUnitSetProperty failed")

    // Initialize the unit
    CheckError(AudioUnitInitialize(player.outputUnit!),
        operation: "Couldn't initialize output unit")
}

func main() {
    var player = SineWavePlayer()

    // Set up output unit and callback
    CreateAndConnectOutputUnit(&player)

    // Start playing
    CheckError(AudioOutputUnitStart(player.outputUnit!),
        operation: "Couldn't start output unit")

    // Play for 5 seconds
    sleep(5)

    // Clean up
    AudioOutputUnitStop(player.outputUnit!)
    AudioUnitUninitialize(player.outputUnit!)
    AudioComponentInstanceDispose(player.outputUnit!)
}

main()
<代码>导入基础 导入音频工具箱 设正弦频率=880.0 //标记:用户数据结构 结构正弦波播放器{ var输出单位:音频单位?=零 var startingFrameCount:Double=0 } //标记:回调函数 让SineWaveRenderProc:AURenderCallback={(inRefCon、ioActionFlags、inTimeStamp、inBusNumber、inNumberFrames、ioData)->OSStatus in var player=unsafemeutablepointer(inRefCon) var j=player.pointee.startingFrameCount 让循环长度=44100/正弦频率 对于0中的帧,循环长度{ j-=循环长度 } } player.pointee.startingFrameCount=j 返回noErr } //标记:效用函数 func CheckError(error:OSStatus,operation:String){ 保护错误!=noErr else{ 返回 } 变量结果:String=“” var char=Int(error.bigEndian)
对于Swift 3中的u in 0..,不能使用初始值设定项转换指针类型。在您的情况下,refcon中的
类型是
UnsafemeutableRawPointer
,因此需要使用
assumingMemoryBound(to:)
方法

还有一点,传递给回调函数的
播放器
的地址需要在声音播放时始终保持稳定,从inout参数(由
&
前缀指定)获取的地址不满足此要求

上面的两件事是固定的,您的代码应该是这样的:

import Foundation
import AudioToolbox

let sineFrequency = 880.0

// MARK: User data struct
struct SineWavePlayer {
    var outputUnit: AudioUnit? = nil
    var startingFrameCount: Double = 0
}

// MARK: Callback function
let SineWaveRenderProc: AURenderCallback = {(inRefCon, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData) -> OSStatus in

    var player = inRefCon.assumingMemoryBound(to: SineWavePlayer.self)


    var j = player.pointee.startingFrameCount
    let cycleLength = 44100 / sineFrequency

    for frame in 0..<inNumberFrames {
        var buffers = UnsafeMutableAudioBufferListPointer(ioData)

        buffers?[0].mData?.assumingMemoryBound(to: Float32.self)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))
        buffers?[1].mData?.assumingMemoryBound(to: Float32.self)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))

        j += 1
        if j > cycleLength {
            j -= cycleLength
        }
    }

    player.pointee.startingFrameCount = j
    return noErr
}

// MARK: Utility function
func CheckError(_ error: OSStatus, operation: String) {
    guard error != noErr else {
        return
    }

    var result: String = ""
    var char = Int(error.bigEndian)

    for _ in 0..<4 {
        guard isprint(Int32(char&255)) == 1 else {
            result = "\(error)"
            break
        }
        result.append(String(describing: UnicodeScalar(char&255)))
        char = char/256
    }

    print("Error: \(operation) (\(result))")

    exit(1)
}

func CreateAndConnectOutputUnit(_ playerPtr: UnsafeMutablePointer<SineWavePlayer>) {
    // Generate a description that matches the output device (speakers)
    var outputcd = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_DefaultOutput, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)

    let comp = AudioComponentFindNext(nil, &outputcd)

    if comp == nil {
        print("Can't get output unit")
        exit(-1)
    }

    CheckError(AudioComponentInstanceNew(comp!, &playerPtr.pointee.outputUnit),
               operation: "Couldn't open component for outputUnit")

    // Register the render callback
    var input = AURenderCallbackStruct(inputProc: SineWaveRenderProc, inputProcRefCon: playerPtr)

    CheckError(AudioUnitSetProperty(playerPtr.pointee.outputUnit!, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, UInt32(MemoryLayout<AURenderCallbackStruct>.size)),
               operation: "AudioUnitSetProperty failed")

    // Initialize the unit
    CheckError(AudioUnitInitialize(playerPtr.pointee.outputUnit!),
               operation: "Couldn't initialize output unit")
}

func main() {
    let playerPtr = UnsafeMutablePointer<SineWavePlayer>.allocate(capacity: 1)
    defer {playerPtr.deallocate(capacity: 1)}
    playerPtr.initialize(to: SineWavePlayer())
    defer {playerPtr.deinitialize()}

    // Set up output unit and callback
    CreateAndConnectOutputUnit(playerPtr)

    // Start playing
    CheckError(AudioOutputUnitStart(playerPtr.pointee.outputUnit!),
               operation: "Couldn't start output unit")

    // Play for 5 seconds
    sleep(5)

    // Clean up
    AudioOutputUnitStop(playerPtr.pointee.outputUnit!)
    AudioUnitUninitialize(playerPtr.pointee.outputUnit!)
    AudioComponentInstanceDispose(playerPtr.pointee.outputUnit!)
}
<代码>导入基础 导入音频工具箱 设正弦频率=880.0 //标记:用户数据结构 结构正弦波播放器{ var输出单位:音频单位?=零 var startingFrameCount:Double=0 } //标记:回调函数 让SineWaveRenderProc:AURenderCallback={(inRefCon、ioActionFlags、inTimeStamp、inBusNumber、inNumberFrames、ioData)->OSStatus in var player=inRefCon.assumingmemorybind(到:SineWavePlayer.self) var j=player.pointee.startingFrameCount 让循环长度=44100/正弦频率 对于0中的帧,循环长度{ j-=循环长度 } } player.pointee.startingFrameCount=j 返回noErr } //标记:效用函数 func CheckError(error:OSStatus,operation:String){ 保护错误!=noErr else{ 返回 } 变量结果:String=“” var char=Int(error.bigEndian)
对于0中的uu。您可以使用与中相同的方法。@MartinR,
SineWavePlayer
是struct,因此相同的方法不起作用。@OOPer:refcon是一个指针,因此使
SineWavePlayer
类更有意义。您能写几行代码吗?应该是什么样的?@MartinR,refcon是类型为
vo的通用指针id*
。将对象引用传递到
void*
是一种黑客行为。我真的怀疑这种黑客行为是否更有意义。谢谢!现在我明白了。现在一切都好了!
import Foundation
import AudioToolbox

let sineFrequency = 880.0

// MARK: User data struct
struct SineWavePlayer {
    var outputUnit: AudioUnit? = nil
    var startingFrameCount: Double = 0
}

// MARK: Callback function
let SineWaveRenderProc: AURenderCallback = {(inRefCon, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData) -> OSStatus in

    var player = inRefCon.assumingMemoryBound(to: SineWavePlayer.self)


    var j = player.pointee.startingFrameCount
    let cycleLength = 44100 / sineFrequency

    for frame in 0..<inNumberFrames {
        var buffers = UnsafeMutableAudioBufferListPointer(ioData)

        buffers?[0].mData?.assumingMemoryBound(to: Float32.self)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))
        buffers?[1].mData?.assumingMemoryBound(to: Float32.self)[Int(frame)] = Float32(sin(2 * M_PI * (j / cycleLength)))

        j += 1
        if j > cycleLength {
            j -= cycleLength
        }
    }

    player.pointee.startingFrameCount = j
    return noErr
}

// MARK: Utility function
func CheckError(_ error: OSStatus, operation: String) {
    guard error != noErr else {
        return
    }

    var result: String = ""
    var char = Int(error.bigEndian)

    for _ in 0..<4 {
        guard isprint(Int32(char&255)) == 1 else {
            result = "\(error)"
            break
        }
        result.append(String(describing: UnicodeScalar(char&255)))
        char = char/256
    }

    print("Error: \(operation) (\(result))")

    exit(1)
}

func CreateAndConnectOutputUnit(_ playerPtr: UnsafeMutablePointer<SineWavePlayer>) {
    // Generate a description that matches the output device (speakers)
    var outputcd = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_DefaultOutput, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)

    let comp = AudioComponentFindNext(nil, &outputcd)

    if comp == nil {
        print("Can't get output unit")
        exit(-1)
    }

    CheckError(AudioComponentInstanceNew(comp!, &playerPtr.pointee.outputUnit),
               operation: "Couldn't open component for outputUnit")

    // Register the render callback
    var input = AURenderCallbackStruct(inputProc: SineWaveRenderProc, inputProcRefCon: playerPtr)

    CheckError(AudioUnitSetProperty(playerPtr.pointee.outputUnit!, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, UInt32(MemoryLayout<AURenderCallbackStruct>.size)),
               operation: "AudioUnitSetProperty failed")

    // Initialize the unit
    CheckError(AudioUnitInitialize(playerPtr.pointee.outputUnit!),
               operation: "Couldn't initialize output unit")
}

func main() {
    let playerPtr = UnsafeMutablePointer<SineWavePlayer>.allocate(capacity: 1)
    defer {playerPtr.deallocate(capacity: 1)}
    playerPtr.initialize(to: SineWavePlayer())
    defer {playerPtr.deinitialize()}

    // Set up output unit and callback
    CreateAndConnectOutputUnit(playerPtr)

    // Start playing
    CheckError(AudioOutputUnitStart(playerPtr.pointee.outputUnit!),
               operation: "Couldn't start output unit")

    // Play for 5 seconds
    sleep(5)

    // Clean up
    AudioOutputUnitStop(playerPtr.pointee.outputUnit!)
    AudioUnitUninitialize(playerPtr.pointee.outputUnit!)
    AudioComponentInstanceDispose(playerPtr.pointee.outputUnit!)
}