git » fp-git.git » commit 9ded0f4

rewritten wave format reading support

author ecalot
2006-02-23 02:46:55 UTC
committer ecalot
2006-02-23 02:46:55 UTC
parent e793d7b7c32d6dcfed6fc24d597e9bba50d9b7a0

rewritten wave format reading support

PR/src/include/common.h +3 -0
PR/src/include/object.h +1 -1
PR/src/include/other.h +1 -0
PR/src/include/sound.h +5 -0
PR/src/include/wav.h +1 -0
PR/src/lib/actions/import.c +2 -2
PR/src/lib/formats/wav.c +71 -4
PR/src/lib/layers/disk.c +1 -1
PR/src/lib/object/object.c +7 -5
PR/src/lib/object/other/binary.c +9 -0
PR/src/lib/object/sound/sound_common.c +34 -3

diff --git a/PR/src/include/common.h b/PR/src/include/common.h
index cb701e9..5e3a510 100644
--- a/PR/src/include/common.h
+++ b/PR/src/include/common.h
@@ -228,5 +228,8 @@ PARSING_OPTRAW\
 #define PR_RESULT_SUCCESS 0
 #define PR_RESULT_COMPRESS_RESULT_FATAL -26 
 #define PR_RESULT_COMPRESS_RESULT_WARNING -27
+#define PR_RESULT_WAV_UNSUPPORTED_BITRATE -28
+#define PR_RESULT_WAV_UNSUPPORTED_SAMPLERATE -29
+#define PR_RESULT_WAV_UNSUPPORTED_STEREO -30
 
 #endif
diff --git a/PR/src/include/object.h b/PR/src/include/object.h
index 8e5d6da..8f12cec 100644
--- a/PR/src/include/object.h
+++ b/PR/src/include/object.h
@@ -39,7 +39,7 @@ object.h: Princed Resources : Main item class types and prototypes
 
 tObject getObject(tResource* r, int* error);
 int writeObject(tObject o, const char* file, int optionflag, const char* backupExtension);
-tObject readObject(const char* file,tResource newRes,int *result);
+tObject readObject(const char* file,tResource* newRes,int *result);
 void setObject(tObject o,int *result);
 
 int paletteGetBits(tObject pal);
diff --git a/PR/src/include/other.h b/PR/src/include/other.h
index 2556e01..00f06f5 100644
--- a/PR/src/include/other.h
+++ b/PR/src/include/other.h
@@ -37,5 +37,6 @@ other.h: Princed Resources :
 
 void* objBinaryCreate(tBinary c, int *error);
 int objBinaryWrite(void* o, const char* file, int optionflag, const char* backupExtension);
+void* objBinaryRead(const char* file,int *result);
 
 #endif
diff --git a/PR/src/include/sound.h b/PR/src/include/sound.h
index 823e6b7..ec6bebd 100644
--- a/PR/src/include/sound.h
+++ b/PR/src/include/sound.h
@@ -50,4 +50,9 @@ void* objSoundCreate(tBinary c, int *error);
 #define objMidiCreate(a,b) objSoundCreate(a,b)
 #define objPcspeakerCreate(a,b) objSoundCreate(a,b)
 
+/*#define objWaveRead(a,b,c,d,e) objSoundRead(a,readWav,b,c,d,e)*/
+void* objSoundRead(const char* file, int read(const char* file, tBinary* c, int *pchannels, long *psamplerate, long *pbps), int *result);
+
+void* objWaveRead(const char* file, int *result);
+
 #endif
diff --git a/PR/src/include/wav.h b/PR/src/include/wav.h
index 2da3aba..aecee0e 100644
--- a/PR/src/include/wav.h
+++ b/PR/src/include/wav.h
@@ -40,6 +40,7 @@ wav.h: Princed Resources : WAV files support headers
 #define WAVE_HEADER {0x52, 0x49, 0x46, 0x46, 0x12, 0x16, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x2B, 0x00, 0x00, 0x11, 0x2B, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x64, 0x61, 0x74, 0x61, 0xA3, 0x15, 0x00, 0x00}
 
 int writeWav(const char* file, tBinary* snd, int optionflag, const char* backupExtension);
