I am trying to mix two audio streams to get a single output stream is it possible in android? In my case, I have one input stream coming from Microphone, i.e, I am recording the users speech using AudioRecord. I want to mix this recording with a short sound clip and then create a new stream which is a mix of both the stream and then send it over a Datagram socket. I have researched a lot and here is what I came to know.
Firstly, SoundPool may help me achieve my goal, but I think I cannot provide Microphone as input source.
Currently I am saving the recording from MIC in a buffer and then streaming it over the datagram socket. I thought I can save the sound clip in another buffer and then add both the buffer(which I know is dumb a idea, as there are various properties of sound that I will have to manage).
Also may be I can save the recording from Microphone to a file and the recording of sound clip to a different file and mix them, however I think I cannot do this, as I am trying to stream the recording over the Datagram socket.
I think what I am trying to achieve may be possible using Java's sound API. But it is not supported by Android.
To summarize, what I am trying to achieve as my end goal is to inject a sound effect in a VoIP (SIP) based call (sound effect like crickets sound along with my voice).
I hope I gave a clear explanation about my problem.
Question 1: How can I achieve this? Question 2: Can I create a JAR file using Java's Sound API and use it in my project? (about this, I think it is not possible)
Here is some code of my Audio Recording and Audio Playback.
This is my code for audio recording:
public void run() {
// TODO Auto-generated method stub
try{
int minbuffer = AudioRecord.getMinBufferSize(sample, config, format);
DatagramSocket socket = new DatagramSocket();
Log.d(TAG, "Socket Created");
socket.setBroadcast(true);
byte[] ubuff = new byte[minbuffer];
DatagramPacket packet;
Log.d(TAG, "Packet Created");
InetAddress dest = InetAddress.getByName("10.10.1.126");
//InetAddress dest = InetAddress.
//InetSocketAddress dest= new InetSocketAddress(host, port);
Log.d(TAG, "Address"+dest);
rec = new AudioRecord(MediaRecorder.AudioSource.MIC,sample,
config,format,minbuffer);
rec.startRecording();
while(status == true){
minbuffer = rec.read(ubuff, 0,ubuff.length);
Log.d(TAG, "Reading While");
packet = new DatagramPacket(ubuff, ubuff.length,dest,port);
socket.send(packet);
}
}catch(Exception e){
Log.d(TAG, "Bad Datagram");
}
}
});
stream.start();
This is my code for audio playback:
@Override
public void run() {
// TODO Auto-generated method stub
try{
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
AudioManager mm = (AudioManager)getSystemService(AUDIO_SERVICE);
DatagramSocket rSocket = new DatagramSocket(8080);
Log.d(TAG, "Recive Socket");
int m_buf = AudioRecord.getMinBufferSize(sample, config, format);
byte[] _buff = new byte[m_buf];
AudioTrack rSpeaker = new AudioTrack(mm.STREAM_MUSIC,sample,config,
format,m_buf,AudioTrack.MODE_STREAM);
mm.setSpeakerphoneOn(false);
mm.setStreamVolume(AudioManager.STREAM_MUSIC, 100, AudioManager.MODE_IN_COMMUNICATION);
Log.d(TAG, "zzRecorder");
rSpeaker.setPlaybackRate(sample);
rSpeaker.play();
while(true){
try{
DatagramPacket rPacket = new DatagramPacket(_buff, _buff.length);
rSocket.receive(rPacket);
_buff = rPacket.getData();
rSpeaker.write(_buff, 0, m_buf);
Log.d(TAG, "Yo Start Write");
}catch(Exception e){
}
}
}catch(Exception e){
}
}
});
rvStrm.start();