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

猜你喜欢

转载自blog.csdn.net/zhuyong006/article/details/86609943
今日推荐