[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20213] trunk/blender: Bug/patch #18714: fix game engine sound on OS X Intel, patch by

Brecht Van Lommel brecht at blender.org
Fri May 15 14:34:01 CEST 2009


Revision: 20213
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20213
Author:   blendix
Date:     2009-05-15 14:34:01 +0200 (Fri, 15 May 2009)

Log Message:
-----------
Bug/patch #18714: fix game engine sound on OS X Intel, patch by
Ken Hursh and myself.

* Get rid of dependency on ALUT. It is really only used to
  load a WAV file, and apparently crashing doing so on OS X Intel,
  (perhaps due to endian issues?). There was already own code
  for doing this on some system, so now it uses that. That code
  had it's own endian issues which are now fixed, along with
  better checks to avoid crashing on corrupt or unsupported files.

* Also get rid of some unecessarily complicate #ifdefs.

* According to the bug report OS X Intel OpenAL only works with
  static openal linking still (WITH_BF_STATICOPENAL for scons).

Modified Paths:
--------------
    trunk/blender/config/irix6-config.py
    trunk/blender/config/linux2-config.py
    trunk/blender/intern/SoundSystem/openal/SND_OpenALDevice.cpp

Modified: trunk/blender/config/irix6-config.py
===================================================================
--- trunk/blender/config/irix6-config.py	2009-05-15 11:19:59 UTC (rev 20212)
+++ trunk/blender/config/irix6-config.py	2009-05-15 12:34:01 UTC (rev 20213)
@@ -24,11 +24,6 @@
 BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
 BF_OPENAL_LIBPATH = LIBDIR + '/lib'
 
-# some distros have a separate libalut
-# if you get linker complaints, you need to uncomment the line below
-# BF_OPENAL_LIB = 'openal alut'  
-# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a'
-
 BF_CXX = '/usr'
 WITH_BF_STATICCXX = 'false'
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'

Modified: trunk/blender/config/linux2-config.py
===================================================================
--- trunk/blender/config/linux2-config.py	2009-05-15 11:19:59 UTC (rev 20212)
+++ trunk/blender/config/linux2-config.py	2009-05-15 12:34:01 UTC (rev 20213)
@@ -28,11 +28,6 @@
 BF_OPENAL_LIB = 'openal'
 BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
 
-# some distros have a separate libalut
-# if you get linker complaints, you need to uncomment the line below
-# BF_OPENAL_LIB = 'openal alut'  
-# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a'
-
 BF_CXX = '/usr'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'

Modified: trunk/blender/intern/SoundSystem/openal/SND_OpenALDevice.cpp
===================================================================
--- trunk/blender/intern/SoundSystem/openal/SND_OpenALDevice.cpp	2009-05-15 11:19:59 UTC (rev 20212)
+++ trunk/blender/intern/SoundSystem/openal/SND_OpenALDevice.cpp	2009-05-15 12:34:01 UTC (rev 20213)
@@ -43,11 +43,9 @@
 #ifdef APPLE_FRAMEWORK_FIX
 #include <al.h>
 #include <alc.h>
-#include <alut.h>
 #else
 #include <AL/al.h>
 #include <AL/alc.h>
-#include <AL/alut.h>
 #endif
 
 #include <stdio.h>
@@ -61,13 +59,12 @@
 
 #include <signal.h>
 
-/* untill openal gets unified we need this hack for non-windows systems */
-#if !defined(WIN32) && !defined(ALC_MAJOR_VERSION)
+/*************************** ALUT replacement *****************************/
 
-#include <malloc.h>
+/* instead of relying on alut, we just implement our own
+ * WAV loading functions, hopefully more reliable */
 
-ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop);
-ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq);
+#include <stdlib.h>
 
 typedef struct                                  /* WAV File-header */
 {
@@ -120,94 +117,190 @@
   ALuint   Size;
 } WAVChunkHdr_Struct;
 
-ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop)
+static void *SND_loadFileIntoMemory(const char *filename, int *len_r)
 {
+	FILE *fp= fopen(filename, "rb");
+	void *data;
+
+	if (!fp) {
+		*len_r= -1;
+		return NULL;
+	}
+
+	fseek(fp, 0L, SEEK_END);
+	*len_r= ftell(fp);
+	fseek(fp, 0L, SEEK_SET);
+
+	data= malloc(*len_r);
+	if (!data) {
+		*len_r= -1;
+		return NULL;
+	}
+
+	if (fread(data, *len_r, 1, fp)!=1) {
+		*len_r= -1;
+		free(data);
+		return NULL;
+	}
+
+	return data;
+}
+
+#define TEST_SWITCH_INT(a) if(big_endian) { \
+    char s_i, *p_i; \
+    p_i= (char *)&(a); \
+    s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
+    s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
+
+#define TEST_SWITCH_SHORT(a) if(big_endian) { \
+    char s_i, *p_i; \
+    p_i= (char *)&(a); \
+    s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; }
+
+static int stream_read(void *out, ALbyte **stream, ALsizei size, ALsizei *memsize)
+{
+	if(size <= *memsize) {
+		memcpy(out, *stream, size);
+		return 1;
+	}
+	else {
+		memset(out, 0, size);
+		return 0;
+	}
+}
+
+static int stream_skip(ALbyte **stream, ALsizei size, ALsizei *memsize)
+{
+	if(size <= *memsize) {
+		*stream += size;
+		*memsize -= size;
+		return 1;
+	}
+	else
+		return 0;
+}
+
+ALvoid SND_alutLoadWAVMemory(ALbyte *memory,ALsizei memsize,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop)
+{
 	WAVChunkHdr_Struct ChunkHdr;
 	WAVFmtExHdr_Struct FmtExHdr;
 	WAVFileHdr_Struct FileHdr;
 	WAVSmplHdr_Struct SmplHdr;
 	WAVFmtHdr_Struct FmtHdr;
-	ALbyte *Stream;
+	ALbyte *Stream= memory;
+	int test_endian= 1;
+	int big_endian= !((char*)&test_endian)[0];
 	
 	*format=AL_FORMAT_MONO16;
 	*data=NULL;
 	*size=0;
 	*freq=22050;
 	*loop=AL_FALSE;
-	if (memory)
+
+	if(!Stream)
+		return;
+ 
+ 	stream_read(&FileHdr,&Stream,sizeof(WAVFileHdr_Struct),&memsize);
+	stream_skip(&Stream,sizeof(WAVFileHdr_Struct),&memsize);
+
+	TEST_SWITCH_INT(FileHdr.Size);
+	FileHdr.Size=((FileHdr.Size+1)&~1)-4;
+
+	while((FileHdr.Size!=0) && stream_read(&ChunkHdr,&Stream,sizeof(WAVChunkHdr_Struct),&memsize))
 	{
-		Stream=memory;
-		if (Stream)
+		TEST_SWITCH_INT(ChunkHdr.Size);
+		stream_skip(&Stream,sizeof(WAVChunkHdr_Struct),&memsize);
+
+		if (!memcmp(ChunkHdr.Id,"fmt ",4))
 		{
-			memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct));
-			Stream+=sizeof(WAVFileHdr_Struct);
-			FileHdr.Size=((FileHdr.Size+1)&~1)-4;
-			while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct))))
+			stream_read(&FmtHdr,&Stream,sizeof(WAVFmtHdr_Struct),&memsize);
+
+			TEST_SWITCH_SHORT(FmtHdr.Format);
+			TEST_SWITCH_SHORT(FmtHdr.Channels);
+			TEST_SWITCH_INT(FmtHdr.SamplesPerSec);
+			TEST_SWITCH_INT(FmtHdr.BytesPerSec);
+			TEST_SWITCH_SHORT(FmtHdr.BlockAlign);
+			TEST_SWITCH_SHORT(FmtHdr.BitsPerSample);
+
+			if (FmtHdr.Format==0x0001)
 			{
-				Stream+=sizeof(WAVChunkHdr_Struct);
-				if (!memcmp(ChunkHdr.Id,"fmt ",4))
+				*format=(FmtHdr.Channels==1?
+						(FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
+						(FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
+				*freq=FmtHdr.SamplesPerSec;
+			} 
+			else
+			{
+				stream_read(&FmtExHdr,&Stream,sizeof(WAVFmtExHdr_Struct),&memsize);
+				TEST_SWITCH_SHORT(FmtExHdr.Size);
+				TEST_SWITCH_SHORT(FmtExHdr.SamplesPerBlock);
+			}
+		}
+		else if (!memcmp(ChunkHdr.Id,"data",4))
+		{
+			if (FmtHdr.Format==0x0001)
+			{
+				if((ALsizei)ChunkHdr.Size <= memsize)
 				{
-					memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct));
-					if (FmtHdr.Format==0x0001)
-					{
-						*format=(FmtHdr.Channels==1?
-								(FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
-								(FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
-						*freq=FmtHdr.SamplesPerSec;
-						Stream+=ChunkHdr.Size;
-					} 
-					else
-					{
-						memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct));
-						Stream+=ChunkHdr.Size;
-					}
-				}
-				else if (!memcmp(ChunkHdr.Id,"data",4))
-				{
-					if (FmtHdr.Format==0x0001)
-					{
-						*size=ChunkHdr.Size;
-						*data=malloc(ChunkHdr.Size+31);
-						if (*data) memcpy(*data,Stream,ChunkHdr.Size);
+					*size=ChunkHdr.Size;
+					*data=malloc(ChunkHdr.Size+31);
+
+					if (*data) {
+						stream_read(*data,&Stream,ChunkHdr.Size,&memsize);
 						memset(((char *)*data)+ChunkHdr.Size,0,31);
-						Stream+=ChunkHdr.Size;
+
+						if(FmtHdr.BitsPerSample == 16 && big_endian) {
+							int a, len= *size/2;
+							short *samples= (short*)*data;
+
+							for(a=0; a<len; a++) {
+								TEST_SWITCH_SHORT(samples[a])
+							}
+						}
 					}
-					else if (FmtHdr.Format==0x0011)
-					{
-						//IMA ADPCM
-					}
-					else if (FmtHdr.Format==0x0055)
-					{
-						//MP3 WAVE
-					}
 				}
-				else if (!memcmp(ChunkHdr.Id,"smpl",4))
-				{
-					memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct));
-					*loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE);
-					Stream+=ChunkHdr.Size;
-				}
-				else Stream+=ChunkHdr.Size;
-				Stream+=ChunkHdr.Size&1;
-				FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
 			}
