今天来看看playback rate相关的接口。包括set和get。
*****************************************源码*************************************************
//Test case 6: setPlaybackRate() accepts values twice the output sample rate
@LargeTest
public void testSetPlaybackRateTwiceOutputSR() throws Exception {
// constants for test
final String TEST_NAME = "testSetPlaybackRateTwiceOutputSR";
final int TEST_SR = 22050;
final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
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,
minBuffSize, TEST_MODE);
byte data[] = new byte[minBuffSize/2];
int outputSR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);
//-------- test --------------
track.write(data, 0, data.length);
track.write(data, 0, data.length);
assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
track.play();
assertTrue(TEST_NAME, track.setPlaybackRate(2*outputSR) == AudioTrack.SUCCESS);
//-------- tear down --------------
track.release();
}
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java
#######################说明################################
//Test case 6: setPlaybackRate() accepts values twice the output sample rate
@LargeTest
public void testSetPlaybackRateTwiceOutputSR() throws Exception {
// constants for test
final String TEST_NAME = "testSetPlaybackRateTwiceOutputSR";
final int TEST_SR = 22050;
final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
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,
minBuffSize, TEST_MODE);
byte data[] = new byte[minBuffSize/2];
int outputSR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);
// +++++++++++++++++++++++++++++getNativeOutputSampleRate+++++++++++++++++++++++++++++++++++
/**
* Returns the hardware output sample rate
*/
static public int getNativeOutputSampleRate(int streamType) {
return native_get_output_sample_rate(streamType);
// +++++++++++++++++++++++++++++android_media_AudioTrack_get_playback_rate+++++++++++++++++++++++++++++++++++
static jint android_media_AudioTrack_get_playback_rate(JNIEnv *env, jobject thiz) {
AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
thiz, javaAudioTrackFields.nativeTrackInJavaObj);
if (lpTrack) {
return (jint) lpTrack->getSampleRate();
// ++++++++++++++++++++++++++++AudioTrack::getSampleRate++++++++++++++++++++++++++++++++++++
uint32_t AudioTrack::getSampleRate()
{
// 直接返回了audio_track_cblk_t中的sample rate。
// audio_track_cblk_t对象在AudioFlinger::ThreadBase::TrackBase::TrackBase的构造函数中被创建:new(mCblk) audio_track_cblk_t();
// 创建audio_track_cblk_t对象后,即对其成员变量sampleRate进行了赋值:mCblk->sampleRate = sampleRate;
// 此处的sampleRate其实是创建AudioTrack对象时传入的sampleRate。
return mCblk->sampleRate;
}
// ----------------------------AudioTrack::getSampleRate------------------------------------
} else {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for getSampleRate()");
return AUDIOTRACK_ERROR;
}
}
// -----------------------------android_media_AudioTrack_get_playback_rate-----------------------------------
}
// -----------------------------getNativeOutputSampleRate-----------------------------------
//-------- test --------------
track.write(data, 0, data.length);
track.write(data, 0, data.length);
assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
track.play();
assertTrue(TEST_NAME, track.setPlaybackRate(2*outputSR) == AudioTrack.SUCCESS);
// ++++++++++++++++++++++++++++setPlaybackRate+++++++++++++++++++++++++++++++++++
/**
* Sets the playback sample rate for this track. This sets the sampling rate at which
* the audio data will be consumed and played back, not the original sampling rate of the
* content. Setting it to half the sample rate of the content will cause the playback to
* last twice as long, but will also result in a negative pitch shift.
* The valid sample rate range if from 1Hz to twice the value returned by
* {@link #getNativeOutputSampleRate(int)}.
* @param sampleRateInHz the sample rate expressed in Hz
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
* {@link #ERROR_INVALID_OPERATION}
*/
// 看看这段注释
// 此处改变的rate,只是播放时的rate,并不是数据本身的rate。
// 例如,如果将rate设置为原来的一半,则播放时间将变为原来的2倍。
// 所设rate的范围是1Hz到原来rate的2倍。
public int setPlaybackRate(int sampleRateInHz) {
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
}
if (sampleRateInHz <= 0) {
return ERROR_BAD_VALUE;
}
return native_set_playback_rate(sampleRateInHz);
// ++++++++++++++++++++++++++++android_media_AudioTrack_set_playback_rate++++++++++++++++++++++++++++++++++++
static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz,
jint sampleRateInHz) {
AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
thiz, javaAudioTrackFields.nativeTrackInJavaObj);
if (lpTrack) {
return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));
// +++++++++++++++++++++++++++AudioTrack::setSampleRate+++++++++++++++++++++++++++++++++++++
status_t AudioTrack::setSampleRate(int rate)
{
int afSamplingRate;
if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
return NO_INIT;
// +++++++++++++++++++++++++++++AudioSystem::getOutputSamplingRate+++++++++++++++++++++++++++++++++++
// 感觉这么熟悉!
// 原来已见过多次!
status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType)
{
OutputDescriptor *outputDesc;
audio_io_handle_t output;
if (streamType == DEFAULT) {
streamType = MUSIC;
}
output = getOutput((stream_type)streamType);
if (output == 0) {
return PERMISSION_DENIED;
}
gLock.lock();
// AudioSystem::AudioFlingerClient::ioConfigChanged函数有往gOutputs中添加成员
outputDesc = AudioSystem::gOutputs.valueFor(output);
if (outputDesc == 0) {
LOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output);
gLock.unlock();
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*samplingRate = af->sampleRate(output);
// +++++++++++++++++++++++++AudioFlinger::sampleRate+++++++++++++++++++++++++++++++++++++++
uint32_t AudioFlinger::sampleRate(int output) const
{
Mutex::Autolock _l(mLock);
PlaybackThread *thread = checkPlaybackThread_l(output);
if (thread == NULL) {
LOGW("sampleRate() unknown thread %d", output);
return 0;
}
return thread->sampleRate();
// +++++++++++++++++++++++++++AudioFlinger::ThreadBase::sampleRate+++++++++++++++++++++++++++++++++++++
uint32_t AudioFlinger::ThreadBase::sampleRate() const
{
// 函数AudioFlinger::PlaybackThread::readOutputParameters中会给mSampleRate赋值: mSampleRate = mOutput->sampleRate();
return mSampleRate;
}
// ---------------------------AudioFlinger::ThreadBase::sampleRate-------------------------------------
}
// -------------------------AudioFlinger::sampleRate---------------------------------------
} else {
LOGV("getOutputSamplingRate() reading from output desc");
*samplingRate = outputDesc->samplingRate;
gLock.unlock();
}
LOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);
return NO_ERROR;
}
// -----------------------------AudioSystem::getOutputSamplingRate-----------------------------------
}
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
// 将rate设置到audio_track_cblk_t对象中
mCblk->sampleRate = rate;
return NO_ERROR;
}
// ---------------------------AudioTrack::setSampleRate-------------------------------------
} else {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setSampleRate()");
return AUDIOTRACK_ERROR;
}
}
// ----------------------------android_media_AudioTrack_set_playback_rate------------------------------------
}
// ----------------------------setPlaybackRate------------------------------------
//-------- tear down --------------
track.release();
}
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
set rate改变的只是播放时的rate,而不是数据本身的rate。
也就是说,set rate若与原来的rate不同的话,播放时间会改变。
函数AudioFlinger::MixerThread::threadLoop中会根据rate计算max period。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
分享到:
相关推荐
project( ' :react-native-android-audio-streaming-aac ' ) . projectDir = new File (settingsDir, ' ../node_modules/react-native-android-audio-streaming-aac ' ) android/app/build.gradle .. . ...
audio 播放器 在vue-audio-better上增加图标名称和大小 非工程化项目使用,绑定vue.js全局使用
DroidPhone的ANDROID-AUDIO-SYSTEM系列,写的极好,我把它整理成文档了,原帖:http://blog.csdn.net/droidphone,感谢作者的辛勤劳作和无私奉献。
android-sun-jarsign-support-1.1.jar
android audio 框架流程分析图
webrtc-audio-processing-0.3.1在arm平台的测试程序,含测试用的pcm文件。
XMOS-Stereo-USB-Audio-Class2-Driver-3033_v4.13.0公板
Demo Importing the Library Add to build.gradle: dependencies { ...} Library is available in jcenter repository How to use Refer to the sample project on how to use visualizer or refer to WIKI docs. ...
simpleaudio-1.0.4-cp310-cp310-win_amd64
数据库安装时补丁包, rpm -ihv zlib-devel-1.2.3-3.i386.rpm rpm -ihv freetype-devel-2.2.1-21.el5_3.i386.rpm ...rpm -ihv audiofile-devel-0.2.6-5.i386.rpm rpm -ihv esound-devel-0.2.36-3.i386.rpm
android-jni-audio-codecAndroid JNI audio codec from android source, now include amr , pcma, pcmu codec.Android JNI 层的音频编解码库,现在已经合入的有 AMR, PCMA, PCMU 编码.说明本文参考了 , 表示感谢. 他...
改SDK可以在多个平台上,以高保真度为XR,3D和360视频项目渲染数百个同步3D音源,包括两个unity独有功能:现场录制和几何混响烘培
Android 12 AudioFlinger 分析(RK3588)
android audio system
本书是在分析Android源码的基础上展开的,而源码文件所在的路径一般都很长,例如,文件AndroidRuntime.cpp的真实路径就是framework/base/core/jni/AndroidRuntime.cpp。为了书 写方便起见,我们在各章节开头把该...
安卓手机查看java源码Android 音频频谱分析仪 一个分支(请参阅 README.old 以获取其原始自述文件) 该软件显示了手机听到的声音的频率分量的幅度分布(称为频谱)。 可用于帮助调整乐器或唱歌时的音调,(暂定)...
Learning Core Audio A Hands-On Guide to Audio Programming for Mac and iOS.pdf iOS音视频开发必读书籍
该文档用来基于STM32的USB相关SDK将STM32枚举成Audio-CCID-HID-CDC-MSC-DFU等USB设备,内含详细说明
LYRICS-TO-AUDIO ALIGNMENT AND PHRASE-LEVEL SEGMENTATION
Android_Audio_overview.ppt 这个ppt要逆天啦 源码分析 英文的 100多页的 胜过国内任何一个分析