aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:32 -0800
commit8b23a6c7e1aee255004dd19098d4c2462b61b849 (patch)
tree7a4d682ba51f0ff0364c5ca2509f515bdaf96de9 /docs
parentf721e3ac031f892af46f255a47d7f54a91317b30 (diff)
downloadexternal_qemu-8b23a6c7e1aee255004dd19098d4c2462b61b849.zip
external_qemu-8b23a6c7e1aee255004dd19098d4c2462b61b849.tar.gz
external_qemu-8b23a6c7e1aee255004dd19098d4c2462b61b849.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'docs')
-rw-r--r--docs/AUDIO.TXT160
-rw-r--r--docs/KERNEL.TXT25
2 files changed, 185 insertions, 0 deletions
diff --git a/docs/AUDIO.TXT b/docs/AUDIO.TXT
new file mode 100644
index 0000000..1a25b77
--- /dev/null
+++ b/docs/AUDIO.TXT
@@ -0,0 +1,160 @@
+HOW AUDIO EMULATION WORKS IN QEMU:
+==================================
+
+Things are a bit tricky, but here's a rough description:
+
+ QEMUSoundCard: models a given emulated sound card
+ SWVoiceOut: models an audio output from a QEMUSoundCard
+ SWVoiceIn: models an audio input from a QEMUSoundCard
+
+ HWVoiceOut: models an audio output (backend) on the host.
+ HWVoiceIn: models an audio input (backend) on the host.
+
+Each voice can have its own settings in terms of sample size, endianess, rate, etc...
+
+
+Emulation for a given soundcard typically does:
+
+ 1/ Create a QEMUSoundCard object and register it with AUD_register_card()
+ 2/ For each emulated output, call AUD_open_out() to create a SWVoiceOut object.
+ 3/ For each emulated input, call AUD_open_in() to create a SWVoiceIn object.
+
+ Note that you must pass a callback function to AUD_open_out() and AUD_open_in();
+ more on this later.
+
+ Each SWVoiceOut is associated to a single HWVoiceOut, each SWVoiceIn is
+ associated to a single HWVoiceIn.
+
+ However you can have several SWVoiceOut associated to the same HWVoiceOut
+ (same thing for SWVoiceIn/HWVoiceIn).
+
+SOUND PLAYBACK DETAILS:
+=======================
+
+Each HWVoiceOut has the following too:
+
+ - A fixed-size circular buffer of stereo samples (for stereo).
+ whose format is either floats or int64_t per sample (depending on build configuration).
+
+ - A 'samples' field giving the (constant) number of sample pairs in the stereo buffer.
+
+ - A target conversion function, called 'clip()' that is used to read from the stereo
+ buffer and write into a platform-specific sound buffers (e.g. WinWave-managed buffers
+ on Windows).
+
+ - A 'rpos' offset into the circular buffer which tells where to read the next samples
+ from the stereo buffer for the next conversion through 'clip'.
+
+ - A 'run_out' method that is called each time to tell the output backend to
+ send samples from the stereo buffer to the host sound card/server. This method
+ shall also modify 'rpos' and returns the number of samples 'played'. A more detailed
+ description of this process appears below.
+
+ - A 'write' method callback used to write a buffer of emulated sound samples from
+ a SWVoiceOut into the stereo buffer. *All* backends simply call the generic
+ function audio_pcm_sw_write() to implement this. It's difficult to see why
+ it's needed at all ?
+
+ (Similarly, all backends have a 'read' methods which simply calls 'audio_pcm_sw_read')
+
+Each SWVoiceOut has the following:
+
+ - a 'conv()' function used to read sound samples from the emulated sound card and
+ copy/mix them to the corresponding HWVoiceOut's stereo buffer.
+
+ - a 'total_hw_samples_mixed' which correspond to the number of samples that have
+ already been mixed into the target HWVoiceOut stereo buffer (starting from the
+ HWVoiceOut's 'rpos' offset). NOTE: this is a count of samples in the HWVoiceOut
+ stereo buffer, not emulated hardware sound samples, which can have different
+ properties (frequency, size, endianess).
+
+ - a 'ratio' value, which is the ratio of the target HWVoiceOut's frequency by
+ the SWVoiceOut's frequency, multiplied by (1 << 32), as a 64-bit integer.
+
+ So, if the HWVoiceOut has a frequency of 44kHz, and the SWVoiceOut has a frequency
+ of 11kHz, then ratio will be (44/11*(1 << 32)) = 0x4_0000_0000
+
+ - a callback provided by the emulated hardware when the SWVoiceOut is created.
+ This function is used to mix the SWVoiceOut's samples into the target
+ HWVoiceOut stereo buffer (it must also perform frequency interpolation,
+ volume adjustment, etc..).
+
+ This callback normally calls another helper functions in the audio subsystem
+ (AUD_write()) to to the mixing/volume-adjustment from emulated hardware sample
+ buffers.
+
+Here's a small graphics that explains it better:
+
+ SWVoiceOut: emulated hardware sound buffers:
+
+ |
+ | (mixed through AUD_write() from user-provided callback)
+ |
+ v
+
+ HWVoiceOut: stereo sample circular buffer
+
+ |
+ | (through HWVoiceOut's 'clip' function, invoked from the
+ | 'run_out' method)
+ v
+
+ backend-specific sound buffers
+
+THERE IS NO COMMON TIMEBASE BETWEEN ALL LAYERS. DON'T EXPECT ANY HIGH-ACCURACY /
+LOW-LATENCY IN THIS IMPLEMENTATION.
+
+
+The function audio_timer() in audio/audio.c is called periodically and it is used as
+a pulse to perform sound buffer transfers and mixing. More specifically for audio
+output voices:
+
+- For each HWVoiceOut, find the number of active SWVoiceOut, and the minimum number
+ of 'total_hw_samples_mixed' that have already been written to the buffer. We will
+ call this value the number of 'live' samples in the stereo buffer.
+
+- if 'live' is 0, call the callback of each active SWVoiceOut to fill the stereo
+ buffer, if needed, then exit.
+
+- otherwise, call the 'run_out' method of the HWVoiceOut object. This will change
+ the value of 'rpos' and return the number of samples played. Then the
+ 'total_hw_samples_mixed' field of all active SWVoiceOuts is decremented by
+ 'played', and the callback is called to re-fill the stereo buffer.
+
+It's important to note that the SWVoiceOut callback:
+
+- takes a 'free' parameter which is the number of emulated sound samples that can
+ be sent to the hardware stereo buffer (before rate adjustment, i.e. not the number
+ of sound samples in the SWVoiceOut emulated hardware sound buffer).
+
+- must call AUD_write(sw, buff, count), where 'buff' points to emulated sound
+ samples, and their 'count', which must be <= the 'free' parameter.
+
+- the implementation of AUD_write() will call the 'write' method of the target
+ HWVoiceOut, which in turns calls the function audio_pcm_sw_write() which does
+ standard rate/volume adjustment before mixing the conversion into the target
+ stereo buffer. It also increases the 'total_hw_samples_mixed' value of the
+ SWVoiceOut.
+
+- audio_pcm_sw_write() returns the number of sound sample *bytes* that have
+ been mixed into the stereo buffer, and so does AUD_write().
+
+So, in the end, we have the pseudo-code:
+
+ every sound timer ticks:
+ for hw in list_HWVoiceOut:
+ live = MIN([sw.total_hw_samples_mixed for sw in hw.list_SWVoiceOut ])
+ if live > 0:
+ played = hw.run_out(live)
+ for sw in hw.list_SWVoiceOut:
+ sw.total_hw_samples_mixed -= played
+
+ for sw in hw.list_SWVoiceOut:
+ free = hw.samples - sw.total_hw_samples_mixed
+ if free > 0:
+ sw.callback(sw, free)
+
+SOUND RECORDING DETAILS:
+========================
+
+Things are similar but in reverse order.
diff --git a/docs/KERNEL.TXT b/docs/KERNEL.TXT
new file mode 100644
index 0000000..7387e55
--- /dev/null
+++ b/docs/KERNEL.TXT
@@ -0,0 +1,25 @@
+HOW TO REBUILT THE ANDROID EMULATOR-SPECIFIC KERNEL:
+====================================================
+
+You need to have the Android toolchain in your path
+(i.e. 'arm-eabi-gcc --version' must work)
+
+then:
+
+git clone git://android.git.kernel.org/kernel/common.git kernel-common
+cd kernel-common
+git checkout origin/android-goldfish-2.6.27
+
+export CROSS_COMPILE=arm-eabi-
+export ARCH=arm
+export SUBARCH=arm
+make goldfish_defconfig # configure the kernel
+make -j2 # build it
+
+=> this generates a file named arch/arm/boot/zImage
+
+Now, you can use it with:
+
+ emulator -kernel path/to/your/new/zImage <other-options>
+
+Voila !