119 lines
15 KiB
HTML
119 lines
15 KiB
HTML
<?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>, &<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 &</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><<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><<code class="varname">channel_count</code>; <code class="varname">j</code>++) {
|
||
<code class="varname">buf</code>[i+j] = <code class="varname">cookie</code>-><code class="varname">value</code>;
|
||
}
|
||
if ((<code class="varname">cookie</code>-><code class="varname">direction</code> == 1.0) && (<code class="varname">cookie</code>-><code class="varname">value</code> >= 1.0)) {
|
||
<code class="varname">cookie</code>-><code class="varname">direction</code> = -1.0;
|
||
}
|
||
else if ((<code class="varname">cookie</code>-><code class="varname">direction</code> == -1.0) && (<code class="varname">cookie</code>-><code class="varname">value</code> <= -1.0)) {
|
||
<code class="varname">cookie</code>-><code class="varname">direction</code> = 1.0;
|
||
}
|
||
<code class="varname">cookie</code>-><code class="varname">value</code> += <code class="varname">cookie</code>-><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>
|