/* The Analysis & Resynthesis Sound Spectrograph Copyright (C) 2005-2008 Michel Rouzic This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/
#include "sound_io.h"
void in_8(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
uint8_t byte;
#ifdef DEBUG
printf("in_8...\n");
#endif
for (i=0; i<samplecount; i++)
for (ic=0;ic<channels;ic++)
{
fread(&byte, 1, 1, wavfile);
sound[ic][i] = (double) byte/128.0 - 1.0;
}
}
void out_8(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
double val;
uint8_t byte;
#ifdef DEBUG
printf("out_8...\n");
#endif
for (i=0; i<samplecount; i++)
for (ic=0;ic<channels;ic++)
{
val = roundoff((sound[ic][i]+1.0)*128.0);
if (val>255)
val=255;
if (val<0)
val=0;
byte = (uint8_t) val;
fwrite(&byte, sizeof(uint8_t), 1, wavfile);
}
}
void in_16(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
#ifdef DEBUG
printf("in_16...\n");
#endif
for (i=0; i<samplecount; i++)
for (ic=0; ic<channels; ic++)
sound[ic][i]=(double) ((int16_t) fread_le_short(wavfile))/32768.0;
}
void out_16(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
double val;
#ifdef DEBUG
printf("out_16...\n");
#endif
for (i=0; i<samplecount; i++)
for (ic=0;ic<channels;ic++)
{
val=roundoff(sound[ic][i]*32768.0);
if (val>32767.0)
val=32767.0;
if (val<-32768.0)
val=-32768.0;
fwrite_le_short((int16_t) val, wavfile);
}
}
void in_32(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
float val;
#ifdef DEBUG
printf("in_32...\n");
#endif
for (i=0;i<samplecount;i++)
for (ic=0;ic<channels;ic++)
{
*(uint32_t *) &val = fread_le_word(wavfile);
sound[ic][i] = (double) val;
}
}
void out_32(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
{
int32_t i, ic;
float val;
#ifdef DEBUG
printf("out_32...\n");
#endif
for (i=0; i<samplecount; i++)
for (ic=0;ic<channels;ic++)
{
val = (float) sound[ic][i];
fwrite_le_word(*(uint32_t *) &val, wavfile);
}
}
double **wav_in(FILE *wavfile, int32_t *channels, int32_t *samplecount, int32_t *samplerate)
{
int32_t i, ic;
double **sound;
int32_t tag[13];
#ifdef DEBUG
printf("wav_in...\n");
#endif
for (i=0; i<13; i++) // tag reading
{
tag[i]=0;
if ((i==5) || (i==6) || (i==9) || (i==10))
tag[i] = fread_le_short(wavfile);
else
tag[i] = fread_le_word(wavfile);
}
//********File format checking********
if (tag[0]!=1179011410 || tag[2]!=1163280727)
{
fprintf(stderr, "This file is not in WAVE format\n");
win_return();
exit(EXIT_FAILURE);
}
if (tag[3]!=544501094 || tag[4]!=16 || tag[11]!=1635017060)
{
fprintf(stderr, "This WAVE file format is not currently supported\n");
win_return();
exit(EXIT_FAILURE);
}
//--------File format checking--------
*channels = tag[6];
*samplecount = tag[12]/(tag[10]/8) / *channels;
*samplerate = tag[7];
sound = malloc (*channels * sizeof(double *)); // allocate sound
for (ic=0; ic < *channels; ic++)
sound[ic] = malloc (*samplecount * sizeof(double));
//********Data loading********
if (tag[10]==8)
in_8(wavfile, sound, *samplecount, *channels);
if (tag[10]==16)
in_16(wavfile, sound, *samplecount, *channels);
if (tag[10]==32)
in_32(wavfile, sound, *samplecount, *channels);
//--------Data loading--------
fclose(wavfile);
return sound;
}
void wav_out(FILE *wavfile, double **sound, int32_t channels, int32_t samplecount, int32_t samplerate, int32_t format_param)
{
int32_t i;
int32_t tag[] = {1179011410, 0, 1163280727, 544501094, 16, 1, 1, 0, 0, 0, 0, 1635017060, 0, 0};
#ifdef DEBUG
printf("wav_out...\n");
#endif
//********WAV tags generation********
tag[12] = samplecount*(format_param/8)*channels;
tag[1] = tag[12]+36;
tag[7] = samplerate;
tag[8] = samplerate*format_param/8;
tag[9] = format_param/8;
tag[6] = channels;
tag[10] = format_param;
if ((format_param==8) || (format_param==16))
tag[5]=1;
if (format_param==32)
tag[5]=3;
//--------WAV tags generation--------
for (i=0; i<13; i++) // tag writing
if ((i==5) || (i==6) || (i==9) || (i==10))
fwrite_le_short(tag[i], wavfile);
else
fwrite_le_word(tag[i], wavfile);
if (format_param==8)
out_8(wavfile, sound, samplecount, channels);
if (format_param==16)
out_16(wavfile, sound, samplecount, channels);
if (format_param==32)
out_32(wavfile, sound, samplecount, channels);
fclose(wavfile);
}
int32_t wav_out_param()
{
int32_t bps;
do
{
printf("Bits per sample (8/16/32) [16] : ");
bps=getfloat();
if (bps==0 || bps<-2147483647) // The -2147483647 check is used for the sake of compatibility with C90
bps = 16;
}
while (bps!=8 && bps!=16 && bps!=32);
return bps;
}