[DEV] update java interfaec of Input and output

This commit is contained in:
Edouard DUPIN 2015-07-01 22:06:29 +02:00
parent 3a0ab73a3a
commit 09e32a815a
6 changed files with 208 additions and 150 deletions

View File

@ -16,18 +16,28 @@ import android.util.Log;
public class OrchestraInterfaceInput extends Thread implements OrchestraConstants {
public class OrchestraInterfaceInput implements Runnable, OrchestraConstants {
private Thread m_thread = null;
private int m_uid = -1;
private OrchestraNative m_orchestraNativeHandle;
public static final int SAMPLE_FREQ_44100 = 44100;
private boolean m_stop = false;
private boolean m_suspend = false;
private AudioRecord m_audio = null;
private int m_sampleRate = 48000;
private int m_nbChannel = 2;
private int m_format = 1;
private int m_bufferSize = BUFFER_SIZE;
public OrchestraInterfaceInput(int id, OrchestraNative instance, int idDevice, int freq, int nbChannel, int format) {
Log.d("InterfaceInput", "new: output");
m_uid = id;
m_orchestraNativeHandle = instance;
public OrchestraInterfaceInput(int _id, OrchestraNative _instance, int _idDevice, int _sampleRate, int _nbChannel, int _format) {
Log.d("InterfaceInput", "new: Input");
m_uid = _id;
m_orchestraNativeHandle = _instance;
m_stop = false;
m_suspend = false;
m_sampleRate = _sampleRate;
m_nbChannel = _nbChannel;
m_format = _format;
m_bufferSize = BUFFER_SIZE * m_nbChannel;
}
public int getUId() {
return m_uid;
@ -35,49 +45,75 @@ public class OrchestraInterfaceInput extends Thread implements OrchestraConstant
public void run() {
Log.e("InterfaceInput", "RUN (start)");
int sampleFreq = 48000;
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 = AudioRecord.getMinBufferSize(sampleFreq, channelConfig, audioFormat);
// TODO : int bufferSize = AudioRecord.getMinBufferSize(m_sampleRate, channelConfig, audioFormat);
int config = 0;
if (m_nbChannel == 1) {
config = AudioFormat.CHANNEL_IN_MONO;
} else {
config = AudioFormat.CHANNEL_IN_STEREO;
}
// Create a streaming AudioTrack for music playback
short[] streamBuffer = new short[bufferSize];
short[] streamBuffer = new short[m_bufferSize];
m_audio = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
m_sampleRate,
config,
audioFormat,
m_bufferSize);
m_audio.startRecording();
m_stop = false;
while (m_stop == false) {
while ( m_stop == false
&& m_suspend == false) {
// Stream PCM data into the local buffer
m_audio.read(streamBuffer, 0, BUFFER_SIZE);
m_audio.read(streamBuffer, 0, m_bufferSize);
// Send it to C++
m_orchestraNativeHandle.record(m_uid, streamBuffer, BUFFER_SIZE/nbChannels);
m_orchestraNativeHandle.record(m_uid, streamBuffer, m_bufferSize/m_nbChannel);
}
m_audio.stop();
m_audio = null;
streamBuffer = null;
Log.e("InterfaceInput", "RUN (stop)");
}
public void autoStart() {
m_stop=false;
if (m_suspend == false) {
Log.e("InterfaceInput", "Create thread");
m_thread = new Thread(this);
Log.e("InterfaceInput", "start thread");
m_thread.start();
Log.e("InterfaceInput", "start thread (done)");
}
}
public void autoStop() {
if(m_audio == null) {
return;
}
m_stop=true;
m_thread = null;
/*
try {
super.join();
} catch(InterruptedException e) { }
*/
}
public void activityResume() {
if(m_audio == null) {
return;
m_suspend = false;
if (m_stop == false) {
Log.i("InterfaceInput", "Resume audio stream : " + m_uid);
m_thread = new Thread(this);
m_thread.start();
}
}
public void activityPause() {
if(m_audio == null) {
return;
}
m_suspend = true;
Log.i("InterfaceInput", "Pause audio stream : " + m_uid);
m_thread = null;
}
}

View File

@ -20,12 +20,20 @@ public class OrchestraInterfaceOutput extends Thread implements OrchestraConstan
private boolean m_stop = false;
private boolean m_suspend = false;
private AudioTrack m_audio = null;
private int m_sampleRate = 48000;
private int m_nbChannel = 2;
private int m_format = 1;
private int m_bufferSize = BUFFER_SIZE;
public OrchestraInterfaceOutput(int id, OrchestraNative instance, int idDevice, int freq, int nbChannel, int format) {
public OrchestraInterfaceOutput(int _id, OrchestraNative _instance, int _idDevice, int _sampleRate, int _nbChannel, int _format) {
Log.d("InterfaceOutput", "new: output");
m_uid = id;
m_orchestraNativeHandle = instance;
m_stop = false;
m_uid = _id;
m_orchestraNativeHandle = _instance;
m_stop = true;
m_sampleRate = _sampleRate;
m_nbChannel = _nbChannel;
m_format = _format;
m_bufferSize = BUFFER_SIZE * m_nbChannel;
}
public int getUId() {
return m_uid;
@ -33,28 +41,34 @@ public class OrchestraInterfaceOutput extends Thread implements OrchestraConstan
public void run() {
Log.e("InterfaceOutput", "RUN (start)");
int sampleFreq = 48000; //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);
//int bufferSize = AudioTrack.getMinBufferSize(m_sampleRate, channelConfig, audioFormat);
int config = 0;
if (m_nbChannel == 1) {
config = AudioFormat.CHANNEL_OUT_MONO;
} else if (m_nbChannel == 4) {
config = AudioFormat.CHANNEL_OUT_QUAD;
} else {
config = AudioFormat.CHANNEL_OUT_STEREO;
}
// Create a streaming AudioTrack for music playback
short[] streamBuffer = new short[bufferSize];
short[] streamBuffer = new short[m_bufferSize];
m_audio = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
m_sampleRate,
config,
audioFormat,
m_bufferSize,
AudioTrack.MODE_STREAM);
m_audio.play();
//m_audio.setPositionNotificationPeriod(2048);
while (m_stop == false) {
// Fill buffer with PCM data from C++
m_orchestraNativeHandle.playback(m_uid, streamBuffer, BUFFER_SIZE/nbChannels);
m_orchestraNativeHandle.playback(m_uid, streamBuffer, m_bufferSize/m_nbChannel);
// Stream PCM data into the music AudioTrack
m_audio.write(streamBuffer, 0, BUFFER_SIZE);
m_audio.write(streamBuffer, 0, m_bufferSize);
}
m_audio.flush();
@ -63,22 +77,32 @@ public class OrchestraInterfaceOutput extends Thread implements OrchestraConstan
streamBuffer = null;
Log.e("InterfaceOutput", "RUN (stop)");
}
public void autoStart() {
m_stop=false;
this.start();
}
public void autoStop() {
if(m_audio == null) {
return;
}
m_stop=true;
try {
super.join();
} catch(InterruptedException e) { }
}
public void activityResume() {
if(m_audio == null) {
return;
}
if (m_audio != null) {
Log.i("InterfaceOutput", "Resume audio stream : " + m_uid);
m_audio.play();
}
}
public void activityPause() {
if(m_audio == null) {
return;
}
if (m_audio != null) {
Log.i("InterfaceOutput", "Pause audio stream : " + m_uid);
m_audio.pause();
}
}
}

View File

@ -22,25 +22,25 @@ import java.util.Vector;
*
*/
public class OrchestraManager implements OrchestraManagerCallback, OrchestraConstants {
private OrchestraNative orchestraHandle;
private int uid = 0;
private Vector<OrchestraInterfaceOutput> outputList;
private Vector<OrchestraInterfaceInput> inputList;
private OrchestraNative m_orchestraHandle;
private int m_uid = 0;
private Vector<OrchestraInterfaceOutput> m_outputList;
private Vector<OrchestraInterfaceInput> m_inputList;
public OrchestraManager() {
// set the java evironement in the C sources :
orchestraHandle = new OrchestraNative(this);
outputList = new Vector<OrchestraInterfaceOutput>();
inputList = new Vector<OrchestraInterfaceInput>();
m_orchestraHandle = new OrchestraNative(this);
m_outputList = new Vector<OrchestraInterfaceOutput>();
m_inputList = new Vector<OrchestraInterfaceInput>();
}
public int getDeviceCount() {
Log.e("Manager", "Get device List");
return 1;
return 2;
}
public String getDeviceProperty(int idDevice) {
if (idDevice == 0) {
public String getDeviceProperty(int _idDevice) {
if (_idDevice == 0) {
return "{\n"
+ " name:'speaker',\n"
+ " type:'output',\n"
@ -49,148 +49,151 @@ public class OrchestraManager implements OrchestraManagerCallback, OrchestraCons
+ " format:['int16'],\n"
+ " default:true\n"
+ "}";
} else if (_idDevice == 1) {
return "{\n"
+ " name:'microphone',\n"
+ " type:'input',\n"
+ " sample-rate:[8000,16000,24000,32000,48000,96000],\n"
+ " channels:['front-left','front-right'],\n"
+ " format:['int16'],\n"
+ " default:true\n"
+ "}";
} else {
return "{}";
}
}
public int openDeviceOutput(int idDevice, int freq, int nbChannel, int format) {
OrchestraInterfaceOutput iface = new OrchestraInterfaceOutput(uid, orchestraHandle, idDevice, freq, nbChannel, format);
uid++;
Log.e("Manager", "Open device Output: " + idDevice + " with UID=" + (uid-1));
public int openDeviceOutput(int _idDevice, int _freq, int _nbChannel, int _format) {
OrchestraInterfaceOutput iface = new OrchestraInterfaceOutput(m_uid, m_orchestraHandle, _idDevice, _freq, _nbChannel, _format);
m_uid++;
Log.e("Manager", "Open device Output: " + _idDevice + " with m_uid=" + (m_uid-1));
if (iface != null) {
outputList.add(iface);
Log.e("Manager", "Added element count=" + outputList.size());
return uid-1;
m_outputList.add(iface);
Log.e("Manager", "Added element count=" + m_outputList.size());
return m_uid-1;
}
return -1;
}
public int openDeviceInput(int idDevice, int freq, int nbChannel, int format) {
OrchestraInterfaceInput iface = new OrchestraInterfaceInput(uid, orchestraHandle, idDevice, freq, nbChannel, format);
uid++;
Log.e("Manager", "Open device Input: " + idDevice + " with UID=" + (uid-1));
public int openDeviceInput(int _idDevice, int _freq, int _nbChannel, int _format) {
OrchestraInterfaceInput iface = new OrchestraInterfaceInput(m_uid, m_orchestraHandle, _idDevice, _freq, _nbChannel, _format);
m_uid++;
Log.e("Manager", "Open device Input: " + _idDevice + " with m_uid=" + (m_uid-1));
if (iface != null) {
inputList.add(iface);
return uid-1;
m_inputList.add(iface);
return m_uid-1;
}
return -1;
}
public boolean closeDevice(int uniqueID) {
Log.e("Manager", "Close device : " + uniqueID);
if (uniqueID<0) {
Log.e("Manager", "Can not Close device with UID: " + uniqueID);
public boolean closeDevice(int _uniqueID) {
Log.e("Manager", "Close device : " + _uniqueID);
if (_uniqueID<0) {
Log.e("Manager", "Can not Close device with m_uid: " + _uniqueID);
return false;
}
// find the Element with his ID:
if (inputList != null) {
for (int iii=0; iii<inputList.size(); iii++) {
if (inputList.get(iii) == null) {
if (m_inputList != null) {
for (int iii=0; iii<m_inputList.size(); iii++) {
if (m_inputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (inputList.get(iii).getUId() == uniqueID) {
if (m_inputList.get(iii).getUId() == _uniqueID) {
// find it ...
inputList.remove(iii);
m_inputList.remove(iii);
return true;
}
}
}
if (outputList != null) {
for (int iii=0; iii<outputList.size(); iii++) {
if (outputList.get(iii) == null) {
if (m_outputList != null) {
for (int iii=0; iii<m_outputList.size(); iii++) {
if (m_outputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (outputList.get(iii).getUId() == uniqueID) {
if (m_outputList.get(iii).getUId() == _uniqueID) {
// find it ...
outputList.remove(iii);
m_outputList.remove(iii);
return true;
}
}
}
Log.e("Manager", "Can not start device with UID: " + uniqueID + " Element does not exist ...");
Log.e("Manager", "Can not start device with m_uid: " + _uniqueID + " Element does not exist ...");
return false;
}
public boolean start(int uniqueID) {
Log.e("Manager", "start device : " + uniqueID);
if (uniqueID<0) {
Log.e("Manager", "Can not start device with UID: " + uniqueID);
public boolean start(int _uniqueID) {
Log.e("Manager", "start device : " + _uniqueID);
if (_uniqueID<0) {
Log.e("Manager", "Can not start device with m_uid: " + _uniqueID);
return false;
}
// find the Element with his ID:
if (inputList != null) {
for (int iii=0; iii<inputList.size(); iii++) {
if (inputList.get(iii) == null) {
if (m_inputList != null) {
for (int iii=0; iii<m_inputList.size(); iii++) {
if (m_inputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (inputList.get(iii).getUId() == uniqueID) {
if (m_inputList.get(iii).getUId() == _uniqueID) {
// find it ...
inputList.get(iii).start();
m_inputList.get(iii).autoStart();
return true;
}
}
}
if (outputList != null) {
for (int iii=0; iii<outputList.size(); iii++) {
if (outputList.get(iii) == null) {
if (m_outputList != null) {
for (int iii=0; iii<m_outputList.size(); iii++) {
if (m_outputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (outputList.get(iii).getUId() == uniqueID) {
if (m_outputList.get(iii).getUId() == _uniqueID) {
// find it ...
outputList.get(iii).start();
m_outputList.get(iii).autoStart();
return true;
}
}
}
Log.e("Manager", "Can not start device with UID: " + uniqueID + " Element does not exist ...");
Log.e("Manager", "Can not start device with UID: " + _uniqueID + " Element does not exist ...");
return false;
}
public boolean stop(int uniqueID) {
Log.e("Manager", "stop device : " + uniqueID);
if (uniqueID<0) {
Log.e("Manager", "Can not stop device with UID: " + uniqueID);
public boolean stop(int _uniqueID) {
Log.e("Manager", "stop device : " + _uniqueID);
if (_uniqueID<0) {
Log.e("Manager", "Can not stop device with UID: " + _uniqueID);
return false;
}
// find the Element with his ID:
if (inputList != null) {
for (int iii=0; iii<inputList.size(); iii++) {
if (inputList.get(iii) == null) {
if (m_inputList != null) {
for (int iii=0; iii<m_inputList.size(); iii++) {
if (m_inputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (inputList.get(iii).getUId() == uniqueID) {
if (m_inputList.get(iii).getUId() == _uniqueID) {
// find it ...
inputList.get(iii).autoStop();
try {
inputList.get(iii).join();
} catch(InterruptedException e) { }
m_inputList.get(iii).autoStop();
return true;
}
}
}
if (outputList != null) {
for (int iii=0; iii<outputList.size(); iii++) {
if (outputList.get(iii) == null) {
if (m_outputList != null) {
for (int iii=0; iii<m_outputList.size(); iii++) {
if (m_outputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
if (outputList.get(iii).getUId() == uniqueID) {
if (m_outputList.get(iii).getUId() == _uniqueID) {
// find it ...
outputList.get(iii).autoStop();
try {
outputList.get(iii).join();
} catch(InterruptedException e) { }
m_outputList.get(iii).autoStop();
return true;
}
}
}
Log.e("Manager", "Can not stop device with UID: " + uniqueID + " Element does not exist ...");
Log.e("Manager", "Can not stop device with UID: " + _uniqueID + " Element does not exist ...");
return false;
}
public void onCreate() {
@ -208,44 +211,44 @@ public class OrchestraManager implements OrchestraManagerCallback, OrchestraCons
public void onResume() {
Log.w("Manager", "onResume ...");
// find the Element with his ID:
if (inputList != null) {
for (int iii=0; iii<inputList.size(); iii++) {
if (inputList.get(iii) == null) {
if (m_inputList != null) {
for (int iii=0; iii<m_inputList.size(); iii++) {
if (m_inputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
inputList.get(iii).activityResume();
m_inputList.get(iii).activityResume();
}
}
if (outputList != null) {
for (int iii=0; iii<outputList.size(); iii++) {
if (outputList.get(iii) == null) {
if (m_outputList != null) {
for (int iii=0; iii<m_outputList.size(); iii++) {
if (m_outputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
outputList.get(iii).activityResume();
m_outputList.get(iii).activityResume();
}
}
}
public void onPause() {
Log.w("Manager", "onPause ...");
// find the Element with his ID:
if (inputList != null) {
for (int iii=0; iii<inputList.size(); iii++) {
if (inputList.get(iii) == null) {
if (m_inputList != null) {
for (int iii=0; iii<m_inputList.size(); iii++) {
if (m_inputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
inputList.get(iii).activityPause();
m_inputList.get(iii).activityPause();
}
}
if (outputList != null) {
for (int iii=0; iii<outputList.size(); iii++) {
if (outputList.get(iii) == null) {
if (m_outputList != null) {
for (int iii=0; iii<m_outputList.size(); iii++) {
if (m_outputList.get(iii) == null) {
Log.e("Manager", "Null input element: " + iii);
continue;
}
outputList.get(iii).activityPause();
m_outputList.get(iii).activityPause();
}
}
}

View File

@ -10,10 +10,10 @@ package org.musicdsp.orchestra;
public interface OrchestraManagerCallback {
public int getDeviceCount();
public String getDeviceProperty(int idDevice);
public int openDeviceInput(int idDevice, int sampleRate, int nbChannel, int format);
public int openDeviceOutput(int idDevice, int sampleRate, int nbChannel, int format);
public boolean closeDevice(int uniqueID);
public boolean start(int uniqueID);
public boolean stop(int uniqueID);
public String getDeviceProperty(int _idDevice);
public int openDeviceInput(int _idDevice, int _sampleRate, int _nbChannel, int _format);
public int openDeviceOutput(int _idDevice, int _sampleRate, int _nbChannel, int _format);
public boolean closeDevice(int _uniqueID);
public boolean start(int _uniqueID);
public boolean stop(int _uniqueID);
}

View File

@ -13,9 +13,9 @@ import java.lang.RuntimeException;
import android.util.Log;
public class OrchestraNative {
public <T extends OrchestraManagerCallback> OrchestraNative(T managerInstance) {
public <T extends OrchestraManagerCallback> OrchestraNative(T _managerInstance) {
try {
NNsetJavaManager(managerInstance);
NNsetJavaManager(_managerInstance);
} catch (java.lang.UnsatisfiedLinkError e) {
Log.e("Orchestra", "JNI binding not present ...");
throw new RuntimeException("Orchestra binding not present ...");
@ -27,17 +27,17 @@ public class OrchestraNative {
NNsetJavaManagerRemove();
}
public void playback(int flowId, short[] bufferData, int nbChunk) {
NNPlayback(flowId, bufferData, nbChunk);
public void playback(int _flowId, short[] _bufferData, int _nbChunk) {
NNPlayback(_flowId, _bufferData, _nbChunk);
}
public void record(int flowId, short[] bufferData, int nbChunk) {
NNRecord(flowId, bufferData, nbChunk);
public void record(int _flowId, short[] _bufferData, int _nbChunk) {
NNRecord(_flowId, _bufferData, _nbChunk);
}
private native <T extends OrchestraManagerCallback> void NNsetJavaManager(T managerInstance);
private native <T extends OrchestraManagerCallback> void NNsetJavaManager(T _managerInstance);
private native void NNsetJavaManagerRemove();
private native void NNPlayback(int flowId, short[] bufferData, int nbChunk);
private native void NNRecord(int flowId, short[] bufferData, int nbChunk);
private native void NNPlayback(int _flowId, short[] _bufferData, int _nbChunk);
private native void NNRecord(int _flowId, short[] _bufferData, int _nbChunk);
}

View File

@ -143,11 +143,6 @@ 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);
if (_mode != audio::orchestra::mode_output) {
ATA_ERROR("Can not start a device input or duplex for Android ...");
return false;
}
m_mode = _mode;
m_userFormat = _format;
m_nUserChannels[modeToIdTable(m_mode)] = _channels;