gpt4 book ai didi

c - 音频延迟使其工作

转载 作者:太空宇宙 更新时间:2023-11-04 00:11:14 24 4
gpt4 key购买 nike

我正在尝试在 C 中实现一个简单的音频延迟。我之前制作了一个测试延迟程序,该程序在打印的正弦波上运行并且有效运行。我尝试将我的延迟合并为 SFProcess - libsndfile - 中的过程,用我的音频“数据”输入替换正弦波输入。

我几乎成功了,但没有出现干净的采样延迟,而是出现了各种故障和失真。

关于如何纠正这个问题的任何想法?

#include <stdio.h>
#include </usr/local/include/sndfile.h>//libsamplerate libsamplerate
//#include </usr/local/include/samplerate.h>

#define BUFFER_LEN 1024 //defines buffer length
#define MAX_CHANNELS 2 //defines max channels

static void process_data (double *data, double*circular,int count, int numchannels, int circular_pointer );

enum {DT_PROGNAME,ARG_INFILE,ARG_OUTFILE,ARG_NARGS, DT_VOL};

int main (int argc, const char * argv[])//Main
{
static double data [BUFFER_LEN]; // the buffer that carries the samples

double circular [44100] = {0}; // the circular buffer for the delay
for (int i = 0; i < 44100; i++) { circular[i] = 0; } // zero the circular buffer

int circular_pointer = 0; // where we currently are in the circular buffer

//float myvolume; // the volume entered by the user as optional 3rd argument

SNDFILE *infile, *outfile;
SF_INFO sfinfo;

int readcount;
const char *infilename = NULL;
const char *outfilename = NULL;

if(argc < ARG_NARGS) {
printf("usage: %s infile outfile\n",argv[DT_PROGNAME]);
return 1;
}

//if(argc > ARG_NARGS) {
//
// myvolume = argv[DT_VOL];
//};
infilename = argv[ARG_INFILE];
outfilename = argv[ARG_OUTFILE];

if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))

{printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
};

if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
{ printf ("Not able to open output file %s.\n", outfilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
} ;

while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{ process_data (data, circular, readcount, sfinfo.channels, circular_pointer) ;
sf_write_double (outfile, data, readcount) ;
};

sf_close (infile) ;
sf_close (outfile) ;

printf("the sample rate is %d\n", sfinfo.samplerate);

return 0;
}


static void process_data (double *data, double *circular, int count, int numchannels, int circular_pointer) {

//int j,k;
//float vol = 1;
int playhead;
int wraparound = 10000;

float delay = 1000; // delay time in samples

for (int ind = 0; ind < BUFFER_LEN; ind++){

circular_pointer = fmod(ind,wraparound); // wrap around pointer
circular[circular_pointer] = data[ind];


playhead = fmod(ind-delay, wraparound); // read the delayed signal

data[ind] = circular[playhead]; // output delayed signal

circular[ind] = data[ind]; // write the incoming signal
};


//volume
/*for (j=0; j<numchannels; j++) {
for (k=0; k<count; k++){
data[k] = data[k]*-vol;*/

//}printf ("the volume is %f", vol);

return;
}

最佳答案

您的代码存在一些问题,导致您超出数组范围进行访问,并且无法按预期方式读取/写入循环缓冲区。

我建议阅读 http://en.wikipedia.org/wiki/Circular_buffer更好地了解循环缓冲区。

您的代码遇到的主要问题:

  1. circular_pointer 应该初始化为延迟量(本质上写头从 0 开始,所以永远不会有任何延迟!)
  2. playhead 和 circular_buffer 在调用 process_data 之间不会更新(circular_buffer 按值传递...)
  3. 播放头正在读取负索引。正确的播放头计算是

    #define MAX_DELAY     44100
    playhead++;
    playhead = playhead%MAX_DELAY;
  4. 在 process_data 末尾对 circular_buffer 的第二次写入是不必要且不正确的。

我强烈建议花一些时间在调试器中运行您的代码,并仔细观察您的播放头和 circular_pointer 在做什么。

迈克

关于c - 音频延迟使其工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16482232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com