Audio播放流程(六)---数据进入AudioTrack

1. 音频数据流的框图

在这里插入图片描述

2. AudioTrack播放音频数据的三个套路

在这里插入图片描述
先看个音频播放例子吧,我是使用Native的AudioTrack播放PCM的音频,这个例子目前还是存在一些问题的,声音能够播放,但是播放的声音存在underrun的问题,目前还没找到原因。希望在分析完音频流后能够解决吧。

#define BUF_SZ 44100
#define FRAME_COUNT 1024
#define pcm_file "/data/xusong-shzj2.wav"

int AudioTrackTest::Test01() {
    long rate = 44100;
	int fd = 0;
	int length = 0;
	unsigned long int MinFrameCount = 0;
	unsigned char mBuffer[FRAME_COUNT];
	
	fd = open(pcm_file,O_RDWR);
	if(fd < 0)
	{
		printf("%s open failed\n",pcm_file);
	}

	/*
	 * MinFrameCount : 
	 *		要达到正常的播放,那么最小的帧数是这么多
	 */
	AudioTrack::getMinFrameCount(&MinFrameCount,AUDIO_STREAM_MUSIC,rate);
	printf("MinFrameCount = %lu\n",MinFrameCount);
	
	sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_MUSIC,// stream type
    							rate,
    							AUDIO_FORMAT_PCM_16_BIT,// word length, PCM
    							AUDIO_CHANNEL_OUT_STEREO,
    							MinFrameCount);

    status_t status = track->initCheck();
    if(status != NO_ERROR) {
		track.clear();
        ALOGD("Failed for initCheck()");
		return -1;
	}

    // start play
    ALOGD("start");
    track->start();

	int us;
	do{
		length = read(fd,mBuffer,FRAME_COUNT);
		if(length > 0)
			track->write(mBuffer,length,false);
		us = length*1000*1000/(rate*2*16);
		usleep(us);
	}while(length > 0);	
	
    usleep(20000);

    ALOGD("stop");
    track->stop();

    usleep(20000);

    return 0;

}

例程和上面的流程图是相匹配的,声音播放对于AudioTrack而言就三步。
第一步:创建AudioTrack的对象,这里面有个参数是MinFrameCount,它意味着要保证播放流 畅,AudioFlinger的回放线程至少需要分配的匿名内存的大小(MinFrameCount通道数采样深度);
第二步:调用track->start,启动播放;
第三步:调用track->write,持续的向匿名内存上写入音频数据即可。

至于AudioTrack的流程,参考Android 音频系统:从 AudioTrack 到 AudioFlinger

在MT6737 Android N平台上,录音到播放录音的流程可以分为以下几个步骤: 1. 打开录音设备 首先,需要打开录音设备并设置相关参数。在Android系统中,可以通过AudioRecord类来实现录音设备的打开和设置。例如: ``` int sampleRateInHz = 44100; // 采样率 int channelConfig = AudioFormat.CHANNEL_IN_MONO; // 声道数 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 采样精度 int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 缓冲区大小 AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes); recorder.startRecording(); // 开始录音 ``` 2. 录制音频数据 接下来,需要不断地读取录音设备中的音频数据,并保存到一个缓冲区中。在Android系统中,可以使用AudioRecord类的read方法来读取音频数据。例如: ``` byte[] buffer = new byte[1024]; while (isRecording) { // isRecording为标志位,表示是否正在录音 int len = recorder.read(buffer, 0, buffer.length); // 读取音频数据 // 将读取到的音频数据写入到文件或网络等 } ``` 3. 停止录音设备 当需要停止录音时,需要停止录音设备,并释放相关资源。在Android系统中,可以使用AudioRecord类的stop和release方法来实现。例如: ``` recorder.stop(); // 停止录音 recorder.release(); // 释放资源 ``` 4. 播放录音数据播放录音时,需要打开播放设备并设置相关参数。在Android系统中,可以使用AudioTrack类来打开播放设备并设置参数。例如: ``` int streamType = AudioManager.STREAM_MUSIC; // 音频流类型 int sampleRateInHz = 44100; // 采样率 int channelConfig = AudioFormat.CHANNEL_OUT_MONO; // 声道数 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 采样精度 int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 缓冲区大小 AudioTrack player = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM); player.play(); // 开始播放 ``` 5. 播放录音数据 接下来,需要将录音数据写入到播放设备中,以实现播放录音的效果。在Android系统中,可以使用AudioTrack类的write方法来将录音数据写入到播放设备中。例如: ``` byte[] buffer = new byte[1024]; while (isPlaying) { // isPlaying为标志位,表示是否正在播放 // 从文件或网络等读取录音数据 int len = ...; // 将读取到的录音数据写入到播放设备中 player.write(buffer, 0, len); } ``` 6. 停止播放设备 当需要停止播放录音时,需要停止播放设备,并释放相关资源。在Android系统中,可以使用AudioTrack类的stop和release方法来实现。例如: ``` player.stop(); // 停止播放 player.release(); // 释放资源 ``` 以上就是录音到播放录音的流程分析。需要注意的是,在实际的开发中还需要考虑很多细节问题,例如音频格式的选择、缓冲区大小的计算、线程的管理等等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值