Loading media/libaudioclient/include/media/AudioMixer.h +39 −42 Original line number Diff line number Diff line Loading @@ -46,10 +46,6 @@ namespace android { class AudioMixer { public: // This mixer has a hard-coded upper limit of active track inputs; // the value is arbitrary but should be less than TRACK0 to avoid confusion. static constexpr int32_t MAX_NUM_TRACKS = 256; // Do not change these unless underlying code changes. // This mixer has a hard-coded upper limit of 8 channels for output. static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8; Loading @@ -61,12 +57,6 @@ public: static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f; enum { // names // track names (MAX_NUM_TRACKS units) TRACK0 = 0x1000, // 0x2000 is unused // setParameter targets TRACK = 0x3000, RESAMPLE = 0x3001, Loading Loading @@ -105,23 +95,33 @@ public: // parameter 'value' is a pointer to the new playback rate. }; AudioMixer(size_t frameCount, uint32_t sampleRate, int32_t maxNumTracks = MAX_NUM_TRACKS) : mMaxNumTracks(maxNumTracks) , mSampleRate(sampleRate) AudioMixer(size_t frameCount, uint32_t sampleRate) : mSampleRate(sampleRate) , mFrameCount(frameCount) { pthread_once(&sOnceControl, &sInitRoutine); } // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS // Allocate a track name. Returns new track name if successful, -1 on failure. // The failure could be because of an invalid channelMask or format, or that // the track capacity of the mixer is exceeded. int getTrackName(audio_channel_mask_t channelMask, audio_format_t format, int sessionId); // Create a new track in the mixer. // // \param name a unique user-provided integer associated with the track. // If name already exists, the function will abort. // \param channelMask output channel mask. // \param format PCM format // \param sessionId Session id for the track. Tracks with the same // session id will be submixed together. // // \return OK on success. // BAD_VALUE if the format does not satisfy isValidFormat() // or the channelMask does not satisfy isValidChannelMask(). status_t create( int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId); bool exists(int name) const { return mTracks.count(name) > 0; } // Free an allocated track by name void deleteTrackName(int name); // Free an allocated track by name. void destroy(int name); // Enable or disable an allocated track by name void enable(int name); Loading Loading @@ -149,6 +149,23 @@ public: mNBLogWriter = logWriter; } static inline bool isValidFormat(audio_format_t format) { switch (format) { case AUDIO_FORMAT_PCM_8_BIT: case AUDIO_FORMAT_PCM_16_BIT: case AUDIO_FORMAT_PCM_24_BIT_PACKED: case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_FLOAT: return true; default: return false; } } static inline bool isValidChannelMask(audio_channel_mask_t channelMask) { return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible. } private: /* For multi-format functions (calls template functions Loading Loading @@ -361,23 +378,9 @@ private: static void convertMixerFormat(void *out, audio_format_t mixerOutFormat, void *in, audio_format_t mixerInFormat, size_t sampleCount); static inline bool isValidPcmTrackFormat(audio_format_t format) { switch (format) { case AUDIO_FORMAT_PCM_8_BIT: case AUDIO_FORMAT_PCM_16_BIT: case AUDIO_FORMAT_PCM_24_BIT_PACKED: case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_FLOAT: return true; default: return false; } } static void sInitRoutine(); // initialization constants const int mMaxNumTracks; const uint32_t mSampleRate; const size_t mFrameCount; Loading @@ -390,12 +393,6 @@ private: std::unique_ptr<int32_t[]> mOutputTemp; std::unique_ptr<int32_t[]> mResampleTemp; // fast lookup of previously deleted track names for reuse. // the AudioMixer tries to return the smallest unused name - // this is an arbitrary decision (actually any non-negative // integer that isn't in mTracks could be used). std::set<int /* name */> mUnusedNames; // set of unused track names (may be empty) // track names grouped by main buffer, in no particular order of main buffer. // however names for a particular main buffer are in order (by construction). std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups; Loading media/libaudioprocessing/AudioMixer.cpp +21 −38 Original line number Diff line number Diff line Loading @@ -90,34 +90,21 @@ static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __un return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT; } int AudioMixer::getTrackName( audio_channel_mask_t channelMask, audio_format_t format, int sessionId) status_t AudioMixer::create( int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId) { if (!isValidPcmTrackFormat(format)) { ALOGE("AudioMixer::getTrackName invalid format (%#x)", format); return -1; } if (mTracks.size() >= (size_t)mMaxNumTracks) { ALOGE("%s: out of track names (max = %d)", __func__, mMaxNumTracks); return -1; } // get a new name for the track. int name; if (mUnusedNames.size() != 0) { // reuse first name for deleted track. auto it = mUnusedNames.begin(); name = *it; (void)mUnusedNames.erase(it); } else { // we're fully populated, so create a new name. name = mTracks.size(); LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name); if (!isValidChannelMask(channelMask)) { ALOGE("%s invalid channelMask: %#x", __func__, channelMask); return BAD_VALUE; } if (!isValidFormat(format)) { ALOGE("%s invalid format: %#x", __func__, format); return BAD_VALUE; } ALOGV("add track (%d)", name); auto t = std::make_shared<Track>(); mTracks[name] = t; { // TODO: move initialization to the Track constructor. // assume default parameters for the track, except where noted below Loading Loading @@ -179,12 +166,14 @@ int AudioMixer::getTrackName( status_t status = t->prepareForDownmix(); if (status != OK) { ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask); return -1; return BAD_VALUE; } // prepareForDownmix() may change mDownmixRequiresFormat ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat); t->prepareForReformat(); return TRACK0 + name; mTracks[name] = t; return OK; } } Loading @@ -193,7 +182,7 @@ int AudioMixer::getTrackName( // which will simplify this logic. bool AudioMixer::setChannelMasks(int name, audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) { LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (trackChannelMask == track->channelMask Loading Loading @@ -361,23 +350,20 @@ void AudioMixer::Track::reconfigureBufferProviders() } } void AudioMixer::deleteTrackName(int name) void AudioMixer::destroy(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); ALOGV("deleteTrackName(%d)", name); if (mTracks[name]->enabled) { invalidate(); } mTracks.erase(name); // deallocate track mUnusedNames.emplace(name); // recycle name } void AudioMixer::enable(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (!track->enabled) { Loading @@ -389,8 +375,7 @@ void AudioMixer::enable(int name) void AudioMixer::disable(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (track->enabled) { Loading Loading @@ -528,8 +513,7 @@ static inline bool setVolumeRampVariables(float newVolume, int32_t ramp, void AudioMixer::setParameter(int name, int target, int param, void *value) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value)); Loading Loading @@ -808,7 +792,6 @@ inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat) size_t AudioMixer::getUnreleasedFrames(int name) const { name -= TRACK0; const auto it = mTracks.find(name); if (it != mTracks.end()) { return it->second->getUnreleasedFrames(); Loading @@ -818,7 +801,7 @@ size_t AudioMixer::getUnreleasedFrames(int name) const void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (track->mInputBufferProvider == bufferProvider) { Loading media/libaudioprocessing/tests/test-mixer.cpp +8 −9 Original line number Diff line number Diff line Loading @@ -143,10 +143,6 @@ int main(int argc, char* argv[]) { usage(progname); return EXIT_FAILURE; } if ((unsigned)argc > AudioMixer::MAX_NUM_TRACKS) { fprintf(stderr, "too many tracks: %d > %u", argc, AudioMixer::MAX_NUM_TRACKS); return EXIT_FAILURE; } size_t outputFrames = 0; Loading Loading @@ -246,9 +242,10 @@ int main(int argc, char* argv[]) { for (size_t i = 0; i < providers.size(); ++i) { //printf("track %d out of %d\n", i, providers.size()); uint32_t channelMask = audio_channel_out_mask_from_count(providers[i].getNumChannels()); int32_t name = mixer->getTrackName(channelMask, formats[i], AUDIO_SESSION_OUTPUT_MIX); ALOG_ASSERT(name >= 0); const int name = i; const status_t status = mixer->create( name, channelMask, formats[i], AUDIO_SESSION_OUTPUT_MIX); LOG_ALWAYS_FATAL_IF(status != OK); names[i] = name; mixer->setBufferProvider(name, &providers[i]); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, Loading Loading @@ -315,8 +312,10 @@ int main(int argc, char* argv[]) { writeFile(outputFilename, outputAddr, outputSampleRate, outputChannels, outputFrames, useMixerFloat); if (auxFilename) { // Aux buffer is always in q4_27 format for now. memcpy_to_i16_from_q4_27((int16_t*)auxAddr, (const int32_t*)auxAddr, outputFrames); // Aux buffer is always in q4_27 format for O and earlier. // memcpy_to_i16_from_q4_27((int16_t*)auxAddr, (const int32_t*)auxAddr, outputFrames); // Aux buffer is always in float format for P. memcpy_to_i16_from_float((int16_t*)auxAddr, (const float*)auxAddr, outputFrames); writeFile(auxFilename, auxAddr, outputSampleRate, 1, outputFrames, false); } Loading services/audioflinger/FastMixer.cpp +13 −13 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ FastMixer::FastMixer() : FastThread("cycle_ms", "load_us"), unsigned i; for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) { mFastTrackNames[i] = -1; mGenerations[i] = 0; } #ifdef FAST_THREAD_STATISTICS Loading Loading @@ -190,7 +189,7 @@ void FastMixer::onStateChange() // FIXME new may block for unbounded time at internal mutex of the heap // implementation; it would be better to have normal mixer allocate for us // to avoid blocking here and to prevent possible priority inversion mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks); mMixer = new AudioMixer(frameCount, mSampleRate); // FIXME See the other FIXME at FastMixer::setNBLogWriter() const size_t mixerFrameSize = mSinkChannelCount * audio_bytes_per_sample(mMixerBufferFormat); Loading Loading @@ -235,7 +234,6 @@ void FastMixer::onStateChange() dumpState->mTrackMask = currentTrackMask; if (current->mFastTracksGen != mFastTracksGen) { ALOG_ASSERT(mMixerBuffer != NULL); int name; // process removed tracks first to avoid running out of track names unsigned removedTracks = previousTrackMask & ~currentTrackMask; Loading @@ -245,9 +243,7 @@ void FastMixer::onStateChange() const FastTrack* fastTrack = ¤t->mFastTracks[i]; ALOG_ASSERT(fastTrack->mBufferProvider == NULL); if (mMixer != NULL) { name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); mMixer->deleteTrackName(name); mMixer->destroy(i); } #if !LOG_NDEBUG mFastTrackNames[i] = -1; Loading @@ -265,10 +261,16 @@ void FastMixer::onStateChange() AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1); if (mMixer != NULL) { name = mMixer->getTrackName(fastTrack->mChannelMask, const int name = i; // for clarity, choose name as fast track index. status_t status = mMixer->create( name, fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX); ALOG_ASSERT(name >= 0); mFastTrackNames[i] = name; LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "%s: cannot create track name" " %d, mask %#x, format %#x, sessionId %d in AudioMixer", __func__, name, fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX); mMixer->setBufferProvider(name, bufferProvider); mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *)mMixerBuffer); Loading Loading @@ -300,8 +302,7 @@ void FastMixer::onStateChange() AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; ALOG_ASSERT(bufferProvider != NULL); if (mMixer != NULL) { name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); const int name = i; mMixer->setBufferProvider(name, bufferProvider); if (fastTrack->mVolumeProvider == NULL) { float f = AudioMixer::UNITY_GAIN_FLOAT; Loading Loading @@ -378,8 +379,7 @@ void FastMixer::onWork() perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten; fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp); int name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); const int name = i; if (fastTrack->mVolumeProvider != NULL) { gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR(); float vlf = float_from_gain(gain_minifloat_unpack_left(vlr)); Loading services/audioflinger/FastMixer.h +0 −2 Original line number Diff line number Diff line Loading @@ -57,8 +57,6 @@ private: static const FastMixerState sInitial; FastMixerState mPreIdle; // copy of state before we went into idle int mFastTrackNames[FastMixerState::kMaxFastTracks]; // handles used by mixer to identify tracks int mGenerations[FastMixerState::kMaxFastTracks]; // last observed mFastTracks[i].mGeneration NBAIO_Sink* mOutputSink; Loading Loading
media/libaudioclient/include/media/AudioMixer.h +39 −42 Original line number Diff line number Diff line Loading @@ -46,10 +46,6 @@ namespace android { class AudioMixer { public: // This mixer has a hard-coded upper limit of active track inputs; // the value is arbitrary but should be less than TRACK0 to avoid confusion. static constexpr int32_t MAX_NUM_TRACKS = 256; // Do not change these unless underlying code changes. // This mixer has a hard-coded upper limit of 8 channels for output. static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8; Loading @@ -61,12 +57,6 @@ public: static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f; enum { // names // track names (MAX_NUM_TRACKS units) TRACK0 = 0x1000, // 0x2000 is unused // setParameter targets TRACK = 0x3000, RESAMPLE = 0x3001, Loading Loading @@ -105,23 +95,33 @@ public: // parameter 'value' is a pointer to the new playback rate. }; AudioMixer(size_t frameCount, uint32_t sampleRate, int32_t maxNumTracks = MAX_NUM_TRACKS) : mMaxNumTracks(maxNumTracks) , mSampleRate(sampleRate) AudioMixer(size_t frameCount, uint32_t sampleRate) : mSampleRate(sampleRate) , mFrameCount(frameCount) { pthread_once(&sOnceControl, &sInitRoutine); } // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS // Allocate a track name. Returns new track name if successful, -1 on failure. // The failure could be because of an invalid channelMask or format, or that // the track capacity of the mixer is exceeded. int getTrackName(audio_channel_mask_t channelMask, audio_format_t format, int sessionId); // Create a new track in the mixer. // // \param name a unique user-provided integer associated with the track. // If name already exists, the function will abort. // \param channelMask output channel mask. // \param format PCM format // \param sessionId Session id for the track. Tracks with the same // session id will be submixed together. // // \return OK on success. // BAD_VALUE if the format does not satisfy isValidFormat() // or the channelMask does not satisfy isValidChannelMask(). status_t create( int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId); bool exists(int name) const { return mTracks.count(name) > 0; } // Free an allocated track by name void deleteTrackName(int name); // Free an allocated track by name. void destroy(int name); // Enable or disable an allocated track by name void enable(int name); Loading Loading @@ -149,6 +149,23 @@ public: mNBLogWriter = logWriter; } static inline bool isValidFormat(audio_format_t format) { switch (format) { case AUDIO_FORMAT_PCM_8_BIT: case AUDIO_FORMAT_PCM_16_BIT: case AUDIO_FORMAT_PCM_24_BIT_PACKED: case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_FLOAT: return true; default: return false; } } static inline bool isValidChannelMask(audio_channel_mask_t channelMask) { return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible. } private: /* For multi-format functions (calls template functions Loading Loading @@ -361,23 +378,9 @@ private: static void convertMixerFormat(void *out, audio_format_t mixerOutFormat, void *in, audio_format_t mixerInFormat, size_t sampleCount); static inline bool isValidPcmTrackFormat(audio_format_t format) { switch (format) { case AUDIO_FORMAT_PCM_8_BIT: case AUDIO_FORMAT_PCM_16_BIT: case AUDIO_FORMAT_PCM_24_BIT_PACKED: case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_FLOAT: return true; default: return false; } } static void sInitRoutine(); // initialization constants const int mMaxNumTracks; const uint32_t mSampleRate; const size_t mFrameCount; Loading @@ -390,12 +393,6 @@ private: std::unique_ptr<int32_t[]> mOutputTemp; std::unique_ptr<int32_t[]> mResampleTemp; // fast lookup of previously deleted track names for reuse. // the AudioMixer tries to return the smallest unused name - // this is an arbitrary decision (actually any non-negative // integer that isn't in mTracks could be used). std::set<int /* name */> mUnusedNames; // set of unused track names (may be empty) // track names grouped by main buffer, in no particular order of main buffer. // however names for a particular main buffer are in order (by construction). std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups; Loading
media/libaudioprocessing/AudioMixer.cpp +21 −38 Original line number Diff line number Diff line Loading @@ -90,34 +90,21 @@ static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __un return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT; } int AudioMixer::getTrackName( audio_channel_mask_t channelMask, audio_format_t format, int sessionId) status_t AudioMixer::create( int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId) { if (!isValidPcmTrackFormat(format)) { ALOGE("AudioMixer::getTrackName invalid format (%#x)", format); return -1; } if (mTracks.size() >= (size_t)mMaxNumTracks) { ALOGE("%s: out of track names (max = %d)", __func__, mMaxNumTracks); return -1; } // get a new name for the track. int name; if (mUnusedNames.size() != 0) { // reuse first name for deleted track. auto it = mUnusedNames.begin(); name = *it; (void)mUnusedNames.erase(it); } else { // we're fully populated, so create a new name. name = mTracks.size(); LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name); if (!isValidChannelMask(channelMask)) { ALOGE("%s invalid channelMask: %#x", __func__, channelMask); return BAD_VALUE; } if (!isValidFormat(format)) { ALOGE("%s invalid format: %#x", __func__, format); return BAD_VALUE; } ALOGV("add track (%d)", name); auto t = std::make_shared<Track>(); mTracks[name] = t; { // TODO: move initialization to the Track constructor. // assume default parameters for the track, except where noted below Loading Loading @@ -179,12 +166,14 @@ int AudioMixer::getTrackName( status_t status = t->prepareForDownmix(); if (status != OK) { ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask); return -1; return BAD_VALUE; } // prepareForDownmix() may change mDownmixRequiresFormat ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat); t->prepareForReformat(); return TRACK0 + name; mTracks[name] = t; return OK; } } Loading @@ -193,7 +182,7 @@ int AudioMixer::getTrackName( // which will simplify this logic. bool AudioMixer::setChannelMasks(int name, audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) { LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (trackChannelMask == track->channelMask Loading Loading @@ -361,23 +350,20 @@ void AudioMixer::Track::reconfigureBufferProviders() } } void AudioMixer::deleteTrackName(int name) void AudioMixer::destroy(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); ALOGV("deleteTrackName(%d)", name); if (mTracks[name]->enabled) { invalidate(); } mTracks.erase(name); // deallocate track mUnusedNames.emplace(name); // recycle name } void AudioMixer::enable(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (!track->enabled) { Loading @@ -389,8 +375,7 @@ void AudioMixer::enable(int name) void AudioMixer::disable(int name) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (track->enabled) { Loading Loading @@ -528,8 +513,7 @@ static inline bool setVolumeRampVariables(float newVolume, int32_t ramp, void AudioMixer::setParameter(int name, int target, int param, void *value) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name); LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value)); Loading Loading @@ -808,7 +792,6 @@ inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat) size_t AudioMixer::getUnreleasedFrames(int name) const { name -= TRACK0; const auto it = mTracks.find(name); if (it != mTracks.end()) { return it->second->getUnreleasedFrames(); Loading @@ -818,7 +801,7 @@ size_t AudioMixer::getUnreleasedFrames(int name) const void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider) { name -= TRACK0; LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name); const std::shared_ptr<Track> &track = mTracks[name]; if (track->mInputBufferProvider == bufferProvider) { Loading
media/libaudioprocessing/tests/test-mixer.cpp +8 −9 Original line number Diff line number Diff line Loading @@ -143,10 +143,6 @@ int main(int argc, char* argv[]) { usage(progname); return EXIT_FAILURE; } if ((unsigned)argc > AudioMixer::MAX_NUM_TRACKS) { fprintf(stderr, "too many tracks: %d > %u", argc, AudioMixer::MAX_NUM_TRACKS); return EXIT_FAILURE; } size_t outputFrames = 0; Loading Loading @@ -246,9 +242,10 @@ int main(int argc, char* argv[]) { for (size_t i = 0; i < providers.size(); ++i) { //printf("track %d out of %d\n", i, providers.size()); uint32_t channelMask = audio_channel_out_mask_from_count(providers[i].getNumChannels()); int32_t name = mixer->getTrackName(channelMask, formats[i], AUDIO_SESSION_OUTPUT_MIX); ALOG_ASSERT(name >= 0); const int name = i; const status_t status = mixer->create( name, channelMask, formats[i], AUDIO_SESSION_OUTPUT_MIX); LOG_ALWAYS_FATAL_IF(status != OK); names[i] = name; mixer->setBufferProvider(name, &providers[i]); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, Loading Loading @@ -315,8 +312,10 @@ int main(int argc, char* argv[]) { writeFile(outputFilename, outputAddr, outputSampleRate, outputChannels, outputFrames, useMixerFloat); if (auxFilename) { // Aux buffer is always in q4_27 format for now. memcpy_to_i16_from_q4_27((int16_t*)auxAddr, (const int32_t*)auxAddr, outputFrames); // Aux buffer is always in q4_27 format for O and earlier. // memcpy_to_i16_from_q4_27((int16_t*)auxAddr, (const int32_t*)auxAddr, outputFrames); // Aux buffer is always in float format for P. memcpy_to_i16_from_float((int16_t*)auxAddr, (const float*)auxAddr, outputFrames); writeFile(auxFilename, auxAddr, outputSampleRate, 1, outputFrames, false); } Loading
services/audioflinger/FastMixer.cpp +13 −13 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ FastMixer::FastMixer() : FastThread("cycle_ms", "load_us"), unsigned i; for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) { mFastTrackNames[i] = -1; mGenerations[i] = 0; } #ifdef FAST_THREAD_STATISTICS Loading Loading @@ -190,7 +189,7 @@ void FastMixer::onStateChange() // FIXME new may block for unbounded time at internal mutex of the heap // implementation; it would be better to have normal mixer allocate for us // to avoid blocking here and to prevent possible priority inversion mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks); mMixer = new AudioMixer(frameCount, mSampleRate); // FIXME See the other FIXME at FastMixer::setNBLogWriter() const size_t mixerFrameSize = mSinkChannelCount * audio_bytes_per_sample(mMixerBufferFormat); Loading Loading @@ -235,7 +234,6 @@ void FastMixer::onStateChange() dumpState->mTrackMask = currentTrackMask; if (current->mFastTracksGen != mFastTracksGen) { ALOG_ASSERT(mMixerBuffer != NULL); int name; // process removed tracks first to avoid running out of track names unsigned removedTracks = previousTrackMask & ~currentTrackMask; Loading @@ -245,9 +243,7 @@ void FastMixer::onStateChange() const FastTrack* fastTrack = ¤t->mFastTracks[i]; ALOG_ASSERT(fastTrack->mBufferProvider == NULL); if (mMixer != NULL) { name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); mMixer->deleteTrackName(name); mMixer->destroy(i); } #if !LOG_NDEBUG mFastTrackNames[i] = -1; Loading @@ -265,10 +261,16 @@ void FastMixer::onStateChange() AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1); if (mMixer != NULL) { name = mMixer->getTrackName(fastTrack->mChannelMask, const int name = i; // for clarity, choose name as fast track index. status_t status = mMixer->create( name, fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX); ALOG_ASSERT(name >= 0); mFastTrackNames[i] = name; LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "%s: cannot create track name" " %d, mask %#x, format %#x, sessionId %d in AudioMixer", __func__, name, fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX); mMixer->setBufferProvider(name, bufferProvider); mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *)mMixerBuffer); Loading Loading @@ -300,8 +302,7 @@ void FastMixer::onStateChange() AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; ALOG_ASSERT(bufferProvider != NULL); if (mMixer != NULL) { name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); const int name = i; mMixer->setBufferProvider(name, bufferProvider); if (fastTrack->mVolumeProvider == NULL) { float f = AudioMixer::UNITY_GAIN_FLOAT; Loading Loading @@ -378,8 +379,7 @@ void FastMixer::onWork() perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten; fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp); int name = mFastTrackNames[i]; ALOG_ASSERT(name >= 0); const int name = i; if (fastTrack->mVolumeProvider != NULL) { gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR(); float vlf = float_from_gain(gain_minifloat_unpack_left(vlr)); Loading
services/audioflinger/FastMixer.h +0 −2 Original line number Diff line number Diff line Loading @@ -57,8 +57,6 @@ private: static const FastMixerState sInitial; FastMixerState mPreIdle; // copy of state before we went into idle int mFastTrackNames[FastMixerState::kMaxFastTracks]; // handles used by mixer to identify tracks int mGenerations[FastMixerState::kMaxFastTracks]; // last observed mFastTracks[i].mGeneration NBAIO_Sink* mOutputSink; Loading