第三方库生成任意大小的16位带符号立体声样本的顺序缓冲区.我无法弄清楚要从这些缓冲区中使用哪些框架/函数.我一直在使用这个答案的例子,AudioQueue
但它显然是不完整的,我无法解决(局部变量被用作对象成员,未声明的变量等).
Apple的SpeakHere示例项目中的代码仅显示如何使用AudioQueue播放文件中的音频.有人能指出我正确的方向吗?
弄清楚了.这是一个简单,完整且有效的白噪声发生器,它使用基于Window的应用程序项目模板创建的AudioQueue.
StaticAppDelegate.h:
// StaticAppDelegate.h #import// STATIC ADDITIONS // Add > Existing Frameworks... > AudioToolbox.framework to your Target #import // END STATIC ADDITIONS @interface StaticAppDelegate : NSObject { UIWindow *window; } @property (nonatomic, retain) IBOutlet UIWindow *window; // STATIC ADDITIONS - (void)startStatic; - (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ buffer:(AudioQueueBufferRef)inBuffer; // END STATIC ADDITIONS @end
StaticAppDelegate.m:
// StaticAppDelegate.m #import "StaticAppDelegate.h" // STATIC ADDITIONS #define kNumberBuffers 4 #define kBufferSize 2048 // AudioQueue callback void AQOutputCallback( void *inData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer ) { StaticAppDelegate *staticApp = (StaticAppDelegate *)inData; [staticApp handleBufferCompleteForQueue:inAQ buffer:inBuffer]; } // END STATIC ADDITIONS @implementation StaticAppDelegate @synthesize window; - (void)applicationDidFinishLaunching:(UIApplication *)application { // Override point for customization after application launch [window makeKeyAndVisible]; // STATIC ADDITIONS [self startStatic]; // END STATIC ADDITIONS } - (void)dealloc { [window release]; [super dealloc]; } // STATIC ADDITIONS - (void)startStatic { srandom(time(NULL)); // initiate audio session AudioSessionInitialize(NULL, NULL, NULL, NULL); UInt32 category = kAudioSessionCategory_MediaPlayback; // plays through sleep lock and silent switch AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category); AudioSessionSetActive(true); // following is modified from http://stackoverflow.com/questions/1710133/playing-generated-audio-on-an-iphone // setup queue AudioQueueRef audioQueue; AudioQueueBufferRef buffers[kNumberBuffers]; AudioStreamBasicDescription format; memset(&format, 0, sizeof(format)); format.mSampleRate = 44100; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; format.mChannelsPerFrame = 1; format.mBitsPerChannel = 16; format.mBytesPerFrame = (format.mBitsPerChannel / 8) * format.mChannelsPerFrame; format.mFramesPerPacket = 1; format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket; AudioQueueNewOutput(&format, AQOutputCallback, self, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &audioQueue); // allocate and fill the buffers for (int i = 0; i < kNumberBuffers; ++i) { AudioQueueAllocateBuffer(audioQueue, kBufferSize, &buffers[i]); AQOutputCallback(self, audioQueue, buffers[i]); } AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1.0); AudioQueueStart(audioQueue, NULL); } - (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ buffer:(AudioQueueBufferRef)inBuffer { inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity; int *buffer = (int *)inBuffer->mAudioData; for (int i = 0; i < inBuffer->mAudioDataByteSize/sizeof(int); ++i) { buffer[i] = (int)rand(); // refill the buffer } AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL); } // END STATIC ADDITIONS @end
一旦我弄清楚如何实际重新填充缓冲区(inBuffer->mAudioData
使用某种类型的铸造),其他一切都已落实到位.