2011-06-09 157 views
4

我在这里有以下问题:我得到一个字节块(uint16_t *)代表音频数据,并且生成它们的设备捕获单声道声音,所以显然我有单声道音频数据。我需要将这些数据传递给其他设备,这些设备需要交错立体声数据(如此,2个通道)。我想要做的是基本上复制数据中的1个通道,这样立体声数据的两个通道将包含相同的字节。你能指点我一个有效的算法吗?单声道到立体声转换

谢谢, f。

+0

你使用什么音频格式/框架? – 2011-06-09 12:41:06

+0

PCM,签名16位,48000khz – fritzone 2011-06-09 12:42:36

+0

安德斯还要求提供框架。 – 2011-06-09 12:43:46

回答

11

如果你只是想交错的立体声采样,那么你可以使用这样的功能:

void interleave(const uint16_t * in_L,  // mono input buffer (left channel) 
       const uint16_t * in_R,  // mono input buffer (right channel) 
       uint16_t * out,   // stereo output buffer 
       const size_t num_samples) // number of samples 
{ 
    for (size_t i = 0; i < num_samples; ++i) 
    { 
     out[i * 2] = in_L[i]; 
     out[i * 2 + 1] = in_R[i]; 
    } 
} 

要生成从单声道立体声缓冲区,那么你将只是传递了IN_L和IN_R,例如相同的指针

interleave(mono_buffer, mono_buffer, stereo_buffer, num_samples); 
+0

下次您删除编辑时,您是否至少可以通知投稿人? : -/ – 2014-06-13 14:04:40

+0

当然,虽然我不确定我该怎么做? – 2014-06-13 14:17:35

+0

我在添加就地版本后忘了添加评论。我的错。 – 2014-06-13 14:20:50

2

传递给两个通道相同的指针?如果违反restrict规则,请使用memcpy()

对不起,但您的问题是其他广泛。 API? OS? CPUArchitectures?

+0

这不起作用,我没有发送每个通道的数据,我发送了大量的字节和设备编号。 2是根据需要将它们分开。 – fritzone 2011-06-09 13:04:12

0

您将不得不复制缓冲区并复制它。因为你没有告诉我们格式,它是如何终止的,我不能给代码,但它看起来像一个简单的for循环。

int_16* allocateInterleaved(int_16* data, int length) 
    int i; 
    int *copy = malloc(sizeof(int_16)*length*2); 
    if(copy == NULL) { 
    /* handle error */ 
    } 
    for(i =0; i<length; i++) { 
    copy[2*i] = data[i]; 
    copy[2*i+1] = data[i]; 
    } 
    return copy; 
} 

原谅任何明显的错别字,我的C有点生疏。 typdef,无论你需要什么类型的16位到int_16。不要忘记释放复制缓冲区,或者更好地重用它。

+0

@保罗R,谢谢,我修好了 – 2011-06-09 13:44:31

1

您可能想要在原地进行转换以节省一些内存。取决于有问题的设备有多少内存。所以,你可能想使用这样的事情,而不是保罗·R的方式的:

void interleave(uint16_t buf[], const int len) 
{ 
    for (int i = len/2 - 1, j = len - 1; i > 0; --i) { 
     buf[j--] = buf[i]; 
     buf[j--] = buf[i]; 
    } 
} 

当从单设备获取的声音数据,你分配一个缓冲区根据需要并传递到单设备的两倍大。这将用单声道音频填充一半缓冲区。然后将该缓冲区传递给上述函数,该函数将其转换为立体声。最后你将缓冲区传递给立体声设备。您节省了额外的分配空间,因此转换的内存减少了33%。

相关问题