Skip to content

Instantly share code, notes, and snippets.

@lucaskuzma
Created January 4, 2021 13:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucaskuzma/f06e0d43e1d0df6c2dae96e174ed49ac to your computer and use it in GitHub Desktop.
Save lucaskuzma/f06e0d43e1d0df6c2dae96e174ed49ac to your computer and use it in GitHub Desktop.
inline all the things
func createGrainNode() -> AVAudioSourceNode? {
guard let audioBuffer = self.source?.audioBuffer,
let sourceData = audioBuffer.floatChannelData else {
return nil
}
grainEngine = GrainEngine(withBuffer: sourceData, length: audioBuffer.frameLength, channels: audioBuffer.stride)
let count = 40000
var grainCount = 0
let bufferLength = audioBuffer.frameLength
let bufferIndex = bufferLength / 2
let indicesPointer = UnsafeMutablePointer<UInt32>.allocate(capacity: count)
return AVAudioSourceNode { _, _, frameCount, audioBufferList -> OSStatus in
let bufferListPointer = UnsafeMutableAudioBufferListPointer(audioBufferList)
let density = self.grainEngine?.density ?? 0.0
for frame in 0..<Int(frameCount) {
if Double(grainCount) < density * Double(count) {
grainCount += 1
}
var sampleSum = SIMD2<Float>(0.0, 0.0)
// iterate over grains and accumulate samples
for i in 0..<grainCount {
let index = (indicesPointer+i).pointee
let grainIndex:Int = Int((bufferIndex + index) % bufferLength)
var sample = SIMD2<Float>(0.0, 0.0)
sample.x = sourceData[0][grainIndex]
sample.y = sourceData[1][grainIndex]
sampleSum += sample
(indicesPointer + i).pointee = (index + 1) % 44100
}
sampleSum = sampleSum / Float(grainCount)
for channel in 0..<bufferListPointer.count {
let outBuffer:UnsafeMutableBufferPointer<Float> = UnsafeMutableBufferPointer(bufferListPointer[channel])
outBuffer[frame] = channel == 0 ? sampleSum.x : sampleSum.y
}
}
return noErr
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment