Loading services/audioflinger/AudioFlinger.cpp +31 −13 Original line number Diff line number Diff line Loading @@ -1594,16 +1594,25 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ audio_stream_out_t *outStream = NULL; // FOR TESTING ONLY: // Enable increased sink precision for mixing mode if kEnableExtendedPrecision is true. if (kEnableExtendedPrecision && // Check only for Normal Mixing mode !(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { // Update format //config.format = AUDIO_FORMAT_PCM_FLOAT; //config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED; //config.format = AUDIO_FORMAT_PCM_32_BIT; //config.format = AUDIO_FORMAT_PCM_8_24_BIT; // This if statement allows overriding the audio policy settings // and forcing a specific format or channel mask to the HAL/Sink device for testing. if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { // Check only for Normal Mixing mode if (kEnableExtendedPrecision) { // Specify format (uncomment one below to choose) //config->format = AUDIO_FORMAT_PCM_FLOAT; //config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED; //config->format = AUDIO_FORMAT_PCM_32_BIT; //config->format = AUDIO_FORMAT_PCM_8_24_BIT; // ALOGV("openOutput() upgrading format to %#08x", config.format); } if (kEnableExtendedChannels) { // Specify channel mask (uncomment one below to choose) //config->channel_mask = audio_channel_out_mask_from_count(4); // for USB 4ch //config->channel_mask = audio_channel_mask_from_representation_and_bits( // AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1); // another 4ch example } } status_t status = hwDevHal->open_output_stream(hwDevHal, id, Loading @@ -1613,8 +1622,8 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ &outStream); mHardwareStatus = AUDIO_HW_IDLE; ALOGV("openOutput_l() openOutputStream returned output %p, SamplingRate %d, Format %#08x, " "Channels %x, status %d", ALOGV("openOutput() openOutputStream returned output %p, sampleRate %d, Format %#x, " "channelMask %#x, status %d", outStream, config->sample_rate, config->format, Loading @@ -1630,7 +1639,7 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ ALOGV("openOutput() created offload output: ID %d thread %p", id, thread); } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || !isValidPcmSinkFormat(config->format) || (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO)) { || !isValidPcmSinkChannelMask(config->channel_mask)) { thread = new DirectOutputThread(this, output, id, device); ALOGV("openOutput() created direct output: ID %d thread %p", id, thread); } else { Loading Loading @@ -1792,7 +1801,6 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) closeOutputFinish(thread); } thread.clear(); return NO_ERROR; } Loading Loading @@ -2515,6 +2523,16 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, return INVALID_OPERATION; } // Check whether the destination thread has a channel count of FCC_2, which is // currently required for (most) effects. Prevent moving the effect chain here rather // than disabling the addEffect_l() call in dstThread below. if (dstThread->mChannelCount != FCC_2) { ALOGW("moveEffectChain_l() effect chain failed because" " destination thread %p channel count(%u) != %u", dstThread, dstThread->mChannelCount, FCC_2); return INVALID_OPERATION; } // remove chain first. This is useful only if reconfiguring effect chain on same output thread, // so that a new chain is created with correct parameters when first effect is added. This is // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is Loading services/audioflinger/AudioFlinger.h +26 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ #include "FastMixer.h" #include <media/nbaio/NBAIO.h> #include "AudioWatchdog.h" #include "AudioMixer.h" #include <powermanager/IPowerManager.h> Loading Loading @@ -327,6 +328,30 @@ private: audio_devices_t devices); void purgeStaleEffects_l(); // Set kEnableExtendedChannels to true to enable greater than stereo output // for the MixerThread and device sink. Number of channels allowed is // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS. static const bool kEnableExtendedChannels = false; // Returns true if channel mask is permitted for the PCM sink in the MixerThread static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) { switch (audio_channel_mask_get_representation(channelMask)) { case AUDIO_CHANNEL_REPRESENTATION_POSITION: { uint32_t channelCount = FCC_2; // stereo is default if (kEnableExtendedChannels) { channelCount = audio_channel_count_from_out_mask(channelMask); if (channelCount > AudioMixer::MAX_NUM_CHANNELS) { return false; } } // check that channelMask is the "canonical" one we expect for the channelCount. return channelMask == audio_channel_out_mask_from_count(channelCount); } default: return false; } } // Set kEnableExtendedPrecision to true to use extended precision in MixerThread static const bool kEnableExtendedPrecision = true; Loading Loading @@ -565,7 +590,7 @@ private: uint32_t version() const { return mHwDevice->common.version; } private: audio_module_handle_t mHandle; const audio_module_handle_t mHandle; const char * const mModuleName; audio_hw_device_t * const mHwDevice; const Flags mFlags; Loading services/audioflinger/AudioMixer.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <common_time/cc_helper.h> #include <media/EffectsFactoryApi.h> #include <audio_effects/effect_downmix.h> #include "AudioMixerOps.h" #include "AudioMixer.h" Loading Loading @@ -941,7 +942,9 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam // but if none exists, it is the channel count (1 for mono). const int resamplerChannelCount = downmixerBufferProvider != NULL ? mMixerChannelCount : channelCount; ALOGVV("Creating resampler with %#x format\n", mMixerInFormat); ALOGVV("Creating resampler:" " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n", mMixerInFormat, resamplerChannelCount, devSampleRate, quality); resampler = AudioResampler::create( mMixerInFormat, resamplerChannelCount, Loading services/audioflinger/AudioMixer.h +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include <media/AudioBufferProvider.h> #include "AudioResampler.h" #include <audio_effects/effect_downmix.h> #include <hardware/audio_effect.h> #include <system/audio.h> #include <media/nbaio/NBLog.h> Loading services/audioflinger/FastMixer.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ FastMixer::FastMixer() : FastThread(), mixer(NULL), mSinkBuffer(NULL), mSinkBufferSize(0), mSinkChannelCount(FCC_2), mMixerBuffer(NULL), mMixerBufferSize(0), mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT), Loading @@ -71,6 +72,9 @@ FastMixer::FastMixer() : FastThread(), current = &initial; mDummyDumpState = &dummyDumpState; // TODO: Add channel mask to NBAIO_Format. // We assume that the channel mask must be a valid positional channel mask. mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount); unsigned i; for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) { Loading Loading @@ -148,10 +152,17 @@ void FastMixer::onStateChange() if (outputSink == NULL) { format = Format_Invalid; sampleRate = 0; mSinkChannelCount = 0; mSinkChannelMask = AUDIO_CHANNEL_NONE; } else { format = outputSink->format(); sampleRate = Format_sampleRate(format); ALOG_ASSERT(Format_channelCount(format) == FCC_2); mSinkChannelCount = Format_channelCount(format); LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS); // TODO: Add channel mask to NBAIO_Format // We assume that the channel mask must be a valid positional channel mask. mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount); } dumpState->mSampleRate = sampleRate; } Loading @@ -169,10 +180,12 @@ void FastMixer::onStateChange() // implementation; it would be better to have normal mixer allocate for us // to avoid blocking here and to prevent possible priority inversion mixer = new AudioMixer(frameCount, sampleRate, FastMixerState::kMaxFastTracks); const size_t mixerFrameSize = FCC_2 * audio_bytes_per_sample(mMixerBufferFormat); const size_t mixerFrameSize = mSinkChannelCount * audio_bytes_per_sample(mMixerBufferFormat); mMixerBufferSize = mixerFrameSize * frameCount; (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize); const size_t sinkFrameSize = FCC_2 * audio_bytes_per_sample(format.mFormat); const size_t sinkFrameSize = mSinkChannelCount * audio_bytes_per_sample(format.mFormat); if (sinkFrameSize > mixerFrameSize) { // need a sink buffer mSinkBufferSize = sinkFrameSize * frameCount; (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize); Loading Loading @@ -252,6 +265,10 @@ void FastMixer::onStateChange() AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT, (void *)(uintptr_t)fastTrack->mFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)fastTrack->mChannelMask); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mSinkChannelMask); mixer->enable(name); } generations[i] = fastTrack->mGeneration; Loading Loading @@ -287,6 +304,8 @@ void FastMixer::onStateChange() (void *)(uintptr_t)fastTrack->mFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)fastTrack->mChannelMask); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mSinkChannelMask); // already enabled } generations[i] = fastTrack->mGeneration; Loading Loading
services/audioflinger/AudioFlinger.cpp +31 −13 Original line number Diff line number Diff line Loading @@ -1594,16 +1594,25 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ audio_stream_out_t *outStream = NULL; // FOR TESTING ONLY: // Enable increased sink precision for mixing mode if kEnableExtendedPrecision is true. if (kEnableExtendedPrecision && // Check only for Normal Mixing mode !(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { // Update format //config.format = AUDIO_FORMAT_PCM_FLOAT; //config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED; //config.format = AUDIO_FORMAT_PCM_32_BIT; //config.format = AUDIO_FORMAT_PCM_8_24_BIT; // This if statement allows overriding the audio policy settings // and forcing a specific format or channel mask to the HAL/Sink device for testing. if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { // Check only for Normal Mixing mode if (kEnableExtendedPrecision) { // Specify format (uncomment one below to choose) //config->format = AUDIO_FORMAT_PCM_FLOAT; //config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED; //config->format = AUDIO_FORMAT_PCM_32_BIT; //config->format = AUDIO_FORMAT_PCM_8_24_BIT; // ALOGV("openOutput() upgrading format to %#08x", config.format); } if (kEnableExtendedChannels) { // Specify channel mask (uncomment one below to choose) //config->channel_mask = audio_channel_out_mask_from_count(4); // for USB 4ch //config->channel_mask = audio_channel_mask_from_representation_and_bits( // AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1); // another 4ch example } } status_t status = hwDevHal->open_output_stream(hwDevHal, id, Loading @@ -1613,8 +1622,8 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ &outStream); mHardwareStatus = AUDIO_HW_IDLE; ALOGV("openOutput_l() openOutputStream returned output %p, SamplingRate %d, Format %#08x, " "Channels %x, status %d", ALOGV("openOutput() openOutputStream returned output %p, sampleRate %d, Format %#x, " "channelMask %#x, status %d", outStream, config->sample_rate, config->format, Loading @@ -1630,7 +1639,7 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_ ALOGV("openOutput() created offload output: ID %d thread %p", id, thread); } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || !isValidPcmSinkFormat(config->format) || (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO)) { || !isValidPcmSinkChannelMask(config->channel_mask)) { thread = new DirectOutputThread(this, output, id, device); ALOGV("openOutput() created direct output: ID %d thread %p", id, thread); } else { Loading Loading @@ -1792,7 +1801,6 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) closeOutputFinish(thread); } thread.clear(); return NO_ERROR; } Loading Loading @@ -2515,6 +2523,16 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, return INVALID_OPERATION; } // Check whether the destination thread has a channel count of FCC_2, which is // currently required for (most) effects. Prevent moving the effect chain here rather // than disabling the addEffect_l() call in dstThread below. if (dstThread->mChannelCount != FCC_2) { ALOGW("moveEffectChain_l() effect chain failed because" " destination thread %p channel count(%u) != %u", dstThread, dstThread->mChannelCount, FCC_2); return INVALID_OPERATION; } // remove chain first. This is useful only if reconfiguring effect chain on same output thread, // so that a new chain is created with correct parameters when first effect is added. This is // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is Loading
services/audioflinger/AudioFlinger.h +26 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ #include "FastMixer.h" #include <media/nbaio/NBAIO.h> #include "AudioWatchdog.h" #include "AudioMixer.h" #include <powermanager/IPowerManager.h> Loading Loading @@ -327,6 +328,30 @@ private: audio_devices_t devices); void purgeStaleEffects_l(); // Set kEnableExtendedChannels to true to enable greater than stereo output // for the MixerThread and device sink. Number of channels allowed is // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS. static const bool kEnableExtendedChannels = false; // Returns true if channel mask is permitted for the PCM sink in the MixerThread static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) { switch (audio_channel_mask_get_representation(channelMask)) { case AUDIO_CHANNEL_REPRESENTATION_POSITION: { uint32_t channelCount = FCC_2; // stereo is default if (kEnableExtendedChannels) { channelCount = audio_channel_count_from_out_mask(channelMask); if (channelCount > AudioMixer::MAX_NUM_CHANNELS) { return false; } } // check that channelMask is the "canonical" one we expect for the channelCount. return channelMask == audio_channel_out_mask_from_count(channelCount); } default: return false; } } // Set kEnableExtendedPrecision to true to use extended precision in MixerThread static const bool kEnableExtendedPrecision = true; Loading Loading @@ -565,7 +590,7 @@ private: uint32_t version() const { return mHwDevice->common.version; } private: audio_module_handle_t mHandle; const audio_module_handle_t mHandle; const char * const mModuleName; audio_hw_device_t * const mHwDevice; const Flags mFlags; Loading
services/audioflinger/AudioMixer.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <common_time/cc_helper.h> #include <media/EffectsFactoryApi.h> #include <audio_effects/effect_downmix.h> #include "AudioMixerOps.h" #include "AudioMixer.h" Loading Loading @@ -941,7 +942,9 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam // but if none exists, it is the channel count (1 for mono). const int resamplerChannelCount = downmixerBufferProvider != NULL ? mMixerChannelCount : channelCount; ALOGVV("Creating resampler with %#x format\n", mMixerInFormat); ALOGVV("Creating resampler:" " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n", mMixerInFormat, resamplerChannelCount, devSampleRate, quality); resampler = AudioResampler::create( mMixerInFormat, resamplerChannelCount, Loading
services/audioflinger/AudioMixer.h +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include <media/AudioBufferProvider.h> #include "AudioResampler.h" #include <audio_effects/effect_downmix.h> #include <hardware/audio_effect.h> #include <system/audio.h> #include <media/nbaio/NBLog.h> Loading
services/audioflinger/FastMixer.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ FastMixer::FastMixer() : FastThread(), mixer(NULL), mSinkBuffer(NULL), mSinkBufferSize(0), mSinkChannelCount(FCC_2), mMixerBuffer(NULL), mMixerBufferSize(0), mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT), Loading @@ -71,6 +72,9 @@ FastMixer::FastMixer() : FastThread(), current = &initial; mDummyDumpState = &dummyDumpState; // TODO: Add channel mask to NBAIO_Format. // We assume that the channel mask must be a valid positional channel mask. mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount); unsigned i; for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) { Loading Loading @@ -148,10 +152,17 @@ void FastMixer::onStateChange() if (outputSink == NULL) { format = Format_Invalid; sampleRate = 0; mSinkChannelCount = 0; mSinkChannelMask = AUDIO_CHANNEL_NONE; } else { format = outputSink->format(); sampleRate = Format_sampleRate(format); ALOG_ASSERT(Format_channelCount(format) == FCC_2); mSinkChannelCount = Format_channelCount(format); LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS); // TODO: Add channel mask to NBAIO_Format // We assume that the channel mask must be a valid positional channel mask. mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount); } dumpState->mSampleRate = sampleRate; } Loading @@ -169,10 +180,12 @@ void FastMixer::onStateChange() // implementation; it would be better to have normal mixer allocate for us // to avoid blocking here and to prevent possible priority inversion mixer = new AudioMixer(frameCount, sampleRate, FastMixerState::kMaxFastTracks); const size_t mixerFrameSize = FCC_2 * audio_bytes_per_sample(mMixerBufferFormat); const size_t mixerFrameSize = mSinkChannelCount * audio_bytes_per_sample(mMixerBufferFormat); mMixerBufferSize = mixerFrameSize * frameCount; (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize); const size_t sinkFrameSize = FCC_2 * audio_bytes_per_sample(format.mFormat); const size_t sinkFrameSize = mSinkChannelCount * audio_bytes_per_sample(format.mFormat); if (sinkFrameSize > mixerFrameSize) { // need a sink buffer mSinkBufferSize = sinkFrameSize * frameCount; (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize); Loading Loading @@ -252,6 +265,10 @@ void FastMixer::onStateChange() AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT, (void *)(uintptr_t)fastTrack->mFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)fastTrack->mChannelMask); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mSinkChannelMask); mixer->enable(name); } generations[i] = fastTrack->mGeneration; Loading Loading @@ -287,6 +304,8 @@ void FastMixer::onStateChange() (void *)(uintptr_t)fastTrack->mFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)fastTrack->mChannelMask); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mSinkChannelMask); // already enabled } generations[i] = fastTrack->mGeneration; Loading