AudioTrack:我应该使用Asynctask,Thread还是Handler?

时间:2018-04-15 11:06:09

标签: android pcm audiotrack

在Android中:我正在尝试播放大小为230mb和20分钟的wav文件,其属性如下:

ffmpeg -i 1.wav

Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s

以下是android中的代码:     float volchange = 0.5f;     @覆盖     public void onCreate(Bundle savedInstanceState){         super.onCreate(savedInstanceState);         的setContentView(R.layout.activity_main);

    // Code to set the volume change variable for the audiotrack


    Button volup = (Button) findViewById(R.id.volup);
    Button voldown = (Button) findViewById(R.id.voldown);

    volup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            volchange = volchange+0.1f;
        }
    });

    voldown.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            volchange = volchange-0.1f;
        }
    });

    // Code to play the Audio track on pressing the button playraw


    Button playraw = (Button) findViewById(R.id.playraw);

    playraw.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int frequency = 44100;
            int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
            int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

            int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
                    channelConfiguration, audioEncoding, bufferSize,
                    AudioTrack.MODE_STREAM);

            int count = 0;
            byte[] data = new byte[bufferSize];
            byte[] datavol = new byte[bufferSize];

            try{
                FileInputStream fileInputStream = new FileInputStream(listMusicFiles.get(0).listmusicfiles_fullfilepath);
                DataInputStream dataInputStream = new DataInputStream(fileInputStream);
                audioTrack.play();

                while((count = dataInputStream.read(data, 0, bufferSize)) > -1){
                    for (int i=0;i<data.length;i++){

                        // *** using the global variable change volume ***

                        datavol[i] = (byte)((float) data[i]*volchange);
                    }
                    audioTrack.write(datavol, 0, count);
                }

                audioTrack.stop();
                audioTrack.release();
                dataInputStream.close();
                fileInputStream.close();
            }
            catch (FileNotFoundException e){
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    })
}

我想在播放时调节音量。但由于Auditrack正在使用主线程,因此我的volup和voldown按钮无法更改音量。

我在单独的帖子中播放音频。

我听说Asynctask仅用于短距离事物。在线程中我无法访问UI

有人可以建议使用哪个,这样如果我更改音量,它也应该改变音频轨道流字节中的音量。

1 个答案:

答案 0 :(得分:0)

我创建了一个线程,并将与audiotrack相关的代码放在其中。并且会立即应用volup和voldown的变化。

最终工作代码:

public class MainActivity extends AppCompatActivity {

    float volchange=0.5f;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Code to set the volume change variable for the audiotrack


        Button volup = (Button) findViewById(R.id.volup);
        Button voldown = (Button) findViewById(R.id.voldown);

        volup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                volchange = volchange+0.1f;
            }
        });

        voldown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                volchange = volchange-0.1f;
            }
        });

        // Code to play the Audio track on pressing the button playraw


        Button playraw = (Button) findViewById(R.id.playraw);

        playraw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startplaying();
            }
        });
    }

    public void startplaying() {
        // do something long
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                int frequency = 44100;
                int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
                int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

                int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
                        channelConfiguration, audioEncoding, bufferSize,
                        AudioTrack.MODE_STREAM);

                int count = 0;
                byte[] data = new byte[bufferSize];
                byte[] datavol = new byte[bufferSize];

                try{
                    FileInputStream fileInputStream = new FileInputStream(listMusicFiles.get(0).listmusicfiles_fullfilepath);
                    DataInputStream dataInputStream = new DataInputStream(fileInputStream);
                    audioTrack.play();

                    while((count = dataInputStream.read(data, 0, bufferSize)) > -1){
                        for (int i=0;i<data.length;i++){

                            // *** using the global variable change volume ***

                            datavol[i] = (byte)((float) data[i]*volchange);
                        }
                        audioTrack.write(datavol, 0, count);
                    }

                    audioTrack.stop();
                    audioTrack.release();
                    dataInputStream.close();
                    fileInputStream.close();
                }
                catch (FileNotFoundException e){
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(runnable).start();
    }
}