Audio Synthesis
Posted: Mon Feb 25, 2013 6:40 pm
The code below creates a simple audio stream for audio synthesis.
What it does is already possible using PortAudio but this is a native approach not requiring anything else.
Include file
What it does is already possible using PortAudio but this is a native approach not requiring anything else.
Include file
Code: Select all
; AudioStream.pbi
#AUDIOBUFFER_SIZE = 16384
#AUDIOBUFFER_SAMPLES = #AUDIOBUFFER_SIZE >> 3
Structure AudioStreamBasicDescription
mSampleRate.d
mFormatID.l
mFormatFlags.l
mBytesPerPacket.l
mFramesPerPacket.l
mBytesPerFrame.l
mChannelsPerFrame.l
mBitsPerChannel.l
mReserved.l
EndStructure
Structure AudioQueueBuffer
mAudioDataBytesCapacity.i
mAudioData.i
mAudioDataByteSize.i
mUserData.i
mPacketDescriptionCapacity.i
mPacketDescriptions.i
mPacketDescriptionCount.i
EndStructure
Structure AudioStreamStereoSample
l.f
r.f
EndStructure
Structure AudioStreamSamples
StructureUnion
s.d[0]
ss.AudioStreamStereoSample[0]
EndStructureUnion
EndStructure
ImportC "/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox"
AudioQueueAllocateBuffer(inAQ, inBufferByteSize, *outBuffer)
AudioQueueDispose(inAQ, inImmediate = #True)
AudioQueueEnqueueBuffer(inAQ, inBuffer, inNumPacketDescs = 0, *inPacketDescs = #Null)
AudioQueueNewOutput(*inFormat, inCallbackProc, *inUserData, inCallbackRunLoop, inCallbackRunLoopMode, inFlags, *outAQ)
AudioQueueSetParameter(inAQ, inParamID, inValue.f)
AudioQueueStart(inAQ, *inStartTime = #Null)
AudioQueueStop(inAQ, inImmediate = #True)
EndImport
Prototype AudioStream_Callback_Proto(*SampleData.Float)
Global AudioStream_Callback.AudioStream_Callback_Proto
Global *AudioStream_Buf1.AudioQueueBuffer, *AudioStream_Buf2.AudioQueueBuffer
Global AudioStream_Queue = 0
ProcedureC AudioStream_Callback_(*ptr, queue, *buf.AudioQueueBuffer)
AudioStream_Callback(*buf\mAudioData)
AudioQueueEnqueueBuffer(queue, *buf)
EndProcedure
Procedure AudioStream_Init(*Callback, Stereo = #False)
AudioStream_Callback = *Callback
Protected fmt.AudioStreamBasicDescription
fmt\mSampleRate = 44100
fmt\mFormatID = $6C70636D; kAudioFormatLinearPCM
fmt\mFormatFlags = 1; kAudioFormatFlagIsFloat
fmt\mFramesPerPacket = 1
fmt\mBytesPerFrame = 8
fmt\mBytesPerPacket = 8
If Stereo
fmt\mChannelsPerFrame = 2
fmt\mBitsPerChannel = 32
Else
fmt\mChannelsPerFrame = 1
fmt\mBitsPerChannel = 64
EndIf
If AudioQueueNewOutput(@fmt, @AudioStream_Callback_(), #Null, #Null, #Null, 0, @AudioStream_Queue) = 0
AudioQueueAllocateBuffer(AudioStream_Queue, #AUDIOBUFFER_SIZE, @*AudioStream_Buf1)
AudioQueueAllocateBuffer(AudioStream_Queue, #AUDIOBUFFER_SIZE, @*AudioStream_Buf2)
*AudioStream_Buf1\mAudioDataByteSize = #AUDIOBUFFER_SIZE
*AudioStream_Buf2\mAudioDataByteSize = #AUDIOBUFFER_SIZE
EndIf
EndProcedure
Procedure AudioStream_SetVolume(volume.f)
If AudioStream_Queue
AudioQueueSetParameter(AudioStream_Queue, 1, volume); 1 = kAudioQueueParam_Volume
EndIf
EndProcedure
Procedure AudioStream_Start()
If AudioStream_Queue
AudioStream_Callback_(#Null, AudioStream_Queue, *AudioStream_Buf1)
AudioStream_Callback_(#Null, AudioStream_Queue, *AudioStream_Buf2)
AudioQueueStart(AudioStream_Queue)
EndIf
EndProcedure
Procedure AudioStream_Stop()
If AudioStream_Queue
AudioQueueStop(AudioStream_Queue)
EndIf
EndProcedure
Procedure AudioStream_Dispose()
If AudioStream_Queue
AudioQueueDispose(AudioStream_Queue)
AudioStream_Queue = 0
EndIf
EndProcedure