I have the following AUGraph code that connects a SineWave Generator to a multichannel mixer, to an output device, this is ok, however, when you play, the tone generated seems to be corrupt...it's almost there, but something is wrong.
Any ideas?
import Cocoa
import CoreAudio
import AudioToolbox
import AudioUnit
import AVFoundation
let sampleRate:Float64 = 41000.0
class ViewController: NSViewController {
var t = 0
let callback2:AURenderCallback = {
(inRefCon: UnsafeMutablePointer<Void>, ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>)
in
let delta:Float = Float(880 * 2 * M_PI / sampleRate)
let abl = UnsafeMutableAudioBufferListPointer(ioData)
var x:Float = 0
for buffer:AudioBuffer in abl {
//x = self._x
memset(buffer.mData, 0, Int(buffer.mDataByteSize))
let s = sizeof(Float)
let r = sizeof(Float32)
let f = abl.count
let buf:UnsafeMutablePointer<Float> = unsafeBitCast(buffer.mData, UnsafeMutablePointer<Float>.self)
for var i:Int = 0; i < Int(inNumberFrames); i++
{
buf[i] = sin(x)
x += delta
}
memcpy(buffer.mData, buf, Int(buffer.mDataByteSize));
let x = 0
}
return noErr
}
struct MyAUGraphPlayer
{
var streamFormat:AudioStreamBasicDescription!
var graph:AUGraph = AUGraph()
var outputNode:AUNode!
var mixerNode:AUNode!
var outputUnit:AudioUnit!
var mixerUnit:AudioUnit!
var firstOutputSampleTime:Float64 = 0.0
init()
{
}
}
func addAUNode(graph:AUGraph, inout desc:AudioComponentDescription) -> AUNode
{
var outputNode:AUNode = AUNode()
let x = AUGraphAddNode(graph, &desc, &outputNode)
print("x: \(x)")
return outputNode
}
override func viewDidLoad() {
super.viewDidLoad()
doit()
}
func doit()
{
var desc:AudioStreamBasicDescription = AudioStreamBasicDescription()
desc.mSampleRate = sampleRate
desc.mFormatID = kAudioFormatLinearPCM
desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked
desc.mFramesPerPacket = 1
desc.mChannelsPerFrame = 2
desc.mBitsPerChannel = UInt32(sizeof(Float32) * 8)
desc.mBytesPerFrame = desc.mChannelsPerFrame * (desc.mBitsPerChannel / 8)
desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket
var graph:AUGraph = AUGraph()
var outputNode:AUNode = AUNode()
var mixerNode:AUNode = AUNode()
var outputUnit:AudioUnit = AudioUnit()
var mixerUnit:AudioUnit = AudioUnit()
let error = NewAUGraph(&graph)
print("error: \(error)")
// Output
var outputDesc:AudioComponentDescription = AudioComponentDescription(componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_DefaultOutput),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0)
let a1 = AUGraphAddNode(graph, &outputDesc, &outputNode)
print("a1: \(a1)")
// Mixer
var mixerDesc:AudioComponentDescription = AudioComponentDescription(componentType: OSType(kAudioUnitType_Mixer), componentSubType: OSType(kAudioUnitSubType_StereoMixer), componentManufacturer: OSType(kAudioUnitManufacturer_Apple), componentFlags: 0, componentFlagsMask: 0)
let b1 = AUGraphAddNode(graph, &mixerDesc, &mixerNode)
print("b1: \(b1)")
// Connect nodes
let y = AUGraphConnectNodeInput(graph,
mixerNode,
0,
outputNode,
0)
print("y: \(y)")
// open
let open = AUGraphOpen(graph)
print("graph should be open: \(open)")
let ufa = AUGraphNodeInfo(graph, mixerNode, nil, &mixerUnit);
print("ufa: \(ufa)")
let uf = AUGraphNodeInfo(graph, outputNode, nil, &outputUnit);
print("uf: \(uf)")
// output
// let w = AudioUnitSetProperty(outputUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Output,
// 0,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription) ))
// print("w: \(w)")
// let w2 = AudioUnitSetProperty(outputUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Input,
// 0,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription) ))
// print("w2: \(w2)")
//
var numbuses:UInt32 = 1
// let gg = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_ElementCount,
// kAudioUnitScope_Input,
// 0,
// &numbuses,
// UInt32(sizeof(UInt32)))
// print("gg: \(gg)")
// let s = sizeof(UInt32)
// numbuses = 1
// let gg2 = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_ElementCount,
// kAudioUnitScope_Output,
// 0,
// &numbuses,
// UInt32(sizeof(UInt32)))
// print("gg2: \(gg2)")
// let m1 = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Output,
// 0,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription) ))
// print("m1: \(m1)")
numbuses = 1
for (var i:UInt32 = 0; i < numbuses; ++i)
{
//
//
let yy = AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, i, 1, 0);
print("yy: \(yy)")
let xx = AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, i, 1, 0);
print("xx: \(xx)")
let zz = AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Enable, kAudioUnitScope_Input, i, 1, 0);
print("zz: \(zz)")
let aa = AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Enable, kAudioUnitScope_Output, i, 1, 0);
print("aa: \(aa)")
var rcbs:AURenderCallbackStruct = AURenderCallbackStruct(inputProc: callback2, inputProcRefCon: &graph)
let result1 = AUGraphSetNodeInputCallback(graph, mixerNode, i, &rcbs)
print("result1: \(result1)")
// let sf1 = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Input,
// i,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription)))
// print("sf1: \(sf1)")
//
// let sf2 = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Output,
// i,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription)))
// print("sf2: \(sf2)")
}
// let sf2 = AudioUnitSetProperty(mixerUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Output,
// 0,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription)))
// print("sf2: \(sf2)")
//
//
// let o1 = AudioUnitSetProperty(outputUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Output,
// 1,
// &desc,
// UInt32(sizeof(AudioStreamBasicDescription)))
// print("o1: \(o1)")
//
let yu = AUGraphInitialize(graph)
print("yu: \(yu)")
let ee = AUGraphStart(graph)
print("ee: \(ee)")
CAShow(UnsafeMutablePointer(graph))
}
}
You ask for 2 channels per frame, but only enough bytes per packet for 1 channel. Check the error return values on your audio property setters.