14

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();
Akash
  • 187
  • 3
  • 11
  • If the sample rates are the same, you can linearly add them, possibly scaling if the instataneous sum would ever exceed full scale. – Chris Stratton Aug 06 '14 at 01:56
  • "How can I achieve this?" -- I have no idea, sorry, as I have zero experience in audio muxing. "Can I create a JAR file using Java's Sound API and use it in my project?" -- I rather doubt it. – CommonsWare Aug 06 '14 at 10:38
  • @ChrisStratton: Thank you for your time, I kind of tried doing that, adding the bytes that I get from microphone with the bytes of the short sound clip and dividing it by 2. It was really bad, and I have no clue about various properties of sound. – Akash Aug 06 '14 at 15:18
  • @CommonsWare: Thank you for your time, I don't know it either, I am trying to find resources to learn how to do that, but could not get anything solid. Do you by any chance know about the Audio Tool Box that is available on iOS (which takes two different audio streams and outputs a single mixed stream)? I did not find any on Android. Is there anything equivalent of that in Android? I know about AudioRecord/AudioTrack , MediaRecord/MediaPlayer and SoundPool and as per my knowledge these are not capable of mixing mic with sound clip. Thanks – Akash Aug 06 '14 at 15:22
  • You are going to have to learn about the properties of your sound sources - sample rate, sample format, etc if you hope to go anywhere with this project. – Chris Stratton Aug 06 '14 at 15:25
  • "Do you by any chance know about the Audio Tool Box that is available on iOS" -- I can usually reliably spell "iOS", and that's about as far as I take it. :-) – CommonsWare Aug 06 '14 at 15:27
  • Sure. I would like to do that, if there is a possibility of me achieving the end goal. Do you any good source where I can read about this? – Akash Aug 06 '14 at 15:30
  • :-) haha thanks @CommonsWare. Appreciate your time. Will try to read about sound as Chris said and will hopefully try to figure it out. – Akash Aug 06 '14 at 15:32
  • @Akash : Have you found any solution for this ?? Even I ma stuck with the same problem and can't figure out any good document or library.Any help will be greatly appreciated. – Siddharth_Vyas Oct 30 '14 at 06:40

1 Answers1

3

EDIT - 31 Aug 2018

Source code forked at https://github.com/aksappy/jsresources-examples

I think this must be helpful to you,

http://www.jsresources.org/examples/AudioConcat.html

The link is an open source example for how to concatenate/mix audio files. I think the source that you will be most interested in will be

MixingAudioInputStream.java

http://www.jsresources.org/examples/MixingAudioInputStream.java.html

I do not know about the Support of Java Sound API, but AFAIK Java Sound API is for basic audio capture and playback. You will still have to do your own way of mixing, wouldnt you?

ATB

aksappy
  • 3,400
  • 3
  • 23
  • 49