在由第三方库解码的iPhone上播放音频 [英] Playing audio on the iPhone decoded by a third-party library
问题描述
第三方库生成任意大小的16位带符号立体声样本的连续缓冲区。我无法弄清楚要从这些缓冲区中使用哪些框架/函数。我一直在这个答案中使用这个例子 AudioQueue
但它显然不完整我无法解决(局部变量被用作对象成员,未声明的变量等)。
The third-party library generates sequential buffers of 16-bit signed stereo samples of any desired size. I can't figure out which framework/functions to use to play from these buffers. I've been working off the example in this answer using AudioQueue
but it's obviously incomplete in ways I can't resolve (local variables are used as if they are object members, undeclared variables, etc).
Apple的SpeakHere示例项目中的代码仅显示如何使用AudioQueue播放文件中的音频。有人能指出我正确的方向吗?
The code in Apple's SpeakHere example project only shows how to use AudioQueue to play audio from a file. Can someone point me in the right direction?
推荐答案
想出来。这是一个简单,完整的工作白噪声生成器,它使用从基于Window的应用程序项目模板创建的AudioQueue。
Figured it out. Here's a simple, complete and working white noise generator using AudioQueue created from the Window-based Application project template.
StaticAppDelegate.h :
// StaticAppDelegate.h
#import <UIKit/UIKit.h>
// STATIC ADDITIONS
// Add > Existing Frameworks... > AudioToolbox.framework to your Target
#import <AudioToolbox/AudioToolbox.h>
// END STATIC ADDITIONS
@interface StaticAppDelegate : NSObject <UIApplicationDelegate> {
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
并使用某种类型转换),其他一切都已落实到位。
Once I figured out how to actually refill the buffer (inBuffer->mAudioData
with some type casting) everything else fell into place.
这篇关于在由第三方库解码的iPhone上播放音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!