Android Audio代码分析19 - setPosition函数

之前我们看过get position,今天来看看set position。


*****************************************源码*************************************************
//Test case 3: setPlaybackHeadPosition() on paused track
@LargeTest
public void testSetPlaybackHeadPositionPaused() throws Exception {
// constants for test
final String TEST_NAME = "testSetPlaybackHeadPositionPaused";
final int TEST_SR = 22050;
final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
final int TEST_MODE = AudioTrack.MODE_STREAM;
final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;

//-------- initialization --------------
int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
2*minBuffSize, TEST_MODE);
byte data[] = new byte[minBuffSize];
//-------- test --------------
assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
track.write(data, 0, data.length);
track.write(data, 0, data.length);
track.play();
track.pause();
assumeTrue(TEST_NAME, track.getPlayState() == AudioTrack.PLAYSTATE_PAUSED);
assertTrue(TEST_NAME, track.setPlaybackHeadPosition(10) == AudioTrack.SUCCESS);
//-------- tear down --------------
track.release();
}
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java


#######################说明################################
//Test case 3: setPlaybackHeadPosition() on paused track
@LargeTest
public void testSetPlaybackHeadPositionPaused() throws Exception {
// constants for test
final String TEST_NAME = "testSetPlaybackHeadPositionPaused";
final int TEST_SR = 22050;
final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
final int TEST_MODE = AudioTrack.MODE_STREAM;
final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;

//-------- initialization --------------
int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
2*minBuffSize, TEST_MODE);
byte data[] = new byte[minBuffSize];
//-------- test --------------
assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
track.write(data, 0, data.length);
track.write(data, 0, data.length);
track.play();
track.pause();
assumeTrue(TEST_NAME, track.getPlayState() == AudioTrack.PLAYSTATE_PAUSED);
assertTrue(TEST_NAME, track.setPlaybackHeadPosition(10) == AudioTrack.SUCCESS);
+++++++++++++++++++++++++++++setPlaybackHeadPosition+++++++++++++++++++++++++++++++++++
/**
* Sets the playback head position. The track must be stopped for the position to be changed.
* @param positionInFrames playback head position expressed in frames
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
* {@link #ERROR_INVALID_OPERATION}
*/
public int setPlaybackHeadPosition(int positionInFrames) {
synchronized(mPlayStateLock) {
if ((mPlayState == PLAYSTATE_STOPPED) || (mPlayState == PLAYSTATE_PAUSED)) {
return native_set_position(positionInFrames);
++++++++++++++++++++++++++++android_media_AudioTrack_set_position++++++++++++++++++++++++++++++++++++
static jint android_media_AudioTrack_set_position(JNIEnv *env, jobject thiz,
jint position) {

AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
thiz, javaAudioTrackFields.nativeTrackInJavaObj);

if (lpTrack) {
return android_media_translateErrorCode( lpTrack->setPosition(position) );
++++++++++++++++++++++++++++AudioTrack::setPosition++++++++++++++++++++++++++++++++++++
status_t AudioTrack::setPosition(uint32_t position)
{
Mutex::Autolock _l(mCblk->lock);


if (!stopped()) return INVALID_OPERATION;


if (position > mCblk->user) return BAD_VALUE;


mCblk->server = position;
mCblk->flags |= CBLK_FORCEREADY_ON;


return NO_ERROR;
}
----------------------------AudioTrack::setPosition------------------------------------
} else {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setPosition()");
return AUDIOTRACK_ERROR;
}
}
----------------------------android_media_AudioTrack_set_position------------------------------------
} else {
return ERROR_INVALID_OPERATION;
}
}
}
-----------------------------setPlaybackHeadPosition-----------------------------------
//-------- tear down --------------
track.release();
}
###########################################################


&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
set position改变的其实是audio_track_cblk_t结构体中的server成员。
也就是AudioMixer中从audio_track_cblk_t中copy数据时的起始地址。
这儿设置position有个限制,就是不能跑到user前面去,
即不能让取数据的其实地址超出已写数据的范围。
在播放器中,大幅度拖动进度条,改变的应该是读取文件时的地址,

而不是audio_track_cblk_t对象中的地址。


另外,只能在stop的状态下才能改变position。

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Lua 语言和 Cocos2d-x 引擎实现按钮放大缩小的示例代码: ```lua -- 创建一个按钮 local button = ccui.Button:create("button_normal.png", "button_pressed.png", "button_disabled.png") button:setPosition(display.cx, display.cy) button:setTitleText("Button") button:setTitleFontSize(24) self:addChild(button) -- 定义按钮缩放的动作 local scaleSmall = cc.ScaleTo:create(0.1, 0.9) local scaleBig = cc.ScaleTo:create(0.1, 1.1) local scaleOrigin = cc.ScaleTo:create(0.1, 1) -- 注册按钮的触摸事件 button:addTouchEventListener(function(sender, eventType) if eventType == ccui.TouchEventType.began then -- 按下时缩小按钮 sender:runAction(scaleSmall) elseif eventType == ccui.TouchEventType.ended then -- 抬起时放大按钮 sender:runAction(scaleBig) -- 在此处添加按钮点击后的逻辑处理 elseif eventType == ccui.TouchEventType.canceled then -- 取消点击时恢复按钮原始大小 sender:runAction(scaleOrigin) end end) ``` 上述代码中,首先创建了一个按钮,并定义了缩小、放大和还原按钮大小的动作。然后注册了按钮的触摸事件,当触摸事件类型为 `ccui.TouchEventType.began`(即按下时)时,执行缩小动作,当事件类型为 `ccui.TouchEventType.ended`(即抬起时)时,执行放大动作并在此处添加按钮点击后的逻辑处理,当事件类型为 `ccui.TouchEventType.canceled`(即取消点击时)时,执行还原按钮大小的动作。 需要注意的是,上述代码中使用了 `ccui.Button` 类创建按钮,如果使用的是 `cc.Sprite` 类,则需要使用 `cc.ScaleBy` 函数创建缩放动作。同时,由于 Lua 中函数名和变量名不区分大小写,因此 `cc.ScaleTo` 函数在 Lua 中也可以写成 `cc.Scaleto` 或 `cc.scaleTo`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值