248 lines
8.8 KiB
C
248 lines
8.8 KiB
C
|
# ifndef _WAVE_STUFF_C_
|
|||
|
# define _WAVE_STUFF_C_
|
|||
|
|
|||
|
# include "stdio.h"
|
|||
|
# include "stdlib.h"
|
|||
|
# include "string.h"
|
|||
|
# include "wave_stuff.h"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int save_wave_from_array(float *x, int nx, char *file, int Frequence, int BitsPerSample)
|
|||
|
{
|
|||
|
FILE *fp;
|
|||
|
unsigned char *uch;
|
|||
|
int i, j, FileSize, tmp, BytePerSec, DataSize, data, noctets;
|
|||
|
short int AudioFormat = 1, NbrCanaux = 1, BytePerBloc, BitsPerSamp;
|
|||
|
|
|||
|
if (file == NULL || x == NULL) return -1;
|
|||
|
|
|||
|
noctets = BitsPerSample/8;
|
|||
|
BytePerBloc = (NbrCanaux * BitsPerSample/8);
|
|||
|
DataSize = nx * BytePerBloc;
|
|||
|
FileSize = DataSize + 44;
|
|||
|
BytePerSec = Frequence * BytePerBloc;
|
|||
|
BitsPerSamp = (short int)BitsPerSample;
|
|||
|
fp = fopen(file,"wb");
|
|||
|
if (fp == NULL) {fprintf(stderr,"could not open file %s to save wav",file);return 1;}
|
|||
|
// [Bloc de d<>claration d'un fichier au format WAVE] 12 octets
|
|||
|
if (fwrite("RIFF",sizeof(char),4,fp) != 4) {fclose(fp); return 2;}
|
|||
|
if (fwrite(&FileSize,sizeof(int),1,fp) != 1) {fclose(fp); return 3;}
|
|||
|
if (fwrite("WAVE",sizeof(char),4,fp) != 4) {fclose(fp); return 4;}
|
|||
|
// [Bloc d<>crivant le format audio] 24 octets
|
|||
|
if (fwrite("fmt ",sizeof(char),4,fp) != 4) {fclose(fp); return 5;}
|
|||
|
tmp = 16; //Nombre d'octets du bloc - 8 (0x10)
|
|||
|
if (fwrite(&tmp,sizeof(int),1,fp) != 1) {fclose(fp); return 6;}
|
|||
|
if (fwrite(&AudioFormat,sizeof(short int),1,fp) != 1)
|
|||
|
{fclose(fp); return 7;}
|
|||
|
if (fwrite(&NbrCanaux,sizeof(short int),1,fp) != 1)
|
|||
|
{fclose(fp); return 8;}
|
|||
|
if (fwrite(&Frequence,sizeof(int),1,fp) != 1) {fclose(fp); return 9;}
|
|||
|
if (fwrite(&BytePerSec,sizeof(int),1,fp) != 1) {fclose(fp); return 10;}
|
|||
|
if (fwrite(&BytePerBloc,sizeof(short int),1,fp) != 1)
|
|||
|
{fclose(fp); return 11;}
|
|||
|
if (fwrite(&BitsPerSamp,sizeof(short int),1,fp) != 1)
|
|||
|
{fclose(fp); return 12;}
|
|||
|
// [Bloc des donn<6E>es] 8 octets + datasize
|
|||
|
if (fwrite("data",sizeof(char),4,fp) != 4) {fclose(fp); return 13;}
|
|||
|
if (fwrite(&DataSize,sizeof(int),1,fp) != 1) {fclose(fp); return 14;}
|
|||
|
for (j = 0, uch = (unsigned char*)&data; j < nx; j++)
|
|||
|
{
|
|||
|
data = (int)x[j];
|
|||
|
if (fwrite(uch,sizeof(unsigned char),noctets,fp) != noctets)
|
|||
|
{fclose(fp); return j;}
|
|||
|
}
|
|||
|
fclose(fp);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
float* read_wave_create_array(char *file, int canal, int verbose, int *ny, int *freq)
|
|||
|
{
|
|||
|
FILE *fp;
|
|||
|
char ch[16];
|
|||
|
unsigned char uch[4];
|
|||
|
int i, j, FileSize, BytePerSec, DataSize, nx, data, noctets;
|
|||
|
short int AudioFormat = 1, NbrCanaux, BytePerBloc, BitsPerSamp, si;
|
|||
|
int Frequence, offset, cont;
|
|||
|
float *xd;
|
|||
|
|
|||
|
if (file == NULL) return NULL;
|
|||
|
|
|||
|
fp = fopen(file,"rb");
|
|||
|
if (fp == NULL)
|
|||
|
{ fprintf(stderr,"could not open file %s to read wav",file); return NULL;}
|
|||
|
// [Bloc de d<>claration d'un fichier au format WAVE] 12 octets
|
|||
|
if (fread(ch,sizeof(char),4,fp) != 4) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read RIFF label"); return NULL; }
|
|||
|
if (strncmp(ch,"RIFF",4) != 0)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read RIFF tag"); return NULL; }
|
|||
|
if (fread(&FileSize,sizeof(int),1,fp) != 1) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read File size"); return NULL;}
|
|||
|
if (verbose) fprintf(stderr,"file size %d",FileSize);
|
|||
|
if (fread(ch,sizeof(char),4,fp) != 4) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read WAVE label"); return NULL; }
|
|||
|
if (strncmp(ch,"WAVE",4) != 0)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read WAVE tag"); return NULL; }
|
|||
|
|
|||
|
// [Bloc d<>crivant le format audio] 24 octets
|
|||
|
if (fread(ch,sizeof(char),4,fp) != 4) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read fmt label"); return NULL; }
|
|||
|
if (strncmp(ch,"fmt ",4) != 0)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read fmt tag"); return NULL; }
|
|||
|
if (fread(&offset,sizeof(int),1,fp) != 1) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read offset"); return NULL; }
|
|||
|
if (verbose) fprintf(stderr,"offset %d",offset); // read 4
|
|||
|
if (fread(&AudioFormat,sizeof(short int),1,fp) != 1) // read 2
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read Audio format"); return NULL;}
|
|||
|
if (fread(&NbrCanaux,sizeof(short int),1,fp) != 1) // read 2
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read Nb. of canaux"); return NULL;}
|
|||
|
if (verbose) fprintf(stderr,"NbrCanaux %d",(int)NbrCanaux); // read 4
|
|||
|
if (fread(&Frequence,sizeof(int),1,fp) != 1)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read Frequence"); return NULL; }
|
|||
|
if (verbose) fprintf(stderr,"Frequence %d",Frequence); // read 4
|
|||
|
if (fread(&BytePerSec,sizeof(int),1,fp) != 1)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read BytePerSec"); return NULL;}
|
|||
|
if (verbose) fprintf(stderr,"BytePerSec %d",BytePerSec);
|
|||
|
if (fread(&BytePerBloc,sizeof(short int),1,fp) != 1) // read 2
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read BytePerSec"); return NULL; }
|
|||
|
if (verbose) fprintf(stderr,"BytePerBloc %d",(int)BytePerBloc);
|
|||
|
if (fread(&BitsPerSamp,sizeof(short int),1,fp) != 1) // read 2
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read BitsPerSamp"); return NULL; }
|
|||
|
if (verbose) fprintf(stderr,"BitsPerSamp %d",(int)BitsPerSamp);
|
|||
|
// [Bloc des donn<6E>es] 8 octets + datasize
|
|||
|
if (fread(ch,sizeof(char),4,fp) != 4) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read data label"); return NULL;}
|
|||
|
|
|||
|
if (strncmp(ch,"LIST",4) == 0)
|
|||
|
{
|
|||
|
if (fread(&offset,sizeof(int),1,fp) != 1) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read offset"); }
|
|||
|
if (verbose) fprintf(stderr,"found list block skipping %d bytes",offset);
|
|||
|
for (i = 0; i < offset; i++)
|
|||
|
{
|
|||
|
if (fread(ch,sizeof(char),1,fp) != 1)
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read data"); return NULL;}
|
|||
|
}
|
|||
|
if (fread(ch,sizeof(char),4,fp) != 4) // read 4
|
|||
|
{ fclose(fp); fprintf(stderr,"could not read data label"); return NULL;}
|
|||
|
}
|
|||
|
if (strncmp(ch,"data",4) != 0)
|
|||
|
{
|
|||
|
ch[4] = 0;
|
|||
|
cont = 0;
|
|||
|
fprintf(stderr,"could not read data tag!\n read %s instead "
|
|||
|
"\ntype 1 to continue anything else to stop",ch);
|
|||
|
scanf("%d",&cont);
|
|||
|
if (cont == 1)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
if (fread(&DataSize,sizeof(int),1,fp) != 1) // read 4
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"could not read datasize");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
noctets = BitsPerSamp/8;
|
|||
|
nx = DataSize/BytePerBloc;
|
|||
|
if (verbose) fprintf(stderr,"DataSize %d nx %d noctets %d" ,DataSize,nx,noctets);
|
|||
|
|
|||
|
if (BytePerBloc != (NbrCanaux * BitsPerSamp/8))
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"Byte per bloc pb!\n"
|
|||
|
"Byte per bloc %d != NbrCanaux %d x Bitspersample %d/8"
|
|||
|
,BytePerBloc,(int)NbrCanaux,(int)BitsPerSamp);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
/*
|
|||
|
if (FileSize != DataSize + 44)
|
|||
|
{
|
|||
|
cont = 0;
|
|||
|
i = fprintf(stderr,"File size pb!\n"
|
|||
|
"File size %d != datasize %d + 44"
|
|||
|
"\ntype 1 to continue anything else to stop"
|
|||
|
,FileSize,DataSize);
|
|||
|
scanf("%d",&cont);
|
|||
|
if (cont == 1)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
*/
|
|||
|
if (BytePerSec != Frequence * BytePerBloc)
|
|||
|
{
|
|||
|
cont = 0;
|
|||
|
i = fprintf(stderr,"Byte count pb!\n"
|
|||
|
"Byte per sec %d != Frequence %d x Byte per bloc %d"
|
|||
|
"\ntype 1 to continue anything else to stop"
|
|||
|
,BytePerSec,Frequence,BytePerBloc);
|
|||
|
scanf("%d",&cont);
|
|||
|
if (cont == 1)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
xd = (float*)calloc(nx,sizeof(float));
|
|||
|
if (xd == NULL)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"could not create float array");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
if (freq) *freq = Frequence;
|
|||
|
if (ny) *ny = nx;
|
|||
|
for (j = 0; j < nx; j++)
|
|||
|
{
|
|||
|
for (i = 0; i < NbrCanaux; i++)
|
|||
|
{
|
|||
|
uch[0] = uch[1] = uch[2] = uch[3] = 0;
|
|||
|
data = 0;
|
|||
|
if (noctets == 1)
|
|||
|
{
|
|||
|
if (fread(uch,sizeof(unsigned char),noctets,fp) != noctets)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"could not read unsigned int data at %d %d",i,j);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
data = uch[0];
|
|||
|
}
|
|||
|
if (noctets == 2)
|
|||
|
{
|
|||
|
if (fread(&si,sizeof(short int),1,fp) != 1)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"could not read short int data at %d %d",i,j);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
data = (int)si;
|
|||
|
}
|
|||
|
if (noctets == 3)
|
|||
|
{ // to be checked
|
|||
|
if (fread(uch,sizeof(unsigned char),noctets,fp) != noctets)
|
|||
|
{
|
|||
|
fclose(fp);
|
|||
|
fprintf(stderr,"could not read data at %d %d",i,j);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
data = (uch[0] << 8) | (uch[1] << 16) | (uch[2] << 24);
|
|||
|
data /= 256;
|
|||
|
}
|
|||
|
if (i == canal) xd[j] = (float)data;
|
|||
|
}
|
|||
|
}
|
|||
|
fclose(fp);
|
|||
|
return xd;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# endif
|