Difference between revisions of ".wav class source"

From Jeskola Buzz Wiki
Jump to: navigation, search
(Original attempt to write this. Improvements are welcome.)
 
(Removed linkwitz-riley crap)
 
Line 2: Line 2:
 
An attempt to write a C++ version of a [[.wav class]].
 
An attempt to write a C++ version of a [[.wav class]].
 
<pre>// WaveLoaderClass.cpp: Defines the entry point for the console application.
 
<pre>// WaveLoaderClass.cpp: Defines the entry point for the console application.
 
 
// #include "StdAfx.h"
 
// #include "StdAfx.h"
 
// #include "direct.h"
 
// #include "direct.h"
 
#include "WaveLoader.h"
 
#include "WaveLoader.h"
 
double const pi=3.1415926535897932384626433832795;
 
  
 
char* DisplayChunkName(unsigned int *value)
 
char* DisplayChunkName(unsigned int *value)
Line 21: Line 18:
 
return txt;
 
return txt;
 
}
 
}
 
// stereo split filter by Joachim
 
class LinkwitzRiley
 
{
 
public:
 
LinkwitzRiley()
 
{
 
this->LR4_Reset();
 
}
 
 
// Linkwitz-Riley-4 reset all variables
 
void LR4_Reset()
 
{
 
lr4_wc = 0;
 
lr4_wc2 = 0;
 
lr4_wc3 = 0;
 
lr4_wc4 = 0;
 
lr4_k = 0;
 
lr4_k2 = 0;
 
lr4_k3 = 0;
 
lr4_k4 = 0;
 
lr4_sqrt2 = 0;
 
lr4_sq_tmp1 = 0;
 
lr4_sq_tmp2 = 0;
 
lr4_a_tmp = 0;
 
lr4_b1 = 0;
 
lr4_b2 = 0;
 
lr4_b3 = 0;
 
lr4_b4 = 0;
 
for (int ch=0; ch<4; ch++)
 
{
 
lr4_xm4lp[ch] = 0;
 
lr4_xm3lp[ch] = 0;
 
lr4_xm2lp[ch] = 0;
 
lr4_xm1lp[ch] = 0;
 
lr4_ym4lp[ch] = 0;
 
lr4_ym3lp[ch] = 0;
 
lr4_ym2lp[ch] = 0;
 
lr4_ym1lp[ch] = 0;
 
lr4_a0lp[ch] = 0;
 
lr4_a1lp[ch] = 0;
 
lr4_a2lp[ch] = 0;
 
lr4_a3lp[ch] = 0;
 
lr4_a4lp[ch] = 0;
 
}
 
return;
 
}
 
 
// Linkwitz-Riley-4 calculate coefficients
 
void LR4_Calc_Coefficients( double fc, double srate )
 
{
 
lr4_wc = 2*pi*fc;
 
lr4_wc2 = lr4_wc*lr4_wc;
 
lr4_wc3 = lr4_wc2*lr4_wc;
 
lr4_wc4 = lr4_wc2*lr4_wc2;
 
lr4_k = lr4_wc/tan(pi*fc/srate);
 
lr4_k2 = lr4_k*lr4_k;
 
lr4_k3 = lr4_k2*lr4_k;
 
lr4_k4 = lr4_k2*lr4_k2;
 
lr4_sqrt2 = sqrtf(2);
 
lr4_sq_tmp1 = lr4_sqrt2*lr4_wc3*lr4_k;
 
lr4_sq_tmp2 = lr4_sqrt2*lr4_wc*lr4_k3;
 
lr4_a_tmp = 4*lr4_wc2*lr4_k2+2*lr4_sq_tmp1+lr4_k4+2*lr4_sq_tmp2+lr4_wc4;
 
 
lr4_b1 = (4*(lr4_wc4+lr4_sq_tmp1-lr4_k4-lr4_sq_tmp2))/lr4_a_tmp;
 
lr4_b2 = (6*lr4_wc4-8*lr4_wc2*lr4_k2+6*lr4_k4)/lr4_a_tmp;
 
lr4_b3 = (4*(lr4_wc4-lr4_sq_tmp1+lr4_sq_tmp2-lr4_k4))/lr4_a_tmp;
 
lr4_b4 = (lr4_k4-2*lr4_sq_tmp1+lr4_wc4-2*lr4_sq_tmp2+4*lr4_wc2*lr4_k2)/lr4_a_tmp;
 
 
// lowpass
 
lr4_a0lp[0] = lr4_wc4/lr4_a_tmp; // left
 
lr4_a1lp[0] = 4*lr4_wc4/lr4_a_tmp;
 
lr4_a2lp[0] = 6*lr4_wc4/lr4_a_tmp;
 
lr4_a3lp[0] = lr4_a1lp[0];
 
lr4_a4lp[0] = lr4_a0lp[0];
 
lr4_a0lp[1] = lr4_wc4/lr4_a_tmp; // right
 
lr4_a1lp[1] = 4*lr4_wc4/lr4_a_tmp;
 
lr4_a2lp[1] = 6*lr4_wc4/lr4_a_tmp;
 
lr4_a3lp[1] = lr4_a1lp[0];
 
lr4_a4lp[1] = lr4_a0lp[1];
 
 
// highpass
 
lr4_a0lp[2] = lr4_k4/lr4_a_tmp; // left
 
lr4_a1lp[2] = -4*lr4_k4/lr4_a_tmp;
 
lr4_a2lp[2] = 6*lr4_k4/lr4_a_tmp;
 
lr4_a3lp[2] = lr4_a1lp[2];
 
lr4_a4lp[2] = lr4_a0lp[2];
 
lr4_a0lp[3] = lr4_k4/lr4_a_tmp; // right
 
lr4_a1lp[3] = -4*lr4_k4/lr4_a_tmp;
 
lr4_a2lp[3] = 6*lr4_k4/lr4_a_tmp;
 
lr4_a3lp[3] = lr4_a1lp[3];
 
lr4_a4lp[3] = lr4_a0lp[3];
 
}
 
 
// Linkwitz-Riley-4 in-loop filtering, use ch 0,1 for lowpass left,right, 2,3 is highpass
 
double LR4_Process( double input, int ch )
 
{
 
double tempy = lr4_a0lp[ch]*input+lr4_a1lp[ch]*lr4_xm1lp[ch]+lr4_a2lp[ch]*lr4_xm2lp[ch]+lr4_a3lp[ch]*lr4_xm3lp[ch]+lr4_a4lp[ch]*lr4_xm4lp[ch]-lr4_b1*lr4_ym1lp[ch]-lr4_b2*lr4_ym2lp[ch]-lr4_b3*lr4_ym3lp[ch]-lr4_b4*lr4_ym4lp[ch];
 
lr4_xm4lp[ch] = lr4_xm3lp[ch];
 
lr4_xm3lp[ch] = lr4_xm2lp[ch];
 
lr4_xm2lp[ch] = lr4_xm1lp[ch];
 
lr4_xm1lp[ch] = input;
 
lr4_ym4lp[ch] = lr4_ym3lp[ch];
 
lr4_ym3lp[ch] = lr4_ym2lp[ch];
 
lr4_ym2lp[ch] = lr4_ym1lp[ch];
 
lr4_ym1lp[ch] = tempy;
 
return tempy;
 
}
 
 
private:
 
double lr4_wc;
 
double lr4_wc2;
 
double lr4_wc3;
 
double lr4_wc4;
 
double lr4_k;
 
double lr4_k2;
 
double lr4_k3;
 
double lr4_k4;
 
double lr4_sqrt2;
 
double lr4_sq_tmp1;
 
double lr4_sq_tmp2;
 
double lr4_a_tmp;
 
double lr4_a0lp[4];
 
double lr4_a1lp[4];
 
double lr4_a2lp[4];
 
double lr4_a3lp[4];
 
double lr4_a4lp[4];
 
double lr4_b1;
 
double lr4_b2;
 
double lr4_b3;
 
double lr4_b4;
 
double lr4_xm4lp[4];
 
double lr4_xm3lp[4];
 
double lr4_xm2lp[4];
 
double lr4_xm1lp[4];
 
double lr4_ym4lp[4];
 
double lr4_ym3lp[4];
 
double lr4_ym2lp[4];
 
double lr4_ym1lp[4];
 
};
 
 
  
 
int main(int argc, char* argv[])
 
