gpt4 book ai didi

c++ - 如何使用 AudioQueue 在 C++ 中为 Mac OSX 播放声音

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:02:56 24 4
gpt4 key购买 nike

我正在尝试在 OSX 上从缓冲区播放声音(例如:等效于 Windows“PlaySound”功能)。

我整理了一些 C++ 代码来使用 AudioQueue 播放音频(据我所知,这是在 OSX 上播放音频的最简单方法)。

但是,不会产生声音,也不会调用音频回调函数。

有没有人知道我做错了什么,或者有没有人有一个简单的 C/C++ 示例来说明如何在 OSX 上播放声音?


#include
#include

#define BUFFER_COUNT 3
static struct AQPlayerState {
AudioStreamBasicDescription desc;
AudioQueueRef queue;
AudioQueueBufferRef buffers[BUFFER_COUNT];
unsigned buffer_size;
} state;

static void audio_callback (void *aux, AudioQueueRef aq, AudioQueueBufferRef bufout)
{
printf("I never get called!\n");
#define nsamples 4096
short data[nsamples];
for (int i=0;imAudioDataByteSize = nsamples * sizeof(short) * 1;

assert(bufout->mAudioDataByteSize mAudioData, data, bufout->mAudioDataByteSize);

AudioQueueEnqueueBuffer(state.queue, bufout, 0, NULL);
}

void audio_init()
{
int i;

bzero(&state, sizeof(state));

state.desc.mFormatID = kAudioFormatLinearPCM;
state.desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
state.desc.mSampleRate = 44100;
state.desc.mChannelsPerFrame = 1;
state.desc.mFramesPerPacket = 1;
state.desc.mBytesPerFrame = sizeof (short) * state.desc.mChannelsPerFrame;
state.desc.mBytesPerPacket = state.desc.mBytesPerFrame;
state.desc.mBitsPerChannel = (state.desc.mBytesPerFrame*8)/state.desc.mChannelsPerFrame;
state.desc.mReserved = 0;

state.buffer_size = state.desc.mBytesPerFrame * state.desc.mSampleRate;

if (noErr != AudioQueueNewOutput(&state.desc, audio_callback, 0, NULL, NULL, 0, &state.queue)) {
printf("audioqueue error\n");
return;
}

// Start some empty playback so we'll get the callbacks that fill in the actual audio.
for (i = 0; i mAudioDataByteSize = state.buffer_size;
AudioQueueEnqueueBuffer(state.queue, state.buffers[i], 0, NULL);
}
if (noErr != AudioQueueStart(state.queue, NULL)) printf("AudioQueueStart failed\n");
printf("started audio\n");
}


int main() {
audio_init();
while (1) {
printf("I can't hear anything!\n");
}
}

最佳答案

引用:

请注意,我必须明确地将 mAudioDataByteSize 设置为我分配的大小。在文档中,他们提到它最初设置为零,这就是我发现的。文档没有说明原因,但我怀疑这是为了允许可变大小的缓冲区或其他东西?

/* Ben's Audio Example for OSX 10.5+ (yeah Audio Queue)
Ben White, Nov, 2011

Makefile:


example: example.c
gcc -o $@ $< -Wimplicit -framework AudioToolbox \
-framework CoreFoundation -lm

*/

#include "AudioToolbox/AudioToolbox.h"

typedef struct {
double phase, phase_inc;
int count;
} PhaseBlah;


void callback (void *ptr, AudioQueueRef queue, AudioQueueBufferRef buf_ref)
{
OSStatus status;
PhaseBlah *p = ptr;
AudioQueueBuffer *buf = buf_ref;
int nsamp = buf->mAudioDataByteSize / 2;
short *samp = buf->mAudioData;
int ii;
printf ("Callback! nsamp: %d\n", nsamp);
for (ii = 0; ii < nsamp; ii++) {
samp[ii] = (int) (30000.0 * sin(p->phase));
p->phase += p->phase_inc;
//printf("phase: %.3f\n", p->phase);
}
p->count++;
status = AudioQueueEnqueueBuffer (queue, buf_ref, 0, NULL);
printf ("Enqueue status: %d\n", status);
}


int main (int argc, char *argv[])
{
AudioQueueRef queue;
PhaseBlah phase = { 0, 2 * 3.14159265359 * 450 / 44100 };
OSStatus status;
AudioStreamBasicDescription fmt = { 0 };
AudioQueueBufferRef buf_ref, buf_ref2;

fmt.mSampleRate = 44100;
fmt.mFormatID = kAudioFormatLinearPCM;
fmt.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
fmt.mFramesPerPacket = 1;
fmt.mChannelsPerFrame = 1; // 2 for stereo
fmt.mBytesPerPacket = fmt.mBytesPerFrame = 2; // x2 for stereo
fmt.mBitsPerChannel = 16;

status = AudioQueueNewOutput(&fmt, callback, &phase, CFRunLoopGetCurrent(),
kCFRunLoopCommonModes, 0, &queue);

if (status == kAudioFormatUnsupportedDataFormatError) puts ("oops!");
else printf("NewOutput status: %d\n", status);

status = AudioQueueAllocateBuffer (queue, 20000, &buf_ref);
printf ("Allocate status: %d\n", status);

AudioQueueBuffer *buf = buf_ref;
printf ("buf: %p, data: %p, len: %d\n", buf, buf->mAudioData, buf->mAudioDataByteSize);
buf->mAudioDataByteSize = 20000;

callback (&phase, queue, buf_ref);

status = AudioQueueAllocateBuffer (queue, 20000, &buf_ref2);
printf ("Allocate2 status: %d\n", status);

buf = buf_ref2;
buf->mAudioDataByteSize = 20000;

callback (&phase, queue, buf_ref2);

status = AudioQueueSetParameter (queue, kAudioQueueParam_Volume, 1.0);
printf ("Volume status: %d\n", status);

status = AudioQueueStart (queue, NULL);
printf ("Start status: %d\n", status);

while (phase.count < 15)
CFRunLoopRunInMode (
kCFRunLoopDefaultMode,
0.25, // seconds
false // don't return after source handled
);

return 0;
}

关于c++ - 如何使用 AudioQueue 在 C++ 中为 Mac OSX 播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4863811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com