For loop being skipped in c-file when run from bash - c

I am running a c file which generates data and writes it to text file. Below is a bash script which runs this file multiple times for different parameters. When I run the c code by itself there are no problems. When I run it with the script below no data is saved to the text file (they are still created). It seems to be that the for loop, which the printing to the text file lies in, is being skipped (ascertained by placing print statements before and after this for loop).
#!/bin/bash
make studentt_sampler
# arguments to pass to ./studentt_sampler
no_samples=5
nu=3.0
mu=1.0
sigma=1.0
data_files=("data_file_0p01.txt" "data_file_0p1.txt" "data_file_1.txt" "data_file_10.txt")
proposal_sigma=(0.01,0.1,1.0,10.0)
# arguments to pass to post_process.py
figure_files=("chain_0p01.pdf" "chain_0p1.pdf" "chain_1.pdf" "chain_10.pdf")
for i in `seq 0 3`;
do
#echo ${data_files[$i]}
./studentt_sampler no_samples nu mu sigma "${data_files[$i]}" "${proposal_sigma[$i]}" &
# ./post_process.py echo ${data_files[$i]} echo ${figure_files[$i]}
done
wait
The main function of the c file is
int main(int argc, char *argv[]) {
/* Initialization */
const gsl_rng_type * T;
gsl_rng * r;
/* set iteration variables and the order of the student-t distribution
* from the command line arguments */
int i, itr = atoi(argv[1]);
/* parameters of student t distributions */
double nu = atof(argv[2]);
double mu = atof(argv[3]);
double sigma = atof(argv[4]);
/* store the parameters in param_type struct */
struct param_type params = {nu,mu,sigma};
/* open text file for writing and make sure it works*/
printf("%s\n",argv[5]);
FILE *f = fopen(argv[5], "w");
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
/* allocate memory for generator and set its seed */
r = gsl_rng_alloc(gsl_rng_mt19937);
gsl_rng_set(r,1);
/* Start initial value */
double x_cur = 1.0;
double proposal_sigma = atof(argv[6]);
double alpha;
double x_prop;
int accept; /* keep track of acceptance rate */
double u; /* to make decision of accept proposal or not */
double accept_prob;
/* Start the MCMC */
for (i=0;i<itr;i++) {
printf("here!!!\n");
/* propose a new x */
x_prop = gsl_ran_gaussian(r,proposal_sigma) + x_cur;
/* Calculate acceptance probability */
accept_prob = lklhood(x_prop, &params)/lklhood(x_cur, &params);
alpha = GSL_MIN(1.0,accept_prob);
/* Accept or not, decide */
u = gsl_ran_flat(r,0.0,1.0);
if (u < alpha) {
x_cur = x_prop;
accept = 1;
}/* print to data file */
else {
accept = 0;
}
fprintf(f," %.5f %i\n",x_cur,accept);
}
/* Clean up time */
fclose(f);
return 0;
}
I appreciate your help.

Is it possible that you forgot the $ in the variables you supply to the program, i.e. shouldn't it be:
./studentt_sampler $no_samples $nu $mu $sigma "${data_files[$i]}" "${proposal_sigma[$i]}" &

Related

C - Shuffling an Array of Structs

