Skip to content

Instantly share code, notes, and snippets.

@mhamilt
Last active September 11, 2019 12:33
Show Gist options
  • Save mhamilt/9a29a409349d0558f078d1a2ec3c7c50 to your computer and use it in GitHub Desktop.
Save mhamilt/9a29a409349d0558f078d1a2ec3c7c50 to your computer and use it in GitHub Desktop.
A CLI sine sweep in Swift
//------------------------------------------------------------------------------
import AVFoundation
//------------------------------------------------------------------------------
var secondsOfAudio:Float = 0.5; // or var secondsOfAudio:Float = Float(CommandLine.arguments[1])!;
//------------------------------------------------------------------------------
var ae:AVAudioEngine? = AVAudioEngine()
var player:AVAudioPlayerNode? = AVAudioPlayerNode()
var mixer:AVAudioMixerNode? = ae?.mainMixerNode;
//------------------------------------------------------------------------------
let sr:Float = Float((mixer?.outputFormat(forBus: 0).sampleRate)!)
let samplesOfAudio = UInt32 (secondsOfAudio * sr)
let n_channels = mixer?.outputFormat(forBus: 0).channelCount
var buffer:AVAudioPCMBuffer? = AVAudioPCMBuffer(pcmFormat: (player?.outputFormat(forBus: 0))!, frameCapacity: samplesOfAudio)
buffer?.frameLength = samplesOfAudio
//------------------------------------------------------------------------------
func convertToRange(number: Float, min: Float, max:Float) -> Float {
return (number - min) / (max - min)
}
//------------------------------------------------------------------------------
// generate sine wave
for i in stride(from:0, to: Int((buffer?.frameLength)!), by: Int(n_channels!))
{
for n in 0..<n_channels!
{
let scale = convertToRange(number: Float(i),
min: 0,
max: Float((buffer?.frameLength)!/2));
let freq = ((Float(n+1) * scale) + 1) * 441.0
let val = sinf(freq*Float(i)*2*Float(Double.pi)/sr)
buffer?.floatChannelData![Int(n)][i] = val * 0.5
}
}
//------------------------------------------------------------------------------
// setup audio engine
ae?.attach(player!)
ae?.connect(player!, to: mixer!, format: player?.outputFormat(forBus: 0))
do{
try ae?.start()
} catch {
}
//------------------------------------------------------------------------------
// play player and buffer
player?.play()
player?.scheduleBuffer(buffer!, at: nil, options: .interrupts, completionHandler: {
player = nil
})
while(player != nil){}
//------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment