研发不同于研究,团队不是个人,你的代码要让别人很容易看懂,这点很重要。在音频软件开发中,经常会遇到单位的换算问题:字节,采样点,秒,毫秒,Block等概念,这些概念本来都让人头晕了,如果你的代码中既没有注释,又随意命名变量,那别人根本就看不懂。参考下面的代码,我总结了几个问题:
1. nativeSeek中的val是什么意思?时间吗?秒还是毫秒?
2. seekValue 是什么意思?字节?Block? 嗯,要想一下才知道。
3. 这段代码看起来好像在做单位换算,然后调用另外一个函数,查了Seek的函数实现,发现确实如此,为了弄清楚,我查询了很多个相关的文件,花了很多时间。 几天后,我又回头来看这段代码,又搞不清楚了,不确定各个参数的准确意思,又要再看一遍相关代码,费事!
4. 这个开发者离职后,找其他人接手,又看不懂了,跟前任一样,又把各种资料翻了一遍,理解了80%,不能100%确定自己的理解是否正确。后续开发难度大哦。
5. 上层APP开发者在调用这个函数的时候,也不知道val应该传什么单位的值,要跟这段代码的作者再确认一下。
int nativeSeek(JNIEnv* env, jclass clazz, jint val)
{
CorePlayer *coreplayer = mp->playlist->GetCorePlayer();
int seekValue = val;
seekValue *= coreplayer->GetSampleRate();
seekValue /= coreplayer->GetBlockSize();
seekValue *= coreplayer->GetChannels();
int bitRate = (coreplayer->GetBps() == 16) ? 2 : 4 ;
seekValue *= bitRate;
coreplayer->Seek(seekValue);
return 0;
}
联系上层APP开发者后,确认传递给nativeSeek的值是毫秒,毫不犹豫把val重命名为positionAsMilliseconds。
很自然的发现seekValue *= coreplayer->GetSampleRate();这一行有问题,因为SampleRate采样率是基于秒的,而不是毫秒。
然后把seekValue改为positionAsBlocks,下面的代码可读性是不是要好很多?即使没有文档,看到这样的参数命名也知道该怎么传递了。
int nativeSeek(JNIEnv* env, jclass clazz, jint positionAsMilliseconds)
{
CorePlayer *coreplayer = mp->playlist->GetCorePlayer();
int positionAsBlocks = positionAsMilliseconds;
positionAsBlocks *= (coreplayer->GetSampleRate()/1000);
positionAsBlocks /= coreplayer->GetBlockSize();
positionAsBlocks *= coreplayer->GetChannels();
int bitRate = (coreplayer->GetBps() == 16) ? 2 : 4 ;
positionAsBlocks *= bitRate;
LOGE("nativeSeek positionAsMilliseconds=%d positionAsBlocks=%d", positionAsMilliseconds, positionAsBlocks);
coreplayer->Seek(positionAsBlocks);
return 0;
}