I'm doing a project for school in C and basically what I need to do is to create a grid of agents (Humans, Zombies or none) and randomly pick which ones I manually control or are "AI" controlled. Basically humans need to run from zombies and zombies have to chase humans to infect them, game ending when there are no humans left.
Problem is, before each turn it should be randomly selected who plays first, and for that I need to shuffle the agents (not touching the grid because the agent positions remain the same, the only thing that changes is their position in the array that I should be using to pick who plays first).
I'm having some troubles with the shuffle because I call the function and after I shuffle the agents I print their Ids. It just give me many many 0s and in between some random numbers like 3, 6, 10, etc and a few more only.
Here's the code:
main file:
#include "showworld.h"
#include "example.h"
#include "shuffle.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/** Horizontal world size. */
#define WORLD_X 20
/** Vertical world size. */
#define WORLD_Y 20
/**
* Structure defining agent properties.
*
* #note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
* */
typedef struct {
AGENT_TYPE type; /**< Agent type. */
unsigned char playable; /**< Is agent playable? */
unsigned short id; /**< Agent ID. */
} AGENT;
/**
* Structure defining world properties.
*
* #note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
* */
typedef struct {
AGENT *grid; /**< World is a grid composed of agents. */
unsigned int xsize; /**< Horizontal world size. */
unsigned int ysize; /**< Vertical world size. */
} WORLD;
/* This function is an implementation of the definition provided by the
* ::get_agent_info_at() function pointer. It only works for AGENT and WORLD
* example structures defined in this file. */
unsigned int example_get_ag_info(void *world, unsigned int x, unsigned int y);
int main() {
/* An instance of a WORLD structure. */
WORLD my_world;
/* An instance of a SHOWWORLD world display. */
SHOWWORLD *sw = NULL;
/* A by-dimensional array of agents, representing agents in a grid. */
AGENT agent_grid[WORLD_X][WORLD_Y];
/* Number of agents created so far. */
unsigned int nagents = 0;
/* Initialize world display. */
sw = showworld_new(WORLD_X, WORLD_Y, example_get_ag_info);
/* Initialize random number generator. */
srand(time(NULL));
/* **************************************************************** */
/* Cycle through all cells in grid and randomly place agents in it. */
/* **************************************************************** */
for (int i = 0; i < WORLD_X; ++i) {
for (int j = 0; j < WORLD_Y; ++j) {
/* Possible agent in grid. By default we assume there is none. */
AGENT ag = {None, 0, 0};
/* Obtain a probability between 0 and 99. */
unsigned char probability = rand() % 100;
/* There is 10% probability of creating an agent. */
if (probability < 10) {
/* If we got here, an agent will be placed at (i,j). */
/* Randomly define agent type. */
ag.type = (rand() % 2 == 0) ? Human : Zombie;
/* Give 10% probablity of agent being playable by user. */
ag.playable = (rand() % 10 == 0);
/* Assign agent ID and then increment number of agents so
far. */
ag.id = nagents++;
}
/* Assign possible agent to grid at (i,j). */
agent_grid[i][j] = ag;
}
}
/* ******************************* */
/* Populate the my_world variable. */
/* ******************************* */
/* A bidimensional array of agents can be interpreted as a pointer to
agents. */
my_world.grid = (AGENT *) agent_grid;
/* World size is defined by constants in this example. */
my_world.xsize = WORLD_X;
my_world.ysize = WORLD_Y;
/* ********************************************************************* */
/* Show world using the simple_show_world() function. This function can */
/* be used in the first part of the project. */
/* ********************************************************************* */
showworld_update(sw, &my_world);
shuffle(my_world.grid, nagents);
/* Before finishing, ask user to press ENTER. */
printf("Press ENTER to continue...");
getchar();
/* Destroy world display. */
showworld_destroy(sw);
/* Bye. */
return 0;
}
/**
* This function is an implementation of the ::get_agent_info_at() function
* definition. It only works for ::AGENT and ::WORLD structures defined in this
* example.
*
* It basically receives a pointer to a ::WORLD structure, obtains the AGENT
* structure in the given coordinates, and returns the agent information in a
* bit-packed `unsigned int`.
*
* #note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
*
* #param w Generic pointer to object representing the simulation world.
* #param x Horizontal coordinate of the simulation world from where to fetch
* the agent information.
* #param y Vertical coordinate of the simulation world from where to fetch
* the agent information.
* #return An integer containing bit-packed information about an agent, as
* follows: bits 0-1 (agent type), bit 2 (is agent playable), bits 3-18 (agent
* ID). Bits 19-31 are available for student-defined agent extensions.
* */
unsigned int example_get_ag_info(void *w, unsigned int x, unsigned int y) {
/* The agent information to return. */
unsigned int ag_info = 0;
/* Convert generic pointer to world to a WORLD object. */
WORLD *my_world = (WORLD *) w;
/* Check if the given (x,y) coordinates are within bounds of the world. */
if ((x >= my_world->xsize) || (y >= my_world->ysize)) {
/* If we got here, then the coordinates are off bounds. As such we will
report that the requested agent is of unknown type. No need to
specify agent ID or playable status, since the agent is unknown. */
ag_info = Unknown;
} else {
/* Given coordinates are within bounds, let's get and pack the request
agent information. */
/* Obtain agent at specified coordinates. */
AGENT ag = my_world->grid[x * my_world->xsize + y];
/* Is there an agent at (x,y)? */
if (ag.type == None) {
/* If there is no agent at the (x,y) coordinates, set agent type to
None. No need to specify agent ID or playable status, since
there is no agent here. */
ag_info = None;
} else {
/* If we get here it's because there is an agent at (x,y). Bit-pack
all the agent information as specified by the get_agent_info_at
function pointer definition. */
ag_info = (ag.id << 3) | (ag.playable << 2) | ag.type;
}
}
/* Return the requested agent information. */
return ag_info;
}
Here's shuffle function
#include "example.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle(AGENT *agents, unsigned int nagents) {
printf("%s\n\n", "------------- Shuffling agents ----------------");
unsigned int i=0;
unsigned int j=0;
AGENT temp;
srand(time(NULL));
for (i = nagents - 1; i > 0; i--) {
j = (rand() % i);
temp = agents[i];
agents[i] = agents[j];
agents[j] = temp;
}
for (i = 0; i < nagents; i++) {
printf("\n\t%d", agents[i].id);
}
Here's showworld file:
#include "showworld.h"
#include <stdio.h>
#include <stdlib.h>
/* The implementation of `SHOWWORLD` type used in this simple text-based world
* visualization code. In this simple case, we only need to keep track of the
* world dimensions and of the function pointer which knows how to read an
* agent from the world data structure.
*
* For a more complex implementation, for example based on the g2 library,
* it would also be necessary to keep the g2 device.
* */
struct showworld {
unsigned int xdim;
unsigned int ydim;
get_agent_info_at aginfo_func;
};
/* Create a new display/visualization object for the simulation world.
*
* This function obeys the `showworld_new()` prototype defined in
* `showworld.h`. */
SHOWWORLD *showworld_new(
unsigned int xdim,
unsigned int ydim,
get_agent_info_at aginfo_func) {
SHOWWORLD *sw = NULL;
sw = malloc(sizeof(SHOWWORLD));
sw->xdim = xdim;
sw->ydim = ydim;
sw->aginfo_func = aginfo_func;
return sw;
}
/* Destroy a display/visualization object for the simulation world.
*
* This function obeys the `showworld_destroy()` prototype defined in
* `showworld.h`. */
void showworld_destroy(SHOWWORLD *sw) {
free(sw);
}
/* Update the simulation world display/visualization.
*
* This function obeys the `showworld_update()` prototype defined in
* `showworld.h`. */
void showworld_update(SHOWWORLD *sw, void *w) {
printf("\n");
/* Cycle through all the rows */
for (unsigned int y = 0; y < sw->ydim; ++y) {
/* Cycle through all the columns for the current row */
for (unsigned int x = 0; x < sw->xdim; ++x) {
/* Get state of the world (in bit packed fashion) using the user
supplied function. */
unsigned int item = sw->aginfo_func(w, x, y);
/* Extract the agent type (2 bits). */
AGENT_TYPE ag_type = item & 0x3;
/* Extract whether the agent is playable (1 bit). */
unsigned char playable = (item >> 2) & 0x1;
/* Extract the agent ID (16 bits). */
unsigned short ag_id = (item >> 3) & 0xFFFF;
/* Determine the agent type. */
switch (ag_type) {
/* If no agent is present at (x,y) just print a dot. */
case None:
printf(" . ");
break;
/* If human agent present at (x,y) print 'h' or 'H'. */
case Human:
if (playable) {
/* Uppercase 'H' for player-controlled human agent. */
printf("H");
} else {
/* Lowercase 'h' for AI-controlled human agent. */
printf("h");
}
/* Print the agent ID in front of the 'h'/'H'. */
printf("%02X ", ag_id);
break;
/* If zombie agent present at (x,y) print 'z' or 'Z'. */
case Zombie:
if (playable) {
/* Uppercase 'Z' for player-controlled zombie agent. */
printf("Z");
} else {
/* Lowercase 'z' for AI-controlled zombie agent. */
printf("z");
}
/* Print the agent ID in front of the 'h'/'H'. */
printf("%02X ", ag_id);
break;
/* Print '?' if unknown type detected. This should *never*
happen. */
default:
printf("? ");
}
}
/* Print two newlines after each row. */
printf("\n\n");
}
/* Print a newline after world is shown/updated. */
printf("\n");
}
Stripping all that code to the relevant:
AGENT agent_grid[WORLD_X][WORLD_Y];
int nagents = populate_grid(agent_grid, WORLD_X, WORLD_Y, 10);
shuffle(agent_grid, nagents);
Here, I've removed my_world to focus on the grid, and created a grid initialization function instead of doing the initialization inline. The hypothetical initialization function int populate_grid(AGENT *grid, int rows, int cols, int percent) fills a sample of the grid with agents (and the rest with AGENT objects of type ``NONE`). It then returns the sample size created.
Then, the grid is shuffled using precisely your call to shuffle, which takes an array of AGENT objects and shuffles them.
Isn't the problem obvious from that narrative? agent_grid is not an array of size nagents as expected by shuffle. It is a two-dimensional array of size WORLD_X * WORLD_Y. In practice, that means that you are shuffling the first 40 (or so) grid slots, leaving the other 360 untouched; we can expect that 90% of those grid slots are empty, which seems to match your described outcome ("many, many 0s").
That is a lot of code, but the first thing I would look for is bounds errors. Make sure your array indices are consistent and do not access items outside of the valid range in your arrays.
The next problem is your shuffle. Jeff Atwood wrote an entire blog about it.
Good luck!

