i'm trying play pure sine wave tone using core audio audioqueue's (swift 3).
it plays nicely, i'm getting popping noises every time audioqueueoutputcallback invoked fill new buffer audio data.
my audiostreamer class looks like:
let knumberbuffers = 3 protocol audiostreamerdelegate { func requestaudiodata() -> [float] } let samplerate = 48000.0 let buffersize = int(samplerate) / 50 let bufferbytesize = uint32(buffersize * sizeof(float)) // 20 mili sec of audio class audiostreamer { var delegate: audiostreamerdelegate var outputqueue: audioqueueref? var buffers = [audioqueuebufferref?](repeatelement(nil, count: knumberbuffers)) var streambasicdescription = audiostreambasicdescription( msamplerate: samplerate, mformatid: kaudioformatlinearpcm, mformatflags: kaudioformatflagsnativefloatpacked | kaudioformatflagisnoninterleaved, mbytesperpacket: uint32(sizeof(float)), mframesperpacket: 1, mbytesperframe: uint32(sizeof(float)), mchannelsperframe: 1, mbitsperchannel: uint32(8 * sizeof(float)), mreserved: 0 ) init(delegate: audiostreamerdelegate) { // create new output audio queue self.delegate = delegate } func play() { let queue = dispatchqueue.main queue.async(execute: { let selfpointer = unsafebitcast(self, to: unsafemutablepointer<void>.self) audioqueuenewoutput( &self.streambasicdescription, audiostreamerouputcallback, selfpointer, nil, nil, 0, &self.outputqueue ) // allocate buffers in 0 ..< knumberbuffers { audioqueueallocatebuffer( self.outputqueue!, bufferbytesize, &self.buffers[i] ) if let bufferref = self.buffers[i] { // configure audio buffer let selfpointer = unsafebitcast(self, to: unsafemutablepointer<void>.self) bufferref.pointee.muserdata = selfpointer bufferref.pointee.maudiodatabytesize = bufferbytesize } } audioqueueprime(self.outputqueue!, 0, nil) bufferref in self.buffers { audiostreamerouputcallback(userdata: unsafebitcast(self, to: unsafemutablepointer<void>.self), queueref: self.outputqueue!, buffer: bufferref!) } audioqueuestart(self.outputqueue!, nil) }) } } func audiostreamerouputcallback(userdata: optional<unsafemutablepointer<void>>, queueref: audioqueueref, buffer: audioqueuebufferref) { let = unmanaged<audiostreamer>.fromopaque(opaquepointer(userdata!)).takeunretainedvalue() let audiodata = this.delegate.requestaudiodata() memcpy(buffer.pointee.maudiodata, unsafebitcast(audiodata, to: unsafemutablepointer<void>.self), int(bufferbytesize)) audioqueueenqueuebuffer(queueref, buffer, 0, nil) }
audio data generator method of viewcontroller class "play" button (theta stored property on viewcontroller):
func generateaudiodata(frequency: double) { semaphore.wait() let amplitude: double = 0.25 let theta_increment: double = 2.0 * m_pi * frequency / samplerate j in 0 ..< int(buffersize) { audiodata[j] = float(sin(theta) * amplitude) theta += theta_increment if theta > 2.0 * m_pi { theta -= 2.0 * m_pi } } }
the problem looks similar on this question, nobody answered.
any appreciated.
in output callback, did not generate new set of audio data, phase of new buffer's first sample increment of last sample of previous buffer.
Comments
Post a Comment