int main(int argc, char* argv[])
Line 168: Line 24:
 
if (argc<=2 || *argv[1]=='?' || *(argv[1]+1)=='?')
 
if (argc<=2 || *argv[1]=='?' || *(argv[1]+1)=='?')
 
{
 
{
printf(".Wav to sound level calculator by Joachim Michaelis 2010\n");
+
printf("Demo application that does nothing.\n");
printf("Usage: %s <input .wav file> <number of output values>\n", argv[0]);
+
printf("Usage: %s <input .wav file> <blergh>\n", argv[0]);
 
return -3;
 
return -3;
 
}
 
}
  
 
char *InputFilename = argv[1];
 
char *InputFilename = argv[1];
char *PixelCountArg = argv[2];
+
char *Blergh = argv[2];
  
 
WaveFile* myFile = new WaveFile();
 
WaveFile* myFile = new WaveFile();
LinkwitzRiley* myFilter = new LinkwitzRiley();
 
  
unsigned long PixelCount = 0;
 
PixelCount = atoi(PixelCountArg);
 
if (PixelCount==0 || PixelCount>10000)
 
{
 
printf("Illegal number of output values\n");
 
return -3;
 
}
 
 
int errorcode = myFile->OpenWav(InputFilename);
 
int errorcode = myFile->OpenWav(InputFilename);
  
 
if (errorcode==0)
 
if (errorcode==0)
 
{
 
{
// unsigned long int total_length = 10; // number of output values (pixels in visualization)
 
 
 
myFile->PrepareToRead();
 
myFile->PrepareToRead();
if (myFile->number_of_samples==0 || myFile->waveHeader.sampleRate==0)
+
for (unsigned long s=0; s<myFile->number_of_samples; s+=myFile->waveHeader.numChannels)
 
{
 
{
printf("File contains %d samples (%d Hz)\n", myFile->number_of_samples, myFile->waveHeader.sampleRate);
+
float sample = 0;
} else
+
for(int channel=0; channel<myFile->waveHeader.numChannels; channel++)
{
+
// prepare the split filter and set its frequency
+
myFilter->LR4_Calc_Coefficients(400, myFile->waveHeader.sampleRate);
+
 
+
unsigned long samples_per_pixel = myFile->number_of_samples / myFile->waveHeader.numChannels / PixelCount;
+
unsigned long pixel = 0;
+
unsigned long s2 = 0;
+
float summed_bass = 0;
+
float summed_treb = 0;
+
float max_bass = 0;
+
float max_treb = 0;
+
printf("Peak bass, Average bass, Peak treble, Average treble\n");
+
for (unsigned long s=0; s<myFile->number_of_samples; s+=myFile->waveHeader.numChannels)
+
 
{
 
{
float sample = 0;
+
sample += myFile->Read1MonoSample(); // add all channels together to mono (example)
for(int channel=0; channel<myFile->waveHeader.numChannels; channel++)
+
}
{
+
sample = sample/myFile->waveHeader.numChannels;
sample += myFile->Read1MonoSample(); // add all channels together to mono
+
}
+
sample = sample/myFile->waveHeader.numChannels;
+
  
float bass = fabsf((float)myFilter->LR4_Process((double)sample, 0)); // 0=left bass
+
// ho-hum...
float treb = fabsf((float)myFilter->LR4_Process((double)sample, 2)); // 2=left treble (we only use mono here)
+
  
summed_bass += bass*bass;
 
summed_treb += treb*treb;
 
if (bass>max_bass)  max_bass = bass;
 
if (treb>max_treb)  max_treb = treb;
 
if (s2>=samples_per_pixel)
 
{
 
pixel++;
 
s2 = 0;
 
summed_bass = sqrtf(summed_bass/(float)samples_per_pixel);
 
summed_treb = sqrtf(summed_treb/(float)samples_per_pixel);
 
printf("%.6f, %.6f, %.6f, %.6f\n", max_bass, summed_bass, max_treb, summed_treb);
 
summed_bass = 0;
 
summed_treb = 0;
 
max_bass = 0;
 
max_treb = 0;
 
}
 
s2++;
 
 
}
 
 
}
 
}
 
myFile->CloseWav();
 
myFile->CloseWav();
 +
return 0;
 
} else
 
} else
 
{
 
{
 
printf("Error %d loading .wav file.\n", errorcode);
 
printf("Error %d loading .wav file.\n", errorcode);
 
}
 
}
 
+
return errorcode;
 
+
 
+
 
+
 
+
 
+
 
+
 
+
 
+
 
+
 
+
 
+
/*
+
if (argc<=2 || *argv[1]=='?' || *(argv[1]+1)=='?')
+
{
+
printf(".Filter test by Joachim Michaelis 2010\n");
+
printf("Usage: %s <input .wav file> <output raw pcm file>\n", argv[0]);
+
return -3;
+
}
+
 
+
char *InputFilename = argv[1];
+
char *OutputFilename = argv[2];
+
 
+
LinkwitzRiley* myFilter = new LinkwitzRiley();
+
myFilter->LR4_Reset();
+
 
+
WaveFile* myFile = new WaveFile();
+
int errorcode = myFile->OpenWav(InputFilename);
+
// static char here[300]; getcwd(here, _MAX_PATH); // current directory
+
 
+
if (errorcode==0)
+
{
+
printf("RIFF file type  : %s\n", DisplayChunkName(&myFile->fileType));
+
printf("RIFF file length: %d\n", myFile->fileLength);
+
myFile->ReadAllIntoFloat();
+
myFile->CloseWav();
+
 
+
if (myFile->waveHeader.sampleRate!=0)
+
{
+
myFilter->LR4_Calc_Coefficients(400, myFile->waveHeader.sampleRate);
+
} else
+
{
+
myFilter->LR4_Calc_Coefficients(400, 44100);
+
}
+
 
+
float ileft = 0;
+
float iright = 0;
+
float oleft = 0;
+
float oright = 0;
+
float ilefto = 0;
+
float irighto = 0;
+
 
+
printf("Processing audio... \n");
+
 
+
// process stuff
+
for (unsigned int counter=0; counter<myFile->audiodata_count-1; counter+=myFile->waveHeader.numChannels)
+
{
+
ilefto = ileft;
+
irighto = iright;
+
ileft = myFile->audiodata[counter];
+
iright = myFile->audiodata[counter+1];
+
 
+
// oleft = oleft*0.99f + atanf((ileft-ilefto)*200)/150+0.04f;
+
// oright = oright*0.99f + atanf((iright-irighto)*200)/150+0.04f;
+
// myFile->audiodata[counter+1] = sinf(oright*3)+0.536f;
+
// myFile->audiodata[counter] = sinf(oleft*3)+0.536f;
+
 
+
float leftbass = (float)myFilter->LR4_Process((double)ileft, 0);
+
float rightbass = (float)myFilter->LR4_Process((double)iright, 1);
+
float lefttreble = (float)myFilter->LR4_Process((double)ileft, 2);
+
float righttreble = (float)myFilter->LR4_Process((double)ileft, 3);
+
myFile->audiodata[counter+1] = lefttreble;
+
myFile->audiodata[counter] = righttreble;
+
}
+
 
+
myFile->WriteWav(OutputFilename);
+
myFile->FreeMem();
+
} else
+
{
+
printf("Error code: %d\n", errorcode);
+
}
+
*/
+
// printf("Press enter to continue\n");
+
// static char dummy[10];
+
// scanf("hmm", dummy);
+
return 0;
+
 
}
 
}
 
</pre>
 
</pre>

Latest revision as of 23:06, 23 November 2010

WaveLoaderClass.cpp

An attempt to write a C++ version of a .wav class.

// WaveLoaderClass.cpp: Defines the entry point for the console application.
// #include "StdAfx.h"
// #include "direct.h"
#include "WaveLoader.h"

char* DisplayChunkName(unsigned int *value)
{
	unsigned char *copyfrom;
	copyfrom = (unsigned char*)value;
	static char txt[5];
	txt[0] = *copyfrom++;
	txt[1] = *copyfrom++;
	txt[2] = *copyfrom++;
	txt[3] = *copyfrom++;
	txt[4] = 0;
	return txt;
}

int main(int argc, char* argv[])
{

	if (argc<=2 || *argv[1]=='?' || *(argv[1]+1)=='?')
	{
		printf("Demo application that does nothing.\n");
		printf("Usage: %s <input .wav file> <blergh>\n", argv[0]);
		return -3;
	}

	char *InputFilename = argv[1];
	char *Blergh = argv[2];

	WaveFile* myFile = new WaveFile();

	int errorcode = myFile->OpenWav(InputFilename);

	if (errorcode==0)
	{
		myFile->PrepareToRead();
		for (unsigned long s=0; s<myFile->number_of_samples; s+=myFile->waveHeader.numChannels)
		{
			float sample = 0;
			for(int channel=0; channel<myFile->waveHeader.numChannels; channel++)
			{
				sample += myFile->Read1MonoSample();		// add all channels together to mono (example)
			}
			sample = sample/myFile->waveHeader.numChannels;

			// ho-hum...

		}
		myFile->CloseWav();
		return 0;
	} else
	{
		printf("Error %d loading .wav file.\n", errorcode);
	}
	return errorcode;
}

WaveLoader.h

// Wave Loader Class by Joachip

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define ReadAndConvertToFloat 0
#define ReadSampleBySample 1

struct WaveHeaderStructure
{
	unsigned short compressionCode;
	unsigned short numChannels;
	unsigned int sampleRate;
	unsigned int bytesPerSecond;
	unsigned short blockAlign;
	unsigned short bitsPerSample;
	unsigned short extraFormatBytes;
};

class WaveFile
{
private:
	FILE* fp;
	FILE* fpw;
	unsigned long pointer;
	unsigned long data_chunk_fileposition;
	unsigned int chunkHeader;			// char[4]
	unsigned int chunkLength;

public:
	WaveHeaderStructure waveHeader;
	unsigned int identifier;			// char[4]
	unsigned int fileLength;
	unsigned int fileType;				// char[4]
	float* audiodata;					// for stereo left and right are interleaved
	unsigned long number_of_samples;	// count to this when using Read1MonoSample() and such
	unsigned int audiodata_count;

	WaveFile()
	{
		this->Initialize();
	}

	void Initialize()
	{
		fp = 0;
		fpw = 0;
		pointer = 0;
		data_chunk_fileposition = 0;
		fileLength = 0;
		waveHeader.sampleRate = 0;
		audiodata = NULL;
		audiodata_count = 0;
		number_of_samples = 0;
	}

	int OpenWav(char *filename)
	{
		if((fp = fopen(filename, "rb"))==NULL)
		{
			printf("Cannot open input file \"%s\".\n", filename);
			fp = 0;
			return 1;
		}

		identifier = GetChunkName();
		fileLength = GetLength_le();
		fileType = GetChunkName();
		if (identifier!=0x46464952)	return 2;		// not a RIFF file (warning: this check is not endianness aware)
		if (fileType!=0x45564157)	return 3;		// not a WAVE file
		return 0;
	}

	void ReadAllIntoFloat()
	{
		this->Parse(ReadAndConvertToFloat);
	}

	// place pointer at start of the data chunk and get ready to call Read1MonoSample() a lot of times
	void PrepareToRead()
	{
		this->Parse(ReadSampleBySample);
		fseek(fp, data_chunk_fileposition, SEEK_SET);
	}

	float Read1MonoSample()
	{
		if (waveHeader.numChannels==0)  return 0;
		float value = 0;
		for (int currentChannel=0; currentChannel<waveHeader.numChannels; currentChannel++)
		{
			if (waveHeader.bitsPerSample==8)
			{
				value += ((float)( fgetc(fp) & 0xFF) )/170;
			}

			if (waveHeader.bitsPerSample==16)
			{
				value += ((float)( (fgetc(fp) & 0xFF) | ((signed char)fgetc(fp))<<8 ) )/32768;
			}

			if (waveHeader.bitsPerSample==24)
			{
				value += ((float)( (fgetc(fp) & 0xFF) | ((signed char)fgetc(fp))<<8 | ((signed char)fgetc(fp))<<16 ) )/8388608;
			}
		}
		value = value/waveHeader.numChannels;
		return value;
	}

	void CloseWav()
	{
		if (fp!=0)
		{
			fclose(fp);
			fp = 0;
		}

		if (fpw!=0)
		{
			fclose(fpw);
			fpw = 0;
		}
	}

	void FreeMem()
	{
		if (audiodata!=NULL)
		{
			delete[] audiodata;
			audiodata = NULL;
		}
	}

	int WriteWav(char *filename)
	{
		if (waveHeader.sampleRate==0 || audiodata==NULL)
		{
			printf("No wave data to write.\n", filename);
			return 5;
		}

		if((fpw = fopen(filename, "wb"))==NULL)
		{
			printf("Cannot open output file \"%s\".\n", filename);
			fpw = 0;
			return 4;
		}

		signed int value = 0;
		unsigned int counter;
		static char byte1 = 0;
		static char byte2 = 0;
		static char byte3 = 0;

		if (waveHeader.bitsPerSample==8)
		{
			for (counter=0; counter<audiodata_count; counter++)
			{
				value = (int)(audiodata[counter]*128);
				if (value>127)  value = 127;
				if (value<-128)  value = -128;
				byte1 = (unsigned char)(value & 0xFF);
				fputc(byte1, fpw);
			}
		}

		if (waveHeader.bitsPerSample==16)
		{
			for (counter=0; counter<audiodata_count; counter++)
			{
				// audiodata[counter] = sinf((float)counter/40.0f)*0.6f;
				value = (int)(audiodata[counter]*32768);
				if (value>32767)  value = 32767;
				if (value<-32768)  value = -32768;
				byte1 = value & 0xFF;
				byte2 = (value>>8) & 0xFF;
				fputc(byte1, fpw);
				fputc(byte2, fpw);
			}
		}

		if (waveHeader.bitsPerSample==24)
		{
			for (counter=0; counter<audiodata_count; counter++)
			{
				value = (int)(audiodata[counter]*8388608);
				if (value>8388607)  value = 8388607;
				if (value<-8388608)  value = -8388608;
				byte1 = value & 0xFF;
				byte2 = (value>>8) & 0xFF;
				byte2 = (value>>16) & 0xFF;
				fputs(&byte1, fpw);
				fputs(&byte2, fpw);
				fputs(&byte3, fpw);
			}
		}

		fclose(fpw);
		fpw = 0;
		return 0;
	}

private:

	void Parse(int readmode)
	{
		if (fp==0)  return;

		// get length
		fseek(fp, 0, SEEK_END);
		unsigned long ActualFileSize = ftell(fp);

		// set at first chunk
		pointer = 12;
		data_chunk_fileposition = 0;
		chunkLength = 4;
		while (pointer>8 && pointer<ActualFileSize && chunkLength!=0)
		{
			// seek to next chunk
			fseek(fp, pointer, SEEK_SET);
			chunkHeader = GetChunkName();
			chunkLength = GetLength_le();
			// printf("Noget: %d, %08X, chunklength=%X (filesize=%X)\n", pointer, chunkHeader, chunkLength, ActualFileSize);
			if (chunkLength>4 && (pointer+chunkLength)<ActualFileSize)
			{
				// printf("\nChunk type found: %s (%d bytes)\n", DispChunkName(&chunkHeader), chunkLength);

				// fmt  chunk
				if (chunkHeader==' tmf' || chunkHeader=='fmt ')
				{
					// printf("Processing format chunk...\n");
					waveHeader.compressionCode = Get16ubit_le();
					waveHeader.numChannels = Get16ubit_le();
					waveHeader.sampleRate = GetLength_le();
					waveHeader.bytesPerSecond = GetLength_le();
					waveHeader.blockAlign = Get16ubit_le();
					waveHeader.bitsPerSample = Get16ubit_le();
					// waveHeader.extraFormatBytes = Get16ubit_le();		// returns wrong result!?
					// printf("numChannels=%d, sampleRate=%d, bitsPerSample=%d\n", waveHeader.numChannels, waveHeader.sampleRate, waveHeader.bitsPerSample);
				}

				// data chunk (but only if we already have the fmt chunk)
				if ((chunkHeader=='atad' || chunkHeader=='data') && waveHeader.sampleRate>0)
				{
					if (readmode==ReadAndConvertToFloat)
					{
						DataChunkToFloat();
					}

					if (readmode==ReadSampleBySample)
					{
						number_of_samples = chunkLength/(waveHeader.bitsPerSample/8)/waveHeader.numChannels;
						data_chunk_fileposition = pointer+8;
					}
				}

				// ToDo: remember unknown chunks

			} else
			{
				// printf("RIFF ended\n");
			}
			pointer += chunkLength+8;
		}
	}

	void DataChunkToFloat()
	{
		// printf("Processing data chunk...\n");

		// malloc and convert to floats
		audiodata = new float[chunkLength/(waveHeader.bitsPerSample/8)];
		unsigned long sample_skip_bytes = waveHeader.bitsPerSample/8; //  * waveHeader.numChannels;
		unsigned int counter=0;
		float value = 0;
		signed int temp = 0;

		if (waveHeader.bitsPerSample==8)
		{
			for (unsigned long datapointer=0; datapointer<chunkLength; datapointer += sample_skip_bytes)
			{
				value = ((float)( fgetc(fp) & 0xFF) )/128;
				audiodata[counter++] = value;
			}
		}

		if (waveHeader.bitsPerSample==16)
		{
			for (unsigned long datapointer=0; datapointer<chunkLength; datapointer += sample_skip_bytes)
			{
				temp = (fgetc(fp) & 0xFF) | (((signed char)fgetc(fp))<<8);
				// value = sinf((float)datapointer/70.0f)*0.6f;
				audiodata[counter++] = ((float)temp) / 32768;
			}
		}

		if (waveHeader.bitsPerSample==24)
		{
			for (unsigned long datapointer=0; datapointer<chunkLength; datapointer += sample_skip_bytes)
			{
				value = ((float)( (fgetc(fp) & 0xFF) | ((signed char)fgetc(fp))<<8 | ((signed char)fgetc(fp))<<16 ) )/8388608;
				audiodata[counter++] = value;
			}
		}
		audiodata_count = counter;
	}

	void GetChunkName2(char *destination)
	{
		for(int a=0; a<4; a++)
		{
			int i = fgetc(fp);
			if(i == EOF) break;
			*destination++ = (char)i;
		}
	}

	char* DispChunkName(unsigned int *value)
	{
		unsigned char *copyfrom;
		copyfrom = (unsigned char*)value;
		static char txt[5];
		txt[0] = *copyfrom++;
		txt[1] = *copyfrom++;
		txt[2] = *copyfrom++;
		txt[3] = *copyfrom++;
		txt[4] = 0;
		return txt;
	}


	signed short Get16sbit_le()
	{
		// get a 16 bit word in little endian (intel byte order)
		signed short value = fgetc(fp) | (fgetc(fp)<<8);
		return value;
	}

	unsigned short Get16ubit_le()
	{
		// get a 16 bit word in little endian (intel byte order)
		unsigned short value = fgetc(fp) | (fgetc(fp)<<8);
		return value;
	}

	unsigned int GetLength_le()
	{
		// get a 32 bit length in little endian
		unsigned int value = fgetc(fp) | (fgetc(fp)<<8) | (fgetc(fp)<<16) | (fgetc(fp)<<24);
		return value;
	}

	// using an int because char[4] and char act weird
	unsigned int GetChunkName()
	{
		// get a 32 bit length in little endian
		unsigned int value = fgetc(fp) | (fgetc(fp)<<8) | (fgetc(fp)<<16) | (fgetc(fp)<<24);
		return value;
	}

};