【问题标题】:play recorded audio using AudioRecord.write()使用 AudioRecord.write() 播放录制的音频
【发布时间】:2015-02-17 00:03:25
【问题描述】:

我尝试使用 AudioTrack.write() 来听到录制的声音但没有输出,所以我需要的目的是通过 AudioRecord 录制音频并通过 AudioTrack 播放而不将其保存在 sd 卡或内部存储中,所以任何帮助将不胜感激。

public class MainActivity extends Activity {


short[]buffer=new short[512];
AudioManager am = null;
AudioRecord record =null;
AudioTrack track =null;

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);

     init();

     final Button jjbt1=(Button)findViewById(R.id.jt1);
     final Button jjbt2=(Button)findViewById(R.id.jt2);

     am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
     am.setMode(AudioManager.MODE_IN_COMMUNICATION);

     record.startRecording();
     track.play();


     jjbt1.setOnClickListener(new View.OnClickListener() {

         public void onClick(View v) {
             for( int i=0 ; i<512 ; i++ ){
                 record.read(buffer, 0,512);
            }
               record.stop();
         }
    });
    jjbt2.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v) {
             try{
                  track.write(buffer, 0,buffer.length);
                }catch(Exception de){Toast.makeText(getBaseContext(), de.getMessage().toString(), Toast.LENGTH_LONG).show();}
        }
    });
}
private void init() {
      int min = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
      record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 8000, AudioFormat.CHANNEL_IN_MONO,
        AudioFormat.ENCODING_PCM_16BIT, min);
      int maxJitter = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
      track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, 8000, AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
     }
 }

【问题讨论】:

    标签: android


    【解决方案1】:

    这对我有用:

    boolean isRecording = false;
    AudioManager am = null;
    AudioRecord record = null;
    AudioTrack track = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
    
        initRecordAndTrack();
    
        am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
        am.setSpeakerphoneOn(true);
    
        (new Thread()
        {
            @Override
            public void run()
            {
                recordAndPlay();
            }
        }).start();
    
        Button startButton = (Button) findViewById(R.id.start_button);
        startButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (!isRecording)
                {
                    startRecordAndPlay();
                }
            }
        });
        Button stopButton = (Button) findViewById(R.id.stop_button);
        stopButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (isRecording)
                {
                    stopRecordAndPlay();
                }
            }
        });
    }
    
    private void initRecordAndTrack()
    {
        int min = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
                                 min);
        if (AcousticEchoCanceler.isAvailable())
        {
            AcousticEchoCanceler echoCancler = AcousticEchoCanceler.create(record.getAudioSessionId());
            echoCancler.setEnabled(true);
        }
        int maxJitter = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter,
                               AudioTrack.MODE_STREAM);
    }
    
    private void recordAndPlay()
    {
        short[] lin = new short[1024];
        int num = 0;
        am.setMode(AudioManager.MODE_IN_COMMUNICATION);
        while (true)
        {
            if (isRecording)
            {
                num = record.read(lin, 0, 1024);
                track.write(lin, 0, num);
            }
        }
    }
    
    private void startRecordAndPlay()
    {
        record.startRecording();
        track.play();
        isRecording = true;
    }
    
    private void stopRecordAndPlay()
    {
        record.stop();
        track.pause();
        isRecording = false;
    }
    

    您的activity_main 布局中还需要两个按钮,ID 为start_buttonstop_button

    此示例还包含一个 EchoCanceler!

    祝你好运!

    【讨论】:

    • 非常感谢您的努力,但我不需要录音和音轨同步工作,我的问题是将它们分开,我的意思是录制音频并将录制的声音数据推送到缓冲区数组(lin in您的情况),最后根据我的操作播放它们(例如单击 btn)。谢谢
    • 您需要了解的重要内容,即我的应用程序背后的核心理念。是通过zend框架将录制的声音插入数据库。我很抱歉,因为我的问题没有组织。谢谢先生。
    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多