如何在iPhone / Mac上与CoreAudio合成声音 [英] How do I synthesize sounds with CoreAudio on iPhone/Mac

查看:147
本文介绍了如何在iPhone / Mac上与CoreAudio合成声音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在iPhone中播放合成声音。而不是使用预录音和使用SystemSoundID播放一个现有的二进制,我想合成它。部分地,这是因为我想要能够连续播放声音(例如,当用户的手指在屏幕上)而不是一次性声音样本。

I'd like to play a synthesised sound in an iPhone. Instead of using a pre-recorded sound and using SystemSoundID to play an existing binary, I'd like to synthesise it. Partially, that's because I want to be able to play the sound continuously (e.g. when the user's finger is on the screen) instead of a one-off sound sample.

如果我想合成中A + 1(A4)(440Hz),我可以使用sin()计算正弦波;我不知道是如何将这些位安排到CoreAudio可以播放的数据包。

If I wanted to synthesise a Middle A+1 (A4) (440Hz), I can calculate a sine wave using sin(); what I don't know is how to arrange those bits into a packet which CoreAudio can then play. Most of the tutorials that exist on the net are concerned with simply playing existing binaries.

任何人都可以帮助我在440Hz的简单合成的正弦声波?

Can anyone help me with a simple synthesised sine sound wave at 440Hz?

推荐答案

你想做什么可能是设置一个AudioQueue。它允许您在回调中用合成音频数据填充缓冲区。您可以将AudeioQueue设置为在新线程中运行:

What you want to do it probably to setup an AudioQueue. It allows you to fill a buffer with synthesized audio data in a callback. You would setup the AudeioQueue to run in a new thread as such:

#define BUFFER_SIZE 16384
#define BUFFER_COUNT 3
static AudioQueueRef audioQueue;
void SetupAudioQueue() {
    OSStatus err = noErr;
    // Setup the audio device.
    AudioStreamBasicDescription deviceFormat;
    deviceFormat.mSampleRate = 44100;
    deviceFormat.mFormatID = kAudioFormatLinearPCM;
    deviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
    deviceFormat.mBytesPerPacket = 4;
    deviceFormat.mFramesPerPacket = 1;
    deviceFormat.mBytesPerFrame = 4;
    deviceFormat.mChannelsPerFrame = 2;
    deviceFormat.mBitsPerChannel = 16;
    deviceFormat.mReserved = 0;
    // Create a new output AudioQueue for the device.
    err = AudioQueueNewOutput(&deviceFormat, AudioQueueCallback, NULL,
                              CFRunLoopGetCurrent(), kCFRunLoopCommonModes,
                              0, &audioQueue);
    // Allocate buffers for the AudioQueue, and pre-fill them.
    for (int i = 0; i < BUFFER_COUNT; ++i) {
        AudioQueueBufferRef mBuffer;
        err = AudioQueueAllocateBuffer(audioQueue, BUFFER_SIZE, mBuffer);
        if (err != noErr) break;
        AudioQueueCallback(NULL, audioQueue, mBuffer);
    }
    if (err == noErr) err = AudioQueueStart(audioQueue, NULL);
    if (err == noErr) CFRunLoopRun();
  }

您的回调方法AudioQueueCallback将在每当AudioQueue需要更多数据时被调用。实现类似:

You callback method AudioQueueCallback will then be called whenever the AudioQueue needs more data. Implement with something like:

void AudioQueueCallback(void* inUserData, AudioQueueRef inAQ,
                        AudioQueueBufferRef inBuffer) {
    void* pBuffer = inBuffer->mAudioData;
    UInt32 bytes = inBuffer->mAudioDataBytesCapacity;
    // Write max <bytes> bytes of audio to <pBuffer>
    outBuffer->mAudioDataByteSize = actualNumberOfBytesWritten
    err = AudioQueueEnqueueBuffer(audioQueue, inBuffer, 0, NULL);
}

这篇关于如何在iPhone / Mac上与CoreAudio合成声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