Procházet zdrojové kódy

Commit everything new before vacation.

Joachim Meyer před 9 roky
rodič
revize
546cff6ae7

+ 6 - 4
build/android/TemplateApp/jni/PolycodeTemplateApp.cpp

@@ -10,6 +10,7 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     core = new POLYCODE_CORE(view, 800,480,false,false, 0,0,60, -1, true);
 
     core->addFileSource("archive", "default.pak");
+    Logger::log("defaultWD: %s", core->getDefaultWorkingDirectory().c_str());
     core->addFileSource("folder", core->getDefaultWorkingDirectory());
     ResourcePool *globalPool = Services()->getResourceManager()->getGlobalPool();
     globalPool->loadResourcesFromFolder("default", true);
@@ -39,16 +40,17 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
         scene->addChild(box);
     }*/
 
-    bgSound = new Sound("FightBG.OGG");
+    Logger::log("before sound");
+//    bgSound = new Sound("FightBG.wav");
 //    bgSound->Play();
-//    bgSound->setPitch(10.0);
 
 
-    //sound1 = new Sound("hit.wav");
+
+//    sound1 = new Sound("hit.wav");
     //Logger::log("before Play");
     //sound1->Play(true);
     //Logger::log("after Play");
-//    sound1->setPitch(2.3);
+    //sound1->setPitch(10);
 
 //    sound2 = new Sound("test.wav");
 //     sound3 = new Sound("curve_02_c.wav");

+ 22 - 3
include/polycode/core/PolyOpenSLAudioInterface.h