OpenACC must have routine information error

I am trying to parallelize a simple mandelbrot c program, yet I get this error that has to do with not including acc routine information. Also, I am not sure whether I should be copying data in and out of the parallel section. PS I am relatively new to parallel programming, so any advice with learning it would be appreciated.
(Warning when compiled)
PGC-S-0155-Procedures called in a compute region must have acc routine information: fwrite (mandelbrot.c: 88)
PGC-S-0155-Accelerator region ignored; see -Minfo messages (mandelbrot.c: 51)
main:
51, Accelerator region ignored
88, Accelerator restriction: call to 'fwrite' with no acc routine information
PGC/x86-64 Linux 16.10-0: compilation completed with severe errors
Here is my code:
#include <stdio.h>
#include <math.h>
int main()
{
/* screen ( integer) coordinate */
int iX,iY;
const int iXmax = 800;
const int iYmax = 800;
/* world ( double) coordinate = parameter plane*/
double Cx,Cy;
const double CxMin=-2.5;
const double CxMax=1.5;
const double CyMin=-2.0;
const double CyMax=2.0;
/* */
double PixelWidth=(CxMax-CxMin)/iXmax;
double PixelHeight=(CyMax-CyMin)/iYmax;
/* color component ( R or G or B) is coded from 0 to 255 */
/* it is 24 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="new1.ppm";
char *comment="# ";/* comment should start with # */
static unsigned char color[3];
/* Z=Zx+Zy*i ; Z0 = 0 */
double Zx, Zy;
double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */
/* */
int Iteration;
const int IterationMax=200;
/* bail-out value , radius of circle ; */
const double EscapeRadius=2;
double ER2=EscapeRadius*EscapeRadius;
/*create new file,give it a name and open it in binary mode */
fp= fopen(filename,"wb"); /* b - binary mode */
/*write ASCII header to the file*/
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
/* compute and write image data bytes to the file*/
#pragma acc parallel loop present(CyMin, iY, PixelHeight, iX, iXmax, CxMin, PixelWidth, Zx, Zy, Zx2, Zy2, Iteration, IterationMax)
for(iY=0;iY<iYmax;iY++)
{
Cy=CyMin + iY*PixelHeight;
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
#pragma acc loop
for(iX=0;iX<iXmax;iX++)
{
Cx=CxMin + iX*PixelWidth;
/* initial value of orbit = critical point Z= 0 */
Zx=0.0;
Zy=0.0;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
/* */
#pragma acc loop
for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
{
Zy=2*Zx*Zy + Cy;
Zx=Zx2-Zy2 +Cx;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
};
/* compute pixel color (24 bit = 3 bytes) */
if (Iteration==IterationMax)
{ /* interior of Mandelbrot set = black */
color[0]=0;
color[1]=0;
color[2]=0;
}
else
{ /* exterior of Mandelbrot set = white */
color[0]=255; /* Red*/
color[1]=255; /* Green */
color[2]=255;/* Blue */
};
/*write color to the file*/
fwrite(color,1,3,fp);
}
}
fclose(fp);
return 0;
}
Since you can't access a file from the GPU, you'll want to capture the results to arrays, copy them back to the host, and then output the results to a file.
Also, the "present" clause indicates that you've already copied the data over to the device and the program will abort if it's not there. Given the usage, I think you meant to use "private", which indicates that the variable should be private to the execution level. However scalars are private by default in OpenACC, so there's no need to manually privatize these variables. If you do manually privatize a variable, be sure to put it at the correct loop level. For example, if you privatize "Zx" on the outer loop, it will only private to that loop level. It would be shared by all the vectors of the inner loop! Again, here, it's best to just let the compiler handle privatizing the scalars, but just be mindful of where you privatize things in the few cases where you have to manually privatize variables.
Here's a corrected version of your code.
#include <stdio.h>
#include <math.h>
int main()
{
/* screen ( integer) coordinate */
int iX,iY;
const int iXmax = 800;
const int iYmax = 800;
/* world ( double) coordinate = parameter plane*/
double Cx,Cy;
const double CxMin=-2.5;
const double CxMax=1.5;
const double CyMin=-2.0;
const double CyMax=2.0;
/* */
double PixelWidth=(CxMax-CxMin)/iXmax;
double PixelHeight=(CyMax-CyMin)/iYmax;
/* color component ( R or G or B) is coded from 0 to 255 */
/* it is 24 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="new1.ppm";
char *comment="# ";/* comment should start with # */
static unsigned char color[3];
unsigned char red[iXmax][iYmax];
unsigned char blue[iXmax][iYmax];
unsigned char green[iXmax][iYmax];
/* Z=Zx+Zy*i ; Z0 = 0 */
double Zx, Zy;
double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */
/* */
int Iteration;
const int IterationMax=200;
/* bail-out value , radius of circle ; */
const double EscapeRadius=2;
double ER2=EscapeRadius*EscapeRadius;
/*create new file,give it a name and open it in binary mode */
fp= fopen(filename,"wb"); /* b - binary mode */
/*write ASCII header to the file*/
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
/* compute and write image data bytes to the file*/
#pragma acc parallel loop copyout(red,blue,green)
for(iY=0;iY<iYmax;iY++)
{
Cy=CyMin + iY*PixelHeight;
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
#pragma acc loop
for(iX=0;iX<iXmax;iX++)
{
Cx=CxMin + iX*PixelWidth;
/* initial value of orbit = critical point Z= 0 */
Zx=0.0;
Zy=0.0;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
/* */
#pragma acc loop
for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
{
Zy=2*Zx*Zy + Cy;
Zx=Zx2-Zy2 +Cx;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
};
/* compute pixel color (24 bit = 3 bytes) */
if (Iteration==IterationMax)
{ /* interior of Mandelbrot set = black */
red[iX][iY]=0;
blue[iX][iY]=0;
green[iX][iY]=0;
}
else
{ /* exterior of Mandelbrot set = white */
red[iX][iY]=255;
blue[iX][iY]=255;
green[iX][iY]=255;
}; }
}
/*write color to the file*/
for(iY=0;iY<iYmax;iY++) {
for(iX=0;iX<iXmax;iX++) {
color[0] = red[iX][iY];
color[1] = blue[iX][iY];
color[2] = green[iX][iY];
fwrite(color,1,3,fp);
}
}
fclose(fp);
return 0;
}
When using OpenACC, the parallel regions are offloaded to a device, like a GPU. GPU devices normally don't have access to the entire system or the IO, and have a reduced subset of the standard library implemented.
In your case, the fwrite function call cannot be offloaded to a device, since you cannot access the disk from the accelerator.
You could do that in OpenMP, where parallel regions are executed on CPU or MIC threads, which typically have access to the entire system library.
The acc routine directive that PGC is suggesting would allow you to annotate any function to create a device version of it.

