am 2ee6ac14: am 25a8a7d3: am 6ffd56c3: am bd732b4c: Docs: Bumping version on home page.
* commit '2ee6ac144398e67b51c7693559cf9588c34152e3':
diff --git a/src/devices/audio.jd b/src/devices/audio.jd
index 4435494..1b85d5e 100644
--- a/src/devices/audio.jd
+++ b/src/devices/audio.jd
@@ -27,7 +27,7 @@
source code that is involved in the implementation:
</p>
<p>
- <img src="images/audio_hal.png">
+ <img src="images/audio_hal.png" alt="Audio architecture" />
</p>
<dl>
<dt>
diff --git a/src/devices/audio/images/medialog_after.png b/src/devices/audio/images/medialog_after.png
new file mode 100644
index 0000000..c175fb3
--- /dev/null
+++ b/src/devices/audio/images/medialog_after.png
Binary files differ
diff --git a/src/devices/audio/images/medialog_before.png b/src/devices/audio/images/medialog_before.png
new file mode 100644
index 0000000..4299087
--- /dev/null
+++ b/src/devices/audio/images/medialog_before.png
Binary files differ
diff --git a/src/devices/audio_debugging.jd b/src/devices/audio_debugging.jd
new file mode 100644
index 0000000..31d61d5
--- /dev/null
+++ b/src/devices/audio_debugging.jd
@@ -0,0 +1,421 @@
+page.title=Audio Debugging
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>
+This article describes some tips and tricks for debugging Android audio.
+</p>
+
+<h2 id="teeSink">Tee Sink</h2>
+
+<p>
+The "tee sink" is
+an AudioFlinger debugging feature, available in custom builds only,
+for retaining a short fragment of recent audio for later analysis.
+This permits comparison between what was actually played or recorded
+vs. what was expected.
+</p>
+
+<p>
+For privacy the tee sink is disabled by default, at both compile-time and
+run-time. To use the tee sink, you will need to enable it by re-compiling,
+and also by setting a property. Be sure to disable this feature after you are
+done debugging; the tee sink should not be left enabled in production builds.
+</p>
+
+<p>
+The instructions in the remainder of this section are for Android 4.4,
+and may require changes for other versions.
+</p>
+
+<h3>Compile-time setup</h3>
+
+<ol>
+<li><code>cd frameworks/av/services/audioflinger</code></li>
+<li>edit <code>Configuration.h</code></li>
+<li>uncomment <code>#define TEE_SINK</code></li>
+<li>re-build <code>libaudioflinger.so</code></li>
+<li><code>adb root</code></li>
+<li><code>adb remount</code></li>
+<li>push or sync the new <code>libaudioflinger.so</code> to the device's <code>/system/lib</code></li>
+</ol>
+
+<h3>Run-time setup</h3>
+
+<ol>
+<li><code>adb shell getprop | grep ro.debuggable</code>
+<br />Confirm that the output is: <code>[ro.debuggable]: [1]</code>
+</li>
+<li><code>adb shell</code></li>
+<li><code>ls -ld /data/misc/media</code>
+<br />
+<p>
+Confirm that the output is:
+</p>
+<pre>
+drwx------ media media ... media
+</pre>
+<br />
+<p>
+If the directory does not exist, create it as follows:
+</p>
+<code>
+mkdir /data/misc/media
+chown media:media /data/misc/media
+</code>
+</li>
+<li><code>echo af.tee=# > /data/local.prop</code>
+<br />where the <code>af.tee</code> value is a number described below
+</li>
+<li><code>chmod 644 /data/local.prop</code></li>
+<li><code>reboot</code></li>
+</ol>
+
+<h4>Values for <code>af.tee</code> property</h4>
+
+<p>
+The value of <code>af.tee</code> is a number between 0 and 7, expressing
+the sum of several bits, one per feature.
+See the code at <code>AudioFlinger::AudioFlinger()</code> in <code>AudioFlinger.cpp</code>
+for an explanation of each bit, but briefly:
+</p>
+<ul>
+<li>1 = input</li>
+<li>2 = FastMixer output</li>
+<li>4 = per-track AudioRecord and AudioTrack</li>
+</ul>
+
+<p>
+There is no bit for deep buffer or normal mixer yet,
+but you can get similar results using "4."
+</p>
+
+<h3>Test and acquire data</h3>
+
+<ol>
+<li>Run your audio test</li>
+<li><code>adb shell dumpsys media.audio_flinger</code></li>
+<li>Look for a line in dumpsys output such as this:<br />
+<code>tee copied to /data/misc/media/20131010101147_2.wav</code>
+<br />This is a PCM .wav file</br>
+</li>
+<li><code>adb pull</code> any <code>/data/misc/media/*.wav</code> files of interest;
+note that track-specific dump filenames do not appear in the dumpsys output,
+but are still saved to <code>/data/misc/media</code> upon track closure
+</li>
+<li>Review the dump files for privacy concerns before sharing with others</li>
+</ol>
+
+<h4>Suggestions</h4>
+
+<p>Try these ideas for more useful results:</p>
+
+<ul>
+<li>Disable touch sounds and key clicks</li>
+<li>Maximize all volumes</li>
+<li>Disable apps that make sound or record from microphone,
+if they are not of interest to your test
+</li>
+<li>Track-specific dumps are only saved when the track is closed;
+you may need to force close an app in order to dump its track-specific data
+<li>Do the <code>dumpsys</code> immediately after test;
+there is a limited amount of recording space available</li>
+<li>To make sure you don't lose your dump files,
+upload them to your host periodically.
+Only a limited number of dump files are preserved;
+older dumps are removed after that limit is reached.</li>
+</ul>
+
+<h3>Restore</h3>
+
+<p>
+As noted above, the tee sink feature should not be left enabled.
+Restore your build and device as follows:
+</p>
+<ol>
+<li>Revert the source code changes to <code>Configuration.h</code></li>
+<li>Re-build <code>libaudioflinger.so</code></li>
+<li>Push or sync the restored <code>libaudioflinger.so</code>
+to the device's <code>/system/lib</code>
+</li>
+<li><code>adb shell</code></li>
+<li><code>rm /data/local.prop</code></li>
+<li><code>rm /data/misc/media/*.wav</code></li>
+<li><code>reboot</code></li>
+</ol>
+
+<h2 id="mediaLog">media.log</h2>
+
+<h3>ALOGx macros</h3>
+
+<p>
+The standard Java language logging API in Android SDK is
+<a class="external-link" href="http://developer.android.com/reference/android/util/Log.html" target="_android">android.util.Log</a>.
+</p>
+
+<p>
+The corresponding C language API in Android NDK is
+<code>__android_log_print</code>
+declared in <code><android/log.h></code>.
+</p>
+
+<p>
+Within the native portion of Android framework, we
+prefer macros named <code>ALOGE</code>, <code>ALOGW</code>,
+<code>ALOGI</code>, <code>ALOGV</code>, etc. They are declared in
+<code><utils/Log.h></code>, and for the purposes of this article
+we'll collectively refer to them as <code>ALOGx</code>.
+</p>
+
+<p>
+All of these APIs are easy-to-use and well-understood, so they are pervasive
+throughout the Android platform. In particular the <code>mediaserver</code>
+process, which includes the AudioFlinger sound server, uses
+<code>ALOGx</code> extensively.
+</p>
+
+<p>
+Nevertheless, there are some limitations to <code>ALOGx</code> and friends:
+</p>
+
+<ul>
+<li>
+They are suspectible to "log spam": the log buffer is a shared resource
+so it can easily overflow due to unrelated log entries, resulting in
+missed information. The <code>ALOGV</code> variant is disabled at
+compile-time by default. But of course even it can result in log spam
+if it is enabled.
+</li>
+<li>
+The underlying kernel system calls could block, possibly resulting in
+priority inversion and consequently measurement disturbances and
+inaccuracies. This is of
+special concern to time-critical threads such as <code>FastMixer</code>.
+</li>
+<li>
+If a particular log is disabled to reduce log spam,
+then any information that would have been captured by that log is lost.
+It is not possible to enable a specific log retroactively,
+<i>after</i> it becomes clear that the log would have been interesting.
+</li>
+</ul>
+
+<h3>NBLOG, media.log, and MediaLogService</h3>
+
+<p>
+The <code>NBLOG</code> APIs and associated <code>media.log</code>
+process and <code>MediaLogService</code>
+service together form a newer logging system for media, and are specifically
+designed to address the issues above. We will loosely use the term
+"media.log" to refer to all three, but strictly speaking <code>NBLOG</code> is the
+C++ logging API, <code>media.log</code> is a Linux process name, and <code>MediaLogService</code>
+is an Android binder service for examining the logs.
+</p>
+
+<p>
+A <code>media.log</code> "timeline" is a series
+of log entries whose relative ordering is preserved.
+By convention, each thread should use it's own timeline.
+</p>
+
+<h3>Benefits</h3>
+
+<p>
+The benefits of the <code>media.log</code> system include:
+</p>
+<ul>
+<li>doesn't spam the main log unless and until it is needed</li>
+<li>can be examined even when <code>mediaserver</code> crashes or hangs</li>
+<li>is non-blocking per timeline</li>
+<li>
+less disturbance to performance
+(of course no form of logging is completely non-intrusive)
+</li>
+</ul>
+
+<h3>Architecture</h3>
+
+<p>
+The diagram below shows the relationship of the <code>mediaserver</code> process
+and the <code>init</code> process, before <code>media.log</code> is introduced:
+</p>
+<img src="audio/images/medialog_before.png" alt="Architecture before media.log" />
+<p>
+Notable points:
+</p>
+<ul>
+<li><code>init</code> forks and execs <code>mediaserver</code></li>
+<li><code>init</code> detects the death of <code>mediaserver</code>, and re-forks as necessary</li>
+<li><code>ALOGx</code> logging is not shown
+</ul>
+
+<p>
+The diagram below shows the new relationship of the components,
+after <code>media.log</code> is added to the architecture:
+</p>
+<img src="audio/images/medialog_after.png" alt="Architecture after media.log" />
+<p>
+Important changes:
+</p>
+
+<ul>
+
+<li>
+Clients use <code>NBLOG</code> API to construct log entries and append them to
+a circular buffer in shared memory.
+</li>
+
+<li>
+<code>MediaLogService</code> can dump the contents of the circular buffer at any time.
+</li>
+
+<li>
+The circular buffer is designed in such a way that any corruption of the
+shared memory will not crash <code>MediaLogService</code>, and it will still be able
+to dump as much of the buffer that is not affected by the corruption.
+</li>
+
+<li>
+The circular buffer is non-blocking and lock-free for both writing
+new entries and reading existing entries.
+</li>
+
+<li>
+No kernel system calls are required to write to or read from the circular buffer
+(other than optional timestamps).
+</li>
+
+</ul>
+
+<h4>Where to use</h4>
+
+<p>
+As of Android 4.4, there are only a few log points in AudioFlinger
+that use the <code>media.log</code> system. Though the new APIs are not as
+easy to use as <code>ALOGx</code>, they are not extremely difficult either.
+We encourage you to learn the new logging system for those
+occasions when it is indispensable.
+In particular, it is recommended for AudioFlinger threads that must
+run frequently, periodically, and without blocking such as the
+<code>FastMixer</code> thread.
+</p>
+
+<h3>How to use</h3>
+
+<h4>Add logs</h4>
+
+<p>
+First, you need to add logs to your code.
+</p>
+
+<p>
+In <code>FastMixer</code> thread, use code such as this:
+</p>
+<pre>
+logWriter->log("string");
+logWriter->logf("format", parameters);
+logWriter->logTimestamp();
+</pre>
+<p>
+As this <code>NBLog</code> timeline is used only by the <code>FastMixer</code> thread,
+there is no need for mutual exclusion.
+</p>
+
+<p>
+In other AudioFlinger threads, use <code>mNBLogWriter</code>:
+</p>
+<pre>
+mNBLogWriter->log("string");
+mNBLogWriter->logf("format", parameters);
+mNBLogWriter->logTimestamp();
+</pre>
+<p>
+For threads other than <code>FastMixer</code>,
+the thread's <code>NBLog</code> timeline can be used by both the thread itself, and
+by binder operations. <code>NBLog::Writer</code> does not provide any
+implicit mutual exclusion per timeline, so be sure that all logs occur
+within a context where the thread's mutex <code>mLock</code> is held.
+</p>
+
+<p>
+After you have added the logs, re-build AudioFlinger.
+</p>
+
+<b>Caution:</b>
+<p>
+A separate <code>NBLog::Writer</code> timeline is required per thread,
+to ensure thread safety, since timelines omit mutexes by design. If you
+want more than one thread to use the same timeline, you can protect with an
+existing mutex (as described above for <code>mLock</code>). Or you can
+use the <code>NBLog::LockedWriter</code> wrapper instead of <code>NBLog::Writer</code>.
+However, this negates a prime benefit of this API: its non-blocking
+behavior.
+</p>
+
+<p>
+The full <code>NBLog</code> API is at <code>frameworks/av/include/media/nbaio/NBLog.h</code>.
+</p>
+
+<h4>Enable media.log</h4>
+
+<p>
+<code>media.log</code> is disabled by default. It is active only when property
+<code>ro.test_harness</code> is <code>1</code>. You can enable it by:
+</p>
+
+<pre>
+adb root
+adb shell
+echo ro.test_harness=1 > /data/local.prop
+chmod 644 /data/local.prop
+reboot
+</pre>
+
+<p>
+The connection is lost during reboot, so:
+</p>
+<pre>
+adb shell
+</pre>
+
+The command <code>ps media</code> will now show two processes:
+<ul>
+<li>media.log</li>
+<li>mediaserver</li>
+</ul>
+<p>
+Note the process ID of <code>mediaserver</code> for later.
+</p>
+
+<h4>Displaying the timelines</h4>
+
+<p>
+You can manually request a log dump at any time.
+This command shows logs from all the active and recent timelines, and then clears them:
+</p>
+<pre>
+dumpsys media.log
+</pre>
+
+<p>
+Note that by design timelines are independent,
+and there is no facility for merging timelines.
+</p>
+
+<h4>Recovering logs after mediaserver death</h4>
+
+<p>
+Now try killing <code>mediaserver</code> process: <code>kill -9 #</code>, where # is
+the process ID you noted earlier. You should see a dump from <code>media.log</code>
+in the main <code>logcat</code>, showing all the logs leading up to the crash.
+</p>
+<pre>
+dumpsys media.log
+</pre>
diff --git a/src/devices/audio_implement.jd b/src/devices/audio_implement.jd
index 9267d9e..26aa5f5 100644
--- a/src/devices/audio_implement.jd
+++ b/src/devices/audio_implement.jd
@@ -98,7 +98,6 @@
<p>AudioFlinger's mixer downmixes the content to stereo
automatically when sent to an audio device that does not support multichannel audio.</p>
-</p>
<h3 id="codecs">Media codecs</h3>
@@ -193,7 +192,6 @@
<li><a
href="http://developer.android.com/reference/android/media/audiofx/NoiseSuppressor.html">Noise Suppression</a></li>
</ul>
-</p>
<p>Pre-processing effects are always paired with the use case mode in which the pre-processing is requested. In Android
@@ -203,14 +201,14 @@
inputSource)</code>. The following sources are exposed to developers:
</p>
<ul>
-<code><li>android.media.MediaRecorder.AudioSource.CAMCORDER</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.VOICE_COMMUNICATION</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.VOICE_CALL</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.VOICE_DOWNLINK</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.VOICE_UPLINK</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.MIC</li></code>
-<code><li>android.media.MediaRecorder.AudioSource.DEFAULT</li></code>
+<li><code>android.media.MediaRecorder.AudioSource.CAMCORDER</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_COMMUNICATION</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_CALL</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_DOWNLINK</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_UPLINK</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.MIC</code></li>
+<li><code>android.media.MediaRecorder.AudioSource.DEFAULT</code></li>
</ul>
<p>The default pre-processing effects that are applied for each <code>AudioSource</code> are
diff --git a/src/devices/audio_src.jd b/src/devices/audio_src.jd
new file mode 100644
index 0000000..b57717c
--- /dev/null
+++ b/src/devices/audio_src.jd
@@ -0,0 +1,143 @@
+page.title=Sample Rate Conversion
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>
+See the Wikipedia article
+<a class="external-link" href="http://en.wikipedia.org/wiki/Resampling_(audio)" target="_android">Resampling (audio)</a>
+for a generic definition of sample rate conversion, also known as "resampling."
+The remainder of this article describes resampling within Android.
+</p>
+
+<p>
+Sample rate conversion is the process of changing a
+stream of discrete samples at one sample rate to another stream at
+another sample rate. A sample rate converter, or resampler, is a module
+that implements sample rate conversion. With respect to the resampler,
+the original stream is called the source signal, and the resampled stream is
+the sink signal.
+</p>
+
+<p>
+Resamplers are used in several places in Android.
+For example, an MP3 file may be encoded at 44.1 kHz sample rate and
+needs to be played back on an Android device supporting 48 kHz audio
+internally. In that case, a resampler would be used to upsample the MP3
+output audio from 44.1 kHz source sample rate to a 48 kHz sink sample rate
+used within the Android device.
+</p>
+
+<p>
+The characteristics of a resampler can be expressed using metrics, including:
+</p>
+
+<ul>
+<li>degree of preservation of the overall amplitude of the signal</li>
+<li>degree of preservation of the frequency bandwidth of the signal,
+ subject to limitations of the sink sample rate</li>
+<li>overall latency through the resampler</li>
+<li>consistent phase and group delay with respect to frequency</li>
+<li>computational complexity, expressed in CPU cycles or power draw</li>
+<li>permitted ratios of source and sink sample rates</li>
+<li>ability to dynamically change sample rate ratios</li>
+<li>which digital audio sample formats are supported</li>
+</ul>
+
+<p>
+The ideal resampler would exactly preserve the source signal's amplitude
+and frequency bandwidth (subject to limitations of the sink
+sample rate), have minimal and consistent delay, have minimal
+computational complexity, permit arbitrary and dynamic conversion ratios,
+and support all common digital audio sample formats.
+In practice, ideal resamplers do not exist, and actual resamplers are
+a compromise among these characteristics.
+For example, the goals of ideal quality conflict with short delay and low complexity.
+</p>
+
+<p>
+Android includes a variety of audio resamplers, so that appropriate
+compromises can be made depending on the application use case and load.
+Section <a href="#srcResamplers">Resampler implementations</a>
+below lists the available resamplers, summarizes their characteristics,
+and identifies where they should typically be used.
+</p>
+
+<h2 id="srcTerms">Terminology</h2>
+
+<dl>
+
+<dt>downsample</dt>
+<dd>to resample, where sink sample rate < source sample rate</dd>
+
+<dt>Nyquist frequency</dt>
+<dd>
+The Nyquist frequency, equal to 1/2 of a given sample rate, is the
+maximum frequency component that can be represented by a discretized
+signal at that sample rate. For example, the human hearing range is
+typically assumed to extend up to approximately 20 kHz, and so a digital
+audio signal must have a sample rate of at least 40 kHz to represent that
+range. In practice, sample rates of 44.1 kHz and 48 kHz are commonly
+used, with Nyquist frequencies of 22.05 kHz and 24 kHz respectively.
+See the Wikipedia articles
+<a class="external-link" href="http://en.wikipedia.org/wiki/Nyquist_frequency" target="_android">Nyquist frequency</a>
+and
+<a class="external-link" href="http://en.wikipedia.org/wiki/Hearing_range" target="_android">Hearing range</a>
+for more information.
+</dd>
+
+<dt>resampler</dt>
+<dd>synonym for sample rate converter</dd>
+
+<dt>resampling</dt>
+<dd>the process of converting sample rate</dd>
+
+<dt>sample rate converter</dt>
+<dd>a module that resamples</dd>
+
+<dt>sink</dt>
+<dd>the output of a resampler</dd>
+
+<dt>source</dt>
+<dd>the input to a resampler</dd>
+
+<dt>upsample</dt>
+<dd>to resample, where sink sample rate > source sample rate</dd>
+
+</dl>
+
+<h2 id="srcResamplers">Resampler implementations</h2>
+
+<p>
+Available resampler implementations change frequently,
+and may be customized by OEMs.
+As of Android 4.4, the default resamplers
+in descending order of signal distortion, and ascending order of
+computational complexity include:
+</p>
+
+<ul>
+<li>linear</li>
+<li>cubic</li>
+<li>sinc with original coefficients</li>
+<li>sinc with revised coefficients</li>
+</ul>
+
+<p>
+In general, the sinc resamplers are more appropriate for higher-quality
+music playback, and the other resamplers should be reserved for cases
+where quality is less important (an example might be "key clicks" or similar).
+</p>
+
+<p>
+The specific resampler implementation selected depends on
+the use case, load, and the value of system property
+<code>af.resampler.quality</code>. For details,
+consult the audio resampler source code in AudioFlinger.
+</p>
diff --git a/src/devices/audio_terminology.jd b/src/devices/audio_terminology.jd
index c21e595..a27703b 100644
--- a/src/devices/audio_terminology.jd
+++ b/src/devices/audio_terminology.jd
@@ -166,7 +166,7 @@
To increase the number of channels, e.g. from mono to stereo, or from stereo to surround sound.
This can be accomplished by duplication, panning, or more advanced signal processing.
Compare to "downmixing".
-</dl>
+</dd>
<dt>virtualizer</dt>
<dd>
@@ -179,6 +179,8 @@
Loudness, the subjective strength of an audio signal.
</dd>
+</dl>
+
<h3 id="hardwareTerms">Hardware and Accessories</h3>
<p>
@@ -294,6 +296,8 @@
an application to the transducer, or vice-versa.
</p>
+<dl>
+
<dt>ADC</dt>
<dd>
Analog to digital converter, a module that converts an analog signal
@@ -364,7 +368,7 @@
target="_android">Pulse-width modulation</a>.
</dd>
-</p>
+</dl>
<h2 id="androidSpecificTerms">Android-Specific Terms</h2>
@@ -436,13 +440,11 @@
<a href="http://developer.android.com/reference/android/media/AudioRecord.html"
target="_android">android.media.AudioRecord</a>.
</dd>
-</dd>
<dt>AudioResampler</dt>
<dd>
-The module within AudioFlinger responsible for sample-rate conversion. See Wikipedia article
-<a class="external-link" href="http://en.wikipedia.org/wiki/Resampling_(audio)" target="_android">Resampling (audio)</a>
-for the generic definition.
+The module within AudioFlinger responsible for
+<a href="audio_src.html">sample rate conversion</a>.
</dd>
<dt>AudioTrack</dt>
@@ -535,7 +537,6 @@
<a href="http://developer.android.com/reference/android/media/SoundPool.html"
target="_android">android.media.SoundPool</a>.
</dd>
-</dd>
<dt>Stagefright</dt>
<dd>
@@ -565,10 +566,8 @@
<dt>tee sink</dt>
<dd>
-An AudioFlinger debugging feature, available in custom builds only,
-for retaining a short fragment of recent audio for later analysis.
-This permits comparison between what was actually played or recorded
-vs. what was expected.
+See the separate article on tee sink in
+<a href="audio_debugging.html#teeSink">Audio Debugging</a>.
</dd>
<dt>tinyalsa</dt>
@@ -609,5 +608,10 @@
</dl>
+<h2 id="srcTerms">Sample Rate Conversion</h2>
+
+<p>
+For terms related to sample rate conversion, see the separate article
+<a href="audio_src.html">Sample Rate Conversion</a>.
</p>
diff --git a/src/devices/audio_warmup.jd b/src/devices/audio_warmup.jd
index d2b5c28..0a0ec04 100644
--- a/src/devices/audio_warmup.jd
+++ b/src/devices/audio_warmup.jd
@@ -55,7 +55,7 @@
the hardware itself might have its own power logic beyond the three seconds that AudioFlinger has.</li>
<li>Press Home, and you should hear a click sound.</li>
<li>Run the following command to receive the measured warmup:
- <pre>adb shell dumpsys media.audio_flinger | grep measuredWarmup</code></pre>
+ <br /><code>adb shell dumpsys media.audio_flinger | grep measuredWarmup</code>
<p>
You should see output like this:
@@ -78,8 +78,8 @@
<li>
Take five measurements and record them all, as well as the mean.
If they are not all approximately the same,
- then it’s likely that a measurement is incorrect.
- For example, if you don’t wait long enough after the audio has been off,
+ then it's likely that a measurement is incorrect.
+ For example, if you don't wait long enough after the audio has been off,
you will see a lower warmup time than the mean value.
</li>
</ol>
@@ -106,6 +106,7 @@
<li>Leaving circuits powered on or not reconfiguring clocks (increases idle power consumption)
<li>Caching computed parameters</li>
</ul>
+<p>
However, beware of excessive optimization. You may find that you
need to tradeoff between low warmup time versus
lack of popping at power transitions.
diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs
index 9de25e1..0a9d150 100644
--- a/src/devices/devices_toc.cs
+++ b/src/devices/devices_toc.cs
@@ -33,20 +33,22 @@
<ul>
<li><a href="<?cs var:toroot ?>devices/audio_implement.html">Implementation</a></li>
<li><a href="<?cs var:toroot ?>devices/audio_warmup.html">Warmup</a></li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>devices/audio_latency.html">
- <span class="en">Latency</span>
- </a>
- </div>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>devices/audio_latency.html">
+ <span class="en">Latency</span>
+ </a>
+ </div>
<ul>
- <li><a href="<?cs var:toroot ?>devices/audio_latency_measure.html">Measure</a></li>
- <li><a href="<?cs var:toroot ?>devices/latency_design.html">Design</a></li>
- <li><a href="<?cs var:toroot ?>devices/testing_circuit.html">Testing Circuit</a></li>
- </ul>
- </li>
+ <li><a href="<?cs var:toroot ?>devices/audio_latency_measure.html">Measure</a></li>
+ <li><a href="<?cs var:toroot ?>devices/latency_design.html">Design</a></li>
+ <li><a href="<?cs var:toroot ?>devices/testing_circuit.html">Testing Circuit</a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>devices/audio_avoiding_pi.html">Priority Inversion</a></li>
+ <li><a href="<?cs var:toroot ?>devices/audio_src.html">Sample Rate Conversion</a></li>
<li><a href="<?cs var:toroot ?>devices/audio_terminology.html">Terminology</a></li>
+ <li><a href="<?cs var:toroot ?>devices/audio_debugging.html">Debugging</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>devices/bluetooth.html">Bluetooth</a></li>