首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用vDSP_ctoz()和vDSP_ztoz()去交错和交错缓冲?

用vDSP_ctoz()和vDSP_ztoz()去交错和交错缓冲?
EN

Stack Overflow用户
提问于 2012-04-28 16:42:21
回答 3查看 3.4K关注 0票数 8

如何将float *newAudio反交错放入float *channel1float* channel2,并将其交错放回newAudio

代码语言:javascript
复制
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
}];

这两行代码会是什么样子呢?我不理解ctoz/ztoz的语法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-30 00:58:42

我在Novocaine的附件类中做了什么,比如Ringbuffer,用于去交错:

代码语言:javascript
复制
float zero = 0.0;  
vDSP_vsadd(data, numChannels, &zero, leftSampleData, 1, numFrames);   
vDSP_vsadd(data+1, numChannels, &zero, rightSampleData, 1, numFrames);  

对于交错:

代码语言:javascript
复制
float zero = 0.0;  
vDSP_vsadd(leftSampleData, 1, &zero, data, numChannels, numFrames);   
vDSP_vsadd(rightSampleData, 1, &zero, data+1, numChannels, numFrames);  

更一般的做法是拥有一个数组数组,例如

代码语言:javascript
复制
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);
    }
}];

这是我在诺沃卡因的RingBuffer附件类中经常使用的。我对vDSP_vsadd和memcpy的速度进行了计时,(非常,非常令人惊讶),没有速度差异。

当然,您总是可以只使用环形缓冲区,这样就省去了麻烦。

代码语言:javascript
复制
#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);
}];

希望这能有所帮助。

票数 12
EN

Stack Overflow用户

发布于 2012-04-28 20:31:47

下面是一个示例:

代码语言:javascript
复制
#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;
}
票数 7
EN

Stack Overflow用户

发布于 2013-08-26 21:25:10

sbooth回答了如何使用vDSP_ctoz去交错。下面是补充操作,即使用vDSP_ztoc进行交错。

代码语言:javascript
复制
#include <stdio.h>
#include <Accelerate/Accelerate.h>

int main(int argc, const char * argv[])
{
    const int NUM_FRAMES = 16;
    const int NUM_CHANNELS = 2;

    // Buffers for left/right channels
    float xL[NUM_FRAMES];
    float xR[NUM_FRAMES];

    // Initialize with some identifiable data
    for (int i = 0; i < NUM_FRAMES; i++)
    {
        xL[i] = 2*i;    // Even
        xR[i] = 2*i+1;  // Odd
    }

    // Buffer for interleaved data
    float stereo[NUM_CHANNELS*NUM_FRAMES];
    vDSP_vclr(stereo, 1, NUM_CHANNELS*NUM_FRAMES);

    // Interleave - take separate left & right buffers, and combine into
    // single buffer alternating left/right/left/right, etc.
    DSPSplitComplex    x = {xL, xR};
    vDSP_ztoc(&x, 1, (DSPComplex*)stereo, 2, NUM_FRAMES);

    // Print the result for verification. Should give output like
    //    i:     L,     R
    //    0:  0.00,  1.00
    //    1:  2.00,  3.00
    //    etc...
    printf(" i:     L,     R\n");
    for (int i = 0; i < NUM_FRAMES; i++)
    {
        printf("%2d: %5.2f, %5.2f\n", i, stereo[2*i], stereo[2*i+1]);
    }
    return 0;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10361974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档