+int readWav(const char* file, tBinary* c, int *pchannels, long *psamplerate, long *pbps);
 int mFormatImportWav(tResource *res);
 
 #endif
diff --git a/PR/src/lib/actions/import.c b/PR/src/lib/actions/import.c
index b85dab8..6e92052 100644
--- a/PR/src/lib/actions/import.c
+++ b/PR/src/lib/actions/import.c
@@ -90,7 +90,7 @@ int import_full(const char* vFiledat, const char* vDirExt, tResourceList* r, int
 /*		newRes.content=mLoadFileArray(vFileext);*/
 /*		if (newRes.content.size>0) {*/
 			/* TODO: let each format handle the files */
-		o=readObject(vFileext,newRes,&result);
+		o=readObject(vFileext,&newRes,&result);
 /*			if (!fatal(ok)) */
 		setObject(o,&result);
 			
@@ -157,7 +157,7 @@ int import_partial(const char* vFiledat, const char* vDirExt, tResourceList* r,
 			/* get save file name (if unknown document is in the XML) */
 			getFileName(vFileext,vDirExt,&res,vFiledat,vDatFileName,optionflag,backupExtension,NULL);
 
-			o=readObject(vFileext,newRes,&result);
+			o=readObject(vFileext,&newRes,&result);
 /*			if (!fatal(ok)) */
 			setObject(o,&result);
 			
diff --git a/PR/src/lib/formats/wav.c b/PR/src/lib/formats/wav.c
index 3f08763..e42f913 100644
--- a/PR/src/lib/formats/wav.c
+++ b/PR/src/lib/formats/wav.c
@@ -35,6 +35,8 @@ wav.c: Princed Resources : WAV files support
 #include "dat.h"
 #include "disk.h"
 #include "wav.h"
+#include <string.h>
+#include <stdlib.h>
 
 int writeWav(const char* file, tBinary* snd, int optionflag, const char* backupExtension) {
 	FILE*         target;
@@ -60,18 +62,83 @@ int writeWav(const char* file, tBinary* snd, int optionflag, const char* backupE
 	return ok?PR_RESULT_SUCCESS:PR_RESULT_ERR_FILE_NOT_WRITE_ACCESS;
 }
 
-int mFormatImportWav(tResource *res) {
+int readWav(const char* file, tBinary* snd, int *pchannels, long *psamplerate, long *pbps) {
+	FILE* fd;
+	int ok;
+	char magic[4];
+	long int ChunkSize;
+	long int SubChunk1Size;
+	short int AudioFormat;
+	short int NumChannels;
+	long int SampleRate;
+	long int ByteRate;
+	short int BlockAlign;
+	short int BitsPerSample;
+	long int SubChunk2Size;
+	
+	fd=fopen(file,"rb");
+	if (!fd) return PR_RESULT_ERR_FILE_NOT_READ_ACCESS; 
+
+	/* Read headers */
+	ok=fread(magic,4,1,fd);
+	ok=ok&&!strncmp(magic,"RIFF",4);
+	ok=ok&&freadlong(&ChunkSize,fd);
+	ok=ok&&fread(magic,4,1,fd);
+	ok=ok&&!strncmp(magic,"WAVE",4);
+	ok=ok&&fread(magic,4,1,fd);
+	ok=ok&&!strncmp(magic,"fmt ",4);
+	ok=ok&&freadlong(&SubChunk1Size,fd);
+	ok=ok&&freadshort(&AudioFormat,fd);
+	ok=ok&&freadshort(&NumChannels,fd);
+	ok=ok&&freadlong(&SampleRate,fd);
+	ok=ok&&freadlong(&ByteRate,fd);
+	ok=ok&&freadshort(&BlockAlign,fd);
+	ok=ok&&freadshort(&BitsPerSample,fd);
+	ok=ok&&fread(magic,4,1,fd);
+	ok=ok&&!strncmp(magic,"data",4);
+	ok=ok&&freadlong(&SubChunk2Size,fd);
+	
+	/* Validate input vars */	
+  ok=ok&& (AudioFormat   == 1 ); /* PCM */
+  ok=ok&& (BlockAlign    == NumChannels * BitsPerSample/8 );
+	ok=ok&& (ByteRate      == SampleRate * NumChannels * BitsPerSample/8 );
+	ok=ok&& (ChunkSize     == 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) );
+  ok=ok&& (SubChunk1Size == 16 ); /* PCM chunk */
+/*	ok=ok&& (SubChunk2Size == NumSamples * NumChannels * BitsPerSample/8 );*/
+	
+	/* Read data*/
+	if (ok) {
+		snd->size=SubChunk2Size;
+		snd->data=malloc(SubChunk2Size);
+		ok=fread(snd->data,SubChunk2Size,1,fd);
+	} else {
+		return PR_RESULT_ERR_FILE_NOT_READ_ACCESS; /* TODO: use a bad format code */
+	}
+	/* TODO: check eof */
+	
+	/*
 	unsigned char wav[]=WAVE_HEADER;
 	int i=sizeof(wav);
 	unsigned char* posAux=res->content.data;
 
-	if (res->content.size<=i) return 0; /* false */
+	if (res->content.size<=i) return 0; * false *
 	res->content.size-=(--i);
 	while ((i==4||i==5||i==6||i==7||i==40||i==41||i==42||i==43||((res->content.data)[i]==wav[i]))&&(i--));
-	(res->content.data)[sizeof(wav)-1]=1; /* First character must be a 0x01 (wav type in DAT) */
+	(res->content.data)[sizeof(wav)-1]=1; * First character must be a 0x01 (wav type in DAT) *
 	res->content.data+=sizeof(wav)-1;
 	if (i==-1) mWriteFileInDatFile(res);
 	res->content.data=posAux;
-	return 1; /* true */
+	return 1; * true */
+
+	if (!ok) {
+		free(snd->data);
+		return PR_RESULT_ERR_FILE_NOT_READ_ACCESS; /* TODO: use a bad format code */
+	}
+	
+	*pchannels    = NumChannels;
+	*psamplerate  = SampleRate;
+	*pbps         = BitsPerSample;
+	
+	return PR_RESULT_SUCCESS;			
 }
 
diff --git a/PR/src/lib/layers/disk.c b/PR/src/lib/layers/disk.c
index 5a23cdd..5fe23d1 100644
--- a/PR/src/lib/layers/disk.c
+++ b/PR/src/lib/layers/disk.c
@@ -367,7 +367,7 @@ int writeOpen(const char* vFileext, FILE* *fp, int optionflag) {
 }
 #endif
 
-int writeData(const unsigned char* data, int ignoreChars, const char* vFileext, int size, int optionflag,const char* backupExtension) {
+int writeData(const unsigned char* data, int ignoreChars, const char* vFileext, int size, int optionflag,const char* backupExtension) { /* TODO: use tBinary */
 	/*
 		Creates vFileext and saves data in it. In case the directory doesn't
 		exist it will be created.
diff --git a/PR/src/lib/object/object.c b/PR/src/lib/object/object.c
index c39f49b..bc1f2f0 100644
--- a/PR/src/lib/object/object.c
+++ b/PR/src/lib/object/object.c
@@ -39,6 +39,8 @@ main.c: Princed Resources : Main item class implementation
 #include "palette.h"
 #include "sound.h"
 
+/* Object polimorphism support layer */
+
 tObject getObject(tResource* r, int* error) {
 	tObject o;
 	if (!r) {
@@ -132,10 +134,10 @@ void setObject(tObject o,int *result) {
 }
 
 /* Format detection function (private function, not in header file) */
-tObject readObject(const char* file,tResource res,int *result) {
+tObject readObject(const char* file,tResource* res,int *result) {
 	/* return true if ok, false if error */
 	tObject o;
-	switch (res.type) {
+	switch (res->type) {
 		case eResTypeLevel:
 			/*o.obj=objLevelRead(file,res.content,result);*/
 			break;
@@ -143,7 +145,7 @@ tObject readObject(const char* file,tResource res,int *result) {
 			/*o.obj=objImageRead(file,res.content,res.palette,result);*/
 			break;
 		case eResTypeWave:
-			/*o.obj=objWaveRead(file,res.content,result);*/
+			o.obj=objWaveRead(file,result);
 			break;
 		case eResTypeMidi:
 			/*o.obj=objMidiRead(file,res.content,result);*/
@@ -156,10 +158,10 @@ tObject readObject(const char* file,tResource res,int *result) {
 			break;
 		case eResTypeBinary:
 		default:
-			/*o.obj=objBinatyRead(file,res,result);*/
+			o.obj=objBinaryRead(file,result);
 			break;
 	}
-	o.type=res.type;
+	o.type=res->type;
 
 	return o;
 }
diff --git a/PR/src/lib/object/other/binary.c b/PR/src/lib/object/other/binary.c
index 92858b1..0dcd22c 100644
--- a/PR/src/lib/object/other/binary.c
+++ b/PR/src/lib/object/other/binary.c
@@ -58,3 +58,12 @@ int objBinaryWrite(void* o, const char* file, int optionflag, const char* backup
 	return writeData(b->data,1,file,b->size,optionflag,backupExtension)?PR_RESULT_SUCCESS:PR_RESULT_ERR_FILE_NOT_WRITE_ACCESS;
 }
 
+void* objBinaryRead(const char* file,int *result) {
+	tBinary o=mLoadFileArray(file);
+	if (o.size<0) {
+		*result=o.size;
+		return NULL;
+	}
+	return objBinaryCreate(o,result);
+}
+
diff --git a/PR/src/lib/object/sound/sound_common.c b/PR/src/lib/object/sound/sound_common.c
index f03a214..6ac6ae0 100644
--- a/PR/src/lib/object/sound/sound_common.c
+++ b/PR/src/lib/object/sound/sound_common.c
@@ -44,13 +44,13 @@ wave.c: Princed Resources :
 |                         Binary Object                         |
 \***************************************************************/
 
-void* objSoundCreate(unsigned char* data, int size, int *error) { /* use get like main.c */
+void* objSoundCreate(tBinary cont, int *error) { /* use get like main.c */
 	tBinary* r;
 	*error=PR_RESULT_SUCCESS;
 	
 	r=(tBinary*)malloc(sizeof(tBinary));
-	r->data=data+1;
-	r->size=size-1;
+	r->data=cont.data+1;
+	r->size=cont.size-1;
 	return (void*)r;
 }
 
@@ -58,3 +58,34 @@ int objSoundWrite(void* o, const char* file, int write(const char* file,tBinary*
 	return write(file,(tBinary*)o,optionflag,backupExtension);
 }
 
+/*void* objSoundRead(const char* file, int read(const char* file, tBinary* c, int *pchannels, long *psamplerate, long *pbps), int *result, int *pchannels, long *psamplerate, long *pbps) {
+	tBinary* o=(tBinary*)malloc(sizeof(tBinary));
+	*result=read(file,o);
+	return (void*)o;
+}*/
+
+
+void* objWaveRead(const char* file, int *result) {
+	int  channels;
+	long samplerate;
+ 	long bps;
+	tBinary* o=(tBinary*)malloc(sizeof(tBinary));
+	
+	*result=readWav(file,o,&channels,&samplerate,&bps);
+
+	if (*result==PR_RESULT_SUCCESS) {
+		if (bps!=8) *result=PR_RESULT_WAV_UNSUPPORTED_BITRATE;
+		if (samplerate!=11025) *result=PR_RESULT_WAV_UNSUPPORTED_SAMPLERATE;
+		if (samplerate!=1) *result=PR_RESULT_WAV_UNSUPPORTED_STEREO;
+	}
+	if (*result!=PR_RESULT_SUCCESS) {
+		free(o->data);
+		return NULL;
+	}
+	
+	return (void*)o;
+}
+
+
+
+