Add audio on android platform ==> first release, can only open one channel

This commit is contained in:
Edouard Dupin 2012-06-29 17:56:15 +02:00
parent c6610b12af
commit 99d026f367
8 changed files with 145 additions and 6 deletions

View File

@ -30,6 +30,7 @@ all:
@cp $(EWOL_FOLDER)/Java/interfaceJNI.java $(EWOL_JAVA_FOLDER)/
@cp $(EWOL_FOLDER)/Java/interfaceOpenGL.java $(EWOL_JAVA_FOLDER)/
@cp $(EWOL_FOLDER)/Java/interfaceSurfaceView.java $(EWOL_JAVA_FOLDER)/
@cp $(EWOL_FOLDER)/Java/interfaceAudio.java $(EWOL_JAVA_FOLDER)/
@echo " (sh) copy the cpp for jni File : $(EWOL_FOLDER)/SourcesJava/ewolAndroidAbstraction.cpp"
@cp $(EWOL_FOLDER)/Java/ewolAndroidAbstraction.cpp jni/
@ -50,7 +51,7 @@ install: all
@echo "------------------------------------------------------------------------"
@# $(PROJECT_SDK)/platform-tools/adb kill-server
@# install application
$(PROJECT_SDK)/platform-tools/adb install -r ./bin/$(PROJECT_NAME)-debug.apk
sudo $(PROJECT_SDK)/platform-tools/adb install -r ./bin/$(PROJECT_NAME)-debug.apk
clean:
@echo "------------------------------------------------------------------------"

View File

