Time/pitchshift in c - c

I'm fairly new to C. As part of a Uni project, I'm required to put together a programme that processes audio in some form. So, I've decided to make a pitch shifter. So far, I've managed to at least make the program process the audiofile, if not actually alter the sound. I've looked into using samplerate, but from what I've gathered, it won't give me the desired outcome.
I've downloaded and compiled the rubberband library but I'm not really sure where to start using it in conjunction with my work. I was just wondering if anyone has any tips/experience with it, perhaps to achieve similar things?
void shiftsoundfile() {
//Part 1 - File input and reading
SNDFILE *inputsf, *outputsf;
SF_INFO ininfo, outinfo2;
SRC_DATA src_data;
static float datain [BUFFER_LEN];
static float dataout [BUFFER_LEN];
int readfile;
const char *inputsfname = "Scifi.wav";
const char *outputsfname = "Scifi2.wav";
ininfo.format = 0;
if ( !(inputsf = sf_open(inputsfname, SFM_READ, &ininfo)))
if (inputsf != inputsfname)
{
printf("The file could not be opened.\n");
exit(0);
}
outputsf = sf_open (outputsfname, SFM_WRITE, &ininfo);
inputsf = sf_open (inputsfname, SFM_READ, &outinfo2);
//Part 2 - Audio file conversion
//>>SOMETHING NEEDS TO GO HERE TO PERFORM THE CONVERSION<<
//librubberband perhaps, or something along these lines?...
/*float shift [BUFFER_LEN];
int j;
for (j = 0; j < readfile; j++) {
shift [j] = datain [j]; }
for (j = 0; j < readfile; j++) {
datain [j] = shift [j]; }*/ //?
//Part 3 - Outputting the new audio file
while (readfile = sf_read_float (inputsf, datain, BUFFER_LEN))
{
sf_write_float (outputsf, datain, BUFFER_LEN);
//Write's the data in the array, pointed to by outputsf, to the file
}
sf_close (inputsf); //closes the 'osf' function
sf_close (outputsf); //closes the 'csf' function

Related

libsndfile cannot encode WAV with float array

I'm trying to write a file using libsndfile in C++, with an array of floats:
void encode_file (const char *outfilename, int filetype)
{
static float buffer [BUFFER_LEN] ;
for (int i = 0; i< BUFFER_LEN; i++) {
buffer[i] = (float)(write_file_buffer.get()[i]);
}
SNDFILE *outfile ;
SF_INFO sfinfo ;
int k, readcount ;
printf (" %s ", outfilename) ;
fflush (stdout) ;
k = 16 - strlen (outfilename) ;
//PUT_DOTS (k) ;
sfinfo.format = filetype ;
if (! sf_format_check (&sfinfo))
{
printf ("Invalid encoding\n") ;
return ;
} ;
if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo))) // It fails here
{ printf ("Error : could not open file : %s\n", outfilename) ;
puts (sf_strerror (NULL)) ;
_exit (1) ;
};
sf_write_float (outfile, buffer, BUFFER_LEN) ; // this won't run anyways if I remove the check above
sf_close (outfile) ;
printf ("ok\n") ;
return ;
}
encode_file is being called like this:
encode_file(c, SF_FORMAT_WAV | SF_FORMAT_PCM_16); // c is a char *, that part is fine
write_file_buffer had previously been filled with doubles (but that shouln't matter due to the conversion above):
write_file_buffer[i] = ((double)(data[i]) - 32767.0)/32767.0;
The error I get of course is "pcmu000.wav Invalid encoding"
But I'm using the same code basically as when I was following this example:
https://vroby.ddns.net/Public/sdlBasic/MinGW/sorgenti/audacity/audacity-src-1.2.2/lib-src/libsndfile/examples/generate.c
And that worked just fine. I'm not clear on what I'm doing wrong since I'm passing in the same encoding as one used in the the working example (SF_FORMAT_WAV | SF_FORMAT_PCM_16).
Any advice would be much appreciated, I've been stuck on this for a minute and am mostly just scratching my head at this point.
Perhaps it expects stereo, or some other info to be loaded in the buffer (it's mono, basically an array of lot of sequential floats between -1.0 and 1.0)?
user253751 above got it: SF_INFO needs more of its parameters initialized. This was solved by going into the encode_file function and adding these lines right around the setting of sf_info.format:
sfinfo.channels = 1;
sfinfo.samplerate = 44100;
Thanks user253751!

Segmentation Fault in binning/jack-knife c program

Why do I get segmentation fault (core dumped)? I can't figure out where the problem is.
The program is supposed to read a data file with thermalised data, bin the data and then resample using a jack-knife method.
No matter how much data is used, I receive a segmentation fault.
/* Ben Marshall 12/03/15
Bin data & Jack-Knife */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int binSize, i=0, j=0, k=0, s=0, dataSize=0;
double *data, *binData, *jackData, mean, test; //variance
/* open files, therm.dat is the data to be jack-knifed,
jack-knife.dat will store the new data */
FILE *thermalised = fopen("therm.dat","r");
FILE *jack = fopen("jack-knife.dat","w");
if(thermalised==NULL || jack==NULL) {
return(-1);
}
// check amount of data to be used
while(fscanf(thermalised, "%lf", &test) != EOF) {
i++;
}
// close and reopen file to reset to start of file
fclose(thermalised);
FILE *therm = fopen("therm.dat","r");
if(therm==NULL) {
return(-1);
}
dataSize=i;
data=malloc(dataSize*sizeof(double));
binData=malloc(dataSize*sizeof(double));
jackData=malloc(dataSize*sizeof(double));
i=0;
while(fscanf(therm, "%lf", &data[i]) != EOF) {
i++;
}
fclose(therm);
/* increasing bin size in multiples of 2 */
for(binSize=1; (dataSize/binSize)>20; (binSize=binSize*2)) {
/* binning the data */
for(j=0; j<dataSize; j=(j+binSize)) {
for(k=0; k<binSize; k++) {
binData[s] = binData[s] + data[j+k];
}
binData[s] = binData[s]/binSize;
s++;
}
/* jack-knifing the binned data */
for(i=0; i<(dataSize/binSize); i++) {
for(s=0; s<(dataSize/binSize); s++) {
jackData[i] = jackData[i] + binData[s] - binData[i];
}
jackData[i] = jackData[i]/((dataSize/binSize)-1);
}
/* calculate mean and variance(FINISH!!) of jackData */
for(i=0; i<(dataSize/binSize); i++) {
mean = mean + jackData[i];
}
mean = mean/(dataSize/binSize);
fprintf(jack, "%d\t%lf\n",binSize,mean);
}
free(data);
free(binData);
free(jackData);
fclose(jack);
return(0);
}
Therm.dat file with 512 data points
0.000000
0.000000
-0.680375
-0.680375
-0.680375
-0.350821
-0.887280
-0.995220
-1.252962
-1.252962
-1.252962
-1.687556
-1.901494
-1.387267
-0.661730
-1.270084
-1.071972
-0.331553
-0.331553
0.231933
0.206068
-0.472156
-0.064220
-0.339324
-0.326490
-0.326490
-0.326490
-0.866318
-0.866318
-0.571235
-0.571235
0.289255
-0.609399
0.218489
0.218489
-0.561976
0.309681
0.309681
1.183490
0.242221
0.242221
0.708890
0.708890
0.683819
0.348371
0.285159
0.285159
0.285159
-0.156746
0.274667
-0.005291
0.286612
0.286612
-0.473538
-0.134213
-0.134213
0.165067
0.165067
-0.149541
-0.866894
-0.866894
-0.866894
-0.866894
-0.298544
-0.298544
0.406136
0.123975
0.260068
0.260068
0.645153
1.192939
1.192939
1.359937
0.546329
1.339987
1.349098
0.379595
-0.490413
-0.256790
-0.756331
-0.344652
0.190825
0.021848
0.533022
0.068725
0.068725
0.068725
0.068725
0.068725
0.716304
0.120708
-0.344601
-0.344601
-0.864071
-0.133875
-0.174296
0.685892
0.763051
0.616413
0.105252
1.001374
0.001387
0.001387
0.001387
0.001387
0.856729
0.010591
-0.177193
0.496544
-0.329510
-0.968900
-1.073870
-0.979022
-1.353796
-1.415412
-1.024003
-1.024003
-1.024003
-1.281823
-1.281823
-1.281823
-1.281823
-1.281823
-1.281823
-1.276340
-0.604276
-0.604276
0.241735
-0.057679
0.446233
0.446233
0.812499
1.349643
1.083498
1.083498
1.062126
0.119195
0.559111
0.120574
0.120574
-0.064506
-0.064506
0.262792
0.393765
0.703879
0.037393
0.569609
0.603709
0.603709
0.603709
0.603709
0.211741
-0.136132
-0.411412
0.219343
0.001131
-0.253185
0.090066
-0.390811
-0.390811
-0.697071
-0.761953
-0.282947
-0.282947
0.529573
0.806371
0.619948
0.286835
0.286835
0.710076
0.710076
0.710076
1.047118
1.047118
0.209257
-0.320486
0.437228
0.437228
-0.448875
-1.172709
-1.172709
-0.767286
-0.767286
-0.767286
-0.919685
-0.467507
-0.467507
-0.394832
-0.394832
0.023062
0.023062
-0.432039
-0.638257
-0.638257
0.005328
0.561397
1.318880
1.597995
0.734204
-0.082765
-0.326956
-0.326956
0.003100
0.214446
-0.003320
0.478868
1.333778
1.039363
1.312167
1.649395
1.649395
1.482254
1.482254
0.958699
0.983845
0.217772
-0.033559
-0.068988
-0.184109
-0.843987
-0.332641
0.015332
-0.443388
-0.443388
-1.238509
-1.060085
-0.070902
-0.070902
0.341742
-0.389328
0.512347
-0.460587
-0.876405
-0.824193
-1.554555
-0.753674
-0.519466
-0.122992
-0.437232
0.299364
1.196347
1.280916
0.896763
1.011643
0.832369
0.675100
0.615301
0.425211
0.701377
-0.076070
-0.029239
0.631120
0.579626
0.341775
0.149383
0.149383
1.009203
0.161747
0.822448
0.822448
1.240791
0.484235
0.484235
0.165943
1.093288
0.536774
0.284845
-0.387362
0.170619
0.170619
0.170619
-0.393905
0.205390
0.403015
0.534997
0.763501
0.763501
0.763501
0.999167
0.524351
0.524351
0.419718
-0.419463
-0.419463
-0.815160
-1.106938
-1.172858
-1.172858
-1.209887
-0.934196
-0.934196
-1.289821
-0.355606
0.517273
0.517273
0.116671
-0.018992
0.978757
1.368280
1.057544
0.342433
0.980111
0.645430
-0.112589
-0.419199
-1.189227
-0.503506
-0.510428
-0.510428
0.107349
0.318306
-0.419542
-0.419542
0.114221
-0.738931
-0.738931
-0.738931
-0.738931
-0.927926
-0.927926
-0.577008
-0.577008
-0.577008
-0.577008
-0.102578
-0.311335
0.354756
-0.375415
-0.704244
-0.928206
-0.928206
-0.224889
-0.382932
-0.784753
-0.784753
-0.010049
0.010331
0.010331
0.241014
0.336769
0.510614
0.697081
0.261887
0.114445
-0.511449
-0.404934
-0.359657
-1.349987
-0.498508
-0.780040
-0.225245
0.335179
-0.511846
-0.437551
-0.314674
-0.314674
-0.314674
-0.848702
-0.922187
-0.877289
-0.877289
-0.877289
-0.244820
-0.160898
-0.160898
-0.970461
-0.970461
-0.634152
-0.438910
-0.560479
-0.804812
-0.760734
-0.480944
-0.480944
0.097673
-0.115412
0.665033
0.665033
0.479649
0.126541
-0.066140
-0.066140
-0.193375
0.768804
0.768804
0.565950
0.024579
0.024579
0.678449
0.703008
0.424989
-0.506374
-0.092152
-0.856560
-0.856560
-0.808172
-0.354146
-1.247427
-1.247427
-1.247427
-0.615559
-0.180127
0.485542
0.233292
0.880815
0.880815
0.880815
0.880815
0.583724
-0.246717
0.551569
0.551569
0.558707
0.972352
0.147571
0.015242
0.633824
0.770137
0.263372
0.263372
0.263372
0.263372
-0.136203
0.208565
-0.084859
0.232177
-0.301226
-0.301226
-1.109600
-1.109600
-1.109600
-1.291821
-0.494729
0.190720
0.702423
0.524186
0.524186
-0.366817
-0.366817
-0.304917
0.181145
0.007122
0.669448
0.716738
-0.135397
-0.188442
-0.647237
-0.175581
-0.442751
-0.442751
-0.137842
0.450729
0.648758
0.288951
-0.001317
0.112005
-0.294367
0.276585
-0.241832
0.241945
0.241945
-0.462878
-0.105833
-0.441753
-1.137753
-0.650209
0.203320
0.174555
-0.605070
-0.667136
-0.667136
-0.355055
-0.074939
0.837230
0.837230
0.837230
0.196938
0.182119
0.247177
0.865210
0.018448
0.931659
0.931659
0.709177
0.709177
-0.025761
0.642050
0.127487
-0.427523
-0.584748
-0.584748
0.222443
0.222443
1.019483
1.019483
1.019483
1.465055
0.589628
0.067904
0.067904
-0.622642
-1.007569
-0.876365
-1.184423
-1.385407
-0.547937
-0.303931
0.422156
0.422156
0.257257
0.257257
0.199488
There are a few problems with your code:
while(fscanf(thermalised, "%lf", &test) != EOF)
This will cause an endless loop if the file contains something that fails to parse as a floating point number. Use this instead:
while(fscanf(thermalised, "%lf", &test) == 1)
Why do you then close and reopen the file instead of just calling rewind() ?
In the second reading loop, you should be more careful, in case another process is writing the "them.dat" file asynchronously. You should just try to parse as many numbers as you allocated:
for (i = 0; i < dataSize; i++) {
if (fscanf(therm, "%lf", &data[i]) != 1) {
printf("error: them.dat changed\n");
exit(1);
}
}
You should not return -1 from main(), most systems only support exit status between 0 and 255.
In the binning phase, you have a potential buffer overflow:
for(binSize=1; (dataSize/binSize)>20; (binSize=binSize*2)) {
/* binning the data */
for(j=0; j<dataSize; j=(j+binSize)) {
for(k=0; k<binSize; k++) {
binData[s] = binData[s] + data[j+k];
}
binData[s] = binData[s]/binSize;
s++;
}
If dataSize is not a power of 2, the last bin may extend beyond the end of the data array, invoking undefined behaviour, possibly the crash you are experiencing. Modify you boundary test to avoid this.
Furthermore, both binData and jackData are used before initialization. You should allocate these arrays with calloc so they start at 0.0 (on systems with IEEE floats ;-), or intialize them to the appropriate values with a loop.
When you compute the mean:
/* calculate mean and variance(FINISH!!) of jackData */
for(i=0; i<(dataSize/binSize); i++) {
mean = mean + jackData[i];
}
mean is not initialized!
When you print it:
fprintf(jack, "%d\t%lf\n",binSize,mean);
"%lf" is undefined, you should use "%f" to print a double or a float.

Data inconsistency in XBee send and receive. Embedded C

I want send a string in the following format from a serial port in embedded C. I am using a Silicon Labs microcontroller. The desired output is
"01001ODR0001\r\n"
"01002ODR0001\r\n"
"01003ODR0001\r\n"
However, when I send the message, there is some randome behavor and the output comes in the following format.
0R00110
010
120 0D
01001ODR0001
0R0ODR0000
1OD01O01R10R
01002OR0001
0O012000
I use the following method for it
sendToXbee("01001ODR0001\r\n");
void sendToXbee(unsigned char *msg) {
while (*msg != '\0') //Checking up to null char
{
SerTx(*msg);
msg++;
Delay(1);
}
}
void SerTx(unsigned char x) {
SBUF0 = x;
while (TI0 == 0)
;
TI0 = 0;
}
/**
* Delay
*/
void Delay(unsigned char temp) {
unsigned int i, j;
for (i = 0; i <= temp; i++) {
for (j = 0; j <= 5000; j++)
;
}
}
Is there a better way of doing this?
Hi Guys thanks for the help. It seems that I was using a screen command on the terminal and at the same time running a python script that was using the same the object and hence the data inconsistency. if u see below the terminal output is better but still not perfect
04001ODR0001
04001OD000
04002ODR001
04002ODR0000
04003ODR0001
04003ODR0000
04004DR0001
04004ODR0000
04005ODR0001
04005ODR000
04004OD0001
0404ODR0000
04003ODR001
04003ODR0000
04003OR0001
04003ODR000
04003ODR001
0403OR000100
04003ODR0000
0400ODR0001
4003ODR000
04003OR0001
0400ODR0000

loop over input in C-code and write data to different files using terminal at once

I wrote a C code which extracts data from a binary file which has size around 1 GB. There are 101 (0 to 100)configurations and the C code extracts data for a selected configuration and writes the output in a file. To compile the C code, I give user defined configuration number like this in the terminal:
gcc binary2textperconfig.c -o f.out
./f.out proton-p000-1.bin out1.txt
Then it asks for configuration number:
Enter the configuration number:
After that the data is written in file "out0.txt". Now I want to run this code for all 101 configurations and write those data to files "out0.txt", "out1.txt",...., "out100.txt" etc. I don't know how to do this without typing the configuration numbers 101 times in the terminal. Could any one please help me? Here is my C-code:
#include <stdio.h>
#include<complex.h>
#include<math.h>
#include <stdlib.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_matrix.h>
typedef double complex dcomplex;
//Data is converted to Bigendian using io-general
double constructfloat(char bytes[sizeof(double)/2], int order)
{
double dRes;
char *pc;
int i;
if (order == 0)
for(i=0, pc = (char*) &dRes; i<=sizeof(double)-1 ; i++, pc++)
(*pc) = bytes[i];
else
for(i=sizeof(double)-1, pc = (char*) &dRes; i>=0; i--, pc++)
(*pc) = bytes[i];
return dRes;
}
int main(int argc, char *argv[]){
int configcount = 101;
int mcount = 14;
int tcount = 64;
int d1count = 4;
int d2count = 4;
int pcount = 45;
int userci;
int usermi;
int userpi;
// number of complex numbers per configuration
int unitcountperconfig =(mcount*tcount*d1count*d2count*pcount);
// initialize loop index variables
int ci = 0; //config
int mi = 0; //mass
int ti = 0;
int d1i = 0;
int d2i = 0;
int pi = 0; //momentum
// for holding the result of read operation ( how many units have been read)
int result;
// for holding the data read from file
char * cbuff;
// input file handle from where binary data is read
FILE * fin = fopen(argv[1],"rb");
// if the input file cannot be read for reading, close opened file handles, show an error message to the user, and exit
if (fin==NULL)
{
fputs ("Error opening input file\n",stderr);
exit (1);
}
FILE * fout = fopen(argv[2],"wt");
// if the output file cannot be opened for writing, close opened file handles, show an error message to the user, and exit
if (fout==NULL)
{
fclose(fin);
fputs ("Error opening output file\n",stderr);
exit (1);
}
// take input from the user
// take input from the user
printf("Enter the configuration number: ");
scanf("%d",&userci);
// allocate memory to contain the chunk of data for a time slice:
cbuff = (char*)malloc(sizeof(dcomplex)*unitcountperconfig );
// show error message and exit if memory allocation failed
if(cbuff == NULL)
{
fputs("Buffer allocation failed.", stderr);
exit(1);
}
// variable to hold a complex number read from the file
dcomplex aComplexNumber;
dcomplex sumpertimeslice[tcount];
// loop on time slices
for( ci = 0; ci< configcount ; ci++){
// index of the complex number being read
unsigned int cNumberIdx = 0;
// debugging message
printf("reading data for configuration: %d\n",ci);
// perform read operation to read the desired chunk of data
result = fread(cbuff, sizeof(char), sizeof(dcomplex)*unitcountperconfig, fin );
// if size of data successfully read is not equal to what we wanted to read, notify the user and exit
if (result != sizeof(dcomplex)*unitcountperconfig) {
fputs ("data reading error\n",stderr);
exit (3);
}
double realP;
double imagP;// variable to hold real and imaginary part of the complex number
double realPSum;
double imagPSum;// variable to hold sum of real and sum of imaginary part of the current sum per time slice
for (mi =0; mi< mcount ; mi++){
for (ti =0; ti< tcount ; ti++){
// array to hold trace for each time slice
sumpertimeslice[ti] = 0.0 + 0.0*_Complex_I;
for (d1i =0; d1i < d1count ; d1i++){
for (d2i =0; d2i < d2count ; d2i++){
for (pi =0; pi < pcount ; pi++){
aComplexNumber = constructfloat( &cbuff[cNumberIdx], 0 ) + constructfloat( &cbuff[cNumberIdx+ ((int)sizeof(dcomplex))/2 ], 0 )*_Complex_I;
if (ci== userci)
{
cNumberIdx += (int)sizeof(dcomplex);
if (cimag(aComplexNumber)>0)
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e+%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
else
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
}
}
}
}
}
}
}
// free the allocated memory
free(cbuff);
// close the opened file handles
fclose(fin);
fclose(fout);
//fclose(complexNumberFileP);
}
Use the seq utility to generate a list of number between 0 & 100, and send it as a string to stdin.
for CNUMBER in $(seq 0 100); do
./f.out proton-p000-1.bin out${CNUMBER}.txt <<< "${CNUMBER}"
done
or
for CNUMBER in $(seq 0 100); do
echo $CNUMBER | ./f.out proton-p000-1.bin out${CNUMBER}.txt
done

audio delay making it work

I am trying to implement a simple audio delay in C.
i previously made a test delay program which operated on a printed sinewave and worked effectively.
I tried incorporating my delay as the process in the SFProcess - libsndfile- replacing the sinewave inputs with my audio 'data' input.
I nearly have it but instead of a clean sample delay I am getting all sorts of glitching and distortion.
Any ideas on how to correct this?
#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;
}
There are a few issues with your code that are causing you to access out of your array bounds and to not read\write your circular buffer in the way intended.
I would suggest reading http://en.wikipedia.org/wiki/Circular_buffer to get a better understanding of circular buffers.
The main issues your code is suffering:
circular_pointer should be initialised to the delay amount (essentially the write head is starting at 0 so there is never any delay!)
playhead and circular_buffer are not updated between calls to process_data (circular_buffer is passed by value...)
playhead is reading from negative indices. The correct playhead calculation is
#define MAX_DELAY 44100
playhead++;
playhead = playhead%MAX_DELAY;
The second write to circular_buffer at the end of process_data is unnecessary and incorrect.
I would strongly suggest spending some time running your code in a debugger and closely watching what your playhead and circular_pointer are doing.
Mike
At least one problem is that you pass circular_pointer by value, not by reference. When you update it in the function, it's back to the same value next time you call the function.
I think you are on the right track, here, but if you want something that's structured a bit better, you might also want to checkout this answer:
how to add echo effect on audio file using objective-c
delay in sample can be put as 100 ms would be sufficient

Resources