Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 单声道到立体声转换_C_Algorithm_Audio - Fatal编程技术网

C 单声道到立体声转换

C 单声道到立体声转换,c,algorithm,audio,C,Algorithm,Audio,我这里有以下问题:我得到一个字节块(uint16_t*)表示音频数据,生成它们的设备正在捕获单声道声音,所以很明显我有单声道音频数据,在一个通道上。我需要将此数据传递到另一个设备,该设备需要交错立体声数据(因此,2个通道)。我想做的基本上是复制数据中的1个通道,这样立体声数据的两个通道将包含相同的字节。你能告诉我一个有效的算法吗 谢谢, f、 是否将同一指针传递到两个通道?如果违反了restrict规则,请使用memcpy() 对不起,你的问题太笼统了。应用程序编程接口?操作系统?CPUArch

我这里有以下问题:我得到一个字节块(uint16_t*)表示音频数据,生成它们的设备正在捕获单声道声音,所以很明显我有单声道音频数据,在一个通道上。我需要将此数据传递到另一个设备,该设备需要交错立体声数据(因此,2个通道)。我想做的基本上是复制数据中的1个通道,这样立体声数据的两个通道将包含相同的字节。你能告诉我一个有效的算法吗

谢谢,
f、 是否将同一指针传递到两个通道?如果违反了
restrict
规则,请使用
memcpy()


对不起,你的问题太笼统了。应用程序编程接口?操作系统?CPUArchitectures?

如果您只需要交错立体声采样,则可以使用如下函数:

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

您必须复制缓冲区并复制它。正如您没有告诉我们的格式,它是如何终止的,我不能给出代码,但它看起来像一个简单的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;
}
int_16*分配交错(int_16*数据,int长度)
int i;
int*copy=malloc(sizeof(int_16)*长度*2);
if(copy==NULL){
/*处理错误*/
}

对于(i=0;i您可能希望就地进行转换以节省一些内存。这取决于所讨论的设备的内存量有多小。因此,您可能希望使用类似这样的方法,而不是Paul 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%。

您需要交错数据,但如果帧长度大于1,则上述解决方案均无效。下面的代码可以解释可变帧长度

void Interleave(BYTE* left, BYTE* right, BYTE* stereo,int numSamples_in, int frameSize)
{
    int writeIndex = 0;
    for (size_t j = 0; j < numSamples_in; j++)
    {
        for (int k = 0; k < frameSize; k++)
        {
            int index = j * frameSize + k;

            stereo[k + writeIndex] = left[index];
            stereo[k + writeIndex + frameSize] = right[index];
        }
        writeIndex += 2 * frameSize;
    }
}
void交织(字节*左、字节*右、字节*立体、整数个示例、整数帧大小)
{
int writeIndex=0;
对于(大小j=0;j
您使用的音频格式/框架是什么?Anders还要求提供框架。框架没有什么特别的,一个设备向指针(void*)发送数据并告诉我样本数(通过回调),另一个设备获取样本数和相同的void*,并播放音频(从回调调用第二个设备).2号设备希望此数据为交错立体声。感谢所有人的响应,问题已解决:)这不起作用,我没有为每个通道发送数据,我发送了一大堆字节,2号设备正在根据需要将它们分开。下次删除编辑时,你能至少通知捐款人吗-/当然可以,不过我不知道该怎么做?我在添加就地版本后忘了添加注释。我的错,没问题。仅供参考,我认为您的编辑虽然包含有用的信息,但不属于本答案的一部分,或许应该作为单独的答案添加。我看你现在已经这样做了:+1!这很接近,但它仅适用于帧深度只有一个字节的特殊情况。我将这个答案扩展到任何帧深度。
void Interleave(BYTE* left, BYTE* right, BYTE* stereo,int numSamples_in, int frameSize)
{
    int writeIndex = 0;
    for (size_t j = 0; j < numSamples_in; j++)
    {
        for (int k = 0; k < frameSize; k++)
        {
            int index = j * frameSize + k;

            stereo[k + writeIndex] = left[index];
            stereo[k + writeIndex + frameSize] = right[index];
        }
        writeIndex += 2 * frameSize;
    }
}