@@ -29,6 +29,23 @@
 #include <SLES/OpenSLES_Android.h>
 
 namespace Polycode {
+	
+	class OpenSLAudioInterface;
+	
+// 	class OpenSLStream : public Threaded {
+// 	public:
+// 		OpenSLStream();
+// 		
+// 		void runThread();
+// 		void updateThread(int16_t *buf);
+// 		void setInterface(OpenSLAudioInterface *itf);
+// 		
+// 		static void queueCallback(SLAndroidSimpleBufferQueueItf caller, void *pContext);
+// 	private:
+// 		OpenSLAudioInterface* itf;
+// 		int currentBufferCount;
+// 		CoreMutex* queueMutex;
+// 	};
 
     class OpenSLAudioInterface : public AudioInterface {
 	public:
@@ -41,18 +58,20 @@ namespace Polycode {
 		void terminateOpenSL();
 		
 		static void queueCallback(SLAndroidSimpleBufferQueueItf caller, void *pContext);
+		
+		SLAndroidSimpleBufferQueueItf mPlayerQueue;
 	private:
+// 		OpenSLStream* stream;
 
+		int16_t* buffer;
+		
 		SLObjectItf mEngineObj;
 		SLEngineItf mEngine;
 		SLObjectItf mOutputMixObj;
 		
 		SLObjectItf mPlayerObj; 
 		SLPlayItf mPlayer;
-		SLAndroidSimpleBufferQueueItf mPlayerQueue;
 		SLVolumeItf mVolume;
-		
-		int16_t buffer[44100];
     };
 }
 

+ 6 - 1
include/polycode/core/PolySoundManager.h

@@ -26,10 +26,14 @@
 #include "polycode/core/PolyQuaternion.h"
 #include "polycode/core/PolySound.h"
 
-#define POLY_FRAMES_PER_BUFFER 2048
+#define POLY_FRAMES_PER_BUFFER 512
 #define POLY_AUDIO_FREQ 44100
 #define POLY_CIRCULAR_BUFFER_SIZE 32
+#if PLATFORM == PLATFORM_ANDROID
+#define POLY_NUM_CHANNELS 1
+#else
 #define POLY_NUM_CHANNELS 2
+#endif
 #define POLY_MIX_BUFFER_SIZE (POLY_FRAMES_PER_BUFFER*POLY_CIRCULAR_BUFFER_SIZE)
 
 namespace Polycode {
@@ -85,6 +89,7 @@ namespace Polycode {
 		void registerSound(Sound *sound);
 		void unregisterSound(Sound *sound);
 		
+		
 	protected:
 		
 		AudioMixer *mixer;

+ 2 - 0
include/polycode/view/android/PolycodeView.h

@@ -79,6 +79,7 @@ namespace Polycode {
 			
 			unsigned int lifecycleFlags;
 			bool isInteractable();
+			bool firstWindowCreate;
     };
 }
 
@@ -113,4 +114,5 @@ void* startApp(void* data);
 
 int JNIGetUnicodeChar(ANativeActivity* native_activity, int eventType, int keyCode, int metaState);
 void JNIAutoHideNavBar(ANativeActivity* native_activity);
+void GetAudioInfo(ANativeActivity* native_activity);
 void JNIWakeLock(ANativeActivity* native_activity, bool acquire);

+ 21 - 5
src/core/PolyAndroidCore.cpp

@@ -84,7 +84,8 @@ AndroidCore::AndroidCore(PolycodeView *view, int xRes, int yRes, bool fullScreen
 	defaultWorkingDirectory = view->native_activity->internalDataPath;
 	userHomeDirectory = view->native_activity->externalDataPath;
 	
-	services->getSoundManager()->setAudioInterface(new OpenSLAudioInterface());
+	services->getSoundManager()->setAudioInterface(new AudioInterface());
+	
 	paused = true;
 	
 	initKeyMap();
@@ -92,6 +93,7 @@ AndroidCore::AndroidCore(PolycodeView *view, int xRes, int yRes, bool fullScreen
 	this->view = view;
 	core = this;
 	
+// 	services->getSoundManager()->setAudioInterface(new OpenSLAudioInterface());
 	extractResources();
 }
 
@@ -247,16 +249,26 @@ void AndroidCore::extractResources(){
 	
 	for(int i = 0; i < entries.size(); i++){
 		source = afileProvider->openFile(entries[i].fullPath,"r");
-		dest = bfileProvider->openFile(defaultWorkingDirectory+"/"+entries[i].name, "wb");
+		dest = bfileProvider->openFile(defaultWorkingDirectory+"/"+entries[i].name, "rb");
 		
-		if(source->tell() != dest->tell()){
+		if(dest){
+			dest->seek(0, SEEK_END);
+			if(source->tell() != dest->tell()){
+				bfileProvider->closeFile(dest);
+				dest = bfileProvider->openFile(defaultWorkingDirectory+"/"+entries[i].name, "wb");
+				while(source->read(buffer, sizeof(char), 1) > 0){
+					dest->write(buffer,sizeof(char), 1);
+				}
+			}
+			bfileProvider->closeFile(dest);
+		} else {
+			dest = bfileProvider->openFile(defaultWorkingDirectory+"/"+entries[i].name, "wb");
 			while(source->read(buffer, sizeof(char), 1) > 0){
 				dest->write(buffer,sizeof(char), 1);
 			}
 		}
 		
 		afileProvider->closeFile(source);
-		bfileProvider->closeFile(dest);
 	}
 	
 	free(buffer);
@@ -265,7 +277,11 @@ void AndroidCore::extractResources(){
 void AndroidCore::addFileSource(const String &type, const String &source) {
 	for(int i=0; i < fileProviders.size(); i++) {
 		if(fileProviders[i]->type == type) {
-			fileProviders[i]->addSource(defaultWorkingDirectory+"/"+source);
+			if(source.substr(0,1) == "/"){
+				fileProviders[i]->addSource(source);
+			}else{
+				fileProviders[i]->addSource(defaultWorkingDirectory+"/"+source);
+			}
 			return;
 		}
 	}

+ 76 - 24
src/core/PolyOpenSLAudioInterface.cpp

@@ -37,13 +37,13 @@ OpenSLAudioInterface::~OpenSLAudioInterface(){
 }
 
 void OpenSLAudioInterface::setMixer(AudioMixer* newMixer){
-	Logger::log("OpenSL setMixer");
 	mixer = newMixer;
-	Logger::log("OpenSL setMixer2");
-// 	Services()->getCore()->createThread(stream);
-	
 	initOpenSL();
-	Logger::log("OpenSL setMixer3");
+// 	Logger::log("finished init");
+// 	stream->setInterface(this);
+// 	Logger::log("stream set");
+// // 	Services()->getCore()->createThread(stream);
+// 	Logger::log("stream running");
 }
 
 void OpenSLAudioInterface::initOpenSL(){
@@ -67,15 +67,19 @@ void OpenSLAudioInterface::initOpenSL(){
 	
 	SLDataLocator_AndroidSimpleBufferQueue lDataLocatorIn;
 	lDataLocatorIn.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
-	lDataLocatorIn.numBuffers = 1;
+	lDataLocatorIn.numBuffers = POLY_CIRCULAR_BUFFER_SIZE;
 	
 	SLDataFormat_PCM lDataFormat;
 	lDataFormat.formatType = SL_DATAFORMAT_PCM;
-	lDataFormat.numChannels = 1; // Mono sound.
-	lDataFormat.samplesPerSec = SL_SAMPLINGRATE_8;
+	lDataFormat.numChannels = POLY_NUM_CHANNELS;
+	lDataFormat.samplesPerSec = POLY_AUDIO_FREQ*1000;
 	lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
 	lDataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
-	lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
+	if(POLY_NUM_CHANNELS > 1){
+		lDataFormat.channelMask = SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_LEFT;
+	} else {
+		lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
+	}
 	lDataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
 	
 	SLDataSource lDataSource;
@@ -91,8 +95,8 @@ void OpenSLAudioInterface::initOpenSL(){
 	lDataSink.pFormat = NULL;
 	
 	const SLuint32 lSoundPlayerIIDCount = 2;
-	const SLInterfaceID lSoundPlayerIIDs[3] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME };
-	const SLboolean lSoundPlayerReqs[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
+	const SLInterfaceID lSoundPlayerIIDs[] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
+	const SLboolean lSoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
 	
 	Logger::log("before player");
 	lRes = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj, &lDataSource, &lDataSink, lSoundPlayerIIDCount, lSoundPlayerIIDs, lSoundPlayerReqs);
@@ -114,15 +118,16 @@ void OpenSLAudioInterface::initOpenSL(){
 	lRes = (*mPlayer)->SetPlayState(mPlayer, SL_PLAYSTATE_PLAYING);
 	Logger::log("play: %d", lRes);
 	
-// 	int16_t *out = (int16_t*)buffer;
-// 	mixer->mixIntoBuffer(out, 44100);
-// 	(*(mPlayerQueue))->Enqueue(mPlayerQueue, out, 44100);
+	buffer = (int16_t*)malloc(sizeof(int16_t)*POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS);
+	int16_t *out = buffer;
+	mixer->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER);
+	(*(mPlayerQueue))->Enqueue(mPlayerQueue, out, POLY_FRAMES_PER_BUFFER);
 }
 
 void OpenSLAudioInterface::terminateOpenSL(){
-// 	if (mPlayerQueue != NULL) {
-// 		(*mPlayerQueue)->Destroy(mPlayerQueue);
-// 	}
+	if (mPlayerObj != NULL) {
+		(*mPlayerObj)->Destroy(mPlayerObj);
+	}
 
 	if (mOutputMixObj != NULL) {
 		(*mOutputMixObj)->Destroy(mOutputMixObj);
@@ -134,11 +139,58 @@ void OpenSLAudioInterface::terminateOpenSL(){
 }
 
 void OpenSLAudioInterface::queueCallback(SLAndroidSimpleBufferQueueItf caller, void* pContext){
-// 	OpenSLAudioInterface *audioInterface = (OpenSLAudioInterface*) pContext;
-// 	if(audioInterface->buffer && audioInterface->getMixer()) {
-// 		int16_t *out = (int16_t*)audioInterface->buffer;
-// 		audioInterface->getMixer()->mixIntoBuffer(out, 44100);
-// 		(*(audioInterface->mPlayerQueue))->Enqueue(audioInterface->mPlayerQueue, out, 44100);
-// 		Logger::log("callback");
-// 	}
+	OpenSLAudioInterface *audioInterface = (OpenSLAudioInterface*) pContext;
+	if(audioInterface->buffer && audioInterface->getMixer()) {
+		int16_t *out = (int16_t*)audioInterface->buffer;
+		audioInterface->getMixer()->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER);
+		(*(audioInterface->mPlayerQueue))->Enqueue(audioInterface->mPlayerQueue, out, POLY_FRAMES_PER_BUFFER);
+	}
 }
+
+// void OpenSLStream::queueCallback(SLAndroidSimpleBufferQueueItf caller, void* pContext){
+// 	OpenSLStream *stream = (OpenSLStream*) pContext;
+// 	stream->queueMutex->lock();
+// 	Logger::log("callback %d", stream->currentBufferCount);
+// 	stream->currentBufferCount--;
+// 	stream->queueMutex->unlock();
+// }
+
+// OpenSLStream::OpenSLStream() : Threaded(){}
+
+// void OpenSLStream::setInterface(OpenSLAudioInterface* itf){
+// 	this->itf = itf;
+// 	queueMutex = Services()->getCore()->createMutex();
+// }
+
+// void OpenSLStream::runThread(){
+// 	int16_t *buffer;
+// 	Logger::log("in run");
+// 	buffer = (int16_t*)malloc(POLY_MIX_BUFFER_SIZE*POLY_NUM_CHANNELS*sizeof(int16_t));
+// 	Logger::log("allocated");
+// 	currentBufferCount = 0;
+// 	while(threadRunning){
+// // 		Logger::log("while");
+// 		updateThread(buffer);
+// // 		usleep(20000000);
+// 	}
+// }
+// 
+// void OpenSLStream::updateThread(int16_t *buf){
+// 	Logger::log("in update");
+// 	if(itf->getMixer()){
+// 		int16_t* out;
+// // 		Logger::log("in mixer");
+// 		
+// 		while(currentBufferCount < POLY_CIRCULAR_BUFFER_SIZE){
+// 			queueMutex->lock();
+// // 			Logger::log("mix %d", currentBufferCount);
+// 			out = buf + sizeof(int16_t)*POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS*currentBufferCount++;
+// 			itf->getMixer()->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER);
+// 			(*(itf->mPlayerQueue))->Enqueue(itf->mPlayerQueue, out, POLY_FRAMES_PER_BUFFER);
+// 			queueMutex->unlock();
+// // 			queueMutex->lock();
+// 		}
+// // 		queueMutex->unlock();
+// // 		Logger::log("unlocked");
+// 	}
+// }

+ 1 - 0
src/core/PolySound.cpp

@@ -95,6 +95,7 @@ long custom_tellfunc(void *datasource) {
 Sound::Sound(const String& fileName) :	referenceDistance(1), maxDistance(MAX_FLOAT), pitch(1), volume(1), numSamples(-1), streamingSound(false), playing(false), playbackOffset(0), streamingSource(NULL), frequencyAdjust(1.0) {
 	soundLoaded = false;
 	setIsPositional(false);
+	Logger::log("sound before load");
 	loadFile(fileName);
 	if(soundLoaded) {
 		Services()->getSoundManager()->registerSound(this);

+ 62 - 2
src/view/android/PolycodeView.cpp

@@ -23,7 +23,10 @@
 #include "polycode/view/android/PolycodeView.h"
 #include "polycode/core/PolyLogger.h"
 #include "polycode/core/PolyRenderer.h"
+#include "polycode/core/PolySoundManager.h"
+#include "polycode/core/PolyOpenSLAudioInterface.h"
 #include <android/looper.h>
+#include <stdlib.h>
 
 using namespace Polycode;
 
@@ -83,12 +86,14 @@ PolycodeView::PolycodeView(ANativeActivity* native, String title){
 	gyroTimestamp = 0;
 	WakeLock = NULL;
 	
+	firstWindowCreate = true;
+	
+	GetAudioInfo(native);
 }
 
 PolycodeView::~PolycodeView(){}
 
 bool PolycodeView::isInteractable(){
-	//Logger::log("isInteractable: %s", ((lifecycleFlags & APP_STATUS_INTERACTABLE) == APP_STATUS_INTERACTABLE) ? "true" : "false");
 	return ((lifecycleFlags & APP_STATUS_INTERACTABLE) == APP_STATUS_INTERACTABLE);
 }
 
@@ -161,7 +166,7 @@ void onWindowFocusChanged(ANativeActivity* activity, int hasFocus){
 		event.eventGroup = AndroidEvent::SYSTEM_FOCUS_EVENT;
 		event.eventCode = Core::EVENT_LOST_FOCUS;
 		if(core)
-			core->handleSystemEvent(event);		
+			core->handleSystemEvent(event);
 		((PolycodeView*)activity->instance)->lifecycleFlags&=~APP_STATUS_FOCUSED;
 	}
 }
@@ -174,6 +179,10 @@ void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow *window){
 	if (width > 0 && height > 0){
 		((PolycodeView*)activity->instance)->lifecycleFlags|=APP_STATUS_HAS_REAL_SURFACE;
 		if(core){
+			if(((PolycodeView*)activity->instance)->firstWindowCreate){
+				Services()->getSoundManager()->setAudioInterface(new OpenSLAudioInterface());
+				((PolycodeView*)activity->instance)->firstWindowCreate = false;
+			}
 			core->recreateContext = true;
 			core->setDeviceSize(width, height);
 			core->setVideoMode(core->getXRes(), core->getYRes(), true, false, core->getAALevel(), 0, true);
@@ -552,3 +561,54 @@ void JNIWakeLock(ANativeActivity* native_activity, bool acquire){
 		javaVM->DetachCurrentThread();
 }
 
+void GetAudioInfo(ANativeActivity* native_activity){
+	JavaVM* javaVM = native_activity->vm;
+	JNIEnv* jniEnv;
+	bool attached = false;
+	
+	if(javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) ==JNI_EDETACHED){
+		JavaVMAttachArgs attachArgs;
+		attachArgs.version = JNI_VERSION_1_6;
+		attachArgs.name = "NativeThread";
+		attachArgs.group = NULL;
+		
+		jint result = javaVM->AttachCurrentThread(&jniEnv, &attachArgs);
+		if(result == JNI_ERR){
+			return;
+		}
+		attached = true;
+	}
+
+	jclass classNativeActivity = jniEnv->FindClass("android/app/NativeActivity");
+	jclass classAudioManager = jniEnv->FindClass("android/os/AudioManager");
+	
+	jmethodID getSystemServiceID = jniEnv->GetMethodID(classNativeActivity, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+	jstring AUDIO_SERVICE = jniEnv->NewStringUTF("audio");
+	jobject AudioManager = jniEnv->CallObjectMethod(native_activity->clazz, getSystemServiceID, AUDIO_SERVICE);
+	
+	jmethodID getProperty = jniEnv->GetMethodID(classAudioManager, "getProperty", "(Ljava/lang/String;)Landroid/os/AudioManager;");
+	
+	jobject fpBID = jniEnv->GetStaticObjectField(classAudioManager, "PROPERTY_OUTPUT_FRAMES_PER_BUFFER", "Ljava/lang/String;");
+	jobject srID = jniEnv->GetStaticObjectField(classAudioManager, "PROPERTY_OUTPUT_SAMPLE_RATE", "Ljava/lang/String;");
+	
+	jobject fpBO = jniEnv->CallObjectMethod(AudioManager, getProperty, fpBID);
+	jobject srO = jniEnv->CallObjectMethod(AudioManager, getProperty, fpBID);
+	
+	const char *nativeString = (*jniEnv)->GetStringUTFChars(jniEnv, fpBO, 0);
+	int fpB = atoi(nativeString);
+	(*jniEnv)->ReleaseStringUTFChars(jniEnv, fpBO, nativeString);
+	
+	nativeString = (*jniEnv)->GetStringUTFChars(jniEnv, srO, 0);
+	int sr = atoi(nativeString);
+	(*jniEnv)->ReleaseStringUTFChars(jniEnv, srO, nativeString);
+	
+	Logger::log("fpB: %d, sr: %d", fpB, sr);
+	
+// 	jniEnv->DeleteLocalRef(jWakeLockTag);
+// 	jniEnv->DeleteLocalRef(POWER_SERVICE);
+	
+// 	((PolycodeView*)native_activity->instance)->WakeLock = jniEnv->NewGlobalRef(WakeLock);
+
+	if(attached)
+		javaVM->DetachCurrentThread();
+}