haiku-website/static/legacy-docs/bebook/BSoundPlayer_Overview.html

119 lines
15 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Be Book - System Overview - The Media Kit</title><link rel="stylesheet" href="be_book.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
<link rel="stylesheet" type="text/css" href="be_book_ie.css" />
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="Access, BeOS, BeBook, API" /><link rel="start" href="index.html" title="The Be Book" /><link rel="up" href="TheMediaKit_Overview.html" title="The Media Kit" /><link rel="prev" href="BSmallBuffer_Overview.html" title="BSmallBuffer" /><link rel="next" href="BTimeCode_Overview.html" title="BTimeCode" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="BSmallBuffer_Overview.html" title="BSmallBuffer"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="TheMediaKit_Overview.html" title="The Media Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="BTimeCode_Overview.html" title="BTimeCode"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="navigindex"><a accesskey="i" href="ClassIndex.html" title="Index">I</a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">The Be Book - System Overview - The Media Kit</div></div><div id="headerB">Prev: <a href="BSmallBuffer_Overview.html">BSmallBuffer</a>  Up: <a href="TheMediaKit_Overview.html">The Media Kit</a>  Next: <a href="BTimeCode_Overview.html">BTimeCode</a></div><hr /></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BSoundPlayer_Overview"></a>BSoundPlayer</h2></div></div></div><a id="id591076" class="indexterm"></a><p>The <a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
class plays sound by directly filling audio buffers with data provided
by a hook function you specify. A single
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
can play multiple sounds at a time.</p><p><a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
takes care of all the nitty-gritty details of instantiating
the necessary sound player node and managing the time source. All you
have to do is start up a
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
and feed it sounds to play.</p><p>You need to implement a hook function that will be
called for each audio buffer passed through the
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>'s
playback node.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id591145"></a>Using BSoundPlayer</h3></div></div></div><p>Once you've instantiated a
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
object, you need to start it up
before you can actually play sounds with it. This instantiates the sound
player node, attaches it to an appropriate time source, and makes sure
the time source is running. This is done by calling the
<a class="link" href="BSoundPlayer.html#BSoundPlayer_Start" title="Start(), Stop()"><code class="methodname">Start()</code></a>
function.</p><p>When you're done using the
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>,
you can delete it if you don't
plan to use it again, or, if you want to keep it around for reuse, you
can just
<a class="link" href="BSoundPlayer.html#BSoundPlayer_Stop"><code class="methodname">Stop()</code></a>
it. This deletes the sound node and cleans up the sounds.</p><p>You can find out the current time of the time source to which sounds are
being synchronized by calling the
<a class="link" href="BSoundPlayer.html#BSoundPlayer_CurrentTime" title="CurrentTime(), PerformanceTime()"><code class="methodname">CurrentTime()</code></a>
function.</p><p>By default, the audio format used by a
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a> is
<code class="classname">BSoundPlayer</code>::<code class="constant">B_AUDIO_FLOAT</code>,
which is to say that the audio is in
floating-point format, where each sample ranges from -1.0 to 1.0. The
Media Kit uses floating-point audio internally, so using floating-point
audio whenever you can will improve your application's performance by
cutting down on format conversions. However, if you want to use another
format, you may do so by specifying a
<a class="link" href="TheMediaKit_DefinedTypes.html#media_raw_audio_format" title="media_raw_audio_format"><span class="type">media_raw_audio_format</span></a>
when you instantiate the
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
object.</p><p>Sound streams may only contain 1 or 2 channels (either mono or stereo, in
other words). There's no support yet for multichannel sound.</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p><a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
can only play sounds in the native byte order.</p></div></div></div><p>The audio mixer performs best if you don't specify a particular buffer
size.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id591270"></a>Playing Sound</h4></div></div></div><p>When you specify a play buffer handler function, either when instantiating
the <a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
object or by calling
<a class="link" href="BSoundPlayer.html#BSoundPlayer_SetCallbacks" title="SetCallbacks()"><code class="methodname">SetCallbacks()</code></a> or
<a class="link" href="BSoundPlayer.html#BSoundPlayer_SetBufferPlayer"><code class="methodname">SetBufferPlayer()</code></a>,
that function will be called once for each buffer that passes through the
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>'s
sound playing node. Your play buffer handler can then fill the buffer with
whatever data you wish.</p><p>The following code sets up a
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a>
that will play a triangle wave.</p><pre class="programlisting example">typedef <span class="type">struct cookie_record</span> {
<span class="type">float</span> <code class="varname">value</code>;
<span class="type">float</span> <code class="varname">direction</code>;
} <span class="type">cookie_record</span>;
...
<span class="type">cookie_record</span> <code class="varname">cookie</code>;
<code class="varname">cookie</code>.<code class="varname">value</code> = 0.0;
<code class="varname">cookie</code>.<code class="varname">direction</code> = 1.0;
<code class="classname">BSoundPlayer</code> <code class="varname">player</code>("wave_player", <code class="function">BufferProc</code>, <code class="constant">NULL</code>, &amp;<code class="varname">cookie</code>);
<code class="varname">player</code>.<code class="methodname">Start</code>();
<code class="varname">player</code>.<code class="methodname">SetHasData</code>(<code class="constant">true</code>);
...
<code class="varname">player</code>.<code class="methodname">Stop</code>();</pre><p>This code establishes a record, cookie, that contains information the
play buffer function will need to track, and creates a
<a class="link" href="BSoundPlayer.html" title="BSoundPlayer"><code class="classname">BSoundPlayer</code></a> named
"wave_player" that will use a function called
<code class="function">BufferProc()</code> to play sound,
and uses the cookie we've created.</p><p>Then the player is started, and
<a class="link" href="BSoundPlayer.html#BSoundPlayer_SetHasData"><code class="methodname">SetHasData()</code></a>
is called to let the sound
player node know that there's data to be played. This will cause the play
buffer function to start being called.</p><p>Once playback is over, the
<a class="link" href="BSoundPlayer.html#BSoundPlayer_Stop"><code class="methodname">Stop()</code></a>
function is called to stop playback.</p><p>The <code class="function">BufferProc()</code> function looks like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="function">BufferProc</code>(<span class="type">void *</span><code class="parameter">theCookie</code>, <span class="type">void *</span><code class="parameter">buffer</code>, <span class="type">size_t</span> <code class="parameter">size</code>,
<span class="type">const media_raw_audio_format &amp;</span><code class="parameter">format</code>) {
<span class="type">size_t</span> <code class="varname">i</code>, <code class="varname">j</code>;
<span class="type">float *</span><code class="varname">buf</code> = (<span class="type">float *</span>) <code class="parameter">buffer</code>;
<span class="type">size_t</span> <code class="varname">float_size</code> = <code class="parameter">size</code>/4;
<span class="type">uint32</span> <code class="varname">channel_count</code> = <code class="parameter">format</code>.<code class="varname">channel_count</code>;
<span class="type">cookie_record *</span><code class="varname">cookie</code> = (<span class="type">cookie_record *</span>) <code class="parameter">theCookie</code>;
<span class="comment">// We're going to be cheap and only work for floating-point audio</span>
if (<code class="parameter">format</code>.<code class="varname">format</code> != <span class="type">media_raw_audio_format</span>::<code class="constant">B_AUDIO_FLOAT</code>) {
return;
}
<span class="comment">// Now fill the buffer with sound!</span>
for (<code class="varname">i</code>=0; <code class="varname">i</code>&lt;<code class="varname">float_size</code>; <code class="varname">i</code>+=<code class="varname">channel_count</code>) {
for (<code class="varname">j</code>=0; <code class="varname">j</code>&lt;<code class="varname">channel_count</code>; <code class="varname">j</code>++) {
<code class="varname">buf</code>[i+j] = <code class="varname">cookie</code>-&gt;<code class="varname">value</code>;
}
if ((<code class="varname">cookie</code>-&gt;<code class="varname">direction</code> == 1.0) &amp;&amp; (<code class="varname">cookie</code>-&gt;<code class="varname">value</code> &gt;= 1.0)) {
<code class="varname">cookie</code>-&gt;<code class="varname">direction</code> = -1.0;
}
else if ((<code class="varname">cookie</code>-&gt;<code class="varname">direction</code> == -1.0) &amp;&amp; (<code class="varname">cookie</code>-&gt;<code class="varname">value</code> &lt;= -1.0)) {
<code class="varname">cookie</code>-&gt;<code class="varname">direction</code> = 1.0;
}
<code class="varname">cookie</code>-&gt;<code class="varname">value</code> += <code class="varname">cookie</code>-&gt;<code class="varname">direction</code>*(1.0/64.0);
}
}</pre><p>This example play buffer function generates a triangle wave, ramping the
wave up and down from 1.0 to -1.0 and back, over and over again, 1/64th
at a time. The next value to store in the buffer and the direction in
which the value is changing are kept in the cookie's fields.</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>The buffers your play buffer function receives are empty. Do with them
as you please (or do nothing at all).</p></div></div></div></div></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="BSmallBuffer_Overview.html">BSmallBuffer</a>  Up: <a href="TheMediaKit_Overview.html">The Media Kit</a>  Next: <a href="BTimeCode_Overview.html">BTimeCode</a> </div><div id="footerB"><div id="footerBL"><a href="BSmallBuffer_Overview.html" title="BSmallBuffer"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="TheMediaKit_Overview.html" title="The Media Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="BTimeCode_Overview.html" title="BTimeCode"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>