@ -56,6 +56,7 @@ import android.content.res.AssetManager;
// inport the ewol package :
import org.ewol.interfaceJNI;
import org.ewol.interfaceSurfaceView;
import org.ewol.interfaceAudio;
import java.io.IOException;
@ -70,6 +71,8 @@ public class __PROJECT_NAME__ extends Activity {
private static native void ActivityParamSetArchiveDir(int mode, String myString);
private interfaceSurfaceView mGLView;
private interfaceAudio mStreams;
private Thread mAudioThread;
static {
System.loadLibrary("__PROJECT_PACKAGE__");
@ -120,6 +123,9 @@ public class __PROJECT_NAME__ extends Activity {
// create bsurface system
mGLView = new interfaceSurfaceView(this);
// create element audio ...
mStreams = new interfaceAudio();
setContentView(mGLView);
}
@ -141,6 +147,10 @@ public class __PROJECT_NAME__ extends Activity {
{
super.onResume();
mGLView.onResume();
mAudioThread = new Thread(mStreams);
if (mAudioThread != NULL) {
mAudioThread.start();
}
// call C
interfaceJNI.ActivityOnResume();
}
@ -149,6 +159,12 @@ public class __PROJECT_NAME__ extends Activity {
{
super.onPause();
mGLView.onPause();
if (mAudioThread != NULL) {
// request audio stop
mAudioThread.Stop();
// wait the thread ended ...
mAudioThread.join();
}
// call C
interfaceJNI.ActivityOnPause();
}

View File

@ -30,6 +30,7 @@
#include <Debug.h>
#include <ewol/threadMsg.h>
#include <ewol/Audio/audio.h>
// declaration of the ewol android abstraction ...
@ -420,5 +421,22 @@ extern "C"
EWOL_NativeRender();
}
}
void Java_org_ewol_interfaceJNI_IOAudioPlayback(JNIEnv* env, void* reserved, jshortArray location, jint frameRate, jint nbChannels)
{
// Get the short* pointer from the Java array
jboolean isCopy;
jshort* dst = env->GetShortArrayElements(location, &isCopy);
if (NULL != dst) {
ewol::audio::GetData(dst, frameRate, nbChannels);
}
//APPL_DEBUG("IO Audio event request: Frames=" << frameRate << " channels=" << nbChannels);
// TODO : Understand why it did not work corectly ...
//if (isCopy == JNI_TRUE) {
// Release the short* pointer
env->ReleaseShortArrayElements(location, dst, 0);
//}
}
};

101
Java/interfaceAudio.java Normal file
View File

@ -0,0 +1,101 @@
/**
*******************************************************************************
* @file ewol interfaceAudio.java
* @brief Java Audio interface code.
* @author Edouard DUPIN
* @date 29/06/2012
* @par Project
* ewol
*
* @par Copyright
* Copyright 2011 Edouard DUPIN, all right reserved
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY.
*
* Licence summary :
* You can modify and redistribute the sources code and binaries.
* You can send me the bug-fix
*
* Term of the licence in in the file licence.txt.
*
*******************************************************************************
*/
package org.ewol;
import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
// inport the ewol package :
import org.ewol.interfaceJNI;
public class interfaceAudio implements Runnable
{
private boolean m_stopAudioThreads = false;
private AudioTrack m_musicTrack;
// constructor :
public interfaceAudio()
{
// nothing to do ...
}
public void run()
{
if(m_musicTrack != null) {
return;
}
int sampleFreq = 44100; //AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int nbChannels = 2;
// we keep the minimum buffer size, otherwite the delay is too big ...
int bufferSize = AudioTrack.getMinBufferSize(sampleFreq, channelConfig, audioFormat);
// Create a streaming AudioTrack for music playback
short[] streamBuffer = new short[bufferSize];
m_musicTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
m_musicTrack.play();
//m_musicTrack.setPositionNotificationPeriod(2048);
while (!m_stopAudioThreads) {
// Fill buffer with PCM data from C++
interfaceJNI.IOAudioPlayback(streamBuffer, 512, nbChannels);
// Stream PCM data into the music AudioTrack
m_musicTrack.write(streamBuffer, 0, 512);
}
m_musicTrack.flush();
m_musicTrack.stop();
}
public void Pause()
{
if(m_musicTrack == null) {
return;
}
m_musicTrack.pause();
}
public void Resume()
{
if(m_musicTrack == null) {
return;
}
m_musicTrack.play();
}
public void Stop()
{
if(m_musicTrack == null) {
return;
}
m_stopAudioThreads=true;
}
};

View File

@ -47,6 +47,9 @@ public class interfaceJNI {
public static native void IOKeyboardEventMove(int type, boolean isDown);
public static native void IOKeyboardEventKey(int uniChar, boolean isDown);
// Audio section ...
public static native void IOAudioPlayback(short[] bufferData, int frames, int nbChannels);
public static int EWOL_SYSTEM_KEY__VOLUME_UP = 1;
public static int EWOL_SYSTEM_KEY__VOLUME_DOWN = 2;
public static int EWOL_SYSTEM_KEY__MENU = 3;

View File

@ -190,7 +190,7 @@ public class interfaceSurfaceView extends GLSurfaceView {
case KeyEvent.KEYCODE_BACK:
// the back key is wrapped in the <esc> key to simplify PC validation ...
interfaceJNI.IOKeyboardEventKey(0x1B, isDown);
return true;
return false;
case KeyEvent.KEYCODE_DEL:
interfaceJNI.IOKeyboardEventKey(0x08, isDown);
return true;

View File

@ -73,7 +73,7 @@ void TOOLS_DisplayTime(void)
}
etk::logLevel_te g_requestedLevel = etk::LOG_LEVEL_ERROR;
etk::logLevel_te g_requestedLevel = etk::LOG_LEVEL_VERBOSE;
void GeneralDebugSetLevel(etk::logLevel_te ccc) {
g_requestedLevel = ccc;
g_requestedLevel = etk::LOG_LEVEL_VERBOSE;
}

View File

@ -50,7 +50,7 @@ void ewol::audio::Init(void)
if (isInit == true) {
EWOL_ERROR("multiple init requested ... at the audio system ...");
}
ewol::audio::effects::VolumeSet(20);
ewol::audio::effects::VolumeSet(0);
ewol::audio::effects::MuteSet(false);
ewol::audio::music::VolumeSet(0);
ewol::audio::music::MuteSet(false);