Android:如何混合 2 个音频文件并使用 soundPool 重现它们

Posted

技术标签:

【中文标题】Android:如何混合 2 个音频文件并使用 soundPool 重现它们【英文标题】:Android: How to mix 2 audio files and reproduce them with soundPool 【发布时间】:2012-10-02 09:09:15 【问题描述】:

我正在尝试开发一个 android 应用程序,该应用程序使用一些声音并将它们混合在一起以创建音乐作品。一开始我试图同时重现声音,但是当我这样做时,它们变得不同步,在阅读论坛几个小时后,我意识到在循环模式下同时重现多个声音的最佳方法就是将音频文件合并为一个文件,然后将它们复制为单个文件。

这是我正在使用的代码:

        //Oppening file 1
        InputStream is = getAssets().open("sounds/sound_1.ogg");
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        //End Oppening file 1

        //Oppening file 2
        InputStream is_2 = getAssets().open("sounds/sound_2.ogg");
        int size_2 = is_2.available();
        byte[] buffer_2 = new byte[size_2];
        is_2.read(buffer_2);
        is_2.close();
        //End Oppening file 2

        //Get Bigger size and Merge Files
        int total_size =0;

        byte[] buffer_final;
        if(buffer.length>buffer_2.length)
            total_size = buffer_2.length;   
        else
            total_size = buffer.length-1;
        

        buffer_final= new byte[total_size];

        for(int i=30; i<total_size-30;i++)


            float a =buffer[i];
            float b =buffer_2[i];
            float c = (a+b)/2;
            buffer_final[i]=(byte) c;      

        

        FileOutputStream fos = new FileOutputStream(f);        
        fos.write(buffer_final);
        fos.close();

然后,我使用 soundPool 读取生成的文件并尝试重现它。

如果我使用这个公式而不合并文件(所以,只使用一个声音,创建一个新文件,然后读取它,它工作得很好,所以我认为问题出在文件合并中,那可能不是就像将字节加在一起然后除以 2 一样简单。

执行此操作后,日志告诉我:

无法加载样本(null)。

而且,当我尝试重现日志时,显示示例尚未准备好。

请对此有任何帮助吗?我已经在谷歌上搜索了几个星期,但我无法解决它......

这是我第一次编写 Android 和音频,所以我有点迷茫。

问题是,我该如何混合这些声音?我是否以正确的方式这样做?哪里有问题?

感谢阅读和帮助:)

【问题讨论】:

第一篇文章格式很好!一个清晰而简洁的问题。干得好。 【参考方案1】:

如果您使用的是原始 PCM 数据,则对样本进行平均可以正常工作。您需要做的是首先将 OGG 文件转换为 PCM 缓冲区。如果您想将输出保留为 OGG,则需要在完成后将其转换回来。

我的经验主要是使用 MP3 库而不是 OGG,但我听说过关于 JOrbis 的好消息。

【讨论】:

其实我不在乎格式(它可以是 .mp3、wav、ogg、...)anythig。最主要的是尝试混合两种声音,并能够在一个循环中重现这个最终结果。那么,最好的方法是什么?谢谢! 好吧,不管是什么格式,你都需要得到原始(PCM)的声音。有些格式比其他格式更容易。例如,WAV 主要是带有一些标头信息的 PCM,因此从中获取原始数据并不是什么大问题。有些(MP3、OGG 等)是压缩/编码的,因此您需要一个库来将它们转换为原始音频。 原始音频放入缓冲区后,您可以像尝试一样添加/分割它们。但是,如果您希望它在大多数玩家身上播放,您将不得不对结果进行一些重新转换。 谢谢大家,对我迟到的回答感到抱歉,最后我可以使用audiopool设法同时重现几个声音而没有延迟,所以我根本不需要合并它们:)所以我的问题解决了!! @TurboTi - 嗨,你能解释一下你是如何使用音频池的吗?在 android 我只知道 SoundPool...【参考方案2】:

这样

soundPool = new SoundPool(NUM_SOUNDS, AudioManager.STREAM_MUSIC, 0);

NUM_SOUNDS 是 soundPool 可以同时播放的声音数量。

【讨论】:

以上是关于Android:如何混合 2 个音频文件并使用 soundPool 重现它们的主要内容,如果未能解决你的问题,请参考以下文章

我应该使用线程编程来混合 2 个音频流吗?

NAudio 使用 WaveMixerStream32() 混合 2 两个音频->如何让第二个音频稍后开始

使用 HTML5 音频的无线电流混合 Android 应用程序的巨大延迟

混合 2 个音频文件

使用 NAudio 混合两个音频文件

在android中混合音频