diff --git a/android/org/musicdsp/orchestra/OrchestraInterfaceInput.java b/android/org/musicdsp/orchestra/OrchestraInterfaceInput.java index 2917a80..b7edbb8 100644 --- a/android/org/musicdsp/orchestra/OrchestraInterfaceInput.java +++ b/android/org/musicdsp/orchestra/OrchestraInterfaceInput.java @@ -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; } } diff --git a/android/org/musicdsp/orchestra/OrchestraInterfaceOutput.java b/android/org/musicdsp/orchestra/OrchestraInterfaceOutput.java index 60b315c..87ffce7 100644 --- a/android/org/musicdsp/orchestra/OrchestraInterfaceOutput.java +++ b/android/org/musicdsp/orchestra/OrchestraInterfaceOutput.java @@ -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(); } - m_audio.play(); } public void activityPause() { if(m_audio == null) { return; } - m_audio.pause(); + if (m_audio != null) { + Log.i("InterfaceOutput", "Pause audio stream : " + m_uid); + m_audio.pause(); + } } } diff --git a/android/org/musicdsp/orchestra/OrchestraManager.java b/android/org/musicdsp/orchestra/OrchestraManager.java index c6a3075..1603326 100644 --- a/android/org/musicdsp/orchestra/OrchestraManager.java +++ b/android/org/musicdsp/orchestra/OrchestraManager.java @@ -22,25 +22,25 @@ import java.util.Vector; * */ public class OrchestraManager implements OrchestraManagerCallback, OrchestraConstants { - private OrchestraNative orchestraHandle; - private int uid = 0; - private Vector outputList; - private Vector inputList; + private OrchestraNative m_orchestraHandle; + private int m_uid = 0; + private Vector m_outputList; + private Vector m_inputList; public OrchestraManager() { // set the java evironement in the C sources : - orchestraHandle = new OrchestraNative(this); - outputList = new Vector(); - inputList = new Vector(); + m_orchestraHandle = new OrchestraNative(this); + m_outputList = new Vector(); + m_inputList = new Vector(); } 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 OrchestraNative(T managerInstance) { + public 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 void NNsetJavaManager(T managerInstance); + private native 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); } diff --git a/audio/orchestra/api/Android.cpp b/audio/orchestra/api/Android.cpp index a8c9175..4e85007 100644 --- a/audio/orchestra/api/Android.cpp +++ b/audio/orchestra/api/Android.cpp @@ -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;