Loading include/media/AudioSystem.h +8 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ public: // to be non-zero if status == NO_ERROR static status_t getOutputSamplingRate(uint32_t* samplingRate, audio_stream_type_t stream); static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, const audio_attributes_t *attr); static status_t getOutputFrameCount(size_t* frameCount, audio_stream_type_t stream); static status_t getOutputLatency(uint32_t* latency, Loading Loading @@ -212,7 +214,12 @@ public: audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL); static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate = 0, audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL); static status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session); Loading include/media/AudioTrack.h +8 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,8 @@ public: transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, int uid = -1, pid_t pid = -1); pid_t pid = -1, audio_attributes_t* pAttributes = NULL); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using Loading Loading @@ -586,6 +587,11 @@ protected: AudioTrack(const AudioTrack& other); AudioTrack& operator = (const AudioTrack& other); void setAttributesFromStreamType(audio_stream_type_t streamType); void setStreamTypeFromAttributes(audio_attributes_t& aa); /* paa is guaranteed non-NULL */ bool isValidAttributes(const audio_attributes_t *paa); /* a small internal class to handle the callback */ class AudioTrackThread : public Thread { Loading Loading @@ -667,6 +673,7 @@ protected: transfer_type mTransfer; audio_offload_info_t mOffloadInfoCopy; const audio_offload_info_t* mOffloadInfo; audio_attributes_t mAttributes; // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data. For 8-bit PCM data, it's // twice as large as mFrameSize because data is expanded to 16-bit before it's stored in buffer. Loading include/media/IAudioPolicyService.h +6 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,12 @@ public: audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate = 0, audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0) = 0; Loading media/libmedia/AudioSystem.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,19 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream return getSamplingRate(output, samplingRate); } status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate, const audio_attributes_t *attr) { if (attr == NULL) { return BAD_VALUE; } audio_io_handle_t output = getOutputForAttr(attr); if (output == 0) { return PERMISSION_DENIED; } return getSamplingRate(output, samplingRate); } status_t AudioSystem::getSamplingRate(audio_io_handle_t output, uint32_t* samplingRate) { Loading Loading @@ -633,6 +646,19 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream, return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo); } audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, audio_output_flags_t flags, const audio_offload_info_t *offloadInfo) { if (attr == NULL) return 0; const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo); } status_t AudioSystem::startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session) Loading media/libmedia/AudioTrack.cpp +165 −15 Original line number Diff line number Diff line Loading @@ -103,6 +103,10 @@ AudioTrack::AudioTrack() mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0) { mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN; mAttributes.usage = AUDIO_USAGE_UNKNOWN; mAttributes.flags = 0x0; strcpy(mAttributes.tags, ""); } AudioTrack::AudioTrack( Loading @@ -129,7 +133,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid); offloadInfo, uid, pid, NULL /*no audio attributes*/); } AudioTrack::AudioTrack( Loading @@ -156,7 +160,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid); uid, pid, NULL /*no audio attributes*/); } AudioTrack::~AudioTrack() Loading Loading @@ -199,7 +203,8 @@ status_t AudioTrack::set( transfer_type transferType, const audio_offload_info_t *offloadInfo, int uid, pid_t pid) pid_t pid, audio_attributes_t* pAttributes) { ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %u, sessionId %d, transferType %d", Loading Loading @@ -259,18 +264,33 @@ status_t AudioTrack::set( if (streamType == AUDIO_STREAM_DEFAULT) { streamType = AUDIO_STREAM_MUSIC; } if (pAttributes == NULL) { if (uint32_t(streamType) >= AUDIO_STREAM_CNT) { ALOGE("Invalid stream type %d", streamType); return BAD_VALUE; } setAttributesFromStreamType(streamType); mStreamType = streamType; } else { if (!isValidAttributes(pAttributes)) { ALOGE("Invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]", pAttributes->usage, pAttributes->content_type, pAttributes->flags, pAttributes->tags); } // stream type shouldn't be looked at, this track has audio attributes memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); setStreamTypeFromAttributes(mAttributes); ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]", mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags); } status_t status; if (sampleRate == 0) { status = AudioSystem::getOutputSamplingRate(&sampleRate, streamType); status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes); if (status != NO_ERROR) { ALOGE("Could not get output sample rate for stream type %d; status %d", streamType, status); mStreamType, status); return status; } } Loading Loading @@ -314,7 +334,7 @@ status_t AudioTrack::set( ((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST); } // only allow deep buffering for music stream type if (streamType != AUDIO_STREAM_MUSIC) { if (mStreamType != AUDIO_STREAM_MUSIC) { flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); } Loading Loading @@ -620,7 +640,7 @@ status_t AudioTrack::setSampleRate(uint32_t rate) } uint32_t afSamplingRate; if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) { return NO_INIT; } // Resampler implementation limits input sampling rate to 2 x output sampling rate. Loading Loading @@ -867,12 +887,12 @@ status_t AudioTrack::createTrack_l(size_t epoch) return NO_INIT; } audio_io_handle_t output = AudioSystem::getOutput(mStreamType, mSampleRate, mFormat, audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat, mChannelMask, mFlags, mOffloadInfo); if (output == AUDIO_IO_HANDLE_NONE) { ALOGE("Could not get audio output for stream type %d, sample rate %u, format %#x, " ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x," " channel mask %#x, flags %#x", mStreamType, mSampleRate, mFormat, mChannelMask, mFlags); mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags); return BAD_VALUE; } { Loading Loading @@ -1858,6 +1878,136 @@ uint32_t AudioTrack::getUnderrunFrames() const return mProxy->getUnderrunFrames(); } void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) { mAttributes.flags = 0x0; switch(streamType) { case AUDIO_STREAM_DEFAULT: case AUDIO_STREAM_MUSIC: mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC; mAttributes.usage = AUDIO_USAGE_MEDIA; break; case AUDIO_STREAM_VOICE_CALL: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; break; case AUDIO_STREAM_ENFORCED_AUDIBLE: mAttributes.flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED; // intended fall through, attributes in common with STREAM_SYSTEM case AUDIO_STREAM_SYSTEM: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; break; case AUDIO_STREAM_RING: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; break; case AUDIO_STREAM_ALARM: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_ALARM; break; case AUDIO_STREAM_NOTIFICATION: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_NOTIFICATION; break; case AUDIO_STREAM_BLUETOOTH_SCO: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; mAttributes.flags |= AUDIO_FLAG_SCO; break; case AUDIO_STREAM_DTMF: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; break; case AUDIO_STREAM_TTS: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; break; default: ALOGE("invalid stream type %d when converting to attributes", streamType); } } void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { // flags to stream type mapping if ((aa.flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { mStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE; return; } if ((aa.flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { mStreamType = AUDIO_STREAM_BLUETOOTH_SCO; return; } // usage to stream type mapping switch (aa.usage) { case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_GAME: case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: mStreamType = AUDIO_STREAM_MUSIC; return; case AUDIO_USAGE_ASSISTANCE_SONIFICATION: mStreamType = AUDIO_STREAM_SYSTEM; return; case AUDIO_USAGE_VOICE_COMMUNICATION: mStreamType = AUDIO_STREAM_VOICE_CALL; return; case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: mStreamType = AUDIO_STREAM_DTMF; return; case AUDIO_USAGE_ALARM: mStreamType = AUDIO_STREAM_ALARM; return; case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: mStreamType = AUDIO_STREAM_RING; return; case AUDIO_USAGE_NOTIFICATION: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case AUDIO_USAGE_NOTIFICATION_EVENT: mStreamType = AUDIO_STREAM_NOTIFICATION; return; case AUDIO_USAGE_UNKNOWN: default: mStreamType = AUDIO_STREAM_MUSIC; } } bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) { // has flags that map to a strategy? if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) { return true; } // has known usage? switch (paa->usage) { case AUDIO_USAGE_UNKNOWN: case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_VOICE_COMMUNICATION: case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: case AUDIO_USAGE_ALARM: case AUDIO_USAGE_NOTIFICATION: case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case AUDIO_USAGE_NOTIFICATION_EVENT: case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: case AUDIO_USAGE_ASSISTANCE_SONIFICATION: case AUDIO_USAGE_GAME: break; default: return false; } return true; } // ========================================================================= void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused) Loading Loading
include/media/AudioSystem.h +8 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ public: // to be non-zero if status == NO_ERROR static status_t getOutputSamplingRate(uint32_t* samplingRate, audio_stream_type_t stream); static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, const audio_attributes_t *attr); static status_t getOutputFrameCount(size_t* frameCount, audio_stream_type_t stream); static status_t getOutputLatency(uint32_t* latency, Loading Loading @@ -212,7 +214,12 @@ public: audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL); static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate = 0, audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL); static status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session); Loading
include/media/AudioTrack.h +8 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,8 @@ public: transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, int uid = -1, pid_t pid = -1); pid_t pid = -1, audio_attributes_t* pAttributes = NULL); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using Loading Loading @@ -586,6 +587,11 @@ protected: AudioTrack(const AudioTrack& other); AudioTrack& operator = (const AudioTrack& other); void setAttributesFromStreamType(audio_stream_type_t streamType); void setStreamTypeFromAttributes(audio_attributes_t& aa); /* paa is guaranteed non-NULL */ bool isValidAttributes(const audio_attributes_t *paa); /* a small internal class to handle the callback */ class AudioTrackThread : public Thread { Loading Loading @@ -667,6 +673,7 @@ protected: transfer_type mTransfer; audio_offload_info_t mOffloadInfoCopy; const audio_offload_info_t* mOffloadInfo; audio_attributes_t mAttributes; // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data. For 8-bit PCM data, it's // twice as large as mFrameSize because data is expanded to 16-bit before it's stored in buffer. Loading
include/media/IAudioPolicyService.h +6 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,12 @@ public: audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate = 0, audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0) = 0; Loading
media/libmedia/AudioSystem.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,19 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream return getSamplingRate(output, samplingRate); } status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate, const audio_attributes_t *attr) { if (attr == NULL) { return BAD_VALUE; } audio_io_handle_t output = getOutputForAttr(attr); if (output == 0) { return PERMISSION_DENIED; } return getSamplingRate(output, samplingRate); } status_t AudioSystem::getSamplingRate(audio_io_handle_t output, uint32_t* samplingRate) { Loading Loading @@ -633,6 +646,19 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream, return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo); } audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, audio_output_flags_t flags, const audio_offload_info_t *offloadInfo) { if (attr == NULL) return 0; const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo); } status_t AudioSystem::startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session) Loading
media/libmedia/AudioTrack.cpp +165 −15 Original line number Diff line number Diff line Loading @@ -103,6 +103,10 @@ AudioTrack::AudioTrack() mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0) { mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN; mAttributes.usage = AUDIO_USAGE_UNKNOWN; mAttributes.flags = 0x0; strcpy(mAttributes.tags, ""); } AudioTrack::AudioTrack( Loading @@ -129,7 +133,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid); offloadInfo, uid, pid, NULL /*no audio attributes*/); } AudioTrack::AudioTrack( Loading @@ -156,7 +160,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid, pid); uid, pid, NULL /*no audio attributes*/); } AudioTrack::~AudioTrack() Loading Loading @@ -199,7 +203,8 @@ status_t AudioTrack::set( transfer_type transferType, const audio_offload_info_t *offloadInfo, int uid, pid_t pid) pid_t pid, audio_attributes_t* pAttributes) { ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " "flags #%x, notificationFrames %u, sessionId %d, transferType %d", Loading Loading @@ -259,18 +264,33 @@ status_t AudioTrack::set( if (streamType == AUDIO_STREAM_DEFAULT) { streamType = AUDIO_STREAM_MUSIC; } if (pAttributes == NULL) { if (uint32_t(streamType) >= AUDIO_STREAM_CNT) { ALOGE("Invalid stream type %d", streamType); return BAD_VALUE; } setAttributesFromStreamType(streamType); mStreamType = streamType; } else { if (!isValidAttributes(pAttributes)) { ALOGE("Invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]", pAttributes->usage, pAttributes->content_type, pAttributes->flags, pAttributes->tags); } // stream type shouldn't be looked at, this track has audio attributes memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); setStreamTypeFromAttributes(mAttributes); ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]", mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags); } status_t status; if (sampleRate == 0) { status = AudioSystem::getOutputSamplingRate(&sampleRate, streamType); status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes); if (status != NO_ERROR) { ALOGE("Could not get output sample rate for stream type %d; status %d", streamType, status); mStreamType, status); return status; } } Loading Loading @@ -314,7 +334,7 @@ status_t AudioTrack::set( ((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST); } // only allow deep buffering for music stream type if (streamType != AUDIO_STREAM_MUSIC) { if (mStreamType != AUDIO_STREAM_MUSIC) { flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); } Loading Loading @@ -620,7 +640,7 @@ status_t AudioTrack::setSampleRate(uint32_t rate) } uint32_t afSamplingRate; if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) { return NO_INIT; } // Resampler implementation limits input sampling rate to 2 x output sampling rate. Loading Loading @@ -867,12 +887,12 @@ status_t AudioTrack::createTrack_l(size_t epoch) return NO_INIT; } audio_io_handle_t output = AudioSystem::getOutput(mStreamType, mSampleRate, mFormat, audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat, mChannelMask, mFlags, mOffloadInfo); if (output == AUDIO_IO_HANDLE_NONE) { ALOGE("Could not get audio output for stream type %d, sample rate %u, format %#x, " ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x," " channel mask %#x, flags %#x", mStreamType, mSampleRate, mFormat, mChannelMask, mFlags); mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags); return BAD_VALUE; } { Loading Loading @@ -1858,6 +1878,136 @@ uint32_t AudioTrack::getUnderrunFrames() const return mProxy->getUnderrunFrames(); } void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) { mAttributes.flags = 0x0; switch(streamType) { case AUDIO_STREAM_DEFAULT: case AUDIO_STREAM_MUSIC: mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC; mAttributes.usage = AUDIO_USAGE_MEDIA; break; case AUDIO_STREAM_VOICE_CALL: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; break; case AUDIO_STREAM_ENFORCED_AUDIBLE: mAttributes.flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED; // intended fall through, attributes in common with STREAM_SYSTEM case AUDIO_STREAM_SYSTEM: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; break; case AUDIO_STREAM_RING: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; break; case AUDIO_STREAM_ALARM: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_ALARM; break; case AUDIO_STREAM_NOTIFICATION: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_NOTIFICATION; break; case AUDIO_STREAM_BLUETOOTH_SCO: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; mAttributes.flags |= AUDIO_FLAG_SCO; break; case AUDIO_STREAM_DTMF: mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; break; case AUDIO_STREAM_TTS: mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; mAttributes.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; break; default: ALOGE("invalid stream type %d when converting to attributes", streamType); } } void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { // flags to stream type mapping if ((aa.flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { mStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE; return; } if ((aa.flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { mStreamType = AUDIO_STREAM_BLUETOOTH_SCO; return; } // usage to stream type mapping switch (aa.usage) { case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_GAME: case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: mStreamType = AUDIO_STREAM_MUSIC; return; case AUDIO_USAGE_ASSISTANCE_SONIFICATION: mStreamType = AUDIO_STREAM_SYSTEM; return; case AUDIO_USAGE_VOICE_COMMUNICATION: mStreamType = AUDIO_STREAM_VOICE_CALL; return; case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: mStreamType = AUDIO_STREAM_DTMF; return; case AUDIO_USAGE_ALARM: mStreamType = AUDIO_STREAM_ALARM; return; case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: mStreamType = AUDIO_STREAM_RING; return; case AUDIO_USAGE_NOTIFICATION: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case AUDIO_USAGE_NOTIFICATION_EVENT: mStreamType = AUDIO_STREAM_NOTIFICATION; return; case AUDIO_USAGE_UNKNOWN: default: mStreamType = AUDIO_STREAM_MUSIC; } } bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) { // has flags that map to a strategy? if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) { return true; } // has known usage? switch (paa->usage) { case AUDIO_USAGE_UNKNOWN: case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_VOICE_COMMUNICATION: case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: case AUDIO_USAGE_ALARM: case AUDIO_USAGE_NOTIFICATION: case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case AUDIO_USAGE_NOTIFICATION_EVENT: case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: case AUDIO_USAGE_ASSISTANCE_SONIFICATION: case AUDIO_USAGE_GAME: break; default: return false; } return true; } // ========================================================================= void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused) Loading