Using KissFFT on a wave file

I am trying to use the KissFFT Library with this 11 second 44kHz .wav sample file as a test input.
However as I process the file with a window size of 512, I am getting only 1 output value. Which is weird, the 11 sec .wav file at 44kHz should not give 1 value as an output with a windows size of 512. A smaller windows like 16 would give me 5 values, which is still a low count.
Does anyone know what I am doing wrong?
This is my code:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#define WIN 512
int main()
{
char *music_file = "C:/MSin44W16-13.wav";
FILE *in;
char buf[WIN * 2];
int nfft = WIN, i, fx;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
in = fopen(music_file, "r");
if (!in) {
printf("unable to open file: %s\n", music_file);
perror("Error");
return 1;
}
fx = 0;
while (fread(buf, 1, WIN * 2, in))
{
for (i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
free(cfg);
scanf("%d");
return 0;
}
This is the output I get:
42.7577
This is the Updated Code version, but I am getting errors at compile:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#include "sndfile.h"
#define WIN 512
int main()
{
char *music_file = "C:/voice.wav";
SNDFILE *infile;
SF_INFO sfinfo;
//int readcount;
short buf[WIN * 2];
int nfft = WIN;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
if (!( infile = sf_open(music_file, SFM_READ, &sfinfo) ))
{ /* Open failed so print an error message. */
printf("Not able to open input file %s.\n", "input.wav");
/* Print the error message fron libsndfile. */
sf_perror(NULL);
return 1;
}
while ((sf_read_short(infile, buf, WIN)))//fread(buf, 1, WIN * 2, in)
{
//system("cls");
for (int i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
sf_close(infile);
free(cfg);
int temp;
scanf_s("%d", &temp);
return 0;
}
I followed the steps on this post:
"error LNK2019: unresolved external symbol" error in Visual Studio 2010
And I still get these errors:
The problem does not comes from KissFFT, but rather from the fact that you are trying to read a binary wave file opened in ASCII mode on the line:
in = fopen(music_file, "r");
As you later try to read data with fread you eventually hit an invalid character. In your specific sample file, the 215th character read is the Substitute Character (hex value 0x1A), which is interpreted as an end of file marker by your C runtime library. Correspondingly, fread stops filling in more data and eventually return 0 (at the second iteration with WIN set to 512 and a little later with WIN set to 16).
To get around this problem, you should open the file in binary more with:
in = fopen(music_file, "rb");
Note that this will ensure the binary data is read as-is into your input buffer, but would not decode the wave file header for you. To properly read and decode a wave file and get meaningful data in, you should look into using an audio library (such as libsndfile to name one). If you must roll your own wave file reader you should read the specifications and/or check out one of many tutorials on the topic.

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