我想在iPhone中播放合成声音.我不想使用预先录制的声音并使用SystemSoundID播放现有的二进制文件,而是想合成它.部分地,这是因为我希望能够连续播放声音(例如,当用户的手指在屏幕上时)而不是一次性声音样本.
如果我想合成一个中A + 1(A4)(440Hz),我可以使用sin()计算正弦波; 我不知道的是如何将这些位安排到CoreAudio随后可以播放的数据包中.网上存在的大多数教程都只关注简单地播放现有的二进制文件.
任何人都可以用440Hz的简单合成正弦声波来帮助我吗?
你想做什么可能是为了设置一个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 maxbytes of audio to outBuffer->mAudioDataByteSize = actualNumberOfBytesWritten err = AudioQueueEnqueueBuffer(audioQueue, inBuffer, 0, NULL); }