当前位置:  开发笔记 > IOS > 正文

如何在iPhone/Mac上使用CoreAudio合成声音

如何解决《如何在iPhone/Mac上使用CoreAudio合成声音》经验,为你挑选了1个好方法。

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

如果我想合成一个中A + 1(A4)(440Hz),我可以使用sin()计算正弦波; 我不知道的是如何将这些位安排到CoreAudio随后可以播放的数据包中.网上存在的大多数教程都只关注简单地播放现有的二进制文件.

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



1> PeyloW..:

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

#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();
  }

每当AudioQueue需要更多数据时,您就会调用回调方法AudioQueueCallback.实现类似于:

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


众神......我很遗憾我采用了实际的代码并试图缩小它的答案...我应该写一些伪代码并添加一个链接到Apple的文档.
我认为看到代码得到纠正是有用的.我并不是说草率,但完美的代码有时可以隐藏实际使用某些框架的复杂性.通过这种方式,我们可以了解出现问题的方法以及解决方法.
推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有