【问题标题】:Android: Mixing multiple AudioTrack instances?Android:混合多个 AudioTrack 实例?
【发布时间】:2011-03-08 00:56:04
【问题描述】:

我需要同时运行两个 AudioTrack 实例。它们必须单独运行,因为我以不同的可变采样率播放它们。我发现如果我在同一个线程中运行它们,它们会“轮流”。我在各自的线程中运行它们,但音频结结巴巴。

关于让两个实例玩得更好的任何想法?如果没有,任何将两个短缓冲区混合为一个的提示,即使我想以不同的采样率播放它们。

【问题讨论】:

    标签: java android sample mixer rate


    【解决方案1】:

    我同时播放了 4 个音轨,它们似乎都可以正常播放。在 HTC Desire 1.1ghz OC 上进行测试。不过,有时我的线程会出现故障。有时,如果四个人都在玩,当我尝试加入线程时,一个人不会停止。需要做更多的测试。 这是我播放在给定路径记录的 wav 文件的类

        package com.ron.audio.functions;
    
    import java.io.BufferedInputStream;
    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    import android.media.AudioFormat;
    import android.media.AudioManager;
    import android.media.AudioTrack;
    
    public class AudioPlayManager implements Runnable {
    
    private File fileName;
    private volatile boolean playing;
    
    public AudioPlayManager() {
        super();
        setPlaying(false);
    }
    
    public void run(){
          // Get the length of the audio stored in the file (16 bit so 2 bytes per short)
          // and create a short array to store the recorded audio.
          int musicLength = (int)(fileName.length()/2);
          short[] music = new short[musicLength];
    
          try {
            // Create a DataInputStream to read the audio data back from the saved file.
            InputStream is = new FileInputStream(fileName);
            BufferedInputStream bis = new BufferedInputStream(is);
            DataInputStream dis = new DataInputStream(bis);
    
            // Read the file into the music array.
            int i = 0;
            while (dis.available() > 0) {
              music[i] = dis.readShort();
              i++;
            }
    
            // Close the input streams.
            dis.close();     
    
            // Create a new AudioTrack object using the same parameters as the AudioRecord
            // object used to create the file.
            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
                                                    11025, 
                                                   AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                                   AudioFormat.ENCODING_PCM_16BIT, 
                                                   musicLength, 
                                                   AudioTrack.MODE_STREAM);
            // Start playback
            audioTrack.play();
    
            // Write the music buffer to the AudioTrack object
            while(playing){
                audioTrack.write(music, 0, musicLength);
            }
    
          }
          catch(Exception e){
              e.printStackTrace();
          }
    
    }
    
    
    public void setFileName(File fileName) {
        this.fileName = fileName;
    }
    
    public File getFileName() {
        return fileName;
    }
    
    public void setPlaying(boolean playing) {
        this.playing = playing;
    }
    
    public boolean isPlaying() {
        return playing;
    }
    

    }

    【讨论】:

    • 谢谢!会试试这个。我没有像你一样在线程回调中创建我的 AudioTrack。我猜这就是解决方法(您的其余代码几乎与我所拥有的相同)。这可以解释为什么两个 AudioTrack 的“切换”——它们相互阻塞。
    • 让我知道这是否适合您。我也将所有这些包裹在另一个类中,它将为我完成所有线程管理。然后我可以调用线程管理器,而不必担心用于记录或回放流的线程。
    • 除此之外还有更多内容,但真正的关键是在线程内创建 AudioTrack。我有一个单独的“设备”类,所以我可以控制它的速度、音量等。将它组合到读取文件的类中并在一个线程中完成所有操作,让它们玩得很好。我现在在我的 Optimus (600mHz) 上 DJ 曲目。 :)
    • 能否提供示例项目,非常感谢。
    • 我可以尝试添加示例项目,但我上次检查时它没有处于工作状态。我们现在要回去 3 年了;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多