在安卓系统中如何将两个音频流混合成单个音频流?

14
我想要将两个音频流混合为一个输出流,这在安卓上是否可能?在我的情况下,我有一个来自麦克风的输入流,也就是说,我正在使用AudioRecord录制用户的语音。我想将此录音与短声音剪辑混合,然后创建一个新的流,其中包含两个流的混合,并将其通过Datagram套接字发送。
我进行了大量研究,以下是我所知道的情况。
首先,SoundPool可以帮助我实现我的目标,但是我认为我不能提供麦克风作为输入源。
目前,我正在将MIC的录音保存在缓冲区中,然后通过数据报套接字进行流传输。我想我可以将声音剪辑保存在另一个缓冲区中,然后添加两个缓冲区(我知道这是愚蠢的想法,因为我必须管理各种声音属性)。
也许我可以将麦克风的录音保存到一个文件中,将声音剪辑的录音保存到不同的文件中并将它们混合,但我认为我无法这样做,因为我正在尝试通过Datagram套接字流传输录音。
我认为可以使用Java的声音API来实现我的目标。但它不受Android支持。
总之,我的最终目标是在VoIP(SIP)通话中注入声音效果(例如蟋蟀声和我的声音一起)。
问题1:我该如何实现这个? 问题2:我可以使用Java的Sound API创建一个JAR文件并在我的项目中使用吗?(关于此,我认为不可能)
以下是我的音频录制和播放的一些代码。
            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();     

这是我的音频播放代码:

        @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();

如果采样率相同,则可以线性地将它们相加,如果瞬时总和超过满量程,则可能进行缩放。 - Chris Stratton
“我怎么能实现这个?”--很抱歉,我没有任何音频混合的经验,无法提供帮助。 “我能否使用Java的Sound API创建一个JAR文件并在我的项目中使用它?”--我相当怀疑。 - CommonsWare
你是否了解iOS上可用的音频工具箱?我通常可以可靠地拼写“iOS”,但仅限于此。 :-) - CommonsWare
:-) 哈哈,谢谢 @CommonsWare。感谢您的时间。我会尝试阅读关于声音的内容,就像 Chris 说的那样,并希望能够弄清楚它。 - Akash
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Siddharth_Vyas
显示剩余4条评论
1个回答

3

编辑-2018年8月31日

源代码分叉在https://github.com/aksappy/jsresources-examples

我认为这对你有帮助,

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

该链接是一个开源示例,演示如何连接/混合音频文件。 我认为你最感兴趣的源代码将是

MixingAudioInputStream.java

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

我不知道Java Sound API的支持情况,但据我所知,Java Sound API用于基本音频捕获和播放。 你仍然必须自己进行混合,不是吗?

祝一切顺利


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接