Loading services/audioflinger/AudioMixer.cpp +298 −131 File changed.Preview size limit exceeded, changes collapsed. Show changes services/audioflinger/AudioMixer.h +25 −20 Original line number Diff line number Diff line Loading @@ -51,12 +51,11 @@ public: static const uint32_t MAX_NUM_TRACKS = 32; // maximum number of channels supported by the mixer // This mixer has a hard-coded upper limit of 2 channels for output. // There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect. // Adding support for > 2 channel output would require more than simply changing this value. static const uint32_t MAX_NUM_CHANNELS = 2; // This mixer has a hard-coded upper limit of 8 channels for output. static const uint32_t MAX_NUM_CHANNELS = 8; static const uint32_t MAX_NUM_VOLUMES = 2; // stereo volume only // maximum number of channels supported for the content static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = 8; static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX; static const uint16_t UNITY_GAIN_INT = 0x1000; static const float UNITY_GAIN_FLOAT = 1.0f; Loading @@ -82,6 +81,7 @@ public: AUX_BUFFER = 0x4003, DOWNMIX_TYPE = 0X4004, MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT) MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output // for target RESAMPLE SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; // parameter 'value' is the new sample rate in Hz. Loading Loading @@ -164,15 +164,15 @@ private: // TODO: Eventually remove legacy integer volume settings union { int16_t volume[MAX_NUM_CHANNELS]; // U4.12 fixed point (top bit should be zero) int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero) int32_t volumeRL; }; int32_t prevVolume[MAX_NUM_CHANNELS]; int32_t prevVolume[MAX_NUM_VOLUMES]; // 16-byte boundary int32_t volumeInc[MAX_NUM_CHANNELS]; int32_t volumeInc[MAX_NUM_VOLUMES]; int32_t auxInc; int32_t prevAuxLevel; Loading Loading @@ -217,18 +217,20 @@ private: audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT) // each track must be converted to this format. float mVolume[MAX_NUM_CHANNELS]; // floating point set volume float mPrevVolume[MAX_NUM_CHANNELS]; // floating point previous volume float mVolumeInc[MAX_NUM_CHANNELS]; // floating point volume increment float mVolume[MAX_NUM_VOLUMES]; // floating point set volume float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment float mAuxLevel; // floating point set aux level float mPrevAuxLevel; // floating point prev aux level float mAuxInc; // floating point aux increment // 16-byte boundary audio_channel_mask_t mMixerChannelMask; uint32_t mMixerChannelCount; bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; } bool setResampler(uint32_t sampleRate, uint32_t devSampleRate); bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate); bool doesResample() const { return resampler != NULL; } void resetResampler() { if (resampler != NULL) resampler->reset(); } void adjustVolumeRamp(bool aux, bool useFloat = false); Loading Loading @@ -377,7 +379,11 @@ private: // OK to call more often than that, but unnecessary. void invalidateState(uint32_t mask); static status_t initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask); bool setChannelMasks(int name, audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask); // TODO: remove unused trackName/trackNum from functions below. static status_t initTrackDownmix(track_t* pTrack, int trackName); static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum); static void unprepareTrackForDownmix(track_t* pTrack, int trackName); static status_t prepareTrackForReformat(track_t* pTrack, int trackNum); Loading Loading @@ -418,27 +424,26 @@ private: * in AudioMixerOps.h). The template parameters are as follows: * * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration) * NCHAN (number of channels, 2 for now) * USEFLOATVOL (set to true if float volume is used) * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards) * TO: int32_t (Q4.27) or float * TI: int32_t (Q4.27) or int16_t (Q0.15) or float * TA: int32_t (Q4.27) */ template <int MIXTYPE, int NCHAN, bool USEFLOATVOL, bool ADJUSTVOL, template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL, typename TO, typename TI, typename TA> static void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t); // multi-format process hooks template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void process_NoResampleOneTrack(state_t* state, int64_t pts); // multi-format track hooks template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void track__Resample(track_t* t, TO* out, size_t frameCount, TO* temp __unused, TA* aux); template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void track__NoResample(track_t* t, TO* out, size_t frameCount, TO* temp __unused, TA* aux); Loading @@ -457,9 +462,9 @@ private: }; // functions for determining the proper process and track hooks. static process_hook_t getProcessHook(int processType, int channels, static process_hook_t getProcessHook(int processType, uint32_t channelCount, audio_format_t mixerInFormat, audio_format_t mixerOutFormat); static hook_t getTrackHook(int trackType, int channels, static hook_t getTrackHook(int trackType, uint32_t channelCount, audio_format_t mixerInFormat, audio_format_t mixerOutFormat); }; Loading services/audioflinger/AudioMixerOps.h +67 −14 Original line number Diff line number Diff line Loading @@ -230,6 +230,8 @@ enum { MIXTYPE_MULTI, MIXTYPE_MONOEXPAND, MIXTYPE_MULTI_SAVEONLY, MIXTYPE_MULTI_MONOVOL, MIXTYPE_MULTI_SAVEONLY_MONOVOL, }; /* Loading Loading @@ -263,6 +265,13 @@ enum { * vol: represents a volume array. * * MIXTYPE_MULTI_SAVEONLY does not accumulate into the out pointer. * * MIXTYPE_MULTI_MONOVOL: * Same as MIXTYPE_MULTI, but uses only volume[0]. * * MIXTYPE_MULTI_SAVEONLY_MONOVOL: * Same as MIXTYPE_MULTI_SAVEONLY, but uses only volume[0]. * */ template <int MIXTYPE, int NCHAN, Loading @@ -283,18 +292,30 @@ inline void volumeRampMulti(TO* out, size_t frameCount, vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); vol[i] += volinc[i]; } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); vol[i] += volinc[i]; *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } in++; vol[0] += volinc[0]; break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } vol[0] += volinc[0]; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -313,18 +334,30 @@ inline void volumeRampMulti(TO* out, size_t frameCount, vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); vol[i] += volinc[i]; } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); vol[i] += volinc[i]; *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); } in++; vol[0] += volinc[0]; break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); } vol[0] += volinc[0]; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -351,16 +384,26 @@ inline void volumeMulti(TO* out, size_t frameCount, *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } in++; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -377,16 +420,26 @@ inline void volumeMulti(TO* out, size_t frameCount, *out++ += MixMul<TO, TI, TV>(*in++, vol[i]); } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); } break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); } in++; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading services/audioflinger/tests/mixer_to_wav_tests.sh +2 −2 Original line number Diff line number Diff line Loading @@ -72,9 +72,9 @@ function createwav() { # track__Resample / track__genericResample # track__NoResample / track__16BitsStereo / track__16BitsMono # Aux buffer adb shell test-mixer $1 -s 9307 \ adb shell test-mixer $1 -c 5 -s 9307 \ -a /sdcard/aux9307gra.wav -o /sdcard/tm9307gra.wav \ sine:2,1000,3000 sine:1,2000,9307 chirp:2,9307 sine:4,1000,3000 sine:1,2000,9307 chirp:3,9307 adb pull /sdcard/tm9307gra.wav $2 adb pull /sdcard/aux9307gra.wav $2 Loading services/audioflinger/tests/test-mixer.cpp +26 −6 Original line number Diff line number Diff line Loading @@ -36,11 +36,12 @@ using namespace android; static void usage(const char* name) { fprintf(stderr, "Usage: %s [-f] [-m]" fprintf(stderr, "Usage: %s [-f] [-m] [-c channels]" " [-s sample-rate] [-o <output-file>] [-a <aux-buffer-file>] [-P csv]" " (<input-file> | <command>)+\n", name); fprintf(stderr, " -f enable floating point input track\n"); fprintf(stderr, " -m enable floating point mixer output\n"); fprintf(stderr, " -c number of mixer output channels\n"); fprintf(stderr, " -s mixer sample-rate\n"); fprintf(stderr, " -o <output-file> WAV file, pcm16 (or float if -m specified)\n"); fprintf(stderr, " -a <aux-buffer-file>\n"); Loading Loading @@ -90,7 +91,7 @@ int main(int argc, char* argv[]) { std::vector<int32_t> Names; std::vector<SignalProvider> Providers; for (int ch; (ch = getopt(argc, argv, "fms:o:a:P:")) != -1;) { for (int ch; (ch = getopt(argc, argv, "fmc:s:o:a:P:")) != -1;) { switch (ch) { case 'f': useInputFloat = true; Loading @@ -98,6 +99,9 @@ int main(int argc, char* argv[]) { case 'm': useMixerFloat = true; break; case 'c': outputChannels = atoi(optarg); break; case 's': outputSampleRate = atoi(optarg); break; Loading Loading @@ -160,7 +164,7 @@ int main(int argc, char* argv[]) { parseCSV(argv[i] + strlen(sine), v); if (v.size() == 3) { printf("creating sine(%d %d)\n", v[0], v[1]); printf("creating sine(%d %d %d)\n", v[0], v[1], v[2]); if (useInputFloat) { Providers[i].setSine<float>(v[0], v[1], v[2], kSeconds); } else { Loading Loading @@ -191,6 +195,8 @@ int main(int argc, char* argv[]) { const size_t outputFrameSize = outputChannels * (useMixerFloat ? sizeof(float) : sizeof(int16_t)); const size_t outputSize = outputFrames * outputFrameSize; const audio_channel_mask_t outputChannelMask = audio_channel_out_mask_from_count(outputChannels); void *outputAddr = NULL; (void) posix_memalign(&outputAddr, 32, outputSize); memset(outputAddr, 0, outputSize); Loading Loading @@ -228,9 +234,23 @@ int main(int argc, char* argv[]) { mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::MIXER_FORMAT, (void *)mixerFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT, AudioMixer::MIXER_FORMAT, (void *)(uintptr_t)mixerFormat); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::FORMAT, (void *)(uintptr_t)inputFormat); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)outputChannelMask); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)channelMask); mixer->setParameter( name, AudioMixer::RESAMPLE, Loading Loading
services/audioflinger/AudioMixer.cpp +298 −131 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/audioflinger/AudioMixer.h +25 −20 Original line number Diff line number Diff line Loading @@ -51,12 +51,11 @@ public: static const uint32_t MAX_NUM_TRACKS = 32; // maximum number of channels supported by the mixer // This mixer has a hard-coded upper limit of 2 channels for output. // There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect. // Adding support for > 2 channel output would require more than simply changing this value. static const uint32_t MAX_NUM_CHANNELS = 2; // This mixer has a hard-coded upper limit of 8 channels for output. static const uint32_t MAX_NUM_CHANNELS = 8; static const uint32_t MAX_NUM_VOLUMES = 2; // stereo volume only // maximum number of channels supported for the content static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = 8; static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX; static const uint16_t UNITY_GAIN_INT = 0x1000; static const float UNITY_GAIN_FLOAT = 1.0f; Loading @@ -82,6 +81,7 @@ public: AUX_BUFFER = 0x4003, DOWNMIX_TYPE = 0X4004, MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT) MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output // for target RESAMPLE SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; // parameter 'value' is the new sample rate in Hz. Loading Loading @@ -164,15 +164,15 @@ private: // TODO: Eventually remove legacy integer volume settings union { int16_t volume[MAX_NUM_CHANNELS]; // U4.12 fixed point (top bit should be zero) int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero) int32_t volumeRL; }; int32_t prevVolume[MAX_NUM_CHANNELS]; int32_t prevVolume[MAX_NUM_VOLUMES]; // 16-byte boundary int32_t volumeInc[MAX_NUM_CHANNELS]; int32_t volumeInc[MAX_NUM_VOLUMES]; int32_t auxInc; int32_t prevAuxLevel; Loading Loading @@ -217,18 +217,20 @@ private: audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT) // each track must be converted to this format. float mVolume[MAX_NUM_CHANNELS]; // floating point set volume float mPrevVolume[MAX_NUM_CHANNELS]; // floating point previous volume float mVolumeInc[MAX_NUM_CHANNELS]; // floating point volume increment float mVolume[MAX_NUM_VOLUMES]; // floating point set volume float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment float mAuxLevel; // floating point set aux level float mPrevAuxLevel; // floating point prev aux level float mAuxInc; // floating point aux increment // 16-byte boundary audio_channel_mask_t mMixerChannelMask; uint32_t mMixerChannelCount; bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; } bool setResampler(uint32_t sampleRate, uint32_t devSampleRate); bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate); bool doesResample() const { return resampler != NULL; } void resetResampler() { if (resampler != NULL) resampler->reset(); } void adjustVolumeRamp(bool aux, bool useFloat = false); Loading Loading @@ -377,7 +379,11 @@ private: // OK to call more often than that, but unnecessary. void invalidateState(uint32_t mask); static status_t initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask); bool setChannelMasks(int name, audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask); // TODO: remove unused trackName/trackNum from functions below. static status_t initTrackDownmix(track_t* pTrack, int trackName); static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum); static void unprepareTrackForDownmix(track_t* pTrack, int trackName); static status_t prepareTrackForReformat(track_t* pTrack, int trackNum); Loading Loading @@ -418,27 +424,26 @@ private: * in AudioMixerOps.h). The template parameters are as follows: * * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration) * NCHAN (number of channels, 2 for now) * USEFLOATVOL (set to true if float volume is used) * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards) * TO: int32_t (Q4.27) or float * TI: int32_t (Q4.27) or int16_t (Q0.15) or float * TA: int32_t (Q4.27) */ template <int MIXTYPE, int NCHAN, bool USEFLOATVOL, bool ADJUSTVOL, template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL, typename TO, typename TI, typename TA> static void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t); // multi-format process hooks template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void process_NoResampleOneTrack(state_t* state, int64_t pts); // multi-format track hooks template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void track__Resample(track_t* t, TO* out, size_t frameCount, TO* temp __unused, TA* aux); template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA> template <int MIXTYPE, typename TO, typename TI, typename TA> static void track__NoResample(track_t* t, TO* out, size_t frameCount, TO* temp __unused, TA* aux); Loading @@ -457,9 +462,9 @@ private: }; // functions for determining the proper process and track hooks. static process_hook_t getProcessHook(int processType, int channels, static process_hook_t getProcessHook(int processType, uint32_t channelCount, audio_format_t mixerInFormat, audio_format_t mixerOutFormat); static hook_t getTrackHook(int trackType, int channels, static hook_t getTrackHook(int trackType, uint32_t channelCount, audio_format_t mixerInFormat, audio_format_t mixerOutFormat); }; Loading
services/audioflinger/AudioMixerOps.h +67 −14 Original line number Diff line number Diff line Loading @@ -230,6 +230,8 @@ enum { MIXTYPE_MULTI, MIXTYPE_MONOEXPAND, MIXTYPE_MULTI_SAVEONLY, MIXTYPE_MULTI_MONOVOL, MIXTYPE_MULTI_SAVEONLY_MONOVOL, }; /* Loading Loading @@ -263,6 +265,13 @@ enum { * vol: represents a volume array. * * MIXTYPE_MULTI_SAVEONLY does not accumulate into the out pointer. * * MIXTYPE_MULTI_MONOVOL: * Same as MIXTYPE_MULTI, but uses only volume[0]. * * MIXTYPE_MULTI_SAVEONLY_MONOVOL: * Same as MIXTYPE_MULTI_SAVEONLY, but uses only volume[0]. * */ template <int MIXTYPE, int NCHAN, Loading @@ -283,18 +292,30 @@ inline void volumeRampMulti(TO* out, size_t frameCount, vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); vol[i] += volinc[i]; } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); vol[i] += volinc[i]; *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } in++; vol[0] += volinc[0]; break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } vol[0] += volinc[0]; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -313,18 +334,30 @@ inline void volumeRampMulti(TO* out, size_t frameCount, vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); vol[i] += volinc[i]; } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); vol[i] += volinc[i]; } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); vol[i] += volinc[i]; *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); } in++; vol[0] += volinc[0]; break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); } vol[0] += volinc[0]; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -351,16 +384,26 @@ inline void volumeMulti(TO* out, size_t frameCount, *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[i], &auxaccum); } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMulAux<TO, TI, TV, TA>(*in, vol[i], &auxaccum); *out++ += MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMulAux<TO, TI, TV, TA>(*in++, vol[0], &auxaccum); } in++; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading @@ -377,16 +420,26 @@ inline void volumeMulti(TO* out, size_t frameCount, *out++ += MixMul<TO, TI, TV>(*in++, vol[i]); } break; case MIXTYPE_MONOEXPAND: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); } in++; break; case MIXTYPE_MULTI_SAVEONLY: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[i]); } break; case MIXTYPE_MONOEXPAND: case MIXTYPE_MULTI_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ += MixMul<TO, TI, TV>(*in, vol[i]); *out++ += MixMul<TO, TI, TV>(*in++, vol[0]); } break; case MIXTYPE_MULTI_SAVEONLY_MONOVOL: for (int i = 0; i < NCHAN; ++i) { *out++ = MixMul<TO, TI, TV>(*in++, vol[0]); } in++; break; default: LOG_ALWAYS_FATAL("invalid mixtype %d", MIXTYPE); Loading
services/audioflinger/tests/mixer_to_wav_tests.sh +2 −2 Original line number Diff line number Diff line Loading @@ -72,9 +72,9 @@ function createwav() { # track__Resample / track__genericResample # track__NoResample / track__16BitsStereo / track__16BitsMono # Aux buffer adb shell test-mixer $1 -s 9307 \ adb shell test-mixer $1 -c 5 -s 9307 \ -a /sdcard/aux9307gra.wav -o /sdcard/tm9307gra.wav \ sine:2,1000,3000 sine:1,2000,9307 chirp:2,9307 sine:4,1000,3000 sine:1,2000,9307 chirp:3,9307 adb pull /sdcard/tm9307gra.wav $2 adb pull /sdcard/aux9307gra.wav $2 Loading
services/audioflinger/tests/test-mixer.cpp +26 −6 Original line number Diff line number Diff line Loading @@ -36,11 +36,12 @@ using namespace android; static void usage(const char* name) { fprintf(stderr, "Usage: %s [-f] [-m]" fprintf(stderr, "Usage: %s [-f] [-m] [-c channels]" " [-s sample-rate] [-o <output-file>] [-a <aux-buffer-file>] [-P csv]" " (<input-file> | <command>)+\n", name); fprintf(stderr, " -f enable floating point input track\n"); fprintf(stderr, " -m enable floating point mixer output\n"); fprintf(stderr, " -c number of mixer output channels\n"); fprintf(stderr, " -s mixer sample-rate\n"); fprintf(stderr, " -o <output-file> WAV file, pcm16 (or float if -m specified)\n"); fprintf(stderr, " -a <aux-buffer-file>\n"); Loading Loading @@ -90,7 +91,7 @@ int main(int argc, char* argv[]) { std::vector<int32_t> Names; std::vector<SignalProvider> Providers; for (int ch; (ch = getopt(argc, argv, "fms:o:a:P:")) != -1;) { for (int ch; (ch = getopt(argc, argv, "fmc:s:o:a:P:")) != -1;) { switch (ch) { case 'f': useInputFloat = true; Loading @@ -98,6 +99,9 @@ int main(int argc, char* argv[]) { case 'm': useMixerFloat = true; break; case 'c': outputChannels = atoi(optarg); break; case 's': outputSampleRate = atoi(optarg); break; Loading Loading @@ -160,7 +164,7 @@ int main(int argc, char* argv[]) { parseCSV(argv[i] + strlen(sine), v); if (v.size() == 3) { printf("creating sine(%d %d)\n", v[0], v[1]); printf("creating sine(%d %d %d)\n", v[0], v[1], v[2]); if (useInputFloat) { Providers[i].setSine<float>(v[0], v[1], v[2], kSeconds); } else { Loading Loading @@ -191,6 +195,8 @@ int main(int argc, char* argv[]) { const size_t outputFrameSize = outputChannels * (useMixerFloat ? sizeof(float) : sizeof(int16_t)); const size_t outputSize = outputFrames * outputFrameSize; const audio_channel_mask_t outputChannelMask = audio_channel_out_mask_from_count(outputChannels); void *outputAddr = NULL; (void) posix_memalign(&outputAddr, 32, outputSize); memset(outputAddr, 0, outputSize); Loading Loading @@ -228,9 +234,23 @@ int main(int argc, char* argv[]) { mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::MIXER_FORMAT, (void *)mixerFormat); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT, AudioMixer::MIXER_FORMAT, (void *)(uintptr_t)mixerFormat); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::FORMAT, (void *)(uintptr_t)inputFormat); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)outputChannelMask); mixer->setParameter( name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)channelMask); mixer->setParameter( name, AudioMixer::RESAMPLE, Loading