+			else if (FmtHdr.Format==0x0011)
+			{
+				//IMA ADPCM
+			}
+			else if (FmtHdr.Format==0x0055)
+			{
+				//MP3 WAVE
+			}
 		}
+		else if (!memcmp(ChunkHdr.Id,"smpl",4))
+		{
+			stream_read(&SmplHdr,&Stream,sizeof(WAVSmplHdr_Struct),&memsize);
+
+			TEST_SWITCH_INT(SmplHdr.Manufacturer);
+			TEST_SWITCH_INT(SmplHdr.Product);
+			TEST_SWITCH_INT(SmplHdr.SamplePeriod);
+			TEST_SWITCH_INT(SmplHdr.Note);
+			TEST_SWITCH_INT(SmplHdr.FineTune);
+			TEST_SWITCH_INT(SmplHdr.SMPTEFormat);
+			TEST_SWITCH_INT(SmplHdr.SMPTEOffest);
+			TEST_SWITCH_INT(SmplHdr.Loops);
+			TEST_SWITCH_INT(SmplHdr.SamplerData);
+
+			*loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE);
+		}
+
+		if(!stream_skip(&Stream, ChunkHdr.Size + (ChunkHdr.Size&1), &memsize))
+			break;
+
+		FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
 	}
 }
 
-ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
+ALvoid SND_alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
 {
 	if (data)
 		free(data);
 }
 
-#endif /* WIN32 */
+/************************ Device Implementation ****************************/
 
-#ifdef __APPLE__
-#define OUDE_OPENAL 1
-#endif
-
-
 SND_OpenALDevice::SND_OpenALDevice()
 	: SND_AudioDevice(),
 	  m_context(NULL),
@@ -223,10 +316,6 @@
 	// let's check if we can get openal to initialize...
 	if (m_audio)
 	{
-#ifdef OUDE_OPENAL
-		m_audio = true;			// openal_2.12
-		alutInit(NULL, NULL);	// openal_2.12
-#else
 		m_audio = false;
 
 		ALCdevice *dev = alcOpenDevice(NULL);
@@ -236,7 +325,6 @@
 			if (m_context) {
 #ifdef AL_VERSION_1_1
 			alcMakeContextCurrent((ALCcontext*)m_context);
-			alutInitWithoutContext(NULL, NULL); /* in this case we dont want alut to initialize the context, see above */
 #else
 			alcMakeContextCurrent(m_context);
 #endif
@@ -259,7 +347,6 @@
 			}
 		}
 
-#endif
 	}
 
 	// then try to generate some buffers
@@ -283,7 +370,7 @@
 	// next: the sources
 	if (m_audio)
 	{
-#ifdef OUDE_OPENAL
+#ifdef __APPLE__
 		ALenum alc_error = ALC_NO_ERROR;	// openal_2.12
 #elif defined(_WIN32)
 		// alcGetError has no arguments on windows
@@ -375,20 +462,11 @@
 	if (m_cdrom)
 		delete m_cdrom;
 #endif
-#ifdef OUDE_OPENAL
-	if (m_audio)
-		alutExit();
-#else
 	if (m_device)
 		alcCloseDevice((ALCdevice*) m_device);
-#ifdef AL_VERSION_1_1
-	alutExit();
-#endif
-#endif
 }
 
 
-
 SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name,
 										  void* memlocation,
 										  int size)
@@ -406,23 +484,22 @@
 		{
 			if (waveslot)
 			{
+				bool freemem = false;
 				int buffer = waveslot->GetBuffer();
 				void* data = NULL;
-#ifndef __APPLE__
 				char loop = 'a';
-#endif
 				int sampleformat, bitrate, numberofchannels;
 				ALenum al_error = alGetError();
+				ALsizei samplerate, numberofsamples;  // openal_2.14+
 				
-#ifdef OUDE_OPENAL

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list