8

float *newAudiofloat *channel1 और float* channel2 में 0 -में इसे कैसे घुमाएं?डी-इंटरलीव और इंटरलीव बफर vDSP_ctoz() और vDSP_ztoz() के साथ?

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 के वाक्यविन्यास को समझ नहीं पा रहा हूं।

उत्तर

11

क्या मैं Ringbuffer तरह नोवोकेन के सहायक कक्षाओं में करते हैं, de-इंटरलिविंग के लिए:

float zero = 0.0; 
vDSP_vsadd(leftSampleData, 1, &zero, data, numChannels, numFrames); 
vDSP_vsadd(rightSampleData, 1, &zero, data+1, numChannels, numFrames); 

: इंटरलिविंग के लिए

float zero = 0.0; 
vDSP_vsadd(data, numChannels, &zero, leftSampleData, 1, numFrames); 
vDSP_vsadd(data+1, numChannels, &zero, rightSampleData, 1, numFrames); 

चीजों को करने का अधिक सामान्य तरीका है एरे की सरणी, जैसे

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); 
    } 
}]; 

जो मैं नोवोकेन के लिए रिंगबफर एक्सेसरी कक्षाओं में आंतरिक रूप से बहुत कुछ उपयोग करता हूं। मैंने 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); 
}]; 

आशा है कि मदद करता है बचा सकता है।

+0

धन्यवाद, ऐसा करने के लिए एक साफ तरीका दिखता है! – bartolsthoorn

+0

एलेक्स, कृपया इस पर एक नज़र डालें (http://stackoverflow.com/questions/13228618/how-to-read-vbr-audio-in-novacaine-as-opposed-to-pcm) प्रश्न, मैं ' मैं आपके novacaine उदाहरण में जोड़ने की कोशिश कर रहा हूं इसे वीबीआर डेटा पढ़ने की अनुमति दे रहा हूं (फ्लोट के बजाय SINT16 में) – abbood

8

यहाँ एक उदाहरण है:

#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; 
} 
3

sbooth उत्तर vDSP_ctoz का उपयोग करके डी-इंटरलीव कैसे करें। यहां पूरक ऑपरेशन है, अर्थात् vDSP_ztoc का उपयोग करके इंटरलीविंग।

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