ost*_*oon 8 signal-processing objective-c core-audio accelerate-framework
如何解交织float *newAudio成float *channel1和float* channel2和交织它放回newAudio?
Novocaine *audioManager = [Novocaine audioManager];
__block float *channel1;
__block float *channel2;
[audioManager setInputBlock:^(float *newAudio, UInt32 numSamples, UInt32 numChannels) {
// Audio comes in interleaved, so,
// if numChannels = 2, newAudio[0] is channel 1, newAudio[1] is channel 2, newAudio[2] is channel 1, etc.
// Deinterleave with vDSP_ctoz()/vDSP_ztoz(); and fill channel1 and channel2
// ... processing on channel1 & channel2
// Interleave channel1 and channel2 with vDSP_ctoz()/vDSP_ztoz(); to newAudio
}];
Run Code Online (Sandbox Code Playgroud)
这两行代码会是什么样的?我不明白ctoz/ztoz的语法.
ale*_*xbw 11
我在Novocaine的附件类中做了什么,比如Ringbuffer,用于去交错:
float zero = 0.0;
vDSP_vsadd(data, numChannels, &zero, leftSampleData, 1, numFrames);
vDSP_vsadd(data+1, numChannels, &zero, rightSampleData, 1, numFrames);
Run Code Online (Sandbox Code Playgroud)
用于交错:
float zero = 0.0;
vDSP_vsadd(leftSampleData, 1, &zero, data, numChannels, numFrames);
vDSP_vsadd(rightSampleData, 1, &zero, data+1, numChannels, numFrames);
Run Code Online (Sandbox Code Playgroud)
更常见的做法是拥有一个数组数组,比如
int maxNumChannels = 2;
int maxNumFrames = 1024;
float **arrays = (float **)calloc(maxNumChannels, sizeof(float *));
for (int i=0; i < maxNumChannels; ++i) {
arrays[i] = (float *)calloc(maxNumFrames, sizeof(float));
}
[[Novocaine audioManager] setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
float zero = 0.0;
for (int iChannel = 0; iChannel < numChannels; ++iChannel) {
vDSP_vsadd(data, numChannels, &zero, arrays[iChannel], 1, numFrames);
}
}];
Run Code Online (Sandbox Code Playgroud)
这是我在Novocaine的RingBuffer配件类中内部使用的内容.我计算了vDSP_vsadd与memcpy的速度,并且(非常非常令人惊讶地),没有速度差异.
当然,你总是可以使用一个环形缓冲区,为自己省去麻烦
#import "RingBuffer.h"
int maxNumFrames = 4096
int maxNumChannels = 2
RingBuffer *ringBuffer = new RingBuffer(maxNumFrames, maxNumChannels)
[[Novocaine audioManager] setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels);
}];
[[Novocaine audioManager] setOuputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
ringBuffer->FetchInterleavedData(data, numFrames, numChannels);
}];
Run Code Online (Sandbox Code Playgroud)
希望有所帮助.
这是一个例子:
#include <Accelerate/Accelerate.h>
int main(int argc, const char * argv[])
{
// Bogus interleaved stereo data
float stereoInput [1024];
for(int i = 0; i < 1024; ++i)
stereoInput[i] = (float)i;
// Buffers to hold the deinterleaved data
float leftSampleData [1024 / 2];
float rightSampleData [1024 / 2];
DSPSplitComplex output = {
.realp = leftSampleData,
.imagp = rightSampleData
};
// Split the data. The left (even) samples will end up in leftSampleData, and the right (odd) will end up in rightSampleData
vDSP_ctoz((const DSPComplex *)stereoInput, 2, &output, 1, 1024 / 2);
// Print the result for verification
for(int i = 0; i < 512; ++i)
printf("%d: %f + %f\n", i, leftSampleData[i], rightSampleData[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3190 次 |
| 最近记录: |