何らかのデバイス(PC, iPhone, ...)から任意の波形を作り音を鳴らすための勉強しています。
Xcode 8.3.2
でiOSアプリを今作っています。
「swiftでCoreAudioを使ってみる。(swift3 update 2017-02)」のサンプルコードをほぼそのまま頂いて、ViewController.swift
からplay()
を呼び出す形にしてあります。
変更したのは、クラス名をMyAudioPlayer
からAudioPlayer
に変えたのと、M_PI
を.pi
に変えた点です。
編集したものが下のコードです。
swift
1import Foundation 2import AudioUnit 3import AudioToolbox 4import AVFoundation 5 6class AudioPlayer 7{ 8 var _audiounit: AudioUnit? = nil 9 var _x: Float = 0 10 let _sampleRate:Double = 44100 11 init() { 12 #if os(iOS) 13 let subtype = kAudioUnitSubType_RemoteIO 14 #else 15 let subtype = kAudioUnitSubType_HALOutput 16 #endif 17 var acd = AudioComponentDescription(componentType: kAudioUnitType_Output, 18 componentSubType:subtype, 19 componentManufacturer: kAudioUnitManufacturer_Apple, 20 componentFlags: 0, 21 componentFlagsMask: 0) 22 23 let ac = AudioComponentFindNext(nil, &acd) 24 AudioComponentInstanceNew(ac!, &_audiounit) 25 AudioUnitInitialize(_audiounit!); 26 // オーディオデータ供給を44100,ステレオ,標準フォーマット(Float32, Non-Interleave)に設定 27 let audioformat:AVAudioFormat = AVAudioFormat(standardFormatWithSampleRate: _sampleRate, channels: 2) 28 var asbd:AudioStreamBasicDescription = audioformat.streamDescription.pointee 29 AudioUnitSetProperty(_audiounit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &asbd, UInt32(MemoryLayout.size(ofValue: asbd))) 30 } 31 let callback: AURenderCallback = { 32 (inRefCon: UnsafeMutableRawPointer, 33 ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, 34 inTimeStamp: UnsafePointer<AudioTimeStamp>, 35 inBusNumber: UInt32, 36 inNumberFrames: UInt32, 37 ioData: UnsafeMutablePointer<AudioBufferList>?) 38 in 39 // ポインタからAudioPlayerインスタンスに変換 40 let AudioPlayer:AudioPlayer = Unmanaged<AudioPlayer>.fromOpaque(inRefCon).takeUnretainedValue() 41 AudioPlayer.render(inNumberFrames, ioData:ioData) 42 return noErr 43 } 44 func render(_ inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) { 45 let delta:Float = Float(443 * 2 * .pi / _sampleRate) 46 guard let abl = UnsafeMutableAudioBufferListPointer(ioData) else { 47 return 48 } 49 var x:Float = 0 50 for buffer:AudioBuffer in abl { 51 x = _x 52 let cap = Int(buffer.mDataByteSize)/MemoryLayout<Float>.size 53 assert(cap == Int(inNumberFrames)) 54 if let buf:UnsafeMutablePointer<Float> = buffer.mData?.bindMemory(to: Float.self, capacity: cap) { 55 for i:Int in 0 ..< Int(inNumberFrames) { 56 buf[i] = sin(x) 57 x += delta 58 } 59 } 60 } 61 if abl.count > 0 { 62 _x = x 63 } 64 } 65 func play() { 66 // AudioPlayerインスタンスをポインタに変換 67 let ref: UnsafeMutableRawPointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) 68 var callbackstruct:AURenderCallbackStruct = AURenderCallbackStruct(inputProc: callback, inputProcRefCon: ref) 69 AudioUnitSetProperty(_audiounit!, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callbackstruct, UInt32(MemoryLayout.size(ofValue: callbackstruct))) 70 71 AudioOutputUnitStart(_audiounit!) 72 } 73 func stop() { 74 AudioOutputUnitStop(_audiounit!) 75 } 76} 77
ほぼ問題なく起動と同時にラ(443Hz)の音が出るのですが、音程が一定しません。微妙にブレるのです。
原因は分かりますでしょうか?
対策はありますか?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/29 13:07
2017/05/31 13:20