[DEV] continue dev of android audio interface
This commit is contained in:
parent
07684a0e54
commit
7d0a38e087
@ -5,14 +5,86 @@
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
package org.musicdsp.orchestra;
|
||||
|
||||
import android.media.AudioTrack;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
import android.util.Log;
|
||||
|
||||
public class InterfaceOutput {
|
||||
public InterfaceOutput() {
|
||||
|
||||
|
||||
public class InterfaceOutput extends Thread implements Constants {
|
||||
private int uid = -1;
|
||||
private Orchestra ORCHESTRA;
|
||||
public static final int SAMPLE_FREQ_44100 = 44100;
|
||||
private boolean m_stopAudioThreads = false;
|
||||
private AudioTrack m_musicTrack = null;
|
||||
|
||||
public InterfaceOutput(int id, Orchestra instance, int idDevice, int freq, int nbChannel, int format) {
|
||||
Log.d("InterfaceOutput", "new: output");
|
||||
uid = id;
|
||||
ORCHESTRA = instance;
|
||||
m_stopAudioThreads = false;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Log.e("audioEWOL", "RUN (start)");
|
||||
int sampleFreq = SAMPLE_FREQ_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,
|
||||
SAMPLE_FREQ_44100,
|
||||
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
bufferSize,
|
||||
AudioTrack.MODE_STREAM);
|
||||
m_musicTrack.play();
|
||||
m_stopAudioThreads = false;
|
||||
//m_musicTrack.setPositionNotificationPeriod(2048);
|
||||
|
||||
while (!m_stopAudioThreads) {
|
||||
// Fill buffer with PCM data from C++
|
||||
// TODO : Set if back ... ORCHESTRA.audioPlayback(streamBuffer, BUFFER_SIZE, nbChannels);
|
||||
int xxx = BUFFER_SIZE;
|
||||
/*
|
||||
while (xxx>0) {
|
||||
Log.e("audioEWOL", (BUFFER_SIZE-xxx) + " data : " + streamBuffer[BUFFER_SIZE-xxx]);
|
||||
xxx--;
|
||||
}
|
||||
*/
|
||||
// Stream PCM data into the music AudioTrack
|
||||
m_musicTrack.write(streamBuffer, 0, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
m_musicTrack.flush();
|
||||
m_musicTrack.stop();
|
||||
m_musicTrack = null;
|
||||
streamBuffer = null;
|
||||
Log.e("audioEWOL", "RUN (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 AutoStop() {
|
||||
if(m_musicTrack == null) {
|
||||
return;
|
||||
}
|
||||
m_stopAudioThreads=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,13 @@
|
||||
package org.musicdsp.orchestra;
|
||||
|
||||
import android.util.Log;
|
||||
import java.util.Vector;
|
||||
|
||||
//import org.musicdsp.orchestra.Constants;
|
||||
//import org.musicdsp.orchestra.ManagerCallback;
|
||||
import org.musicdsp.orchestra.Orchestra;
|
||||
import org.musicdsp.orchestra.InterfaceOutput;
|
||||
import org.musicdsp.orchestra.InterfaceInput;
|
||||
|
||||
/**
|
||||
* @brief Class :
|
||||
@ -20,10 +23,14 @@ import org.musicdsp.orchestra.Orchestra;
|
||||
*/
|
||||
public class Manager implements ManagerCallback, Constants {
|
||||
private Orchestra orchestraHandle;
|
||||
private int uid = 0;
|
||||
private Vector<InterfaceOutput> outputList;
|
||||
private Vector<InterfaceInput> inputList;
|
||||
|
||||
public Manager() {
|
||||
// set the java evironement in the C sources :
|
||||
orchestraHandle = new Orchestra(this);
|
||||
outputList = new Vector<InterfaceOutput>();
|
||||
}
|
||||
|
||||
public int getDeviceCount() {
|
||||
@ -33,13 +40,26 @@ public class Manager implements ManagerCallback, Constants {
|
||||
|
||||
public String getDeviceProperty(int idDevice) {
|
||||
if (idDevice == 0) {
|
||||
return "speaker:out:8000,16000,24000,32000,48000,96000:2:int16";
|
||||
return "{\n"
|
||||
+ " name:'speaker',\n"
|
||||
+ " type:'output',\n"
|
||||
+ " sample-rate:[8000,16000,24000,32000,48000,96000],\n"
|
||||
+ " channels:['front-left','front-right'],\n"
|
||||
+ " format:['int16'],\n"
|
||||
+ " default:true\n"
|
||||
+ "}";
|
||||
} else {
|
||||
return "::::";
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean openDevice(int idDevice, int freq, int nbChannel, int format) {
|
||||
InterfaceOutput iface = new InterfaceOutput(uid, orchestraHandle, idDevice, freq, nbChannel, format);
|
||||
uid++;
|
||||
if (iface != null) {
|
||||
outputList.add(iface);
|
||||
}
|
||||
return false;
|
||||
/*
|
||||
if (idDevice == 0) {
|
||||
mAudioStarted = true;
|
||||
@ -54,7 +74,6 @@ public class Manager implements ManagerCallback, Constants {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean closeDevice(int idDevice) {
|
||||
|
@ -11,6 +11,6 @@ package org.musicdsp.orchestra;
|
||||
public interface ManagerCallback {
|
||||
public int getDeviceCount();
|
||||
public String getDeviceProperty(int idDevice);
|
||||
public boolean openDevice(int idDevice, int freq, int nbChannel, int format);
|
||||
public boolean openDevice(int idDevice, int sampleRate, int nbChannel, int format);
|
||||
public boolean closeDevice(int idDevice);
|
||||
}
|
||||
|
@ -8,11 +8,18 @@
|
||||
|
||||
package org.musicdsp.orchestra;
|
||||
|
||||
import java.lang.UnsatisfiedLinkError;
|
||||
import java.lang.RuntimeException;
|
||||
import android.util.Log;
|
||||
|
||||
public class Orchestra {
|
||||
public <T extends ManagerCallback> Orchestra(T managerInstance) {
|
||||
NNsetJavaManager(managerInstance);
|
||||
try {
|
||||
NNsetJavaManager(managerInstance);
|
||||
} catch (java.lang.UnsatisfiedLinkError e) {
|
||||
Log.e("Orchestra", "JNI binding not present ...");
|
||||
throw new RuntimeException("Orchestra binding not present ...");
|
||||
}
|
||||
Log.d("Orchestra", "new ...");
|
||||
}
|
||||
|
||||
|
@ -11,60 +11,20 @@
|
||||
#include <unistd.h>
|
||||
#include <audio/orchestra/Interface.h>
|
||||
#include <audio/orchestra/debug.h>
|
||||
#include <audio/orchestra/api/AndroidNativeInterface.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "api::Android"
|
||||
|
||||
int32_t ttttttt();
|
||||
|
||||
audio::orchestra::Api* audio::orchestra::api::Android::create() {
|
||||
ATA_INFO("Create Android device ... : " << ttttttt());
|
||||
ATA_INFO("Create Android device ... ");
|
||||
return new audio::orchestra::api::Android();
|
||||
}
|
||||
|
||||
|
||||
audio::orchestra::api::Android::Android() {
|
||||
ATA_INFO("new Android");
|
||||
// On android, we set a static device ...
|
||||
ATA_INFO("get context");
|
||||
#if 0
|
||||
ewol::Context& tmpContext = ewol::getContext();
|
||||
ATA_INFO("done p=" << (int64_t)&tmpContext);
|
||||
int32_t deviceCount = tmpContext.audioGetDeviceCount();
|
||||
ATA_ERROR("Get count devices : " << deviceCount);
|
||||
for (int32_t iii=0; iii<deviceCount; ++iii) {
|
||||
std::string property = tmpContext.audioGetDeviceProperty(iii);
|
||||
ATA_ERROR("Get devices property : " << property);
|
||||
std::vector<std::string> listProperty = etk::split(property, ':');
|
||||
audio::orchestra::DeviceInfo tmp;
|
||||
tmp.name = listProperty[0];
|
||||
std::vector<std::string> listFreq = etk::split(listProperty[2], ',');
|
||||
for(size_t fff=0; fff<listFreq.size(); ++fff) {
|
||||
tmp.sampleRates.push_back(etk::string_to_int32_t(listFreq[fff]));
|
||||
}
|
||||
tmp.outputChannels = 0;
|
||||
tmp.inputChannels = 0;
|
||||
tmp.duplexChannels = 0;
|
||||
if (listProperty[1] == "out") {
|
||||
tmp.isDefaultOutput = true;
|
||||
tmp.isDefaultInput = false;
|
||||
tmp.outputChannels = etk::string_to_int32_t(listProperty[3]);
|
||||
} else if (listProperty[1] == "in") {
|
||||
tmp.isDefaultOutput = false;
|
||||
tmp.isDefaultInput = true;
|
||||
tmp.inputChannels = etk::string_to_int32_t(listProperty[3]);
|
||||
} else {
|
||||
/* duplex */
|
||||
tmp.isDefaultOutput = true;
|
||||
tmp.isDefaultInput = true;
|
||||
tmp.duplexChannels = etk::string_to_int32_t(listProperty[3]);
|
||||
}
|
||||
tmp.nativeFormats = audio::getListFormatFromString(listProperty[4]);
|
||||
m_devices.push_back(tmp);
|
||||
}
|
||||
#endif
|
||||
ATA_INFO("Create Android interface (end)");
|
||||
ATA_INFO("Create Android interface");
|
||||
}
|
||||
|
||||
audio::orchestra::api::Android::~Android() {
|
||||
@ -73,16 +33,16 @@ audio::orchestra::api::Android::~Android() {
|
||||
|
||||
uint32_t audio::orchestra::api::Android::getDeviceCount() {
|
||||
//ATA_INFO("Get device count:"<< m_devices.size());
|
||||
return m_devices.size();
|
||||
return audio::orchestra::api::android::getDeviceCount();
|
||||
}
|
||||
|
||||
audio::orchestra::DeviceInfo audio::orchestra::api::Android::getDeviceInfo(uint32_t _device) {
|
||||
//ATA_INFO("Get device info ...");
|
||||
return m_devices[_device];
|
||||
return audio::orchestra::api::android::getDeviceInfo(_device);
|
||||
}
|
||||
|
||||
enum audio::orchestra::error audio::orchestra::api::Android::closeStream() {
|
||||
ATA_INFO("Clese Stream");
|
||||
ATA_INFO("Close Stream");
|
||||
// Can not close the stream now...
|
||||
return audio::orchestra::error_none;
|
||||
}
|
||||
@ -168,6 +128,7 @@ bool audio::orchestra::api::Android::probeDeviceOpen(uint32_t _device,
|
||||
const audio::orchestra::StreamOptions& _options) {
|
||||
bool ret = false;
|
||||
ATA_INFO("Probe : device=" << _device << " channels=" << _channels << " firstChannel=" << _firstChannel << " sampleRate=" << _sampleRate);
|
||||
ret = audio::orchestra::api::android::open(_device, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options);
|
||||
#if 0
|
||||
if (_mode != audio::orchestra::mode_output) {
|
||||
ATA_ERROR("Can not start a device input or duplex for Android ...");
|
||||
|
@ -8,27 +8,357 @@
|
||||
#include <pthread.h>
|
||||
#include <mutex>
|
||||
#include <audio/orchestra/debug.h>
|
||||
#include <audio/orchestra/error.h>
|
||||
#include <audio/orchestra/api/AndroidNativeInterface.h>
|
||||
/* include auto generated file */
|
||||
#include <org_musicdsp_orchestra_Constants.h>
|
||||
#include <jvm-basics/jvm-basics.h>
|
||||
#include <etk/memory.h>
|
||||
#include <etk/tool.h>
|
||||
#include <ejson/ejson.h>
|
||||
|
||||
class AndroidOrchestraContext {
|
||||
public:
|
||||
AndroidOrchestraContext(JNIEnv* _env,
|
||||
jclass _classBase,
|
||||
jobject _objCallback) {
|
||||
ATA_ERROR("kjlkjlk");
|
||||
// get a resources from the java environement :
|
||||
JNIEnv* m_JavaVirtualMachinePointer; //!< the JVM
|
||||
jclass m_javaClassOrchestra; //!< main activity class (android ...)
|
||||
jclass m_javaClassOrchestraCallback;
|
||||
jobject m_javaObjectOrchestraCallback;
|
||||
jmethodID m_javaMethodOrchestraActivityAudioGetDeviceCount;
|
||||
jmethodID m_javaMethodOrchestraActivityAudioGetDeviceProperty;
|
||||
jmethodID m_javaMethodOrchestraActivityAudioOpenDevice;
|
||||
jmethodID m_javaMethodOrchestraActivityAudioCloseDevice;
|
||||
jclass m_javaDefaultClassString; //!< default string class
|
||||
private:
|
||||
bool safeInitMethodID(jmethodID& _mid, jclass& _cls, const char* _name, const char* _sign) {
|
||||
_mid = m_JavaVirtualMachinePointer->GetMethodID(_cls, _name, _sign);
|
||||
if(_mid == nullptr) {
|
||||
ATA_ERROR("C->java : Can't find the method " << _name);
|
||||
/* remove access on the virtual machine : */
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool java_attach_current_thread(int *_rstatus) {
|
||||
ATA_DEBUG("C->java : call java");
|
||||
if (jvm_basics::getJavaVM() == nullptr) {
|
||||
ATA_ERROR("C->java : JVM not initialised");
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
return false;
|
||||
}
|
||||
*_rstatus = jvm_basics::getJavaVM()->GetEnv((void **) &m_JavaVirtualMachinePointer, JNI_VERSION_1_6);
|
||||
if (*_rstatus == JNI_EDETACHED) {
|
||||
JavaVMAttachArgs lJavaVMAttachArgs;
|
||||
lJavaVMAttachArgs.version = JNI_VERSION_1_6;
|
||||
lJavaVMAttachArgs.name = "EwolNativeThread";
|
||||
lJavaVMAttachArgs.group = nullptr;
|
||||
int status = jvm_basics::getJavaVM()->AttachCurrentThread(&m_JavaVirtualMachinePointer, &lJavaVMAttachArgs);
|
||||
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
|
||||
if (status != JNI_OK) {
|
||||
ATA_ERROR("C->java : AttachCurrentThread failed : " << status);
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void java_detach_current_thread(int _status) {
|
||||
if(_status == JNI_EDETACHED) {
|
||||
jvm_basics::getJavaVM()->DetachCurrentThread();
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
AndroidOrchestraContext(JNIEnv* _env, jclass _classBase, jobject _objCallback) :
|
||||
m_JavaVirtualMachinePointer(nullptr),
|
||||
m_javaClassOrchestra(0),
|
||||
m_javaClassOrchestraCallback(0),
|
||||
m_javaObjectOrchestraCallback(0),
|
||||
|
||||
m_javaMethodOrchestraActivityAudioGetDeviceCount(0),
|
||||
m_javaMethodOrchestraActivityAudioGetDeviceProperty(0),
|
||||
m_javaMethodOrchestraActivityAudioOpenDevice(0),
|
||||
m_javaMethodOrchestraActivityAudioCloseDevice(0),
|
||||
m_javaDefaultClassString(0) {
|
||||
ATA_DEBUG("*******************************************");
|
||||
ATA_DEBUG("** set JVM Pointer (orchestra) **");
|
||||
ATA_DEBUG("*******************************************");
|
||||
m_JavaVirtualMachinePointer = _env;
|
||||
// get default needed all time elements :
|
||||
if (m_JavaVirtualMachinePointer == nullptr) {
|
||||
ATA_ERROR("C->java: NULLPTR jvm interface");
|
||||
return;
|
||||
}
|
||||
ATA_DEBUG("C->java: try load org/musicdsp/orchestra/Orchestra class");
|
||||
m_javaClassOrchestra = m_JavaVirtualMachinePointer->FindClass("org/musicdsp/orchestra/Orchestra" );
|
||||
if (m_javaClassOrchestra == 0) {
|
||||
ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/Orchestra class");
|
||||
// remove access on the virtual machine :
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
return;
|
||||
}
|
||||
/* The object field extends Activity and implement OrchestraCallback */
|
||||
m_javaClassOrchestraCallback = m_JavaVirtualMachinePointer->GetObjectClass(_objCallback);
|
||||
if(m_javaClassOrchestraCallback == nullptr) {
|
||||
ATA_ERROR("C->java : Can't find org/musicdsp/orchestra/ManagerCallback class");
|
||||
// remove access on the virtual machine :
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
return;
|
||||
}
|
||||
bool functionCallbackIsMissing = false;
|
||||
bool ret= false;
|
||||
|
||||
ret = safeInitMethodID(m_javaMethodOrchestraActivityAudioGetDeviceCount,
|
||||
m_javaClassOrchestraCallback,
|
||||
"getDeviceCount",
|
||||
"()I");
|
||||
if (ret == false) {
|
||||
jvm_basics::checkExceptionJavaVM(_env);
|
||||
ATA_ERROR("system can not start without function : getDeviceCount");
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
|
||||
ret = safeInitMethodID(m_javaMethodOrchestraActivityAudioGetDeviceProperty,
|
||||
m_javaClassOrchestraCallback,
|
||||
"getDeviceProperty",
|
||||
"(I)Ljava/lang/String;");
|
||||
if (ret == false) {
|
||||
jvm_basics::checkExceptionJavaVM(_env);
|
||||
ATA_ERROR("system can not start without function : getDeviceProperty");
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
ret = safeInitMethodID(m_javaMethodOrchestraActivityAudioOpenDevice,
|
||||
m_javaClassOrchestraCallback,
|
||||
"openDevice",
|
||||
"(IIII)Z");
|
||||
if (ret == false) {
|
||||
jvm_basics::checkExceptionJavaVM(_env);
|
||||
ATA_ERROR("system can not start without function : openDevice");
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
ret = safeInitMethodID(m_javaMethodOrchestraActivityAudioCloseDevice,
|
||||
m_javaClassOrchestraCallback,
|
||||
"closeDevice",
|
||||
"(I)Z");
|
||||
if (ret == false) {
|
||||
jvm_basics::checkExceptionJavaVM(_env);
|
||||
ATA_ERROR("system can not start without function : closeDevice");
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
|
||||
|
||||
m_javaObjectOrchestraCallback = _env->NewGlobalRef(_objCallback);
|
||||
if (m_javaObjectOrchestraCallback == nullptr) {
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
|
||||
m_javaDefaultClassString = m_JavaVirtualMachinePointer->FindClass("java/lang/String" );
|
||||
if (m_javaDefaultClassString == 0) {
|
||||
ATA_ERROR("C->java : Can't find java/lang/String" );
|
||||
// remove access on the virtual machine :
|
||||
m_JavaVirtualMachinePointer = nullptr;
|
||||
functionCallbackIsMissing = true;
|
||||
}
|
||||
if (functionCallbackIsMissing == true) {
|
||||
ATA_CRITICAL(" mission one function ==> system can not work withut it...");
|
||||
}
|
||||
}
|
||||
|
||||
~AndroidOrchestraContext() {
|
||||
// TODO ...
|
||||
}
|
||||
|
||||
void unInit(JNIEnv* _env) {
|
||||
_env->DeleteGlobalRef(m_javaObjectOrchestraCallback);
|
||||
m_javaObjectOrchestraCallback = nullptr;
|
||||
}
|
||||
|
||||
uint32_t getDeviceCount() {
|
||||
// Request the clipBoard :
|
||||
ATA_DEBUG("C->java : audio get device count");
|
||||
int status;
|
||||
if(!java_attach_current_thread(&status)) {
|
||||
return 0;
|
||||
}
|
||||
ATA_DEBUG("Call CallIntMethod ...");
|
||||
//Call java ...
|
||||
jint ret = m_JavaVirtualMachinePointer->CallIntMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioGetDeviceCount);
|
||||
// manage execption :
|
||||
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
|
||||
java_detach_current_thread(status);
|
||||
return (uint32_t)ret;
|
||||
return 0;
|
||||
}
|
||||
audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _idDevice) {
|
||||
audio::orchestra::DeviceInfo info;
|
||||
// Request the clipBoard :
|
||||
ATA_DEBUG("C->java : audio get device count");
|
||||
int status;
|
||||
if(!java_attach_current_thread(&status)) {
|
||||
return info;
|
||||
}
|
||||
//Call java ...
|
||||
jstring returnString = (jstring) m_JavaVirtualMachinePointer->CallObjectMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioGetDeviceProperty, _idDevice);
|
||||
const char *js = m_JavaVirtualMachinePointer->GetStringUTFChars(returnString, nullptr);
|
||||
std::string retString(js);
|
||||
m_JavaVirtualMachinePointer->ReleaseStringUTFChars(returnString, js);
|
||||
//m_JavaVirtualMachinePointer->DeleteLocalRef(returnString);
|
||||
// manage execption :
|
||||
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
|
||||
java_detach_current_thread(status);
|
||||
ATA_WARNING("get device information : " << retString);
|
||||
ejson::Document doc;
|
||||
if (doc.parse(retString) == false) {
|
||||
return info;
|
||||
}
|
||||
info.name = doc.getStringValue("name", "no-name");
|
||||
if (doc.getStringValue("type", "output") == "output") {
|
||||
info.input = false;
|
||||
} else {
|
||||
info.input = true;
|
||||
}
|
||||
std11::shared_ptr<const ejson::Array> list = doc.getArray("sample-rate");
|
||||
if (list != nullptr) {
|
||||
for (size_t iii=0; iii<list->size(); ++iii) {
|
||||
info.sampleRates.push_back(int32_t(list->getNumberValue(iii, 48000)));
|
||||
}
|
||||
}
|
||||
list = doc.getArray("channels");
|
||||
if (list != nullptr) {
|
||||
for (size_t iii=0; iii<list->size(); ++iii) {
|
||||
info.channels.push_back(audio::getChannelFromString(list->getStringValue(iii, "???")));
|
||||
}
|
||||
}
|
||||
list = doc.getArray("format");
|
||||
if (list != nullptr) {
|
||||
for (size_t iii=0; iii<list->size(); ++iii) {
|
||||
info.nativeFormats.push_back(audio::getFormatFromString(list->getStringValue(iii, "???")));
|
||||
}
|
||||
}
|
||||
info.isDefault = doc.getBooleanValue("default", false);
|
||||
/*
|
||||
+ " sample-rate:[8000,16000,24000,32000,48000,96000],\n"
|
||||
+ " channels=[front-left,front-right],\n"
|
||||
+ " format:[int16]\n"
|
||||
*/
|
||||
//return retString;
|
||||
return info;
|
||||
}
|
||||
private:
|
||||
//AndroidAudioCallback m_audioCallBack;
|
||||
//void* m_audioCallBackUserData;
|
||||
public:
|
||||
int32_t open(uint32_t _idDevice,
|
||||
audio::orchestra::mode _mode,
|
||||
uint32_t _channels,
|
||||
uint32_t _firstChannel,
|
||||
uint32_t _sampleRate,
|
||||
audio::format _format,
|
||||
uint32_t *_bufferSize,
|
||||
const audio::orchestra::StreamOptions& _options) {
|
||||
ATA_DEBUG("C->java : audio open device");
|
||||
int status;
|
||||
if(!java_attach_current_thread(&status)) {
|
||||
return -1;
|
||||
}
|
||||
//Call java ...
|
||||
jboolean ret = m_JavaVirtualMachinePointer->CallBooleanMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioOpenDevice, _idDevice, _sampleRate, _channels, /*_format*/ 1);
|
||||
// manage execption :
|
||||
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
|
||||
java_detach_current_thread(status);
|
||||
if (bool(ret) == true) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public:
|
||||
enum audio::orchestra::error closeStream(int32_t _id) {
|
||||
ATA_DEBUG("C->java : audio close device");
|
||||
int status;
|
||||
if(!java_attach_current_thread(&status)) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
//Call java ...
|
||||
jboolean ret = m_JavaVirtualMachinePointer->CallBooleanMethod(m_javaObjectOrchestraCallback, m_javaMethodOrchestraActivityAudioCloseDevice, _id);
|
||||
// manage execption :
|
||||
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
|
||||
java_detach_current_thread(status);
|
||||
if (bool(ret) == false) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
return audio::orchestra::error_none;
|
||||
}
|
||||
|
||||
enum audio::orchestra::error startStream(int32_t _id) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
enum audio::orchestra::error stopStream(int32_t _id) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
enum audio::orchestra::error abortStream(int32_t _id) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
};
|
||||
|
||||
static std::shared_ptr<AndroidOrchestraContext> s_localContext;
|
||||
static int32_t s_nbContextRequested(0);
|
||||
|
||||
int32_t ttttttt() {
|
||||
return etk::tool::irand(0,54456);
|
||||
|
||||
uint32_t audio::orchestra::api::android::getDeviceCount() {
|
||||
if (s_localContext == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return s_localContext->getDeviceCount();
|
||||
}
|
||||
|
||||
audio::orchestra::DeviceInfo audio::orchestra::api::android::getDeviceInfo(uint32_t _device) {
|
||||
if (s_localContext == nullptr) {
|
||||
return audio::orchestra::DeviceInfo();
|
||||
}
|
||||
return s_localContext->getDeviceInfo(_device);
|
||||
}
|
||||
|
||||
int32_t audio::orchestra::api::android::open(uint32_t _device,
|
||||
audio::orchestra::mode _mode,
|
||||
uint32_t _channels,
|
||||
uint32_t _firstChannel,
|
||||
uint32_t _sampleRate,
|
||||
audio::format _format,
|
||||
uint32_t *_bufferSize,
|
||||
const audio::orchestra::StreamOptions& _options) {
|
||||
if (s_localContext == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
return s_localContext->open(_device, _mode, _channels, _firstChannel, _sampleRate, _format, _bufferSize, _options);
|
||||
}
|
||||
|
||||
enum audio::orchestra::error audio::orchestra::api::android::closeStream(int32_t _id) {
|
||||
if (s_localContext == nullptr) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
return s_localContext->closeStream(_id);
|
||||
}
|
||||
|
||||
enum audio::orchestra::error audio::orchestra::api::android::startStream(int32_t _id) {
|
||||
if (s_localContext == nullptr) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
return s_localContext->startStream(_id);
|
||||
}
|
||||
|
||||
enum audio::orchestra::error audio::orchestra::api::android::stopStream(int32_t _id) {
|
||||
if (s_localContext == nullptr) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
return s_localContext->stopStream(_id);
|
||||
}
|
||||
|
||||
enum audio::orchestra::error audio::orchestra::api::android::abortStream(int32_t _id) {
|
||||
if (s_localContext == nullptr) {
|
||||
return audio::orchestra::error_fail;
|
||||
}
|
||||
return s_localContext->abortStream(_id);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@ -0,0 +1,39 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#if !defined(__AUDIO_ORCHESTRA_API_ANDROID_NATIVE_H__) && defined(ORCHESTRA_BUILD_JAVA)
|
||||
#define __AUDIO_ORCHESTRA_API_ANDROID_NATIVE_H__
|
||||
|
||||
#include <audio/orchestra/DeviceInfo.h>
|
||||
#include <audio/orchestra/mode.h>
|
||||
#include <audio/orchestra/error.h>
|
||||
#include <audio/orchestra/StreamOptions.h>
|
||||
#include <audio/format.h>
|
||||
|
||||
namespace audio {
|
||||
namespace orchestra {
|
||||
namespace api {
|
||||
namespace android {
|
||||
uint32_t getDeviceCount();
|
||||
audio::orchestra::DeviceInfo getDeviceInfo(uint32_t _device);
|
||||
int32_t open(uint32_t _device,
|
||||
audio::orchestra::mode _mode,
|
||||
uint32_t _channels,
|
||||
uint32_t _firstChannel,
|
||||
uint32_t _sampleRate,
|
||||
audio::format _format,
|
||||
uint32_t *_bufferSize,
|
||||
const audio::orchestra::StreamOptions& _options);
|
||||
enum audio::orchestra::error closeStream(int32_t _id);
|
||||
enum audio::orchestra::error startStream(int32_t _id);
|
||||
enum audio::orchestra::error stopStream(int32_t _id);
|
||||
enum audio::orchestra::error abortStream(int32_t _id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -72,11 +72,13 @@ def create(target):
|
||||
# create inter language interface
|
||||
myModule.add_src_file('org.musicdsp.orchestra.Constants.javah')
|
||||
myModule.add_path(tools.get_current_path(__file__) + '/android/', type='java')
|
||||
myModule.add_module_depend(['SDK', 'jvm-basics'])
|
||||
myModule.add_module_depend(['SDK', 'jvm-basics', 'ejson'])
|
||||
myModule.add_export_flag('c++', ['-DORCHESTRA_BUILD_JAVA'])
|
||||
|
||||
myModule.add_src_file('audio/orchestra/api/Android.cpp')
|
||||
myModule.add_src_file('audio/orchestra/api/AndroidNativeInterface.cpp')
|
||||
# add tre creator of the basic java class ...
|
||||
target.add_action("PACKAGE", 11, "audio-orchestra-out-wrapper", tool_generate_add_java_section_in_class)
|
||||
else:
|
||||
debug.warning("unknow target for audio_orchestra : " + target.name);
|
||||
|
||||
@ -85,3 +87,30 @@ def create(target):
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
##################################################################
|
||||
##
|
||||
## Android specific section
|
||||
##
|
||||
##################################################################
|
||||
def tool_generate_add_java_section_in_class(target, module, package_name):
|
||||
module.pkg_add("GENERATE_SECTION__IMPORT", [
|
||||
"import org.musicdsp.orchestra.Manager;"
|
||||
])
|
||||
module.pkg_add("GENERATE_SECTION__DECLARE", [
|
||||
"private Manager MANAGER;"
|
||||
])
|
||||
module.pkg_add("GENERATE_SECTION__CONSTRUCTOR", [
|
||||
"// load audio maneger if it does not work, it is not critical ...",
|
||||
"try {",
|
||||
" MANAGER = new Manager();",
|
||||
"} catch (RuntimeException e) {",
|
||||
" Log.e(\"" + package_name + "\", \"Can not load Audio interface (maybe not really needed) :\" + e);",
|
||||
"}"
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user