summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp2
-rw-r--r--services/audioflinger/AudioFlinger.h2
-rw-r--r--services/audioflinger/AudioMixer.cpp2
-rw-r--r--services/audioflinger/AudioMixer.h2
-rw-r--r--services/audioflinger/AudioResampler.h3
-rw-r--r--services/audioflinger/AudioResamplerCubic.cpp3
-rw-r--r--services/audioflinger/AudioResamplerCubic.h2
-rw-r--r--services/audioflinger/AudioResamplerDyn.cpp2
-rw-r--r--services/audioflinger/AudioResamplerDyn.h2
-rw-r--r--services/audioflinger/AudioResamplerFirGen.h2
-rw-r--r--services/audioflinger/AudioResamplerFirOps.h2
-rw-r--r--services/audioflinger/AudioResamplerFirProcess.h2
-rw-r--r--services/audioflinger/AudioResamplerFirProcessNeon.h2
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp2
-rw-r--r--services/audioflinger/AudioResamplerSinc.h2
-rw-r--r--services/audioflinger/AudioResamplerSincDown.h260
-rw-r--r--services/audioflinger/AudioResamplerSincUp.h260
-rw-r--r--services/audioflinger/Configuration.h5
-rw-r--r--services/audioflinger/Effects.cpp2
-rw-r--r--services/audioflinger/FastCapture.cpp139
-rw-r--r--services/audioflinger/FastCapture.h26
-rw-r--r--services/audioflinger/FastCaptureState.cpp15
-rw-r--r--services/audioflinger/FastCaptureState.h14
-rw-r--r--services/audioflinger/FastMixer.cpp246
-rw-r--r--services/audioflinger/FastMixer.h47
-rw-r--r--services/audioflinger/FastMixerDumpState.cpp61
-rw-r--r--services/audioflinger/FastMixerDumpState.h24
-rw-r--r--services/audioflinger/FastMixerState.cpp15
-rw-r--r--services/audioflinger/FastMixerState.h3
-rw-r--r--services/audioflinger/FastThread.cpp273
-rw-r--r--services/audioflinger/FastThread.h69
-rw-r--r--services/audioflinger/FastThreadDumpState.cpp25
-rw-r--r--services/audioflinger/FastThreadDumpState.h15
-rw-r--r--services/audioflinger/FastThreadState.cpp12
-rw-r--r--services/audioflinger/FastThreadState.h2
-rw-r--r--services/audioflinger/PatchPanel.cpp2
-rw-r--r--services/audioflinger/Threads.cpp10
-rw-r--r--services/audioflinger/Tracks.cpp2
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp2
-rw-r--r--services/camera/libcameraservice/CameraFlashlight.cpp582
-rw-r--r--services/camera/libcameraservice/CameraFlashlight.h122
-rw-r--r--services/camera/libcameraservice/CameraService.cpp214
-rw-r--r--services/camera/libcameraservice/CameraService.h22
-rw-r--r--services/camera/libcameraservice/common/CameraModule.cpp17
-rw-r--r--services/camera/libcameraservice/common/CameraModule.h2
-rw-r--r--services/camera/libcameraservice/device1/CameraHardwareInterface.h3
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.cpp3
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp4
48 files changed, 1534 insertions, 996 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f3780a9..940267a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2949,4 +2949,4 @@ status_t AudioFlinger::onTransact(
return BnAudioFlinger::onTransact(code, data, reply, flags);
}
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index aa0af1f..f5dec97 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -799,6 +799,6 @@ const char *formatToString(audio_format_t format);
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 836f550..93d821a 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -2300,4 +2300,4 @@ AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t
}
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index c5df08a..381036b 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -485,6 +485,6 @@ private:
};
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
#endif // ANDROID_AUDIO_MIXER_H
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index 069d946..863614a 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -170,7 +170,6 @@ private:
};
// ----------------------------------------------------------------------------
-}
-; // namespace android
+} // namespace android
#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp
index 8f14ff9..d3cbd1c 100644
--- a/services/audioflinger/AudioResamplerCubic.cpp
+++ b/services/audioflinger/AudioResamplerCubic.cpp
@@ -185,5 +185,4 @@ save_state:
}
// ----------------------------------------------------------------------------
-}
-; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerCubic.h b/services/audioflinger/AudioResamplerCubic.h
index b315da5..1ddc5f9 100644
--- a/services/audioflinger/AudioResamplerCubic.h
+++ b/services/audioflinger/AudioResamplerCubic.h
@@ -63,6 +63,6 @@ private:
};
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index 0eeb201..c21d4ca 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -618,4 +618,4 @@ template class AudioResamplerDyn<int16_t, int16_t, int32_t>;
template class AudioResamplerDyn<int32_t, int16_t, int32_t>;
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerDyn.h b/services/audioflinger/AudioResamplerDyn.h
index e886a68..238b163 100644
--- a/services/audioflinger/AudioResamplerDyn.h
+++ b/services/audioflinger/AudioResamplerDyn.h
@@ -127,6 +127,6 @@ private:
void* mCoefBuffer; // if a filter is created, this is not null
};
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/
diff --git a/services/audioflinger/AudioResamplerFirGen.h b/services/audioflinger/AudioResamplerFirGen.h
index a9c84de..ad18965 100644
--- a/services/audioflinger/AudioResamplerFirGen.h
+++ b/services/audioflinger/AudioResamplerFirGen.h
@@ -707,6 +707,6 @@ static inline void firKaiserGen(T* coef, int L, int halfNumCoef,
}
}
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_FIR_GEN_H*/
diff --git a/services/audioflinger/AudioResamplerFirOps.h b/services/audioflinger/AudioResamplerFirOps.h
index 4af328c..658285d 100644
--- a/services/audioflinger/AudioResamplerFirOps.h
+++ b/services/audioflinger/AudioResamplerFirOps.h
@@ -158,6 +158,6 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
#endif
}
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_FIR_OPS_H*/
diff --git a/services/audioflinger/AudioResamplerFirProcess.h b/services/audioflinger/AudioResamplerFirProcess.h
index 91d7c54..176202e 100644
--- a/services/audioflinger/AudioResamplerFirProcess.h
+++ b/services/audioflinger/AudioResamplerFirProcess.h
@@ -434,6 +434,6 @@ void fir(TO* const out,
}
}
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_FIR_PROCESS_H*/
diff --git a/services/audioflinger/AudioResamplerFirProcessNeon.h b/services/audioflinger/AudioResamplerFirProcessNeon.h
index e8d1318..3de9edd 100644
--- a/services/audioflinger/AudioResamplerFirProcessNeon.h
+++ b/services/audioflinger/AudioResamplerFirProcessNeon.h
@@ -1209,6 +1209,6 @@ inline void Process<2, 16>(float* const out,
#endif //USE_NEON
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_FIR_PROCESS_NEON_H*/
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index fdad8b6..ba9a356 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -601,4 +601,4 @@ void AudioResamplerSinc::interpolate(
}
}
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 4691d0a..6d8e85d 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -95,6 +95,6 @@ private:
};
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/services/audioflinger/AudioResamplerSincDown.h b/services/audioflinger/AudioResamplerSincDown.h
index b2b5969..2d0fb86 100644
--- a/services/audioflinger/AudioResamplerSincDown.h
+++ b/services/audioflinger/AudioResamplerSincDown.h
@@ -1,129 +1,131 @@
- 0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
- 0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
- 0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
- 0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
- 0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
- 0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
- 0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
- 0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
- 0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
- 0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
- 0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
- 0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
- 0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
- 0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
- 0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
- 0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
- 0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
- 0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
- 0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
- 0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
- 0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
- 0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
- 0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
- 0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
- 0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
- 0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
- 0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
- 0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
- 0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
- 0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
- 0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
- 0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
- 0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
- 0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
- 0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
- 0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
- 0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
- 0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
- 0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
- 0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
- 0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
- 0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
- 0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
- 0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
- 0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
- 0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
- 0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
- 0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
- 0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
- 0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
- 0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
- 0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
- 0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
- 0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
- 0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
- 0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
- 0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
- 0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
- 0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
- 0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
- 0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
- 0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
- 0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
- 0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
- 0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
- 0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
- 0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
- 0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
- 0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
- 0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
- 0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
- 0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
- 0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
- 0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
- 0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
- 0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
- 0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
- 0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
- 0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
- 0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
- 0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
- 0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
- 0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
- 0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
- 0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
- 0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
- 0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
- 0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
- 0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
- 0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
- 0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
- 0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
- 0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
- 0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
- 0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
- 0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
- 0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
- 0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
- 0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
- 0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
- 0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
- 0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
- 0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
- 0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
- 0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
- 0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
- 0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
- 0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
- 0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
- 0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
- 0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
- 0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
- 0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
- 0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
- 0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
- 0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
- 0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
- 0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
- 0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
- 0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
- 0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
- 0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
- 0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
- 0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
- 0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
- 0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
- 0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
- 0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
- 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
+// cmd-line: fir -l 7 -s48000 -c 17189
+
+ 0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
+ 0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
+ 0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
+ 0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
+ 0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
+ 0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
+ 0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
+ 0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
+ 0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
+ 0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
+ 0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
+ 0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
+ 0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
+ 0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
+ 0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
+ 0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
+ 0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
+ 0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
+ 0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
+ 0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
+ 0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
+ 0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
+ 0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
+ 0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
+ 0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
+ 0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
+ 0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
+ 0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
+ 0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
+ 0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
+ 0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
+ 0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
+ 0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
+ 0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
+ 0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
+ 0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
+ 0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
+ 0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
+ 0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
+ 0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
+ 0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
+ 0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
+ 0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
+ 0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
+ 0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
+ 0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
+ 0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
+ 0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
+ 0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
+ 0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
+ 0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
+ 0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
+ 0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
+ 0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
+ 0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
+ 0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
+ 0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
+ 0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
+ 0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
+ 0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
+ 0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
+ 0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
+ 0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
+ 0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
+ 0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
+ 0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
+ 0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
+ 0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
+ 0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
+ 0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
+ 0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
+ 0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
+ 0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
+ 0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
+ 0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
+ 0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
+ 0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
+ 0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
+ 0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
+ 0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
+ 0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
+ 0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
+ 0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
+ 0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
+ 0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
+ 0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
+ 0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
+ 0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
+ 0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
+ 0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
+ 0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
+ 0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
+ 0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
+ 0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
+ 0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
+ 0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
+ 0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
+ 0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
+ 0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
+ 0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
+ 0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
+ 0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
+ 0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
+ 0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
+ 0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
+ 0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
+ 0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
+ 0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
+ 0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
+ 0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
+ 0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
+ 0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
+ 0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
+ 0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
+ 0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
+ 0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
+ 0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
+ 0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
+ 0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
+ 0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
+ 0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
+ 0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
+ 0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
+ 0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
+ 0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
+ 0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
+ 0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
+ 0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
+ 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
diff --git a/services/audioflinger/AudioResamplerSincUp.h b/services/audioflinger/AudioResamplerSincUp.h
index eab20aa..fd5367e 100644
--- a/services/audioflinger/AudioResamplerSincUp.h
+++ b/services/audioflinger/AudioResamplerSincUp.h
@@ -1,129 +1,131 @@
- 0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
- 0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
- 0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
- 0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
- 0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
- 0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
- 0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
- 0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
- 0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
- 0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
- 0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
- 0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
- 0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
- 0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
- 0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
- 0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
- 0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
- 0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
- 0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
- 0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
- 0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
- 0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
- 0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
- 0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
- 0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
- 0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
- 0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
- 0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
- 0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
- 0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
- 0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
- 0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
- 0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
- 0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
- 0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
- 0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
- 0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
- 0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
- 0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
- 0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
- 0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
- 0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
- 0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
- 0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
- 0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
- 0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
- 0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
- 0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
- 0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
- 0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
- 0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
- 0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
- 0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
- 0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
- 0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
- 0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
- 0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
- 0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
- 0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
- 0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
- 0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
- 0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
- 0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
- 0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
- 0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
- 0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
- 0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
- 0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
- 0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
- 0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
- 0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
- 0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
- 0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
- 0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
- 0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
- 0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
- 0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
- 0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
- 0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
- 0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
- 0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
- 0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
- 0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
- 0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
- 0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
- 0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
- 0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
- 0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
- 0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
- 0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
- 0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
- 0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
- 0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
- 0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
- 0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
- 0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
- 0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
- 0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
- 0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
- 0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
- 0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
- 0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
- 0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
- 0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
- 0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
- 0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
- 0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
- 0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
- 0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
- 0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
- 0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
- 0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
- 0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
- 0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
- 0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
- 0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
- 0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
- 0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
- 0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
- 0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
- 0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
- 0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
- 0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
- 0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
- 0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
- 0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
- 0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
- 0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
- 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
+// cmd-line: fir -l 7 -s48000 -c 20478
+
+ 0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
+ 0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
+ 0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
+ 0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
+ 0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
+ 0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
+ 0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
+ 0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
+ 0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
+ 0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
+ 0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
+ 0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
+ 0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
+ 0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
+ 0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
+ 0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
+ 0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
+ 0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
+ 0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
+ 0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
+ 0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
+ 0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
+ 0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
+ 0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
+ 0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
+ 0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
+ 0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
+ 0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
+ 0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
+ 0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
+ 0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
+ 0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
+ 0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
+ 0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
+ 0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
+ 0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
+ 0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
+ 0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
+ 0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
+ 0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
+ 0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
+ 0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
+ 0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
+ 0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
+ 0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
+ 0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
+ 0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
+ 0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
+ 0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
+ 0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
+ 0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
+ 0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
+ 0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
+ 0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
+ 0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
+ 0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
+ 0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
+ 0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
+ 0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
+ 0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
+ 0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
+ 0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
+ 0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
+ 0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
+ 0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
+ 0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
+ 0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
+ 0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
+ 0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
+ 0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
+ 0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
+ 0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
+ 0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
+ 0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
+ 0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
+ 0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
+ 0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
+ 0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
+ 0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
+ 0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
+ 0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
+ 0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
+ 0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
+ 0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
+ 0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
+ 0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
+ 0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
+ 0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
+ 0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
+ 0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
+ 0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
+ 0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
+ 0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
+ 0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
+ 0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
+ 0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
+ 0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
+ 0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
+ 0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
+ 0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
+ 0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
+ 0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
+ 0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
+ 0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
+ 0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
+ 0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
+ 0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
+ 0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
+ 0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
+ 0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
+ 0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
+ 0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
+ 0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
+ 0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
+ 0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
+ 0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
+ 0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
+ 0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
+ 0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
+ 0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
+ 0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
+ 0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
+ 0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
+ 0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
+ 0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
+ 0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
+ 0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
+ 0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
+ 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index 6a8aeb1..845697a 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -29,9 +29,8 @@
// uncomment to display CPU load adjusted for CPU frequency
//#define CPU_FREQUENCY_STATISTICS
-// uncomment to enable fast mixer to take performance samples for later statistical analysis
-#define FAST_MIXER_STATISTICS
-// FIXME rename to FAST_THREAD_STATISTICS
+// uncomment to enable fast threads to take performance samples for later statistical analysis
+#define FAST_THREAD_STATISTICS
// uncomment for debugging timing problems related to StateQueue::push()
//#define STATE_QUEUE_DUMP
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index bcaf8ae..8bccb47 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1953,4 +1953,4 @@ void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread)
}
}
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index 255496e..9e7e8a4 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -29,18 +29,18 @@
namespace android {
-/*static*/ const FastCaptureState FastCapture::initial;
+/*static*/ const FastCaptureState FastCapture::sInitial;
FastCapture::FastCapture() : FastThread(),
- inputSource(NULL), inputSourceGen(0), pipeSink(NULL), pipeSinkGen(0),
- readBuffer(NULL), readBufferState(-1), format(Format_Invalid), sampleRate(0),
- // dummyDumpState
- totalNativeFramesRead(0)
+ mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0),
+ mReadBuffer(NULL), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
+ // mDummyDumpState
+ mTotalNativeFramesRead(0)
{
- previous = &initial;
- current = &initial;
+ mPrevious = &sInitial;
+ mCurrent = &sInitial;
- mDummyDumpState = &dummyDumpState;
+ mDummyDumpState = &mDummyFastCaptureDumpState;
}
FastCapture::~FastCapture()
@@ -63,13 +63,13 @@ void FastCapture::setLog(NBLog::Writer *logWriter __unused)
void FastCapture::onIdle()
{
- preIdle = *(const FastCaptureState *)current;
- current = &preIdle;
+ mPreIdle = *(const FastCaptureState *)mCurrent;
+ mCurrent = &mPreIdle;
}
void FastCapture::onExit()
{
- delete[] readBuffer;
+ free(mReadBuffer);
}
bool FastCapture::isSubClassCommand(FastThreadState::Command command)
@@ -86,69 +86,67 @@ bool FastCapture::isSubClassCommand(FastThreadState::Command command)
void FastCapture::onStateChange()
{
- const FastCaptureState * const current = (const FastCaptureState *) this->current;
- const FastCaptureState * const previous = (const FastCaptureState *) this->previous;
- FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
+ const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
+ const FastCaptureState * const previous = (const FastCaptureState *) mPrevious;
+ FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
const size_t frameCount = current->mFrameCount;
bool eitherChanged = false;
// check for change in input HAL configuration
- NBAIO_Format previousFormat = format;
- if (current->mInputSourceGen != inputSourceGen) {
- inputSource = current->mInputSource;
- inputSourceGen = current->mInputSourceGen;
- if (inputSource == NULL) {
- format = Format_Invalid;
- sampleRate = 0;
+ NBAIO_Format previousFormat = mFormat;
+ if (current->mInputSourceGen != mInputSourceGen) {
+ mInputSource = current->mInputSource;
+ mInputSourceGen = current->mInputSourceGen;
+ if (mInputSource == NULL) {
+ mFormat = Format_Invalid;
+ mSampleRate = 0;
} else {
- format = inputSource->format();
- sampleRate = Format_sampleRate(format);
- unsigned channelCount = Format_channelCount(format);
+ mFormat = mInputSource->format();
+ mSampleRate = Format_sampleRate(mFormat);
+ unsigned channelCount = Format_channelCount(mFormat);
ALOG_ASSERT(channelCount == 1 || channelCount == 2);
}
- dumpState->mSampleRate = sampleRate;
+ dumpState->mSampleRate = mSampleRate;
eitherChanged = true;
}
// check for change in pipe
- if (current->mPipeSinkGen != pipeSinkGen) {
- pipeSink = current->mPipeSink;
- pipeSinkGen = current->mPipeSinkGen;
+ if (current->mPipeSinkGen != mPipeSinkGen) {
+ mPipeSink = current->mPipeSink;
+ mPipeSinkGen = current->mPipeSinkGen;
eitherChanged = true;
}
// input source and pipe sink must be compatible
- if (eitherChanged && inputSource != NULL && pipeSink != NULL) {
- ALOG_ASSERT(Format_isEqual(format, pipeSink->format()));
+ if (eitherChanged && mInputSource != NULL && mPipeSink != NULL) {
+ ALOG_ASSERT(Format_isEqual(mFormat, mPipeSink->format()));
}
- if ((!Format_isEqual(format, previousFormat)) || (frameCount != previous->mFrameCount)) {
- // FIXME to avoid priority inversion, don't delete here
- delete[] readBuffer;
- readBuffer = NULL;
- if (frameCount > 0 && sampleRate > 0) {
+ if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
+ // FIXME to avoid priority inversion, don't free here
+ free(mReadBuffer);
+ mReadBuffer = NULL;
+ if (frameCount > 0 && mSampleRate > 0) {
// FIXME new may block for unbounded time at internal mutex of the heap
// implementation; it would be better to have normal capture thread allocate for
// us to avoid blocking here and to prevent possible priority inversion
- unsigned channelCount = Format_channelCount(format);
- // FIXME frameSize
- readBuffer = new short[frameCount * channelCount];
- periodNs = (frameCount * 1000000000LL) / sampleRate; // 1.00
- underrunNs = (frameCount * 1750000000LL) / sampleRate; // 1.75
- overrunNs = (frameCount * 500000000LL) / sampleRate; // 0.50
- forceNs = (frameCount * 950000000LL) / sampleRate; // 0.95
- warmupNsMin = (frameCount * 750000000LL) / sampleRate; // 0.75
- warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25
+ (void)posix_memalign(&mReadBuffer, 32, frameCount * Format_frameSize(mFormat));
+ mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
+ mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
+ mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
+ mForceNs = (frameCount * 950000000LL) / mSampleRate; // 0.95
+ mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate; // 0.75
+ mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
} else {
- periodNs = 0;
- underrunNs = 0;
- overrunNs = 0;
- forceNs = 0;
- warmupNsMin = 0;
- warmupNsMax = LONG_MAX;
+ mPeriodNs = 0;
+ mUnderrunNs = 0;
+ mOverrunNs = 0;
+ mForceNs = 0;
+ mWarmupNsMin = 0;
+ mWarmupNsMax = LONG_MAX;
}
- readBufferState = -1;
+ mReadBufferState = -1;
dumpState->mFrameCount = frameCount;
}
@@ -156,44 +154,43 @@ void FastCapture::onStateChange()
void FastCapture::onWork()
{
- const FastCaptureState * const current = (const FastCaptureState *) this->current;
- FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
- const FastCaptureState::Command command = this->command;
+ const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
+ FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
+ const FastCaptureState::Command command = mCommand;
const size_t frameCount = current->mFrameCount;
if ((command & FastCaptureState::READ) /*&& isWarm*/) {
- ALOG_ASSERT(inputSource != NULL);
- ALOG_ASSERT(readBuffer != NULL);
+ ALOG_ASSERT(mInputSource != NULL);
+ ALOG_ASSERT(mReadBuffer != NULL);
dumpState->mReadSequence++;
ATRACE_BEGIN("read");
- ssize_t framesRead = inputSource->read(readBuffer, frameCount,
+ ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount,
AudioBufferProvider::kInvalidPTS);
ATRACE_END();
dumpState->mReadSequence++;
if (framesRead >= 0) {
LOG_ALWAYS_FATAL_IF((size_t) framesRead > frameCount);
- totalNativeFramesRead += framesRead;
- dumpState->mFramesRead = totalNativeFramesRead;
- readBufferState = framesRead;
+ mTotalNativeFramesRead += framesRead;
+ dumpState->mFramesRead = mTotalNativeFramesRead;
+ mReadBufferState = framesRead;
} else {
dumpState->mReadErrors++;
- readBufferState = 0;
+ mReadBufferState = 0;
}
// FIXME rename to attemptedIO
- attemptedWrite = true;
+ mAttemptedWrite = true;
}
if (command & FastCaptureState::WRITE) {
- ALOG_ASSERT(pipeSink != NULL);
- ALOG_ASSERT(readBuffer != NULL);
- if (readBufferState < 0) {
- unsigned channelCount = Format_channelCount(format);
- // FIXME frameSize
- memset(readBuffer, 0, frameCount * channelCount * sizeof(short));
- readBufferState = frameCount;
+ ALOG_ASSERT(mPipeSink != NULL);
+ ALOG_ASSERT(mReadBuffer != NULL);
+ if (mReadBufferState < 0) {
+ unsigned channelCount = Format_channelCount(mFormat);
+ memset(mReadBuffer, 0, frameCount * Format_frameSize(mFormat));
+ mReadBufferState = frameCount;
}
- if (readBufferState > 0) {
- ssize_t framesWritten = pipeSink->write(readBuffer, readBufferState);
+ if (mReadBufferState > 0) {
+ ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
// FIXME This supports at most one fast capture client.
// To handle multiple clients this could be converted to an array,
// or with a lot more work the control block could be shared by all clients.
diff --git a/services/audioflinger/FastCapture.h b/services/audioflinger/FastCapture.h
index da0fe2f..e258a4d 100644
--- a/services/audioflinger/FastCapture.h
+++ b/services/audioflinger/FastCapture.h
@@ -46,19 +46,21 @@ private:
virtual void onStateChange();
virtual void onWork();
- static const FastCaptureState initial;
- FastCaptureState preIdle; // copy of state before we went into idle
+ static const FastCaptureState sInitial;
+
+ FastCaptureState mPreIdle; // copy of state before we went into idle
// FIXME by renaming, could pull up many of these to FastThread
- NBAIO_Source *inputSource;
- int inputSourceGen;
- NBAIO_Sink *pipeSink;
- int pipeSinkGen;
- short *readBuffer;
- ssize_t readBufferState; // number of initialized frames in readBuffer, or -1 to clear
- NBAIO_Format format;
- unsigned sampleRate;
- FastCaptureDumpState dummyDumpState;
- uint32_t totalNativeFramesRead; // copied to dumpState->mFramesRead
+ NBAIO_Source* mInputSource;
+ int mInputSourceGen;
+ NBAIO_Sink* mPipeSink;
+ int mPipeSinkGen;
+ void* mReadBuffer;
+ ssize_t mReadBufferState; // number of initialized frames in readBuffer,
+ // or -1 to clear
+ NBAIO_Format mFormat;
+ unsigned mSampleRate;
+ FastCaptureDumpState mDummyFastCaptureDumpState;
+ uint32_t mTotalNativeFramesRead; // copied to dumpState->mFramesRead
}; // class FastCapture
diff --git a/services/audioflinger/FastCaptureState.cpp b/services/audioflinger/FastCaptureState.cpp
index 1d029b7..c4d5e45 100644
--- a/services/audioflinger/FastCaptureState.cpp
+++ b/services/audioflinger/FastCaptureState.cpp
@@ -27,4 +27,19 @@ FastCaptureState::~FastCaptureState()
{
}
+// static
+const char *FastCaptureState::commandToString(Command command)
+{
+ const char *str = FastThreadState::commandToString(command);
+ if (str != NULL) {
+ return str;
+ }
+ switch (command) {
+ case FastCaptureState::READ: return "READ";
+ case FastCaptureState::WRITE: return "WRITE";
+ case FastCaptureState::READ_WRITE: return "READ_WRITE";
+ }
+ LOG_ALWAYS_FATAL("%s", __func__);
+}
+
} // android
diff --git a/services/audioflinger/FastCaptureState.h b/services/audioflinger/FastCaptureState.h
index 29c865a..9bca2d4 100644
--- a/services/audioflinger/FastCaptureState.h
+++ b/services/audioflinger/FastCaptureState.h
@@ -29,21 +29,23 @@ struct FastCaptureState : FastThreadState {
/*virtual*/ ~FastCaptureState();
// all pointer fields use raw pointers; objects are owned and ref-counted by RecordThread
- NBAIO_Source *mInputSource; // HAL input device, must already be negotiated
+ NBAIO_Source* mInputSource; // HAL input device, must already be negotiated
// FIXME by renaming, could pull up these fields to FastThreadState
int mInputSourceGen; // increment when mInputSource is assigned
- NBAIO_Sink *mPipeSink; // after reading from input source, write to this pipe sink
+ NBAIO_Sink* mPipeSink; // after reading from input source, write to this pipe sink
int mPipeSinkGen; // increment when mPipeSink is assigned
size_t mFrameCount; // number of frames per fast capture buffer
- audio_track_cblk_t *mCblk; // control block for the single fast client, or NULL
+ audio_track_cblk_t* mCblk; // control block for the single fast client, or NULL
// Extends FastThreadState::Command
static const Command
// The following commands also process configuration changes, and can be "or"ed:
- READ = 0x8, // read from input source
- WRITE = 0x10, // write to pipe sink
- READ_WRITE = 0x18; // read from input source and write to pipe sink
+ READ = 0x8, // read from input source
+ WRITE = 0x10, // write to pipe sink
+ READ_WRITE = 0x18; // read from input source and write to pipe sink
+ // never returns NULL; asserts if command is invalid
+ static const char *commandToString(Command command);
}; // struct FastCaptureState
} // namespace android
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 8b12f28..e070f90 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -31,7 +31,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <system/audio.h>
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
#include <cpustats/CentralTendencyStatistics.h>
#ifdef CPU_FREQUENCY_STATISTICS
#include <cpustats/ThreadCpuUsage.h>
@@ -45,15 +45,15 @@
namespace android {
-/*static*/ const FastMixerState FastMixer::initial;
+/*static*/ const FastMixerState FastMixer::sInitial;
FastMixer::FastMixer() : FastThread(),
- slopNs(0),
- // fastTrackNames
- // generations
- outputSink(NULL),
- outputSinkGen(0),
- mixer(NULL),
+ mSlopNs(0),
+ // mFastTrackNames
+ // mGenerations
+ mOutputSink(NULL),
+ mOutputSinkGen(0),
+ mMixer(NULL),
mSinkBuffer(NULL),
mSinkBufferSize(0),
mSinkChannelCount(FCC_2),
@@ -61,30 +61,30 @@ FastMixer::FastMixer() : FastThread(),
mMixerBufferSize(0),
mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
mMixerBufferState(UNDEFINED),
- format(Format_Invalid),
- sampleRate(0),
- fastTracksGen(0),
- totalNativeFramesWritten(0),
+ mFormat(Format_Invalid),
+ mSampleRate(0),
+ mFastTracksGen(0),
+ mTotalNativeFramesWritten(0),
// timestamp
- nativeFramesWrittenButNotPresented(0) // the = 0 is to silence the compiler
+ mNativeFramesWrittenButNotPresented(0) // the = 0 is to silence the compiler
{
- // FIXME pass initial as parameter to base class constructor, and make it static local
- previous = &initial;
- current = &initial;
+ // FIXME pass sInitial as parameter to base class constructor, and make it static local
+ mPrevious = &sInitial;
+ mCurrent = &sInitial;
- mDummyDumpState = &dummyDumpState;
+ mDummyDumpState = &mDummyFastMixerDumpState;
// 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) {
- fastTrackNames[i] = -1;
- generations[i] = 0;
+ mFastTrackNames[i] = -1;
+ mGenerations[i] = 0;
}
-#ifdef FAST_MIXER_STATISTICS
- oldLoad.tv_sec = 0;
- oldLoad.tv_nsec = 0;
+#ifdef FAST_THREAD_STATISTICS
+ mOldLoad.tv_sec = 0;
+ mOldLoad.tv_nsec = 0;
#endif
}
@@ -104,20 +104,20 @@ const FastThreadState *FastMixer::poll()
void FastMixer::setLog(NBLog::Writer *logWriter)
{
- if (mixer != NULL) {
- mixer->setLog(logWriter);
+ if (mMixer != NULL) {
+ mMixer->setLog(logWriter);
}
}
void FastMixer::onIdle()
{
- preIdle = *(const FastMixerState *)current;
- current = &preIdle;
+ mPreIdle = *(const FastMixerState *)mCurrent;
+ mCurrent = &mPreIdle;
}
void FastMixer::onExit()
{
- delete mixer;
+ delete mMixer;
free(mMixerBuffer);
free(mSinkBuffer);
}
@@ -136,84 +136,84 @@ bool FastMixer::isSubClassCommand(FastThreadState::Command command)
void FastMixer::onStateChange()
{
- const FastMixerState * const current = (const FastMixerState *) this->current;
- const FastMixerState * const previous = (const FastMixerState *) this->previous;
- FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->dumpState;
+ const FastMixerState * const current = (const FastMixerState *) mCurrent;
+ const FastMixerState * const previous = (const FastMixerState *) mPrevious;
+ FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
const size_t frameCount = current->mFrameCount;
// handle state change here, but since we want to diff the state,
- // we're prepared for previous == &initial the first time through
+ // we're prepared for previous == &sInitial the first time through
unsigned previousTrackMask;
// check for change in output HAL configuration
- NBAIO_Format previousFormat = format;
- if (current->mOutputSinkGen != outputSinkGen) {
- outputSink = current->mOutputSink;
- outputSinkGen = current->mOutputSinkGen;
- if (outputSink == NULL) {
- format = Format_Invalid;
- sampleRate = 0;
+ NBAIO_Format previousFormat = mFormat;
+ if (current->mOutputSinkGen != mOutputSinkGen) {
+ mOutputSink = current->mOutputSink;
+ mOutputSinkGen = current->mOutputSinkGen;
+ if (mOutputSink == NULL) {
+ mFormat = Format_Invalid;
+ mSampleRate = 0;
mSinkChannelCount = 0;
mSinkChannelMask = AUDIO_CHANNEL_NONE;
} else {
- format = outputSink->format();
- sampleRate = Format_sampleRate(format);
- mSinkChannelCount = Format_channelCount(format);
+ mFormat = mOutputSink->format();
+ mSampleRate = Format_sampleRate(mFormat);
+ mSinkChannelCount = Format_channelCount(mFormat);
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;
+ dumpState->mSampleRate = mSampleRate;
}
- if ((!Format_isEqual(format, previousFormat)) || (frameCount != previous->mFrameCount)) {
+ if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
// FIXME to avoid priority inversion, don't delete here
- delete mixer;
- mixer = NULL;
+ delete mMixer;
+ mMixer = NULL;
free(mMixerBuffer);
mMixerBuffer = NULL;
free(mSinkBuffer);
mSinkBuffer = NULL;
- if (frameCount > 0 && sampleRate > 0) {
+ if (frameCount > 0 && mSampleRate > 0) {
// 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
- mixer = new AudioMixer(frameCount, sampleRate, FastMixerState::kMaxFastTracks);
+ mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
const size_t mixerFrameSize = mSinkChannelCount
* audio_bytes_per_sample(mMixerBufferFormat);
mMixerBufferSize = mixerFrameSize * frameCount;
(void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
const size_t sinkFrameSize = mSinkChannelCount
- * audio_bytes_per_sample(format.mFormat);
+ * audio_bytes_per_sample(mFormat.mFormat);
if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
mSinkBufferSize = sinkFrameSize * frameCount;
(void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
}
- periodNs = (frameCount * 1000000000LL) / sampleRate; // 1.00
- underrunNs = (frameCount * 1750000000LL) / sampleRate; // 1.75
- overrunNs = (frameCount * 500000000LL) / sampleRate; // 0.50
- forceNs = (frameCount * 950000000LL) / sampleRate; // 0.95
- warmupNsMin = (frameCount * 750000000LL) / sampleRate; // 0.75
- warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25
+ mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
+ mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
+ mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
+ mForceNs = (frameCount * 950000000LL) / mSampleRate; // 0.95
+ mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate; // 0.75
+ mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
} else {
- periodNs = 0;
- underrunNs = 0;
- overrunNs = 0;
- forceNs = 0;
- warmupNsMin = 0;
- warmupNsMax = LONG_MAX;
+ mPeriodNs = 0;
+ mUnderrunNs = 0;
+ mOverrunNs = 0;
+ mForceNs = 0;
+ mWarmupNsMin = 0;
+ mWarmupNsMax = LONG_MAX;
}
mMixerBufferState = UNDEFINED;
#if !LOG_NDEBUG
for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
- fastTrackNames[i] = -1;
+ mFastTrackNames[i] = -1;
}
#endif
// we need to reconfigure all active tracks
previousTrackMask = 0;
- fastTracksGen = current->mFastTracksGen - 1;
+ mFastTracksGen = current->mFastTracksGen - 1;
dumpState->mFrameCount = frameCount;
} else {
previousTrackMask = previous->mTrackMask;
@@ -222,7 +222,7 @@ void FastMixer::onStateChange()
// check for change in active track set
const unsigned currentTrackMask = current->mTrackMask;
dumpState->mTrackMask = currentTrackMask;
- if (current->mFastTracksGen != fastTracksGen) {
+ if (current->mFastTracksGen != mFastTracksGen) {
ALOG_ASSERT(mMixerBuffer != NULL);
int name;
@@ -233,16 +233,16 @@ void FastMixer::onStateChange()
removedTracks &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
- if (mixer != NULL) {
- name = fastTrackNames[i];
+ if (mMixer != NULL) {
+ name = mFastTrackNames[i];
ALOG_ASSERT(name >= 0);
- mixer->deleteTrackName(name);
+ mMixer->deleteTrackName(name);
}
#if !LOG_NDEBUG
- fastTrackNames[i] = -1;
+ mFastTrackNames[i] = -1;
#endif
// don't reset track dump state, since other side is ignoring it
- generations[i] = fastTrack->mGeneration;
+ mGenerations[i] = fastTrack->mGeneration;
}
// now process added tracks
@@ -252,29 +252,29 @@ void FastMixer::onStateChange()
addedTracks &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
- ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
- if (mixer != NULL) {
- name = mixer->getTrackName(fastTrack->mChannelMask,
+ ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
+ if (mMixer != NULL) {
+ name = mMixer->getTrackName(fastTrack->mChannelMask,
fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
ALOG_ASSERT(name >= 0);
- fastTrackNames[i] = name;
- mixer->setBufferProvider(name, bufferProvider);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
+ mFastTrackNames[i] = name;
+ mMixer->setBufferProvider(name, bufferProvider);
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
(void *)mMixerBuffer);
// newly allocated track names default to full scale volume
- mixer->setParameter(
+ mMixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
(void *)(uintptr_t)fastTrack->mFormat);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
(void *)(uintptr_t)fastTrack->mChannelMask);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
(void *)(uintptr_t)mSinkChannelMask);
- mixer->enable(name);
+ mMixer->enable(name);
}
- generations[i] = fastTrack->mGeneration;
+ mGenerations[i] = fastTrack->mGeneration;
}
// finally process (potentially) modified tracks; these use the same slot
@@ -284,38 +284,38 @@ void FastMixer::onStateChange()
int i = __builtin_ctz(modifiedTracks);
modifiedTracks &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
- if (fastTrack->mGeneration != generations[i]) {
+ if (fastTrack->mGeneration != mGenerations[i]) {
// this track was actually modified
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
ALOG_ASSERT(bufferProvider != NULL);
- if (mixer != NULL) {
- name = fastTrackNames[i];
+ if (mMixer != NULL) {
+ name = mFastTrackNames[i];
ALOG_ASSERT(name >= 0);
- mixer->setBufferProvider(name, bufferProvider);
+ mMixer->setBufferProvider(name, bufferProvider);
if (fastTrack->mVolumeProvider == NULL) {
float f = AudioMixer::UNITY_GAIN_FLOAT;
- mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
- mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
+ mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
+ mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
}
- mixer->setParameter(name, AudioMixer::RESAMPLE,
+ mMixer->setParameter(name, AudioMixer::RESAMPLE,
AudioMixer::REMOVE, NULL);
- mixer->setParameter(
+ mMixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
(void *)(uintptr_t)fastTrack->mFormat);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
(void *)(uintptr_t)fastTrack->mChannelMask);
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
+ mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
(void *)(uintptr_t)mSinkChannelMask);
// already enabled
}
- generations[i] = fastTrack->mGeneration;
+ mGenerations[i] = fastTrack->mGeneration;
}
}
- fastTracksGen = current->mFastTracksGen;
+ mFastTracksGen = current->mFastTracksGen;
dumpState->mNumTracks = popcount(currentTrackMask);
}
@@ -323,12 +323,12 @@ void FastMixer::onStateChange()
void FastMixer::onWork()
{
- const FastMixerState * const current = (const FastMixerState *) this->current;
- FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->dumpState;
- const FastMixerState::Command command = this->command;
+ const FastMixerState * const current = (const FastMixerState *) mCurrent;
+ FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
+ const FastMixerState::Command command = mCommand;
const size_t frameCount = current->mFrameCount;
- if ((command & FastMixerState::MIX) && (mixer != NULL) && isWarm) {
+ if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
ALOG_ASSERT(mMixerBuffer != NULL);
// for each track, update volume and check for underrun
unsigned currentTrackMask = current->mTrackMask;
@@ -338,9 +338,9 @@ void FastMixer::onWork()
const FastTrack* fastTrack = &current->mFastTracks[i];
// Refresh the per-track timestamp
- if (timestampStatus == NO_ERROR) {
+ if (mTimestampStatus == NO_ERROR) {
uint32_t trackFramesWrittenButNotPresented =
- nativeFramesWrittenButNotPresented;
+ mNativeFramesWrittenButNotPresented;
uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
// Can't provide an AudioTimestamp before first frame presented,
// or during the brief 32-bit wraparound window
@@ -348,20 +348,20 @@ void FastMixer::onWork()
AudioTimestamp perTrackTimestamp;
perTrackTimestamp.mPosition =
trackFramesWritten - trackFramesWrittenButNotPresented;
- perTrackTimestamp.mTime = timestamp.mTime;
+ perTrackTimestamp.mTime = mTimestamp.mTime;
fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
}
}
- int name = fastTrackNames[i];
+ int name = mFastTrackNames[i];
ALOG_ASSERT(name >= 0);
if (fastTrack->mVolumeProvider != NULL) {
gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
- mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
- mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
+ mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
+ mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
}
// FIXME The current implementation of framesReady() for fast tracks
// takes a tryLock, which can block
@@ -382,43 +382,43 @@ void FastMixer::onWork()
if (framesReady == 0) {
underruns.mBitFields.mEmpty++;
underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
- mixer->disable(name);
+ mMixer->disable(name);
} else {
// allow mixing partial buffer
underruns.mBitFields.mPartial++;
underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
- mixer->enable(name);
+ mMixer->enable(name);
}
} else {
underruns.mBitFields.mFull++;
underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
- mixer->enable(name);
+ mMixer->enable(name);
}
ftDump->mUnderruns = underruns;
ftDump->mFramesReady = framesReady;
}
int64_t pts;
- if (outputSink == NULL || (OK != outputSink->getNextWriteTimestamp(&pts))) {
+ if (mOutputSink == NULL || (OK != mOutputSink->getNextWriteTimestamp(&pts))) {
pts = AudioBufferProvider::kInvalidPTS;
}
// process() is CPU-bound
- mixer->process(pts);
+ mMixer->process(pts);
mMixerBufferState = MIXED;
} else if (mMixerBufferState == MIXED) {
mMixerBufferState = UNDEFINED;
}
//bool didFullWrite = false; // dumpsys could display a count of partial writes
- if ((command & FastMixerState::WRITE) && (outputSink != NULL) && (mMixerBuffer != NULL)) {
+ if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
if (mMixerBufferState == UNDEFINED) {
memset(mMixerBuffer, 0, mMixerBufferSize);
mMixerBufferState = ZEROED;
}
void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
- if (format.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
- memcpy_by_audio_format(buffer, format.mFormat, mMixerBuffer, mMixerBufferFormat,
- frameCount * Format_channelCount(format));
+ if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
+ memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
+ frameCount * Format_channelCount(mFormat));
}
// if non-NULL, then duplicate write() to this non-blocking sink
NBAIO_Sink* teeSink;
@@ -429,31 +429,31 @@ void FastMixer::onWork()
// but this code should be modified to handle both non-blocking and blocking sinks
dumpState->mWriteSequence++;
ATRACE_BEGIN("write");
- ssize_t framesWritten = outputSink->write(buffer, frameCount);
+ ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
ATRACE_END();
dumpState->mWriteSequence++;
if (framesWritten >= 0) {
ALOG_ASSERT((size_t) framesWritten <= frameCount);
- totalNativeFramesWritten += framesWritten;
- dumpState->mFramesWritten = totalNativeFramesWritten;
+ mTotalNativeFramesWritten += framesWritten;
+ dumpState->mFramesWritten = mTotalNativeFramesWritten;
//if ((size_t) framesWritten == frameCount) {
// didFullWrite = true;
//}
} else {
dumpState->mWriteErrors++;
}
- attemptedWrite = true;
+ mAttemptedWrite = true;
// FIXME count # of writes blocked excessively, CPU usage, etc. for dump
- timestampStatus = outputSink->getTimestamp(timestamp);
- if (timestampStatus == NO_ERROR) {
- uint32_t totalNativeFramesPresented = timestamp.mPosition;
- if (totalNativeFramesPresented <= totalNativeFramesWritten) {
- nativeFramesWrittenButNotPresented =
- totalNativeFramesWritten - totalNativeFramesPresented;
+ mTimestampStatus = mOutputSink->getTimestamp(mTimestamp);
+ if (mTimestampStatus == NO_ERROR) {
+ uint32_t totalNativeFramesPresented = mTimestamp.mPosition;
+ if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
+ mNativeFramesWrittenButNotPresented =
+ mTotalNativeFramesWritten - totalNativeFramesPresented;
} else {
// HAL reported that more frames were presented than were written
- timestampStatus = INVALID_OPERATION;
+ mTimestampStatus = INVALID_OPERATION;
}
}
}
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 7649db2..06a68fb 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -48,36 +48,39 @@ private:
virtual void onStateChange();
virtual void onWork();
- // FIXME these former local variables need comments and to be renamed to have "m" prefix
- static const FastMixerState initial;
- FastMixerState preIdle; // copy of state before we went into idle
- long slopNs; // accumulated time we've woken up too early (> 0) or too late (< 0)
- int fastTrackNames[FastMixerState::kMaxFastTracks]; // handles used by mixer to identify tracks
- int generations[FastMixerState::kMaxFastTracks]; // last observed mFastTracks[i].mGeneration
- NBAIO_Sink *outputSink;
- int outputSinkGen;
- AudioMixer* mixer;
+ // FIXME these former local variables need comments
+ static const FastMixerState sInitial;
+
+ FastMixerState mPreIdle; // copy of state before we went into idle
+ long mSlopNs; // accumulated time we've woken up too early (> 0) or too late (< 0)
+ int mFastTrackNames[FastMixerState::kMaxFastTracks];
+ // handles used by mixer to identify tracks
+ int mGenerations[FastMixerState::kMaxFastTracks];
+ // last observed mFastTracks[i].mGeneration
+ NBAIO_Sink* mOutputSink;
+ int mOutputSinkGen;
+ AudioMixer* mMixer;
// mSinkBuffer audio format is stored in format.mFormat.
- void* mSinkBuffer; // used for mixer output format translation
+ void* mSinkBuffer; // used for mixer output format translation
// if sink format is different than mixer output.
- size_t mSinkBufferSize;
- uint32_t mSinkChannelCount;
+ size_t mSinkBufferSize;
+ uint32_t mSinkChannelCount;
audio_channel_mask_t mSinkChannelMask;
- void* mMixerBuffer; // mixer output buffer.
- size_t mMixerBufferSize;
- audio_format_t mMixerBufferFormat; // mixer output format: AUDIO_FORMAT_PCM_(16_BIT|FLOAT).
+ void* mMixerBuffer; // mixer output buffer.
+ size_t mMixerBufferSize;
+ audio_format_t mMixerBufferFormat; // mixer output format: AUDIO_FORMAT_PCM_(16_BIT|FLOAT).
enum {UNDEFINED, MIXED, ZEROED} mMixerBufferState;
- NBAIO_Format format;
- unsigned sampleRate;
- int fastTracksGen;
- FastMixerDumpState dummyDumpState;
- uint32_t totalNativeFramesWritten; // copied to dumpState->mFramesWritten
+ NBAIO_Format mFormat;
+ unsigned mSampleRate;
+ int mFastTracksGen;
+ FastMixerDumpState mDummyFastMixerDumpState;
+ uint32_t mTotalNativeFramesWritten; // copied to dumpState->mFramesWritten
// next 2 fields are valid only when timestampStatus == NO_ERROR
- AudioTimestamp timestamp;
- uint32_t nativeFramesWrittenButNotPresented;
+ AudioTimestamp mTimestamp;
+ uint32_t mNativeFramesWrittenButNotPresented;
}; // class FastMixer
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 0ddd908..386b29d 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -18,7 +18,7 @@
//#define LOG_NDEBUG 0
#include "Configuration.h"
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
#include <cpustats/CentralTendencyStatistics.h>
#ifdef CPU_FREQUENCY_STATISTICS
#include <cpustats/ThreadCpuUsage.h>
@@ -30,39 +30,14 @@
namespace android {
-FastMixerDumpState::FastMixerDumpState(
-#ifdef FAST_MIXER_STATISTICS
- uint32_t samplingN
-#endif
- ) : FastThreadDumpState(),
+FastMixerDumpState::FastMixerDumpState() : FastThreadDumpState(),
mWriteSequence(0), mFramesWritten(0),
mNumTracks(0), mWriteErrors(0),
mSampleRate(0), mFrameCount(0),
mTrackMask(0)
{
-#ifdef FAST_MIXER_STATISTICS
- increaseSamplingN(samplingN);
-#endif
}
-#ifdef FAST_MIXER_STATISTICS
-void FastMixerDumpState::increaseSamplingN(uint32_t samplingN)
-{
- if (samplingN <= mSamplingN || samplingN > kSamplingN || roundup(samplingN) != samplingN) {
- return;
- }
- uint32_t additional = samplingN - mSamplingN;
- // sample arrays aren't accessed atomically with respect to the bounds,
- // so clearing reduces chance for dumpsys to read random uninitialized samples
- memset(&mMonotonicNs[mSamplingN], 0, sizeof(mMonotonicNs[0]) * additional);
- memset(&mLoadNs[mSamplingN], 0, sizeof(mLoadNs[0]) * additional);
-#ifdef CPU_FREQUENCY_STATISTICS
- memset(&mCpukHz[mSamplingN], 0, sizeof(mCpukHz[0]) * additional);
-#endif
- mSamplingN = samplingN;
-}
-#endif
-
FastMixerDumpState::~FastMixerDumpState()
{
}
@@ -87,34 +62,6 @@ void FastMixerDumpState::dump(int fd) const
dprintf(fd, " FastMixer not initialized\n");
return;
}
-#define COMMAND_MAX 32
- char string[COMMAND_MAX];
- switch (mCommand) {
- case FastMixerState::INITIAL:
- strcpy(string, "INITIAL");
- break;
- case FastMixerState::HOT_IDLE:
- strcpy(string, "HOT_IDLE");
- break;
- case FastMixerState::COLD_IDLE:
- strcpy(string, "COLD_IDLE");
- break;
- case FastMixerState::EXIT:
- strcpy(string, "EXIT");
- break;
- case FastMixerState::MIX:
- strcpy(string, "MIX");
- break;
- case FastMixerState::WRITE:
- strcpy(string, "WRITE");
- break;
- case FastMixerState::MIX_WRITE:
- strcpy(string, "MIX_WRITE");
- break;
- default:
- snprintf(string, COMMAND_MAX, "%d", mCommand);
- break;
- }
double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
(mMeasuredWarmupTs.tv_nsec / 1000000.0);
double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
@@ -122,11 +69,11 @@ void FastMixerDumpState::dump(int fd) const
" numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
" sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
" mixPeriod=%.2f ms\n",
- string, mWriteSequence, mFramesWritten,
+ FastMixerState::commandToString(mCommand), mWriteSequence, mFramesWritten,
mNumTracks, mWriteErrors, mUnderruns, mOverruns,
mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
mixPeriodSec * 1e3);
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
// find the interval of valid samples
uint32_t bounds = mBounds;
uint32_t newestOpen = bounds & 0xFFFF;
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index f8354dd..ac15e7c 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -55,22 +55,12 @@ private:
struct FastTrackDump {
FastTrackDump() : mFramesReady(0) { }
/*virtual*/ ~FastTrackDump() { }
- FastTrackUnderruns mUnderruns;
- size_t mFramesReady; // most recent value only; no long-term statistics kept
+ FastTrackUnderruns mUnderruns;
+ size_t mFramesReady; // most recent value only; no long-term statistics kept
};
-// The FastMixerDumpState keeps a cache of FastMixer statistics that can be logged by dumpsys.
-// Each individual native word-sized field is accessed atomically. But the
-// overall structure is non-atomic, that is there may be an inconsistency between fields.
-// No barriers or locks are used for either writing or reading.
-// Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks).
-// It has a different lifetime than the FastMixer, and so it can't be a member of FastMixer.
struct FastMixerDumpState : FastThreadDumpState {
- FastMixerDumpState(
-#ifdef FAST_MIXER_STATISTICS
- uint32_t samplingN = kSamplingNforLowRamDevice
-#endif
- );
+ FastMixerDumpState();
/*virtual*/ ~FastMixerDumpState();
void dump(int fd) const; // should only be called on a stable copy, not the original
@@ -83,14 +73,6 @@ struct FastMixerDumpState : FastThreadDumpState {
size_t mFrameCount;
uint32_t mTrackMask; // mask of active tracks
FastTrackDump mTracks[FastMixerState::kMaxFastTracks];
-
-#ifdef FAST_MIXER_STATISTICS
- // Compile-time constant for a "low RAM device", must be a power of 2 <= kSamplingN.
- // This value was chosen such that each array uses 1 small page (4 Kbytes).
- static const uint32_t kSamplingNforLowRamDevice = 0x400;
- // Increase sampling window after construction, must be a power of 2 <= kSamplingN
- void increaseSamplingN(uint32_t samplingN);
-#endif
};
} // android
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 3aa8dad..a8c2634 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -39,4 +39,19 @@ FastMixerState::~FastMixerState()
{
}
+// static
+const char *FastMixerState::commandToString(Command command)
+{
+ const char *str = FastThreadState::commandToString(command);
+ if (str != NULL) {
+ return str;
+ }
+ switch (command) {
+ case FastMixerState::MIX: return "MIX";
+ case FastMixerState::WRITE: return "WRITE";
+ case FastMixerState::MIX_WRITE: return "MIX_WRITE";
+ }
+ LOG_ALWAYS_FATAL("%s", __func__);
+}
+
} // namespace android
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 661c9ca..916514f 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -73,6 +73,9 @@ struct FastMixerState : FastThreadState {
// This might be a one-time configuration rather than per-state
NBAIO_Sink* mTeeSink; // if non-NULL, then duplicate write()s to this non-blocking sink
+
+ // never returns NULL; asserts if command is invalid
+ static const char *commandToString(Command command);
}; // struct FastMixerState
} // namespace android
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index b69cc85..5ca579b 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -36,47 +36,47 @@
namespace android {
FastThread::FastThread() : Thread(false /*canCallJava*/),
- // re-initialized to &initial by subclass constructor
- previous(NULL), current(NULL),
- /* oldTs({0, 0}), */
- oldTsValid(false),
- sleepNs(-1),
- periodNs(0),
- underrunNs(0),
- overrunNs(0),
- forceNs(0),
- warmupNsMin(0),
- warmupNsMax(LONG_MAX),
- // re-initialized to &dummyDumpState by subclass constructor
+ // re-initialized to &sInitial by subclass constructor
+ mPrevious(NULL), mCurrent(NULL),
+ /* mOldTs({0, 0}), */
+ mOldTsValid(false),
+ mSleepNs(-1),
+ mPeriodNs(0),
+ mUnderrunNs(0),
+ mOverrunNs(0),
+ mForceNs(0),
+ mWarmupNsMin(0),
+ mWarmupNsMax(LONG_MAX),
+ // re-initialized to &mDummySubclassDumpState by subclass constructor
mDummyDumpState(NULL),
- dumpState(NULL),
- ignoreNextOverrun(true),
-#ifdef FAST_MIXER_STATISTICS
- // oldLoad
- oldLoadValid(false),
- bounds(0),
- full(false),
- // tcu
+ mDumpState(NULL),
+ mIgnoreNextOverrun(true),
+#ifdef FAST_THREAD_STATISTICS
+ // mOldLoad
+ mOldLoadValid(false),
+ mBounds(0),
+ mFull(false),
+ // mTcu
#endif
- coldGen(0),
- isWarm(false),
- /* measuredWarmupTs({0, 0}), */
- warmupCycles(0),
- warmupConsecutiveInRangeCycles(0),
- // dummyLogWriter
- logWriter(&dummyLogWriter),
- timestampStatus(INVALID_OPERATION),
+ mColdGen(0),
+ mIsWarm(false),
+ /* mMeasuredWarmupTs({0, 0}), */
+ mWarmupCycles(0),
+ mWarmupConsecutiveInRangeCycles(0),
+ // mDummyLogWriter
+ mLogWriter(&mDummyLogWriter),
+ mTimestampStatus(INVALID_OPERATION),
- command(FastThreadState::INITIAL),
+ mCommand(FastThreadState::INITIAL),
#if 0
frameCount(0),
#endif
- attemptedWrite(false)
+ mAttemptedWrite(false)
{
- oldTs.tv_sec = 0;
- oldTs.tv_nsec = 0;
- measuredWarmupTs.tv_sec = 0;
- measuredWarmupTs.tv_nsec = 0;
+ mOldTs.tv_sec = 0;
+ mOldTs.tv_nsec = 0;
+ mMeasuredWarmupTs.tv_sec = 0;
+ mMeasuredWarmupTs.tv_nsec = 0;
}
FastThread::~FastThread()
@@ -88,34 +88,34 @@ bool FastThread::threadLoop()
for (;;) {
// either nanosleep, sched_yield, or busy wait
- if (sleepNs >= 0) {
- if (sleepNs > 0) {
- ALOG_ASSERT(sleepNs < 1000000000);
- const struct timespec req = {0, sleepNs};
+ if (mSleepNs >= 0) {
+ if (mSleepNs > 0) {
+ ALOG_ASSERT(mSleepNs < 1000000000);
+ const struct timespec req = {0, mSleepNs};
nanosleep(&req, NULL);
} else {
sched_yield();
}
}
// default to long sleep for next cycle
- sleepNs = FAST_DEFAULT_NS;
+ mSleepNs = FAST_DEFAULT_NS;
// poll for state change
const FastThreadState *next = poll();
if (next == NULL) {
// continue to use the default initial state until a real state is available
- // FIXME &initial not available, should save address earlier
- //ALOG_ASSERT(current == &initial && previous == &initial);
- next = current;
+ // FIXME &sInitial not available, should save address earlier
+ //ALOG_ASSERT(mCurrent == &sInitial && previous == &sInitial);
+ next = mCurrent;
}
- command = next->mCommand;
- if (next != current) {
+ mCommand = next->mCommand;
+ if (next != mCurrent) {
// As soon as possible of learning of a new dump area, start using it
- dumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
- logWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &dummyLogWriter;
- setLog(logWriter);
+ mDumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
+ mLogWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &mDummyLogWriter;
+ setLog(mLogWriter);
// We want to always have a valid reference to the previous (non-idle) state.
// However, the state queue only guarantees access to current and previous states.
@@ -126,37 +126,38 @@ bool FastThread::threadLoop()
// non-idle -> idle update previous from copy of current
// idle -> idle don't update previous
// idle -> non-idle don't update previous
- if (!(current->mCommand & FastThreadState::IDLE)) {
- if (command & FastThreadState::IDLE) {
+ if (!(mCurrent->mCommand & FastThreadState::IDLE)) {
+ if (mCommand & FastThreadState::IDLE) {
onIdle();
- oldTsValid = false;
-#ifdef FAST_MIXER_STATISTICS
- oldLoadValid = false;
+ mOldTsValid = false;
+#ifdef FAST_THREAD_STATISTICS
+ mOldLoadValid = false;
#endif
- ignoreNextOverrun = true;
+ mIgnoreNextOverrun = true;
}
- previous = current;
+ mPrevious = mCurrent;
}
- current = next;
+ mCurrent = next;
}
#if !LOG_NDEBUG
next = NULL; // not referenced again
#endif
- dumpState->mCommand = command;
+ mDumpState->mCommand = mCommand;
+ // FIXME what does this comment mean?
// << current, previous, command, dumpState >>
- switch (command) {
+ switch (mCommand) {
case FastThreadState::INITIAL:
case FastThreadState::HOT_IDLE:
- sleepNs = FAST_HOT_IDLE_NS;
+ mSleepNs = FAST_HOT_IDLE_NS;
continue;
case FastThreadState::COLD_IDLE:
// only perform a cold idle command once
// FIXME consider checking previous state and only perform if previous != COLD_IDLE
- if (current->mColdGen != coldGen) {
- int32_t *coldFutexAddr = current->mColdFutexAddr;
+ if (mCurrent->mColdGen != mColdGen) {
+ int32_t *coldFutexAddr = mCurrent->mColdFutexAddr;
ALOG_ASSERT(coldFutexAddr != NULL);
int32_t old = android_atomic_dec(coldFutexAddr);
if (old <= 0) {
@@ -168,42 +169,42 @@ bool FastThread::threadLoop()
}
// This may be overly conservative; there could be times that the normal mixer
// requests such a brief cold idle that it doesn't require resetting this flag.
- isWarm = false;
- measuredWarmupTs.tv_sec = 0;
- measuredWarmupTs.tv_nsec = 0;
- warmupCycles = 0;
- warmupConsecutiveInRangeCycles = 0;
- sleepNs = -1;
- coldGen = current->mColdGen;
-#ifdef FAST_MIXER_STATISTICS
- bounds = 0;
- full = false;
+ mIsWarm = false;
+ mMeasuredWarmupTs.tv_sec = 0;
+ mMeasuredWarmupTs.tv_nsec = 0;
+ mWarmupCycles = 0;
+ mWarmupConsecutiveInRangeCycles = 0;
+ mSleepNs = -1;
+ mColdGen = mCurrent->mColdGen;
+#ifdef FAST_THREAD_STATISTICS
+ mBounds = 0;
+ mFull = false;
#endif
- oldTsValid = !clock_gettime(CLOCK_MONOTONIC, &oldTs);
- timestampStatus = INVALID_OPERATION;
+ mOldTsValid = !clock_gettime(CLOCK_MONOTONIC, &mOldTs);
+ mTimestampStatus = INVALID_OPERATION;
} else {
- sleepNs = FAST_HOT_IDLE_NS;
+ mSleepNs = FAST_HOT_IDLE_NS;
}
continue;
case FastThreadState::EXIT:
onExit();
return false;
default:
- LOG_ALWAYS_FATAL_IF(!isSubClassCommand(command));
+ LOG_ALWAYS_FATAL_IF(!isSubClassCommand(mCommand));
break;
}
// there is a non-idle state available to us; did the state change?
- if (current != previous) {
+ if (mCurrent != mPrevious) {
onStateChange();
#if 1 // FIXME shouldn't need this
// only process state change once
- previous = current;
+ mPrevious = mCurrent;
#endif
}
// do work using current state here
- attemptedWrite = false;
+ mAttemptedWrite = false;
onWork();
// To be exactly periodic, compute the next sleep time based on current time.
@@ -212,13 +213,13 @@ bool FastThread::threadLoop()
struct timespec newTs;
int rc = clock_gettime(CLOCK_MONOTONIC, &newTs);
if (rc == 0) {
- //logWriter->logTimestamp(newTs);
- if (oldTsValid) {
- time_t sec = newTs.tv_sec - oldTs.tv_sec;
- long nsec = newTs.tv_nsec - oldTs.tv_nsec;
+ //mLogWriter->logTimestamp(newTs);
+ if (mOldTsValid) {
+ time_t sec = newTs.tv_sec - mOldTs.tv_sec;
+ long nsec = newTs.tv_nsec - mOldTs.tv_nsec;
ALOGE_IF(sec < 0 || (sec == 0 && nsec < 0),
"clock_gettime(CLOCK_MONOTONIC) failed: was %ld.%09ld but now %ld.%09ld",
- oldTs.tv_sec, oldTs.tv_nsec, newTs.tv_sec, newTs.tv_nsec);
+ mOldTs.tv_sec, mOldTs.tv_nsec, newTs.tv_sec, newTs.tv_nsec);
if (nsec < 0) {
--sec;
nsec += 1000000000;
@@ -227,69 +228,69 @@ bool FastThread::threadLoop()
// do not start pulling data from tracks and mixing until warmup is complete.
// Warmup is considered complete after the earlier of:
// MIN_WARMUP_CYCLES consecutive in-range write() attempts,
- // where "in-range" means warmupNsMin <= cycle time <= warmupNsMax
+ // where "in-range" means mWarmupNsMin <= cycle time <= mWarmupNsMax
// MAX_WARMUP_CYCLES write() attempts.
// This is overly conservative, but to get better accuracy requires a new HAL API.
- if (!isWarm && attemptedWrite) {
- measuredWarmupTs.tv_sec += sec;
- measuredWarmupTs.tv_nsec += nsec;
- if (measuredWarmupTs.tv_nsec >= 1000000000) {
- measuredWarmupTs.tv_sec++;
- measuredWarmupTs.tv_nsec -= 1000000000;
+ if (!mIsWarm && mAttemptedWrite) {
+ mMeasuredWarmupTs.tv_sec += sec;
+ mMeasuredWarmupTs.tv_nsec += nsec;
+ if (mMeasuredWarmupTs.tv_nsec >= 1000000000) {
+ mMeasuredWarmupTs.tv_sec++;
+ mMeasuredWarmupTs.tv_nsec -= 1000000000;
}
- ++warmupCycles;
- if (warmupNsMin <= nsec && nsec <= warmupNsMax) {
- ALOGV("warmup cycle %d in range: %.03f ms", warmupCycles, nsec * 1e-9);
- ++warmupConsecutiveInRangeCycles;
+ ++mWarmupCycles;
+ if (mWarmupNsMin <= nsec && nsec <= mWarmupNsMax) {
+ ALOGV("warmup cycle %d in range: %.03f ms", mWarmupCycles, nsec * 1e-9);
+ ++mWarmupConsecutiveInRangeCycles;
} else {
- ALOGV("warmup cycle %d out of range: %.03f ms", warmupCycles, nsec * 1e-9);
- warmupConsecutiveInRangeCycles = 0;
+ ALOGV("warmup cycle %d out of range: %.03f ms", mWarmupCycles, nsec * 1e-9);
+ mWarmupConsecutiveInRangeCycles = 0;
}
- if ((warmupConsecutiveInRangeCycles >= MIN_WARMUP_CYCLES) ||
- (warmupCycles >= MAX_WARMUP_CYCLES)) {
- isWarm = true;
- dumpState->mMeasuredWarmupTs = measuredWarmupTs;
- dumpState->mWarmupCycles = warmupCycles;
+ if ((mWarmupConsecutiveInRangeCycles >= MIN_WARMUP_CYCLES) ||
+ (mWarmupCycles >= MAX_WARMUP_CYCLES)) {
+ mIsWarm = true;
+ mDumpState->mMeasuredWarmupTs = mMeasuredWarmupTs;
+ mDumpState->mWarmupCycles = mWarmupCycles;
}
}
- sleepNs = -1;
- if (isWarm) {
- if (sec > 0 || nsec > underrunNs) {
+ mSleepNs = -1;
+ if (mIsWarm) {
+ if (sec > 0 || nsec > mUnderrunNs) {
ATRACE_NAME("underrun");
// FIXME only log occasionally
ALOGV("underrun: time since last cycle %d.%03ld sec",
(int) sec, nsec / 1000000L);
- dumpState->mUnderruns++;
- ignoreNextOverrun = true;
- } else if (nsec < overrunNs) {
- if (ignoreNextOverrun) {
- ignoreNextOverrun = false;
+ mDumpState->mUnderruns++;
+ mIgnoreNextOverrun = true;
+ } else if (nsec < mOverrunNs) {
+ if (mIgnoreNextOverrun) {
+ mIgnoreNextOverrun = false;
} else {
// FIXME only log occasionally
ALOGV("overrun: time since last cycle %d.%03ld sec",
(int) sec, nsec / 1000000L);
- dumpState->mOverruns++;
+ mDumpState->mOverruns++;
}
// This forces a minimum cycle time. It:
// - compensates for an audio HAL with jitter due to sample rate conversion
// - works with a variable buffer depth audio HAL that never pulls at a
- // rate < than overrunNs per buffer.
+ // rate < than mOverrunNs per buffer.
// - recovers from overrun immediately after underrun
// It doesn't work with a non-blocking audio HAL.
- sleepNs = forceNs - nsec;
+ mSleepNs = mForceNs - nsec;
} else {
- ignoreNextOverrun = false;
+ mIgnoreNextOverrun = false;
}
}
-#ifdef FAST_MIXER_STATISTICS
- if (isWarm) {
+#ifdef FAST_THREAD_STATISTICS
+ if (mIsWarm) {
// advance the FIFO queue bounds
- size_t i = bounds & (dumpState->mSamplingN - 1);
- bounds = (bounds & 0xFFFF0000) | ((bounds + 1) & 0xFFFF);
- if (full) {
- bounds += 0x10000;
- } else if (!(bounds & (dumpState->mSamplingN - 1))) {
- full = true;
+ size_t i = mBounds & (mDumpState->mSamplingN - 1);
+ mBounds = (mBounds & 0xFFFF0000) | ((mBounds + 1) & 0xFFFF);
+ if (mFull) {
+ mBounds += 0x10000;
+ } else if (!(mBounds & (mDumpState->mSamplingN - 1))) {
+ mFull = true;
}
// compute the delta value of clock_gettime(CLOCK_MONOTONIC)
uint32_t monotonicNs = nsec;
@@ -301,9 +302,9 @@ bool FastThread::threadLoop()
struct timespec newLoad;
rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &newLoad);
if (rc == 0) {
- if (oldLoadValid) {
- sec = newLoad.tv_sec - oldLoad.tv_sec;
- nsec = newLoad.tv_nsec - oldLoad.tv_nsec;
+ if (mOldLoadValid) {
+ sec = newLoad.tv_sec - mOldLoad.tv_sec;
+ nsec = newLoad.tv_nsec - mOldLoad.tv_nsec;
if (nsec < 0) {
--sec;
nsec += 1000000000;
@@ -314,42 +315,42 @@ bool FastThread::threadLoop()
}
} else {
// first time through the loop
- oldLoadValid = true;
+ mOldLoadValid = true;
}
- oldLoad = newLoad;
+ mOldLoad = newLoad;
}
#ifdef CPU_FREQUENCY_STATISTICS
// get the absolute value of CPU clock frequency in kHz
int cpuNum = sched_getcpu();
- uint32_t kHz = tcu.getCpukHz(cpuNum);
+ uint32_t kHz = mTcu.getCpukHz(cpuNum);
kHz = (kHz << 4) | (cpuNum & 0xF);
#endif
// save values in FIFO queues for dumpsys
// these stores #1, #2, #3 are not atomic with respect to each other,
// or with respect to store #4 below
- dumpState->mMonotonicNs[i] = monotonicNs;
- dumpState->mLoadNs[i] = loadNs;
+ mDumpState->mMonotonicNs[i] = monotonicNs;
+ mDumpState->mLoadNs[i] = loadNs;
#ifdef CPU_FREQUENCY_STATISTICS
- dumpState->mCpukHz[i] = kHz;
+ mDumpState->mCpukHz[i] = kHz;
#endif
// this store #4 is not atomic with respect to stores #1, #2, #3 above, but
// the newest open & oldest closed halves are atomic with respect to each other
- dumpState->mBounds = bounds;
+ mDumpState->mBounds = mBounds;
ATRACE_INT("cycle_ms", monotonicNs / 1000000);
ATRACE_INT("load_us", loadNs / 1000);
}
#endif
} else {
// first time through the loop
- oldTsValid = true;
- sleepNs = periodNs;
- ignoreNextOverrun = true;
+ mOldTsValid = true;
+ mSleepNs = mPeriodNs;
+ mIgnoreNextOverrun = true;
}
- oldTs = newTs;
+ mOldTs = newTs;
} else {
// monotonic clock is broken
- oldTsValid = false;
- sleepNs = periodNs;
+ mOldTsValid = false;
+ mSleepNs = mPeriodNs;
}
} // for (;;)
diff --git a/services/audioflinger/FastThread.h b/services/audioflinger/FastThread.h
index cb32e9d..2efb6de 100644
--- a/services/audioflinger/FastThread.h
+++ b/services/audioflinger/FastThread.h
@@ -48,44 +48,45 @@ protected:
virtual void onStateChange() = 0;
virtual void onWork() = 0;
- // FIXME these former local variables need comments and to be renamed to have an "m" prefix
- const FastThreadState *previous;
- const FastThreadState *current;
- struct timespec oldTs;
- bool oldTsValid;
- long sleepNs; // -1: busy wait, 0: sched_yield, > 0: nanosleep
- long periodNs; // expected period; the time required to render one mix buffer
- long underrunNs; // underrun likely when write cycle is greater than this value
- long overrunNs; // overrun likely when write cycle is less than this value
- long forceNs; // if overrun detected, force the write cycle to take this much time
- long warmupNsMin; // warmup complete when write cycle is greater than or equal to this value
- long warmupNsMax; // and less than or equal to this value
- FastThreadDumpState *mDummyDumpState;
- FastThreadDumpState *dumpState;
- bool ignoreNextOverrun; // used to ignore initial overrun and first after an underrun
-#ifdef FAST_MIXER_STATISTICS
- struct timespec oldLoad; // previous value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
- bool oldLoadValid; // whether oldLoad is valid
- uint32_t bounds;
- bool full; // whether we have collected at least mSamplingN samples
+ // FIXME these former local variables need comments
+ const FastThreadState* mPrevious;
+ const FastThreadState* mCurrent;
+ struct timespec mOldTs;
+ bool mOldTsValid;
+ long mSleepNs; // -1: busy wait, 0: sched_yield, > 0: nanosleep
+ long mPeriodNs; // expected period; the time required to render one mix buffer
+ long mUnderrunNs; // underrun likely when write cycle is greater than this value
+ long mOverrunNs; // overrun likely when write cycle is less than this value
+ long mForceNs; // if overrun detected,
+ // force the write cycle to take this much time
+ long mWarmupNsMin; // warmup complete when write cycle is greater than or equal to
+ // this value
+ long mWarmupNsMax; // and less than or equal to this value
+ FastThreadDumpState* mDummyDumpState;
+ FastThreadDumpState* mDumpState;
+ bool mIgnoreNextOverrun; // used to ignore initial overrun and first after an
+ // underrun
+#ifdef FAST_THREAD_STATISTICS
+ struct timespec mOldLoad; // previous value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
+ bool mOldLoadValid; // whether oldLoad is valid
+ uint32_t mBounds;
+ bool mFull; // whether we have collected at least mSamplingN samples
#ifdef CPU_FREQUENCY_STATISTICS
- ThreadCpuUsage tcu; // for reading the current CPU clock frequency in kHz
+ ThreadCpuUsage mTcu; // for reading the current CPU clock frequency in kHz
#endif
#endif
- unsigned coldGen; // last observed mColdGen
- bool isWarm; // true means ready to mix, false means wait for warmup before mixing
- struct timespec measuredWarmupTs; // how long did it take for warmup to complete
- uint32_t warmupCycles; // counter of number of loop cycles during warmup phase
- uint32_t warmupConsecutiveInRangeCycles; // number of consecutive cycles in range
- NBLog::Writer dummyLogWriter;
- NBLog::Writer *logWriter;
- status_t timestampStatus;
+ unsigned mColdGen; // last observed mColdGen
+ bool mIsWarm; // true means ready to mix,
+ // false means wait for warmup before mixing
+ struct timespec mMeasuredWarmupTs; // how long did it take for warmup to complete
+ uint32_t mWarmupCycles; // counter of number of loop cycles during warmup phase
+ uint32_t mWarmupConsecutiveInRangeCycles; // number of consecutive cycles in range
+ NBLog::Writer mDummyLogWriter;
+ NBLog::Writer* mLogWriter;
+ status_t mTimestampStatus;
- FastThreadState::Command command;
-#if 0
- size_t frameCount;
-#endif
- bool attemptedWrite;
+ FastThreadState::Command mCommand;
+ bool mAttemptedWrite;
}; // class FastThread
diff --git a/services/audioflinger/FastThreadDumpState.cpp b/services/audioflinger/FastThreadDumpState.cpp
index d7b825d..9df5c4c 100644
--- a/services/audioflinger/FastThreadDumpState.cpp
+++ b/services/audioflinger/FastThreadDumpState.cpp
@@ -22,16 +22,37 @@ FastThreadDumpState::FastThreadDumpState() :
mCommand(FastThreadState::INITIAL), mUnderruns(0), mOverruns(0),
/* mMeasuredWarmupTs({0, 0}), */
mWarmupCycles(0)
-#ifdef FAST_MIXER_STATISTICS
- , mSamplingN(1), mBounds(0)
+#ifdef FAST_THREAD_STATISTICS
+ , mSamplingN(0), mBounds(0)
#endif
{
mMeasuredWarmupTs.tv_sec = 0;
mMeasuredWarmupTs.tv_nsec = 0;
+#ifdef FAST_THREAD_STATISTICS
+ increaseSamplingN(1);
+#endif
}
FastThreadDumpState::~FastThreadDumpState()
{
}
+#ifdef FAST_THREAD_STATISTICS
+void FastThreadDumpState::increaseSamplingN(uint32_t samplingN)
+{
+ if (samplingN <= mSamplingN || samplingN > kSamplingN || roundup(samplingN) != samplingN) {
+ return;
+ }
+ uint32_t additional = samplingN - mSamplingN;
+ // sample arrays aren't accessed atomically with respect to the bounds,
+ // so clearing reduces chance for dumpsys to read random uninitialized samples
+ memset(&mMonotonicNs[mSamplingN], 0, sizeof(mMonotonicNs[0]) * additional);
+ memset(&mLoadNs[mSamplingN], 0, sizeof(mLoadNs[0]) * additional);
+#ifdef CPU_FREQUENCY_STATISTICS
+ memset(&mCpukHz[mSamplingN], 0, sizeof(mCpukHz[0]) * additional);
+#endif
+ mSamplingN = samplingN;
+}
+#endif
+
} // android
diff --git a/services/audioflinger/FastThreadDumpState.h b/services/audioflinger/FastThreadDumpState.h
index 17afbe5..1ce0914 100644
--- a/services/audioflinger/FastThreadDumpState.h
+++ b/services/audioflinger/FastThreadDumpState.h
@@ -22,7 +22,12 @@
namespace android {
-// FIXME extract common part of comment at FastMixerDumpState
+// The FastThreadDumpState keeps a cache of FastThread statistics that can be logged by dumpsys.
+// Each individual native word-sized field is accessed atomically. But the
+// overall structure is non-atomic, that is there may be an inconsistency between fields.
+// No barriers or locks are used for either writing or reading.
+// Only POD types are permitted, and the contents shouldn't be trusted (i.e. do range checks).
+// It has a different lifetime than the FastThread, and so it can't be a member of FastThread.
struct FastThreadDumpState {
FastThreadDumpState();
/*virtual*/ ~FastThreadDumpState();
@@ -33,12 +38,15 @@ struct FastThreadDumpState {
struct timespec mMeasuredWarmupTs; // measured warmup time
uint32_t mWarmupCycles; // number of loop cycles required to warmup
-#ifdef FAST_MIXER_STATISTICS
+#ifdef FAST_THREAD_STATISTICS
// Recently collected samples of per-cycle monotonic time, thread CPU time, and CPU frequency.
// kSamplingN is max size of sampling frame (statistics), and must be a power of 2 <= 0x8000.
// The sample arrays are virtually allocated based on this compile-time constant,
// but are only initialized and used based on the runtime parameter mSamplingN.
static const uint32_t kSamplingN = 0x8000;
+ // Compile-time constant for a "low RAM device", must be a power of 2 <= kSamplingN.
+ // This value was chosen such that each array uses 1 small page (4 Kbytes).
+ static const uint32_t kSamplingNforLowRamDevice = 0x400;
// Corresponding runtime maximum size of sample arrays, must be a power of 2 <= kSamplingN.
uint32_t mSamplingN;
// The bounds define the interval of valid samples, and are represented as follows:
@@ -52,6 +60,9 @@ struct FastThreadDumpState {
#ifdef CPU_FREQUENCY_STATISTICS
uint32_t mCpukHz[kSamplingN]; // absolute CPU clock frequency in kHz, bits 0-3 are CPU#
#endif
+
+ // Increase sampling window after construction, must be a power of 2 <= kSamplingN
+ void increaseSamplingN(uint32_t samplingN);
#endif
}; // struct FastThreadDumpState
diff --git a/services/audioflinger/FastThreadState.cpp b/services/audioflinger/FastThreadState.cpp
index e6cf85c..ad5f31f 100644
--- a/services/audioflinger/FastThreadState.cpp
+++ b/services/audioflinger/FastThreadState.cpp
@@ -29,4 +29,16 @@ FastThreadState::~FastThreadState()
{
}
+// static
+const char *FastThreadState::commandToString(FastThreadState::Command command)
+{
+ switch (command) {
+ case FastThreadState::INITIAL: return "INITIAL";
+ case FastThreadState::HOT_IDLE: return "HOT_IDLE";
+ case FastThreadState::COLD_IDLE: return "COLD_IDLE";
+ case FastThreadState::EXIT: return "EXIT";
+ }
+ return NULL;
+}
+
} // namespace android
diff --git a/services/audioflinger/FastThreadState.h b/services/audioflinger/FastThreadState.h
index 011921d..f18f846 100644
--- a/services/audioflinger/FastThreadState.h
+++ b/services/audioflinger/FastThreadState.h
@@ -46,6 +46,8 @@ struct FastThreadState {
FastThreadDumpState* mDumpState; // if non-NULL, then update dump state periodically
NBLog::Writer* mNBLogWriter; // non-blocking logger
+ // returns NULL if command belongs to a subclass
+ static const char *commandToString(Command command);
}; // struct FastThreadState
} // android
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 4f0c6b1..efbdcff 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -694,4 +694,4 @@ status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_co
}
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 40ab0af..7451245 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3116,8 +3116,10 @@ ssize_t AudioFlinger::MixerThread::threadLoop_write()
#endif
}
state->mCommand = FastMixerState::MIX_WRITE;
+#ifdef FAST_THREAD_STATISTICS
mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
- FastMixerDumpState::kSamplingNforLowRamDevice : FastMixerDumpState::kSamplingN);
+ FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
+#endif
sq->end();
sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
if (kUseFastMixer == FastMixer_Dynamic) {
@@ -5386,8 +5388,8 @@ reacquire_wakelock:
state->mCommand = FastCaptureState::READ_WRITE;
#if 0 // FIXME
mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
- FastCaptureDumpState::kSamplingNforLowRamDevice :
- FastMixerDumpState::kSamplingN);
+ FastThreadDumpState::kSamplingNforLowRamDevice :
+ FastThreadDumpState::kSamplingN);
#endif
didModify = true;
}
@@ -6520,4 +6522,4 @@ void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *co
config->ext.mix.usecase.source = mAudioSource;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index fa0beaa..8329be4 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2182,4 +2182,4 @@ void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffe
mProxy->releaseBuffer(buffer);
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b48dc80..53ec0f6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4467,7 +4467,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate
if (device) break;
device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
if (device) break;
- if (mPhoneState != AUDIO_MODE_IN_CALL) {
+ if (!isInCall()) {
device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
if (device) break;
device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 00a70eb..8e894cd 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "CameraFlashlight"
#define ATRACE_TAG ATRACE_TAG_CAMERA
-#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -32,16 +32,21 @@
namespace android {
+/////////////////////////////////////////////////////////////////////
+// CameraFlashlight implementation begins
+// used by camera service to control flashflight.
+/////////////////////////////////////////////////////////////////////
CameraFlashlight::CameraFlashlight(CameraModule& cameraModule,
const camera_module_callbacks_t& callbacks) :
mCameraModule(&cameraModule),
- mCallbacks(&callbacks) {
+ mCallbacks(&callbacks),
+ mFlashlightMapInitialized(false) {
}
CameraFlashlight::~CameraFlashlight() {
}
-status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) {
+status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
cameraId.string());
if (mFlashControl != NULL) {
@@ -52,7 +57,7 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) {
if (mCameraModule->getRawModule()->module_api_version >=
CAMERA_MODULE_API_VERSION_2_4) {
- mFlashControl = new FlashControl(*mCameraModule, *mCallbacks);
+ mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks);
if (mFlashControl == NULL) {
ALOGV("%s: cannot create flash control for module api v2.4+",
__FUNCTION__);
@@ -67,7 +72,7 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) {
res = mCameraModule->getCameraInfo(
atoi(String8(cameraId).string()), &info);
if (res) {
- ALOGV("%s: failed to get camera info for camera %s",
+ ALOGE("%s: failed to get camera info for camera %s",
__FUNCTION__, cameraId.string());
return res;
}
@@ -83,18 +88,19 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) {
}
mFlashControl = flashControl;
- }
- else {
- // todo: implement for device api 1
- return INVALID_OPERATION;
+ } else {
+ mFlashControl =
+ new CameraHardwareInterfaceFlashControl(*mCameraModule,
+ *mCallbacks);
}
}
return OK;
}
-status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) {
- if (!mCameraModule) {
+status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.");
return NO_INIT;
}
@@ -105,6 +111,10 @@ status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled)
Mutex::Autolock l(mLock);
if (mFlashControl == NULL) {
+ if (enabled == false) {
+ return OK;
+ }
+
res = createFlashlightControl(cameraId);
if (res) {
return res;
@@ -130,88 +140,169 @@ status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled)
return res;
}
-bool CameraFlashlight::hasFlashUnit(const String16& cameraId) {
+status_t CameraFlashlight::findFlashUnits() {
+ Mutex::Autolock l(mLock);
status_t res;
+ int32_t numCameras = mCameraModule->getNumberOfCameras();
- Mutex::Autolock l(mLock);
+ mHasFlashlightMap.clear();
+ mFlashlightMapInitialized = false;
- if (mFlashControl == NULL) {
- res = createFlashlightControl(cameraId);
+ for (int32_t i = 0; i < numCameras; i++) {
+ bool hasFlash = false;
+ String8 id = String8::format("%d", i);
+
+ res = createFlashlightControl(id);
if (res) {
- ALOGE("%s: failed to create flash control for %s ",
- __FUNCTION__, cameraId.string());
- return false;
+ ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
+ id.string());
+ } else {
+ res = mFlashControl->hasFlashUnit(id, &hasFlash);
+ if (res == -EUSERS || res == -EBUSY) {
+ ALOGE("%s: failed to check if camera %s has a flash unit. Some "
+ "camera devices may be opened", __FUNCTION__,
+ id.string());
+ return res;
+ } else if (res) {
+ ALOGE("%s: failed to check if camera %s has a flash unit. %s"
+ " (%d)", __FUNCTION__, id.string(), strerror(-res),
+ res);
+ }
+
+ mFlashControl.clear();
}
+ mHasFlashlightMap.add(id, hasFlash);
}
- bool flashUnit = false;
+ mFlashlightMapInitialized = true;
+ return OK;
+}
- // if flash control already exists, querying if a camera device has a flash
- // unit may fail if it's module v1
- res = mFlashControl->hasFlashUnit(cameraId, &flashUnit);
- if (res == BAD_INDEX) {
- // need to close the flash control before query.
- mFlashControl.clear();
- res = createFlashlightControl(cameraId);
- if (res) {
- ALOGE("%s: failed to create flash control for %s ", __FUNCTION__,
- cameraId.string());
- return false;
- }
- res = mFlashControl->hasFlashUnit(cameraId, &flashUnit);
- if (res) {
- flashUnit = false;
- }
+bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
+ status_t res;
+
+ Mutex::Autolock l(mLock);
+ return hasFlashUnitLocked(cameraId);
+}
+
+bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.");
+ return false;
+ }
+
+ ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
+ if (index == NAME_NOT_FOUND) {
+ ALOGE("%s: camera %s not present when findFlashUnits() was called",
+ __FUNCTION__, cameraId.string());
+ return false;
}
- return flashUnit;
+ return mHasFlashlightMap.valueAt(index);
}
-status_t CameraFlashlight::prepareDeviceOpen() {
+status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
ALOGV("%s: prepare for device open", __FUNCTION__);
Mutex::Autolock l(mLock);
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.");
+ return NO_INIT;
+ }
- if (mCameraModule && mCameraModule->getRawModule()->module_api_version <
+ if (mCameraModule->getRawModule()->module_api_version <
CAMERA_MODULE_API_VERSION_2_4) {
// framework is going to open a camera device, all flash light control
// should be closed for backward compatible support.
- if (mFlashControl != NULL) {
- mFlashControl.clear();
+ mFlashControl.clear();
+
+ if (mOpenedCameraIds.size() == 0) {
+ // notify torch unavailable for all cameras with a flash
+ int numCameras = mCameraModule->getNumberOfCameras();
+ for (int i = 0; i < numCameras; i++) {
+ if (hasFlashUnitLocked(String8::format("%d", i))) {
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ String8::format("%d", i).string(),
+ TORCH_MODE_STATUS_NOT_AVAILABLE);
+ }
+ }
}
+
+ // close flash control that may be opened by calling hasFlashUnitLocked.
+ mFlashControl.clear();
+ }
+
+ if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
+ mOpenedCameraIds.add(cameraId);
}
return OK;
}
+status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
+ ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
-FlashControlBase::~FlashControlBase() {
+ Mutex::Autolock l(mLock);
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.");
+ return NO_INIT;
+ }
+
+ ssize_t index = mOpenedCameraIds.indexOf(cameraId);
+ if (index == NAME_NOT_FOUND) {
+ ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
+ cameraId.string());
+ } else {
+ mOpenedCameraIds.removeAt(index);
+ }
+
+ // Cannot do anything until all cameras are closed.
+ if (mOpenedCameraIds.size() != 0)
+ return OK;
+
+ if (mCameraModule->getRawModule()->module_api_version <
+ CAMERA_MODULE_API_VERSION_2_4) {
+ // notify torch available for all cameras with a flash
+ int numCameras = mCameraModule->getNumberOfCameras();
+ for (int i = 0; i < numCameras; i++) {
+ if (hasFlashUnitLocked(String8::format("%d", i))) {
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ String8::format("%d", i).string(),
+ TORCH_MODE_STATUS_AVAILABLE_OFF);
+ }
+ }
+ }
+
+ return OK;
}
+// CameraFlashlight implementation ends
+
+FlashControlBase::~FlashControlBase() {
+}
-FlashControl::FlashControl(CameraModule& cameraModule,
+/////////////////////////////////////////////////////////////////////
+// ModuleFlashControl implementation begins
+// Flash control for camera module v2.4 and above.
+/////////////////////////////////////////////////////////////////////
+ModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule,
const camera_module_callbacks_t& callbacks) :
mCameraModule(&cameraModule) {
}
-FlashControl::~FlashControl() {
+ModuleFlashControl::~ModuleFlashControl() {
}
-status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) {
+status_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) {
if (!hasFlash) {
return BAD_VALUE;
}
*hasFlash = false;
-
Mutex::Autolock l(mLock);
- if (!mCameraModule) {
- return NO_INIT;
- }
-
camera_info info;
- status_t res = mCameraModule->getCameraInfo(atoi(String8(cameraId).string()),
+ status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()),
&info);
if (res != 0) {
return res;
@@ -228,33 +319,31 @@ status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) {
return OK;
}
-status_t FlashControl::setTorchMode(const String16& cameraId, bool enabled) {
+status_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) {
ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
cameraId.string(), enabled);
Mutex::Autolock l(mLock);
- if (!mCameraModule) {
- return NO_INIT;
- }
-
- return mCameraModule->setTorchMode(String8(cameraId).string(), enabled);
+ return mCameraModule->setTorchMode(cameraId.string(), enabled);
}
+// ModuleFlashControl implementation ends
+/////////////////////////////////////////////////////////////////////
+// CameraDeviceClientFlashControl implementation begins
+// Flash control for camera module <= v2.3 and camera HAL v2-v3
+/////////////////////////////////////////////////////////////////////
CameraDeviceClientFlashControl::CameraDeviceClientFlashControl(
CameraModule& cameraModule,
const camera_module_callbacks_t& callbacks) :
mCameraModule(&cameraModule),
mCallbacks(&callbacks),
mTorchEnabled(false),
- mMetadata(NULL) {
+ mMetadata(NULL),
+ mStreaming(false) {
}
CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() {
- if (mDevice != NULL) {
- mDevice->flush();
- mDevice->deleteStream(mStreamId);
- mDevice.clear();
- }
+ disconnectCameraDevice();
if (mMetadata) {
delete mMetadata;
}
@@ -269,13 +358,13 @@ CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() {
ALOGV("%s: notify the framework that torch was turned off",
__FUNCTION__);
mCallbacks->torch_mode_status_change(mCallbacks,
- String8(mCameraId).string(), TORCH_MODE_STATUS_OFF);
+ mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
}
}
}
-status_t CameraDeviceClientFlashControl::initializeSurface(int32_t width,
- int32_t height) {
+status_t CameraDeviceClientFlashControl::initializeSurface(
+ sp<CameraDeviceBase> &device, int32_t width, int32_t height) {
status_t res;
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
@@ -295,27 +384,16 @@ status_t CameraDeviceClientFlashControl::initializeSurface(int32_t width,
return res;
}
- bool useAsync = false;
- int32_t consumerUsage;
- res = mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage);
- if (res) {
- return res;
- }
-
- if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
- useAsync = true;
- }
-
- mAnw = new Surface(mProducer, useAsync);
+ mAnw = new Surface(mProducer, /*useAsync*/ true);
if (mAnw == NULL) {
return NO_MEMORY;
}
- res = mDevice->createStream(mAnw, width, height, format, &mStreamId);
+ res = device->createStream(mAnw, width, height, format, &mStreamId);
if (res) {
return res;
}
- res = mDevice->configureStreams();
+ res = device->configureStreams();
if (res) {
return res;
}
@@ -342,7 +420,21 @@ status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize(
int32_t ww = streamConfigs.data.i32[i + 1];
int32_t hh = streamConfigs.data.i32[i + 2];
- if (w* h > ww * hh) {
+ if (w * h > ww * hh) {
+ w = ww;
+ h = hh;
+ }
+ }
+ }
+
+ // if stream configuration is not found, try available processed sizes.
+ if (streamConfigs.count == 0) {
+ camera_metadata_entry availableProcessedSizes =
+ metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+ for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
+ int32_t ww = availableProcessedSizes.data.i32[i];
+ int32_t hh = availableProcessedSizes.data.i32[i + 1];
+ if (w * h > ww * hh) {
w = ww;
h = hh;
}
@@ -360,24 +452,24 @@ status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize(
}
status_t CameraDeviceClientFlashControl::connectCameraDevice(
- const String16& cameraId) {
- String8 id = String8(cameraId);
+ const String8& cameraId) {
camera_info info;
- status_t res = mCameraModule->getCameraInfo(atoi(id.string()), &info);
+ status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info);
if (res != 0) {
ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
- mCameraId.string());
+ cameraId.string());
return res;
}
- mDevice = CameraDeviceFactory::createDevice(atoi(id.string()));
- if (mDevice == NULL) {
+ sp<CameraDeviceBase> device =
+ CameraDeviceFactory::createDevice(atoi(cameraId.string()));
+ if (device == NULL) {
return NO_MEMORY;
}
- res = mDevice->initialize(mCameraModule);
+ res = device->initialize(mCameraModule);
if (res) {
- goto fail;
+ return res;
}
int32_t width, height;
@@ -385,22 +477,30 @@ status_t CameraDeviceClientFlashControl::connectCameraDevice(
if (res) {
return res;
}
- res = initializeSurface(width, height);
+ res = initializeSurface(device, width, height);
if (res) {
- goto fail;
+ return res;
}
mCameraId = cameraId;
+ mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1);
+ mDevice = device;
return OK;
+}
-fail:
- mDevice.clear();
- return res;
+status_t CameraDeviceClientFlashControl::disconnectCameraDevice() {
+ if (mDevice != NULL) {
+ mDevice->disconnect();
+ mDevice.clear();
+ }
+
+ return OK;
}
-status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId,
+
+status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId,
bool *hasFlash) {
ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__,
cameraId.string());
@@ -411,19 +511,14 @@ status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId,
}
status_t CameraDeviceClientFlashControl::hasFlashUnitLocked(
- const String16& cameraId, bool *hasFlash) {
- if (!mCameraModule) {
- ALOGE("%s: camera module is NULL", __FUNCTION__);
- return NO_INIT;
- }
-
+ const String8& cameraId, bool *hasFlash) {
if (!hasFlash) {
return BAD_VALUE;
}
camera_info info;
status_t res = mCameraModule->getCameraInfo(
- atoi(String8(cameraId).string()), &info);
+ atoi(cameraId.string()), &info);
if (res != 0) {
ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
cameraId.string());
@@ -441,7 +536,7 @@ status_t CameraDeviceClientFlashControl::hasFlashUnitLocked(
return OK;
}
-status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) {
+status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() {
status_t res;
if (mMetadata == NULL) {
@@ -456,27 +551,29 @@ status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) {
}
}
- uint8_t torchOn = enabled ? ANDROID_FLASH_MODE_TORCH :
- ANDROID_FLASH_MODE_OFF;
-
+ uint8_t torchOn = ANDROID_FLASH_MODE_TORCH;
mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1);
mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1);
+ uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
+ mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
int32_t requestId = 0;
mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1);
- List<const CameraMetadata> metadataRequestList;
- metadataRequestList.push_back(*mMetadata);
-
- int64_t lastFrameNumber = 0;
- res = mDevice->captureList(metadataRequestList, &lastFrameNumber);
-
+ if (mStreaming) {
+ res = mDevice->setStreamingRequest(*mMetadata);
+ } else {
+ res = mDevice->capture(*mMetadata);
+ }
return res;
}
+
+
status_t CameraDeviceClientFlashControl::setTorchMode(
- const String16& cameraId, bool enabled) {
+ const String8& cameraId, bool enabled) {
bool hasFlash = false;
Mutex::Autolock l(mLock);
@@ -499,6 +596,13 @@ status_t CameraDeviceClientFlashControl::setTorchMode(
} else if (mDevice == NULL || cameraId != mCameraId) {
// disabling the torch mode of an un-opened or different device.
return OK;
+ } else {
+ // disabling the torch mode of currently opened device
+ disconnectCameraDevice();
+ mTorchEnabled = false;
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+ return OK;
}
if (mDevice == NULL) {
@@ -508,13 +612,263 @@ status_t CameraDeviceClientFlashControl::setTorchMode(
}
}
- res = submitTorchRequest(enabled);
+ res = submitTorchEnabledRequest();
if (res) {
return res;
}
- mTorchEnabled = enabled;
+ mTorchEnabled = true;
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
+ return OK;
+}
+// CameraDeviceClientFlashControl implementation ends
+
+
+/////////////////////////////////////////////////////////////////////
+// CameraHardwareInterfaceFlashControl implementation begins
+// Flash control for camera module <= v2.3 and camera HAL v1
+/////////////////////////////////////////////////////////////////////
+CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
+ CameraModule& cameraModule,
+ const camera_module_callbacks_t& callbacks) :
+ mCameraModule(&cameraModule),
+ mCallbacks(&callbacks),
+ mTorchEnabled(false) {
+
+}
+
+CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
+ disconnectCameraDevice();
+
+ mAnw.clear();
+ mSurfaceTexture.clear();
+ mProducer.clear();
+ mConsumer.clear();
+
+ if (mTorchEnabled) {
+ if (mCallbacks) {
+ ALOGV("%s: notify the framework that torch was turned off",
+ __FUNCTION__);
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+ }
+ }
+}
+
+status_t CameraHardwareInterfaceFlashControl::setTorchMode(
+ const String8& cameraId, bool enabled) {
+ Mutex::Autolock l(mLock);
+
+ // pre-check
+ status_t res;
+ if (enabled) {
+ bool hasFlash = false;
+ res = hasFlashUnitLocked(cameraId, &hasFlash);
+ // invalid camera?
+ if (res) {
+ // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
+ // another camera device.
+ return res == BAD_INDEX ? BAD_INDEX : -EINVAL;
+ }
+ // no flash unit?
+ if (!hasFlash) {
+ return -ENOSYS;
+ }
+ } else if (mDevice == NULL || cameraId != mCameraId) {
+ // disabling the torch mode of an un-opened or different device.
+ return OK;
+ } else {
+ // disabling the torch mode of currently opened device
+ disconnectCameraDevice();
+ mTorchEnabled = false;
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+ return OK;
+ }
+
+ res = startPreviewAndTorch();
+ if (res) {
+ return res;
+ }
+
+ mTorchEnabled = true;
+ mCallbacks->torch_mode_status_change(mCallbacks,
+ cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
+ return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
+ const String8& cameraId, bool *hasFlash) {
+ Mutex::Autolock l(mLock);
+ return hasFlashUnitLocked(cameraId, hasFlash);
+}
+
+status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
+ const String8& cameraId, bool *hasFlash) {
+ if (!hasFlash) {
+ return BAD_VALUE;
+ }
+
+ status_t res;
+ if (mDevice == NULL) {
+ res = connectCameraDevice(cameraId);
+ if (res) {
+ return res;
+ }
+ }
+
+ if (cameraId != mCameraId) {
+ return BAD_INDEX;
+ }
+
+ const char *flashMode =
+ mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
+ if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
+ *hasFlash = true;
+ } else {
+ *hasFlash = false;
+ }
+
+ return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() {
+ status_t res = OK;
+ res = mDevice->startPreview();
+ if (res) {
+ ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ return res;
+ }
+
+ mParameters.set(CameraParameters::KEY_FLASH_MODE,
+ CameraParameters::FLASH_MODE_TORCH);
+
+ return mDevice->setParameters(mParameters);
+}
+
+status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize(
+ int32_t *width, int32_t *height) {
+ if (!width || !height) {
+ return BAD_VALUE;
+ }
+
+ int32_t w = INT32_MAX;
+ int32_t h = 1;
+ Vector<Size> sizes;
+
+ mParameters.getSupportedPreviewSizes(sizes);
+ for (size_t i = 0; i < sizes.size(); i++) {
+ Size s = sizes[i];
+ if (w * h > s.width * s.height) {
+ w = s.width;
+ h = s.height;
+ }
+ }
+
+ if (w == INT32_MAX) {
+ return NAME_NOT_FOUND;
+ }
+
+ *width = w;
+ *height = h;
+
+ return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
+ sp<CameraHardwareInterface> device, int32_t width, int32_t height) {
+ status_t res;
+ BufferQueue::createBufferQueue(&mProducer, &mConsumer);
+
+ mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL,
+ true, true);
+ if (mSurfaceTexture == NULL) {
+ return NO_MEMORY;
+ }
+
+ int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ res = mSurfaceTexture->setDefaultBufferSize(width, height);
+ if (res) {
+ return res;
+ }
+ res = mSurfaceTexture->setDefaultBufferFormat(format);
+ if (res) {
+ return res;
+ }
+
+ mAnw = new Surface(mProducer, /*useAsync*/ true);
+ if (mAnw == NULL) {
+ return NO_MEMORY;
+ }
+
+ res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
+ if (res) {
+ ALOGE("%s: Unable to connect to native window", __FUNCTION__);
+ return res;
+ }
+
+ return device->setPreviewWindow(mAnw);
+}
+
+status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
+ const String8& cameraId) {
+ sp<CameraHardwareInterface> device =
+ new CameraHardwareInterface(cameraId.string());
+
+ status_t res = device->initialize(mCameraModule);
+ if (res) {
+ ALOGE("%s: initializing camera %s failed", __FUNCTION__,
+ cameraId.string());
+ return res;
+ }
+
+ // need to set __get_memory in set_callbacks().
+ device->setCallbacks(NULL, NULL, NULL, NULL);
+
+ mParameters = device->getParameters();
+
+ int32_t width, height;
+ res = getSmallestSurfaceSize(&width, &height);
+ if (res) {
+ ALOGE("%s: failed to get smallest surface size for camera %s",
+ __FUNCTION__, cameraId.string());
+ return res;
+ }
+
+ res = initializePreviewWindow(device, width, height);
+ if (res) {
+ ALOGE("%s: failed to initialize preview window for camera %s",
+ __FUNCTION__, cameraId.string());
+ return res;
+ }
+
+ mCameraId = cameraId;
+ mDevice = device;
+ return OK;
+}
+
+status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() {
+ if (mDevice == NULL) {
+ return OK;
+ }
+
+ mParameters.set(CameraParameters::KEY_FLASH_MODE,
+ CameraParameters::FLASH_MODE_OFF);
+ mDevice->setParameters(mParameters);
+ mDevice->stopPreview();
+ status_t res = native_window_api_disconnect(mAnw.get(),
+ NATIVE_WINDOW_API_CAMERA);
+ if (res) {
+ ALOGW("%s: native_window_api_disconnect failed: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ mDevice->setPreviewWindow(NULL);
+ mDevice->release();
+
return OK;
}
+// CameraHardwareInterfaceFlashControl implementation ends
}
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index a0de0b0..30f01f0 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -19,9 +19,11 @@
#include "hardware/camera_common.h"
#include "utils/KeyedVector.h"
+#include "utils/SortedVector.h"
#include "gui/GLConsumer.h"
#include "gui/Surface.h"
#include "common/CameraDeviceBase.h"
+#include "device1/CameraHardwareInterface.h"
namespace android {
@@ -37,11 +39,11 @@ class FlashControlBase : public virtual VirtualLightRefBase {
// cause the torch mode to be turned off in HAL v1 devices. If
// previously-on torch mode is turned off,
// callbacks.torch_mode_status_change() should be invoked.
- virtual status_t hasFlashUnit(const String16& cameraId,
+ virtual status_t hasFlashUnit(const String8& cameraId,
bool *hasFlash) = 0;
// set the torch mode to on or off.
- virtual status_t setTorchMode(const String16& cameraId,
+ virtual status_t setTorchMode(const String8& cameraId,
bool enabled) = 0;
};
@@ -54,43 +56,61 @@ class CameraFlashlight : public virtual VirtualLightRefBase {
const camera_module_callbacks_t& callbacks);
virtual ~CameraFlashlight();
- // set the torch mode to on or off.
- status_t setTorchMode(const String16& cameraId, bool enabled);
+ // Find all flash units. This must be called before other methods. All
+ // camera devices must be closed when it's called because HAL v1 devices
+ // need to be opened to query available flash modes.
+ status_t findFlashUnits();
- // Whether a camera device has a flash unit. Calling this function may
- // cause the torch mode to be turned off in HAL v1 devices.
- bool hasFlashUnit(const String16& cameraId);
+ // Whether a camera device has a flash unit. Before findFlashUnits() is
+ // called, this function always returns false.
+ bool hasFlashUnit(const String8& cameraId);
+
+ // set the torch mode to on or off.
+ status_t setTorchMode(const String8& cameraId, bool enabled);
// Notify CameraFlashlight that camera service is going to open a camera
// device. CameraFlashlight will free the resources that may cause the
// camera open to fail. Camera service must call this function before
// opening a camera device.
- status_t prepareDeviceOpen();
+ status_t prepareDeviceOpen(const String8& cameraId);
+
+ // Notify CameraFlashlight that camera service has closed a camera
+ // device. CameraFlashlight may invoke callbacks for torch mode
+ // available depending on the implementation.
+ status_t deviceClosed(const String8& cameraId);
private:
// create flashlight control based on camera module API and camera
// device API versions.
- status_t createFlashlightControl(const String16& cameraId);
+ status_t createFlashlightControl(const String8& cameraId);
+
+ // mLock should be locked.
+ bool hasFlashUnitLocked(const String8& cameraId);
sp<FlashControlBase> mFlashControl;
CameraModule *mCameraModule;
const camera_module_callbacks_t *mCallbacks;
+ SortedVector<String8> mOpenedCameraIds;
- Mutex mLock;
+ // camera id -> if it has a flash unit
+ KeyedVector<String8, bool> mHasFlashlightMap;
+ bool mFlashlightMapInitialized;
+
+ Mutex mLock; // protect CameraFlashlight API
};
/**
* Flash control for camera module v2.4 and above.
*/
-class FlashControl : public FlashControlBase {
+class ModuleFlashControl : public FlashControlBase {
public:
- FlashControl(CameraModule& cameraModule,
+ ModuleFlashControl(CameraModule& cameraModule,
const camera_module_callbacks_t& callbacks);
- virtual ~FlashControl();
+ virtual ~ModuleFlashControl();
// FlashControlBase
- status_t hasFlashUnit(const String16& cameraId, bool *hasFlash);
- status_t setTorchMode(const String16& cameraId, bool enabled);
+ status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
+ status_t setTorchMode(const String8& cameraId, bool enabled);
private:
CameraModule *mCameraModule;
@@ -108,30 +128,38 @@ class CameraDeviceClientFlashControl : public FlashControlBase {
virtual ~CameraDeviceClientFlashControl();
// FlashControlBase
- status_t setTorchMode(const String16& cameraId, bool enabled);
- status_t hasFlashUnit(const String16& cameraId, bool *hasFlash);
+ status_t setTorchMode(const String8& cameraId, bool enabled);
+ status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
private:
// connect to a camera device
- status_t connectCameraDevice(const String16& cameraId);
+ status_t connectCameraDevice(const String8& cameraId);
+ // disconnect and free mDevice
+ status_t disconnectCameraDevice();
// initialize a surface
- status_t initializeSurface(int32_t width, int32_t height);
+ status_t initializeSurface(sp<CameraDeviceBase>& device, int32_t width,
+ int32_t height);
- // submit a request with the given torch mode
- status_t submitTorchRequest(bool enabled);
+ // submit a request to enable the torch mode
+ status_t submitTorchEnabledRequest();
// get the smallest surface size of IMPLEMENTATION_DEFINED
status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width,
int32_t *height);
- status_t hasFlashUnitLocked(const String16& cameraId, bool *hasFlash);
+ // protected by mLock
+ status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
CameraModule *mCameraModule;
const camera_module_callbacks_t *mCallbacks;
- String16 mCameraId;
+ String8 mCameraId;
bool mTorchEnabled;
CameraMetadata *mMetadata;
+ // WORKAROUND: will be set to true for HAL v2 devices where
+ // setStreamingRequest() needs to be call for torch mode settings to
+ // take effect.
+ bool mStreaming;
sp<CameraDeviceBase> mDevice;
@@ -144,6 +172,54 @@ class CameraDeviceClientFlashControl : public FlashControlBase {
Mutex mLock;
};
+/**
+ * Flash control for camera module <= v2.3 and camera HAL v1
+ */
+class CameraHardwareInterfaceFlashControl : public FlashControlBase {
+ public:
+ CameraHardwareInterfaceFlashControl(CameraModule& cameraModule,
+ const camera_module_callbacks_t& callbacks);
+ virtual ~CameraHardwareInterfaceFlashControl();
+
+ // FlashControlBase
+ status_t setTorchMode(const String8& cameraId, bool enabled);
+ status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
+
+ private:
+ // connect to a camera device
+ status_t connectCameraDevice(const String8& cameraId);
+
+ // disconnect and free mDevice
+ status_t disconnectCameraDevice();
+
+ // initialize the preview window
+ status_t initializePreviewWindow(sp<CameraHardwareInterface> device,
+ int32_t width, int32_t height);
+
+ // start preview and enable torch
+ status_t startPreviewAndTorch();
+
+ // get the smallest surface
+ status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
+
+ // protected by mLock
+ status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
+
+ CameraModule *mCameraModule;
+ const camera_module_callbacks_t *mCallbacks;
+ sp<CameraHardwareInterface> mDevice;
+ String8 mCameraId;
+ CameraParameters mParameters;
+ bool mTorchEnabled;
+
+ sp<IGraphicBufferProducer> mProducer;
+ sp<IGraphicBufferConsumer> mConsumer;
+ sp<GLConsumer> mSurfaceTexture;
+ sp<ANativeWindow> mAnw;
+
+ Mutex mLock;
+};
+
} // namespace android
#endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index d65ac21..6f37f16 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -101,14 +101,14 @@ static void torch_mode_status_change(
ICameraServiceListener::TorchStatus status;
switch (new_status) {
- case TORCH_MODE_STATUS_AVAILABLE:
- status = ICameraServiceListener::TORCH_STATUS_AVAILABLE;
- break;
- case TORCH_MODE_STATUS_RESOURCE_BUSY:
+ case TORCH_MODE_STATUS_NOT_AVAILABLE:
status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
break;
- case TORCH_MODE_STATUS_OFF:
- status = ICameraServiceListener::TORCH_STATUS_OFF;
+ case TORCH_MODE_STATUS_AVAILABLE_OFF:
+ status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
+ break;
+ case TORCH_MODE_STATUS_AVAILABLE_ON:
+ status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
break;
default:
ALOGE("Unknown torch status %d", new_status);
@@ -116,7 +116,7 @@ static void torch_mode_status_change(
}
cs->onTorchStatusChanged(
- String16(camera_id),
+ String8(camera_id),
status);
}
} // extern "C"
@@ -156,23 +156,29 @@ void CameraService::onFirstRef()
}
else {
mModule = new CameraModule(rawModule);
- mFlashlight = new CameraFlashlight(*mModule, *this);
-
const hw_module_t *common = mModule->getRawModule();
- ALOGI("Loaded \"%s\" camera module", common->name);
+ ALOGI("Loaded \"%s\" cameraCa module", common->name);
mNumberOfCameras = mModule->getNumberOfCameras();
if (mNumberOfCameras > MAX_CAMERAS) {
ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
mNumberOfCameras, MAX_CAMERAS);
mNumberOfCameras = MAX_CAMERAS;
}
+
+ mFlashlight = new CameraFlashlight(*mModule, *this);
+ status_t res = mFlashlight->findFlashUnits();
+ if (res) {
+ // impossible because we haven't open any camera devices.
+ ALOGE("failed to find flash units.");
+ }
+
for (int i = 0; i < mNumberOfCameras; i++) {
setCameraFree(i);
- String16 cameraName = String16(String8::format("%d", i));
+ String8 cameraName = String8::format("%d", i);
if (mFlashlight->hasFlashUnit(cameraName)) {
mTorchStatusMap.add(cameraName,
- ICameraServiceListener::TORCH_STATUS_AVAILABLE);
+ ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
}
}
@@ -207,7 +213,7 @@ CameraService::~CameraService() {
void CameraService::onDeviceStatusChanged(int cameraId,
int newStatus)
{
- ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
+ ALOGV("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
cameraId, newStatus);
if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
@@ -268,24 +274,30 @@ void CameraService::onDeviceStatusChanged(int cameraId,
}
-void CameraService::onTorchStatusChanged(const String16& cameraId,
+void CameraService::onTorchStatusChanged(const String8& cameraId,
ICameraServiceListener::TorchStatus newStatus) {
Mutex::Autolock al(mTorchStatusMutex);
onTorchStatusChangedLocked(cameraId, newStatus);
}
-void CameraService::onTorchStatusChangedLocked(const String16& cameraId,
+void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
ICameraServiceListener::TorchStatus newStatus) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
__FUNCTION__, cameraId.string(), newStatus);
- if (getTorchStatusLocked(cameraId) == newStatus) {
+ ICameraServiceListener::TorchStatus status;
+ status_t res = getTorchStatusLocked(cameraId, &status);
+ if (res) {
+ ALOGE("%s: cannot get torch status of camera %s", cameraId.string());
+ return;
+ }
+ if (status == newStatus) {
ALOGE("%s: Torch state transition to the same status 0x%x not allowed",
__FUNCTION__, (uint32_t)newStatus);
return;
}
- status_t res = setTorchStatusLocked(cameraId, newStatus);
+ res = setTorchStatusLocked(cameraId, newStatus);
if (res) {
ALOGE("%s: Failed to set the torch status", __FUNCTION__,
(uint32_t)newStatus);
@@ -294,7 +306,7 @@ void CameraService::onTorchStatusChangedLocked(const String16& cameraId,
Vector<sp<ICameraServiceListener> >::const_iterator it;
for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
- (*it)->onTorchStatusChanged(newStatus, cameraId);
+ (*it)->onTorchStatusChanged(newStatus, String16(cameraId.string()));
}
}
@@ -484,19 +496,6 @@ int CameraService::getDeviceVersion(int cameraId, int* facing) {
return deviceVersion;
}
-status_t CameraService::filterOpenErrorCode(status_t err) {
- switch(err) {
- case NO_ERROR:
- case -EBUSY:
- case -EINVAL:
- case -EUSERS:
- return err;
- default:
- break;
- }
- return -ENODEV;
-}
-
status_t CameraService::filterGetInfoErrorCode(status_t err) {
switch(err) {
case NO_ERROR:
@@ -754,7 +753,7 @@ status_t CameraService::connectHelperLocked(
bool legacyMode) {
// give flashlight a chance to close devices if necessary.
- mFlashlight->prepareDeviceOpen();
+ mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
@@ -932,44 +931,94 @@ status_t CameraService::connectLegacy(
return OK;
}
+bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) {
+ // invalid string for int
+ if (cameraId.string() == NULL) {
+ return false;
+ }
+ errno = 0;
+ char *endptr;
+ long id = strtol(cameraId.string(), &endptr, 10); // base 10
+ if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) {
+ return false;
+ }
+
+ // id matches one of the plugged-in devices?
+ ICameraServiceListener::Status deviceStatus = getStatus(id);
+ if (deviceStatus != ICameraServiceListener::STATUS_PRESENT &&
+ deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+ return false;
+ }
+
+ return true;
+}
+
status_t CameraService::setTorchMode(const String16& cameraId, bool enabled,
const sp<IBinder>& clientBinder) {
if (enabled && clientBinder == NULL) {
ALOGE("%s: torch client binder is NULL", __FUNCTION__);
- return -ENOSYS;
+ return -EINVAL;
}
- Mutex::Autolock al(mTorchStatusMutex);
- status_t res = mFlashlight->setTorchMode(cameraId, enabled);
+ String8 id = String8(cameraId.string());
+
+ // verify id is valid.
+ if (validCameraIdForSetTorchMode(id) == false) {
+ ALOGE("%s: camera id is invalid %s", id.string());
+ return -EINVAL;
+ }
+
+ {
+ Mutex::Autolock al(mTorchStatusMutex);
+ ICameraServiceListener::TorchStatus status;
+ status_t res = getTorchStatusLocked(id, &status);
+ if (res) {
+ ALOGE("%s: getting current torch status failed for camera %s",
+ __FUNCTION__, id.string());
+ return -EINVAL;
+ }
+
+ if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) {
+ if (getStatus(atoi(id.string())) ==
+ ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+ ALOGE("%s: torch mode of camera %s is not available because "
+ "camera is in use", __FUNCTION__, id.string());
+ return -EBUSY;
+ } else {
+ ALOGE("%s: torch mode of camera %s is not available due to "
+ "insufficient resources", __FUNCTION__, id.string());
+ return -EUSERS;
+ }
+ }
+ }
+
+ status_t res = mFlashlight->setTorchMode(id, enabled);
if (res) {
- ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__,
- cameraId.string(), enabled);
+ ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)",
+ __FUNCTION__, id.string(), enabled, strerror(-res), res);
return res;
}
- // update the link to client's death
- ssize_t index = mTorchClientMap.indexOfKey(cameraId);
- if (enabled) {
- if (index == NAME_NOT_FOUND) {
- mTorchClientMap.add(cameraId, clientBinder);
- } else {
- const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
- oldBinder->unlinkToDeath(this);
+ {
+ // update the link to client's death
+ Mutex::Autolock al(mTorchClientMapMutex);
+ ssize_t index = mTorchClientMap.indexOfKey(id);
+ if (enabled) {
+ if (index == NAME_NOT_FOUND) {
+ mTorchClientMap.add(id, clientBinder);
+ } else {
+ const sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
+ oldBinder->unlinkToDeath(this);
- mTorchClientMap.replaceValueAt(index, clientBinder);
+ mTorchClientMap.replaceValueAt(index, clientBinder);
+ }
+ clientBinder->linkToDeath(this);
+ } else if (index != NAME_NOT_FOUND) {
+ sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
+ oldBinder->unlinkToDeath(this);
}
- clientBinder->linkToDeath(this);
- } else if (index != NAME_NOT_FOUND) {
- sp<IBinder> oldBinder = mTorchClientMap.valueAt(index);
- oldBinder->unlinkToDeath(this);
}
- // notify the listeners the change.
- ICameraServiceListener::TorchStatus status = enabled ?
- ICameraServiceListener::TORCH_STATUS_ON :
- ICameraServiceListener::TORCH_STATUS_OFF;
- onTorchStatusChangedLocked(cameraId, status);
-
return OK;
}
@@ -1099,7 +1148,7 @@ status_t CameraService::connectDevice(
int deviceVersion = getDeviceVersion(cameraId, &facing);
// give flashlight a chance to close devices if necessary.
- mFlashlight->prepareDeviceOpen();
+ mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId));
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
@@ -1176,8 +1225,8 @@ status_t CameraService::addListener(
{
Mutex::Autolock al(mTorchStatusMutex);
for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
- listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i),
- mTorchStatusMap.keyAt(i));
+ String16 id = String16(mTorchStatusMap.keyAt(i).string());
+ listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id);
}
}
@@ -1616,6 +1665,9 @@ status_t CameraService::BasicClient::finishCameraOps() {
mCameraId,
&rejectSourceStates);
+ // Notify flashlight that a camera device is closed.
+ mCameraService->mFlashlight->deviceClosed(
+ String8::format("%d", mCameraId));
}
// Always stop watching, even if no camera op is active
if (mOpsCallback != NULL) {
@@ -1862,17 +1914,18 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
}
void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
- Mutex::Autolock al(mTorchStatusMutex);
+ Mutex::Autolock al(mTorchClientMapMutex);
for (size_t i = 0; i < mTorchClientMap.size(); i++) {
if (mTorchClientMap[i] == who) {
// turn off the torch mode that was turned on by dead client
- String16 cameraId = mTorchClientMap.keyAt(i);
- mFlashlight->setTorchMode(cameraId, false);
+ String8 cameraId = mTorchClientMap.keyAt(i);
+ status_t res = mFlashlight->setTorchMode(cameraId, false);
+ if (res) {
+ ALOGE("%s: torch client died but couldn't turn off torch: "
+ "%s (%d)", __FUNCTION__, strerror(-res), res);
+ return;
+ }
mTorchClientMap.removeItemsAt(i);
-
- // notify torch mode was turned off
- onTorchStatusChangedLocked(cameraId,
- ICameraServiceListener::TORCH_STATUS_OFF);
break;
}
}
@@ -1968,6 +2021,19 @@ void CameraService::updateStatus(ICameraServiceListener::Status status,
}
}
+ if (status == ICameraServiceListener::STATUS_NOT_PRESENT ||
+ status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+ // update torch status to not available when the camera device
+ // becomes not present or not available.
+ onTorchStatusChanged(String8::format("%d", cameraId),
+ ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE);
+ } else if (status == ICameraServiceListener::STATUS_PRESENT) {
+ // update torch status to available when the camera device becomes
+ // present or available
+ onTorchStatusChanged(String8::format("%d", cameraId),
+ ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);
+ }
+
Vector<sp<ICameraServiceListener> >::const_iterator it;
for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
(*it)->onStatusChanged(status, cameraId);
@@ -1985,17 +2051,23 @@ ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
return mStatusList[cameraId];
}
-ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked(
- const String16& cameraId) const {
+status_t CameraService::getTorchStatusLocked(
+ const String8& cameraId,
+ ICameraServiceListener::TorchStatus *status) const {
+ if (!status) {
+ return BAD_VALUE;
+ }
ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
- return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
+ // invalid camera ID or the camera doesn't have a flash unit
+ return NAME_NOT_FOUND;
}
- return mTorchStatusMap.valueAt(index);
+ *status = mTorchStatusMap.valueAt(index);
+ return OK;
}
-status_t CameraService::setTorchStatusLocked(const String16& cameraId,
+status_t CameraService::setTorchStatusLocked(const String8& cameraId,
ICameraServiceListener::TorchStatus status) {
ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 84bcdb8..22afc8c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -72,7 +72,7 @@ public:
// HAL Callbacks
virtual void onDeviceStatusChanged(int cameraId,
int newStatus);
- virtual void onTorchStatusChanged(const String16& cameraId,
+ virtual void onTorchStatusChanged(const String8& cameraId,
ICameraServiceListener::TorchStatus
newStatus);
@@ -150,7 +150,6 @@ public:
/////////////////////////////////////////////////////////////////////
// Shared utilities
- static status_t filterOpenErrorCode(status_t err);
static status_t filterGetInfoErrorCode(status_t err);
/////////////////////////////////////////////////////////////////////
@@ -418,28 +417,33 @@ private:
// flashlight control
sp<CameraFlashlight> mFlashlight;
- // guard mTorchStatusMap and mTorchClientMap
+ // guard mTorchStatusMap
Mutex mTorchStatusMutex;
+ // guard mTorchClientMap
+ Mutex mTorchClientMapMutex;
// camera id -> torch status
- KeyedVector<String16, ICameraServiceListener::TorchStatus> mTorchStatusMap;
+ KeyedVector<String8, ICameraServiceListener::TorchStatus> mTorchStatusMap;
// camera id -> torch client binder
// only store the last client that turns on each camera's torch mode
- KeyedVector<String16, sp<IBinder> > mTorchClientMap;
+ KeyedVector<String8, sp<IBinder> > mTorchClientMap;
// check and handle if torch client's process has died
void handleTorchClientBinderDied(const wp<IBinder> &who);
// handle torch mode status change and invoke callbacks. mTorchStatusMutex
// should be locked.
- void onTorchStatusChangedLocked(const String16& cameraId,
+ void onTorchStatusChangedLocked(const String8& cameraId,
ICameraServiceListener::TorchStatus newStatus);
+ // validate the camera id for use of setting a torch mode.
+ bool validCameraIdForSetTorchMode(const String8& cameraId);
+
// get a camera's torch status. mTorchStatusMutex should be locked.
- ICameraServiceListener::TorchStatus getTorchStatusLocked(
- const String16 &cameraId) const;
+ status_t getTorchStatusLocked(const String8 &cameraId,
+ ICameraServiceListener::TorchStatus *status) const;
// set a camera's torch status. mTorchStatusMutex should be locked.
- status_t setTorchStatusLocked(const String16 &cameraId,
+ status_t setTorchStatusLocked(const String8 &cameraId,
ICameraServiceListener::TorchStatus status);
// IBinder::DeathRecipient implementation
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index 85a4df9..5f767ad 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -91,7 +91,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
}
int CameraModule::open(const char* id, struct hw_device_t** device) {
- return mModule->common.methods->open(&mModule->common, id, device);
+ return filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
}
int CameraModule::openLegacy(
@@ -125,5 +125,20 @@ int CameraModule::setTorchMode(const char* camera_id, bool enable) {
return mModule->set_torch_mode(camera_id, enable);
}
+
+status_t CameraModule::filterOpenErrorCode(status_t err) {
+ switch(err) {
+ case NO_ERROR:
+ case -EBUSY:
+ case -EINVAL:
+ case -EUSERS:
+ return err;
+ default:
+ break;
+ }
+ return -ENODEV;
+}
+
+
}; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h
index 31b9ae2..16207aa 100644
--- a/services/camera/libcameraservice/common/CameraModule.h
+++ b/services/camera/libcameraservice/common/CameraModule.h
@@ -50,6 +50,8 @@ public:
private:
// Derive camera characteristics keys defined after HAL device version
static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+ status_t filterOpenErrorCode(status_t err);
+
camera_module_t *mModule;
CameraMetadata mCameraCharacteristics[MAX_CAMERAS_PER_MODULE];
camera_info mCameraInfo[MAX_CAMERAS_PER_MODULE];
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 9e1cdc9..f5ebbf8 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -104,8 +104,7 @@ public:
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
- rc = CameraService::filterOpenErrorCode(module->open(
- mName.string(), (hw_device_t **)&mDevice));
+ rc = module->open(mName.string(), (hw_device_t **)&mDevice);
}
if (rc != OK) {
ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index be66c4d..43c8307 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -68,8 +68,7 @@ status_t Camera2Device::initialize(CameraModule *module)
camera2_device_t *device;
- res = CameraService::filterOpenErrorCode(module->open(
- name, reinterpret_cast<hw_device_t**>(&device)));
+ res = module->open(name, reinterpret_cast<hw_device_t**>(&device));
if (res != OK) {
ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 9a4e5ac..bca9bfd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -106,8 +106,8 @@ status_t Camera3Device::initialize(CameraModule *module)
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
- res = CameraService::filterOpenErrorCode(module->open(
- deviceName.string(), reinterpret_cast<hw_device_t**>(&device)));
+ res = module->open(deviceName.string(),
+ reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (res != OK) {