songplayer/wave_stuff.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é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é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