1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xml:lang="en-US" lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
3  <head>
4    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5    <meta http-equiv="Content-Style-Type" content="text/css" />
6    <title>WaveCodecCtr.dll</title>
7    <style type="text/css">
8    <!--
9    body {
10    /*
11        font-size       : 10pt;
12    */
13        font-weight     : normal;
14        color           : #000000;
15        margin          : 8px;
16    }
17
18    div {
19        width           : 98%;
20        /* white-space     : nowrap; */
21    }
22
23    div.title {
24        text-align      : left;
25        font-weight     : bold;
26    /*
27        font-size       : 16pt;
28    */
29        font-size       : 150%;
30        color           : #202020;
31        border-style    : double;
32        border-width    : 8px;
33        /* タイトルを囲む枠線の色を指定 */
34        border-color    : #CD202C;
35
36        /* RVLプラットフォーム系列 */
37    /*
38        border-color    : #34beed;
39    */
40
41        /* TWLプラットフォーム系列 */
42    /*
43        border-color    : #ff458f;
44    */
45
46        margin          : 4px;
47        padding         : 4px;
48    }
49    H1 {
50      font-size     : 150%;
51      font-family       : Arial;
52      border-bottom-width   : 5px;
53      border-bottom-style   : solid;
54      border-bottom-color   : #CD202C;
55      padding-bottom        : 1px;
56      margin-bottom     : 20px;
57      letter-spacing        : normal;
58      font-weight       : bold;
59    }
60
61    h2 {
62        font-weight     : bold;
63        font-size       : 150%;
64        border-style    : none none solid double;
65        border-width    : 0px 0px 2px 8px;
66        border-color    : #CD202C;
67
68        margin-left     : 2px;
69        padding-left    : 4px;
70    }
71    CODE {
72      font-family       : "Courier New", monospace;
73      position      : normal;
74      left          : 12px;
75      font-size     : 10pt;
76    }
77    table {
78      margin-top        : 2pt;
79      margin-bottom     : 2pt;
80      margin-left       : 0pt;
81      margin-right      : 0pt;
82      padding-left      : 0pt;
83      padding-right     : 0pt;
84      position          : relative;
85      left              : 12px;
86      font-family       : Arial;
87      font-size         : 10pt;
88      border-style      : none none none none;
89    }
90    td,th {
91      padding           : 2pt;
92      border-width      : 2pt;
93      border-style      : none none none none;
94      font-style        : normal;
95      text-align        : left;
96    }
97    td {
98      background        : #e8f4f4;
99      font-weight       : normal;
100    }
101    th {
102      background        : #c0d8d8;
103      font-weight       : bold;
104    }
105
106    p {
107        margin-left     : 4px;
108    }
109    p.code {
110      font-family       : "Courier New", monospace;
111      position      : normal;
112      left          : 12px;
113      font-size     : 10pt;
114      background            : #e8f4f4;
115    }
116
117    pre.definition {
118      padding: 10px;
119      background: #F0F0F0;
120      border: 1px solid #CCC;
121      font-size: 13px;
122    }
123    div.subSection {
124      white-space: wrap;
125    }
126    div.subSection pre,
127    div.subSection table,
128    div.subSection p,
129    div.subSection ol
130    {
131      margin-left: 2em;
132    }
133    div.subSection h3
134    {
135        border-bottom: 2px solid #CD202C;
136        padding-bottom: 4px;
137        margin-top: 2em;
138    }
139    div.subSection h4
140    {
141        font-weight: normal;
142        margin-left: .6em;
143    }
144    p.warning {
145        font-weight: bold;
146        color: red;
147    }
148    -->
149    </style>
150
151
152  </head>
153  <body>
154    <h1><CODE>WaveCodecCtr.dll</CODE></h1>
155    <h2>Contents</h2>
156      <ul>
157        <li><a href="#overview">Overview</a></li>
158        <li><a href="#api">Exported Functions</a></li>
159        <li><a href="#sampleCode">Sample Code</a></li>
160        <li><a href="#caution">Cautions for Encoding and Playing Looped Wave Files</a></li>
161        <li><a href="#history">Revision History</a></li>
162      </ul>
163
164    <h2><a name="overview"></a>Overview</h2>
165    <p>
166    <CODE>WaveCodecCtr.dll</CODE> is a Win32 run-time dynamic link library (DLL). This library provides an API for encoding and decoding between 16-bit signed (little-endian) sampling data and the DSP ADPCM compressed format.
167    </p>
168    <p>
169    The DSP ADPCM format is a compressed format that can be played by a CTR system's DSP. It can result in data sizes that are 1/3.5 of 16-bit PCM. This format can be used through the <a href="../api/nn/snd/CTR/Voice/Overview.html"><CODE>nn::snd::Voice</CODE></a> class and the <a href="../api/nn/snd/CTR/WaveBuffer/Overview.html"><CODE>nn::snd::WaveBuffer</CODE></a> structure.
170    </p>
171    <p>
172    This DLL is for developers who want to develop their own tools for creating and previewing DSP ADPCM sampling data. Note that this DLL is single-threaded.
173    </p>
174    <p>
175    <CODE><a href="ctr_WaveConverter.html">ctr_WaveConverter</a></CODE> uses the features of this DLL to create BCWAV files in ADPCM format.</p>
176
177    <h2><a name="api"></a>Exported Functions</h2>
178    <ul>
179      <li><a href="#getBytesForAdpcmBuffer"><CODE>getBytesForAdpcmBuffer</CODE></a></li>
180      <li><a href="#getBytesForAdpcmSamples"><CODE>getBytesForAdpcmSamples</CODE></a></li>
181      <li><a href="#getBytesForPcmBuffer"><CODE>getBytesForPcmBuffer</CODE></a></li>
182      <li><a href="#getBytesForPcmSamples"><CODE>getBytesForPcmSamples</CODE></a></li>
183      <li><a href="#getSampleForAdpcmNibble"><CODE>getSampleForAdpcmNibble</CODE></a></li>
184      <li><a href="#getNibbleAddress"><CODE>getNibbleAddress</CODE></a></li>
185      <li><a href="#getLoopContext"><CODE>getLoopContext</CODE></a></li>
186      <li><a href="#encode"><CODE>encode</CODE></a></li>
187      <li><a href="#decode"><CODE>decode</CODE></a></li>
188    </ul>
189    <div class="subSection">
190    <h3><a name="getBytesForAdpcmBuffer"></a><CODE>getBytesForAdpcmBuffer</CODE></h3>
191    <h4>Syntax</h4>
192    <pre class="definition">u32 getBytesForAdpcmBuffer(u32 samples);</pre>
193    <h4>Arguments</h4>
194    <table class="arguments">
195      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
196      <tbody>
197        <tr>
198          <td>in</td>
199          <th>samples</th>
200          <td>Number of (16-bit PCM) samples to encode.</td>
201        </tr>
202      </tbody>
203    </table>
204    <h4>Return Values</h4>
205    <p>The number of bytes required to store the DSP ADPCM-encoded samples.</p>
206    <h4>Description</h4>
207    <p>
208    <CODE>getBytesForAdpcmBuffer</CODE> calculates and returns the number of bytes required to store the sampling data that are being DSP ADPCM-encoded.
209    </p>
210    <p>Note that the number of bytes will be a multiple of the 8-byte length of DSP ADPCM frames.</p>
211    <p>The actual length (in bytes) of the sampling data being encoded will probably be smaller than the value returned by this function. (For more information, see the section <CODE><a href="#getBytesForAdpcmSamples">getBytesForAdpcmSamples</a></CODE>.)</p>
212    <p>
213    Use this function before encoding to allocate storage for the result.
214    </p>
215
216    <h3><a name="getBytesForAdpcmSamples"></a><CODE>getBytesForAdpcmSamples</CODE></h3>
217    <h4>Syntax</h4>
218    <pre class="definition">u32 getBytesForAdpcmSamples(u32 samples);</pre>
219    <h4>Arguments</h4>
220    <table class="arguments">
221      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
222      <tbody>
223        <tr>
224          <td>in</td>
225          <th>samples</th>
226          <td>Number of (16-bit PCM) samples to encode.</td>
227        </tr>
228      </tbody>
229    </table>
230    <h4>Return Values</h4>
231    <p> The actual length (in bytes) of the encoded sampling data. </p>
232    <h4>Description</h4>
233    <p><CODE>getBytesForAdpcmSamples</CODE> returns the actual number of bytes occupied by the sampling data that are being DSP ADPCM-encoded.</p>
234
235    <h3><a name="getBytesForPcmBuffer"></a><CODE>getBytesForPcmBuffer</CODE></h3>
236    <h4>Syntax</h4>
237    <pre class="definition">u32 getBytesForPcmBuffer(u32 samples); </pre>
238    <h4>Arguments</h4>
239    <table class="arguments">
240      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
241      <tbody>
242        <tr>
243          <td>in</td>
244          <th>samples</th>
245          <td>The number of samples being decoded.</td>
246        </tr>
247      </tbody>
248    </table>
249    <h4>Return Values</h4>
250    <p>The predicted length (in bytes) of the DSP ADPCM sampling data being decoded.</p>
251    <h4>Description</h4>
252    <p><CODE>getBytesForPcmBuffer</CODE> calculates and returns the number of bytes of data that must be stored after the number of samples passed in the argument have been decoded from the DSP ADPCM format.</p>
253
254
255    <h3><a name="getBytesForPcmSamples"></a><CODE>getBytesForPcmSamples</CODE></h3>
256    <h4>Syntax</h4>
257    <pre class="definition">u32 getBytesForPcmSamples(u32 samples);</pre>
258    <h4>Arguments</h4>
259    <table class="arguments">
260      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
261      <tbody>
262        <tr>
263          <td>in</td>
264          <th>samples</th>
265          <td>Number of samples.</td>
266        </tr>
267      </tbody>
268    </table>
269    <h4>Return Values</h4>
270    <p>The length (in bytes) of the value specified in the sampling data.</p>
271    <h4>Description</h4>
272    <p><CODE>getBytesForPcmSamples</CODE> returns the number of bytes for copying the specified user application value in the sampling data.
273    </p>
274
275
276    <h3><a name="getSampleForAdpcmNibble"></a><CODE>getSampleForAdpcmNibble</CODE></h3>
277    <h4>Syntax</h4>
278    <pre class="definition">u32 getSampleForAdpcmNibble(u32 nibble);</pre>
279    <h4>Arguments</h4>
280    <table class="arguments">
281      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
282      <tbody>
283        <tr>
284          <td>in</td>
285          <th>nibble</th>
286          <td>ADPCM nibble offset, including frame headers.</td>
287        </tr>
288      </tbody>
289    </table>
290    <h4>Return Values</h4>
291    <p>The zero-based sample index for the corresponding ADPCM sampling data.</p>
292    <h4>Description</h4>
293    <p><CODE>getSampleForAdpcmNibble</CODE> returns the number of zero-based samples for the corresponding ADPCM nibble.</p>
294
295    <h3><a name="getNibbleAddress"></a><CODE>getNibbleAddress</CODE></h3>
296    <h4>Syntax</h4>
297    <pre class="definition">u32 getNibbleAddress(u32 samples);</pre>
298    <h4>Arguments</h4>
299    <table class="arguments">
300      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
301      <tbody>
302        <tr>
303          <td>in</td>
304          <th>samples</th>
305          <td>16-bit PCM address offset. <CODE>0</CODE> is the first sample.  <CODE>100</CODE> is the 101st sample.</td>
306        </tr>
307      </tbody>
308    </table>
309    <h4>Return Values</h4>
310    <p>Corresponding nibble address.</p>
311    <h4>Description</h4>
312    <p>
313    <CODE>getNibbleAddress</CODE> calculates and returns the nibble corresponding to the sampling data, as based on the offset passed to the argument. </p>
314    <p>For example, the 100th sample (where the count starts at <CODE>0</CODE>) corresponds to the 116th nibble (where the count also starts at <CODE>0</CODE>). Note that the calculated nibble address incorporates the 2-nibble frame header that is already in DSP ADPCM compressed format.
315    </p>
316    <p>One more example: The 0th sample corresponds to a nibble offset of 2,  which is the 3rd nibble (counting from 0).</p>
317
318    <h3><a name="getLoopContext"></a><CODE>getLoopContext</CODE></h3>
319    <h4>Syntax</h4>
320    <pre class="definition">
321typedef struct
322{
323    // start context
324    s16 coef[16];
325    u16 gain;
326    u16 pred_scale;
327    s16 yn1;
328    s16 yn2;
329
330    // loop context
331    u16 loop_pred_scale;
332    s16 loop_yn1;
333    s16 loop_yn2;
334} ADPCMINFO;
335
336void getLoopContext(
337    u8          *src,       // location of ADPCM buffer in RAM
338    ADPCMINFO   *cxt,       // location of adpcminfo
339    u32         samples     // samples to desired context
340);
341</pre>
342    <h4>Arguments</h4>
343    <table class="arguments">
344      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
345      <tbody>
346        <tr>
347          <td>in</td>
348          <th>src</th>
349          <td>Pointer to the buffer containing the DSP ADPCM encoded sample.</td>
350        </tr>
351        <tr>
352          <td>out</td>
353          <th>cxt</th>
354          <td>The pointer to the ADPCMINFO structure. The <CODE>getLoopContext</CODE> function places the loop context information inside this structure.</td>
355        </tr>
356        <tr>
357          <td>in</td>
358          <th>samples</th>
359          <td>The offset from the starting position of the loop in the sampling data. This loop starting position is not a nibble address, but rather the raw sample number where the loop starts (in other words, the first sample played in the loop). <br> If the loop begins at the very first sample, the offset is zero. If the loop begins at the 101st sample, the offset is 100.</td>
360        </tr>
361      </tbody>
362    </table>
363    <h4>Return Values</h4>
364    <p>None.</p>
365    <h4>Description</h4>
366    <p><CODE>getLoopContext</CODE> returns the DSP ADPCM loop context, based on the offset in the sample data given to the argument.</p>
367
368    <h3><a name="encode"></a><CODE>encode</CODE></h3>
369    <h4>Syntax</h4>
370    <pre class="definition">
371typedef struct
372{
373    // start context
374    s16 coef[16];
375    u16 gain;
376    u16 pred_scale;
377    s16 yn1;
378    s16 yn2;
379
380    // loop context
381    u16 loop_pred_scale;
382    s16 loop_yn1;
383    s16 loop_yn2;
384} ADPCMINFO;
385
386void encode(
387    s16         *src,       // location of source samples (16bit PCM signed little endian)
388    u8          *dst,       // location of destination buffer
389    ADPCMINFO   *cxt,       // location of adpcm info
390    u32         samples     // number of samples to encode
391);
392</pre>
393    <h4>Arguments</h4>
394    <table class="arguments">
395      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
396      <tbody>
397        <tr>
398          <td>in</td>
399          <th>src</th>
400          <td>Pointer to the buffer for signed little-endian 16-bit PCM sampling data.</td>
401        </tr>
402        <tr>
403          <td>out</td>
404          <th>dst</th>
405          <td>The pointer to the buffer where the DSP ADPCM encoded data are output.<br> The application must allocate memory for this buffer. You must calculate the buffer size using <CODE><a href="#getBytesForAdpcmBuffer">getBytesForAdpcmBuffer</a></CODE>.</td>
406        </tr>
407        <tr>
408          <td>in</td>
409          <th>cxt</th>
410          <td>Pointer to the <CODE>ADPCMINFO</CODE> structure. The <CODE>encode</CODE> function stores sampling data coefficients and context information in this structure. <br>Note that a number of parameters (<SPAN class="argument">gain</SPAN>, <SPAN class="argument">yn1</SPAN>, and <SPAN class="argument">yn2</SPAN>) are always <CODE>0</CODE>. <br>Before decoding commences, the corresponding registers in the DSP decoder hardware must be cleared. These parameters are included in the structure to force this to happen. <br>After <CODE>encode</CODE> has been called, the loop context parameters always become <CODE>0</CODE>. To set these values, you must call <CODE><a href="#getLoopContext">getLoopContext</a></CODE> after the sampling data have been looped.</td>
411        </tr>
412        <tr>
413          <td>in</td>
414          <th>samples</th>
415          <td>Number of samples to encode.</td>
416        </tr>
417      </tbody>
418    </table>
419    <h4>Return Values</h4>
420    <p>None.</p>
421    <h4>Description</h4>
422    <p><CODE>encode</CODE> compresses 16-bit PCM data into DSP ADPCM format.</p>
423
424    <h3><a name="decode"></a>decode</h3>
425    <h4>Syntax</h4>
426    <pre class="definition">
427typedef struct
428{
429    // start context
430    s16 coef[16];
431    u16 gain;
432    u16 pred_scale;
433    s16 yn1;
434    s16 yn2;
435
436    // loop context
437    u16 loop_pred_scale;
438    s16 loop_yn1;
439    s16 loop_yn2;
440} ADPCMINFO;
441
442void decode(
443    u8          *src,   // location of encoded source samples
444    s16         *dst,   // location of destination buffer (16 bits / sample)
445    ADPCMINFO   *cxt,   // location of adpcm info
446    u32         samples // number of samples to decode
447);
448</pre>
449    <h4>Arguments</h4>
450    <table class="arguments">
451      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
452      <tbody>
453        <tr>
454          <td>in</td>
455          <th>src</th>
456          <td>Pointer to the buffer containing the DSP ADPCM data.</td>
457        </tr>
458        <tr>
459          <td>out</td>
460          <th>dst</th>
461          <td>Pointer to a buffer that has been allocated for storing the uncompressed PCM data. <br>The size of this buffer is calculated by calling <CODE><a href="#getBytesForPcmBuffer">getBytesForPcmBuffer</a></CODE>.</td>
462        </tr>
463        <tr>
464          <td>in</td>
465          <th>cxt</th>
466          <td>Pointer to the <CODE>ADPCMINFO</CODE> structure.<br> This structure must contain the coefficient and initial state data that corresponds to the sample being decoded.</td>
467        </tr>
468        <tr>
469          <td>in</td>
470          <th>samples</th>
471          <td>Number of samples to decode.</td>
472        </tr>
473      </tbody>
474    </table>
475    <h4>Return Values</h4>
476    <p>None.</p>
477    <h4>Description</h4>
478    <p>
479    <CODE>decode</CODE> is used for decoding DSP ADPCM sample data into signed, little-endian, 16-bit PCM data.
480    </p>
481<!-- テンプレ     <h3></h3>     <h4>構文</h4>     <pre class="definition"></pre>
482    <h4>Arguments</h4>
483    <table class="arguments">
484      <thead> <tr> <td width="15"> </td><th>Name</th> <td>Description</td> </tr> </thead>
485      <tbody>
486        <tr>
487          <td>in</td>
488          <th></th>
489          <td></td>
490        </tr>
491      </tbody>
492    </table>
493    <h4>Return Values</h4>
494    <h4>Description</h4>
495-->
496
497    </div>
498
499
500    <h2><a name="sampleCode"></a>Sample Code</h2>
501    <p><CODE>WaveCodecCtr.dll</CODE> has been created for use with Win32 applications. This section provides some samples.</p>
502    <ul>
503      <li><a href="#usage_init">Initialization</a></li>
504      <li><a href="#usage_encode">Encoding</a></li>
505      <li><a href="#usage_decode">Decoding</a></li>
506    </ul>
507
508    <div class="subSection">
509    <h3><a name="usage_init"></a>Initialization</h3>
510    <p>Applications that call DLLs must comply with Win32 rules when calling <CODE>WaveCodecCtr.dll</CODE>.
511    </p>
512<pre class="definition">
513typedef signed short   s16;
514typedef unsigned char  u8;
515typedef unsigned short u16;
516typedef unsigned long  u32;
517
518/* ---------------------------------------------------------------
519
520  Import the <CODE>WaveCodecCtr.dll</CODE> API.
521
522 ---------------------------------------------------------------- */
523typedef struct
524{
525    // start context
526    s16 coef[16];
527    u16 gain;
528    u16 pred_scale;
529    s16 yn1;
530    s16 yn2;
531
532    // loop context
533    u16 loop_pred_scale;
534    s16 loop_yn1;
535    s16 loop_yn2;
536
537} ADPCMINFO;
538
539static HINSTANCE hDll;
540typedef u32 (*lpFunc1)(u32);
541typedef u32 (*lpFunc2)(void);
542typedef void (*lpFunc3)(s16*, u8*, ADPCMINFO*, u32);
543typedef void (*lpFunc4)(u8*, s16*, ADPCMINFO*, u32);
544typedef void (*lpFunc5)(u8*, ADPCMINFO*, u32);
545lpFunc1 getBytesForAdpcmBuffer;
546lpFunc1 getBytesForAdpcmSamples;
547lpFunc1 getBytesForPcmBuffer;
548lpFunc1 getBytesForPcmSamples;
549lpFunc1 getSampleForAdpcmNibble;
550lpFunc1 getNibbleAddress;
551lpFunc2 getBytesForAdpcmInfo;
552lpFunc3 encode;
553lpFunc4 decode;
554lpFunc5 getLoopContext;
555
556/*--------------------------------------------------------------------------*/
557void clean_up(void)
558{
559    if (hDll)
560        FreeLibrary(hDll);
561}
562
563/*--------------------------------------------------------------------------*/
564int getDll(void)
565{
566    hDll = LoadLibrary("WaveCodecCtr.dll");
567    if (hDll)
568    {
569        if (!(getBytesForAdpcmBuffer =
570                (lpFunc1)GetProcAddress(
571                             hDll,
572                             "getBytesForAdpcmBuffer"
573                             ))) return 1;
574        if (!(getBytesForAdpcmSamples =
575                (lpFunc1)GetProcAddress(
576                             hDll,
577                             "getBytesForAdpcmSamples"
578                             ))) return 1;
579        if (!(getBytesForPcmBuffer =
580                (lpFunc1)GetProcAddress(
581                             hDll,
582                             "getBytesForPcmBuffer"
583                             ))) return 1;
584        if (!(getBytesForPcmSamples =
585                (lpFunc1)GetProcAddress(
586                             hDll,
587                             "getBytesForPcmSamples"
588                             ))) return 1;
589        if (!(getNibbleAddress =
590                (lpFunc1)GetProcAddress(
591                             hDll,
592                             "getNibbleAddress"
593                             ))) return 1;
594        if (!(getSampleForAdpcmNibble =
595                (lpFunc1)GetProcAddress(
596                             hDll,
597                             "getSampleForAdpcmNibble"
598                             ))) return 1;
599        if (!(getBytesForAdpcmInfo =
600                (lpFunc2)GetProcAddress(
601                             hDll,
602                             "getBytesForAdpcmInfo"
603                             ))) return 1;
604        if (!(encode =
605                (lpFunc3)GetProcAddress(
606                            hDll,
607                            "encode"
608                            ))) return 1;
609        if (!(decode =
610                (lpFunc4)GetProcAddress(
611                            hDll,
612                            "decode"
613                            ))) return 1;
614        if (!(getLoopContext =
615                (lpFunc5)GetProcAddress(
616                             hDll,
617                             "getLoopContext"
618                             ))) return 1;
619        return(0);
620    }
621    return(1);
622}
623
624
625/*--------------------------------------------------------------------------*/
626int _tmain(int argc, _TCHAR* argv[])
627{
628    if (getDll())
629    {
630        clean_up();
631        exit(1);
632    }
633
634    // do stuff here
635
636    clean_up();
637}
638</pre>
639
640    <h3><a name="usage_encode"></a>Encoding</h3>
641    <p>
642    The encoding function assumes that the data are 16-bit, little endian, PCM data (as used for Windows <CODE>.wav</CODE> files). If you want the application to encode big-endian data, you must flip the endian before encoding.</p>
643    <pre class="definition">
644//... loaded WaveCodecCtr.dll
645
646//... put some PCM buffer in memory, reverse the endian if you have to
647u8 *adpcm = (u8*)malloc(getBytesForAdpcmBuffer(samplesToEncode));
648
649if (adpcm)
650{
651    ADPCMINFO adpcminfo;
652
653    // ok.. lets encode it!
654    encode(source, adpcm, &amp;adpcminfo, samplesToEncode);
655
656    // get ADPCM loop context if sample is looped
657    if (samplesToLoopStart)
658            getLoopContext(adpcm, &amp;adpcminfo, samplesToLoopStart);
659
660    // see how many bytes to store the encoded data stream
661    u32 nBytesToStore = getBytesForAdpcmSamples(samplesToEncode);
662
663    ... store encoded ADPCM data stream to file
664
665    ... store ADPCM context to file
666
667    u32 nibbleStartOffset   = getNibbleAddress(0);
668    u32 nibbleLoopStartOffset = getNibbleAddress(samplesToLoopStart);
669    u32 nibbleEndAddress  = getNibbleAddress(samplesToEncode);
670
671    ... store nibble addressing to file
672
673    // don't need the ADPCM buffer anymore
674    free(adpcm);
675}
676
677... continue
678    </pre>
679
680    <h3><a name="usage_decode"></a>Decoding</h3>
681    <p>
682    The decoding result is output as 16-bit, little-endian, PCM data.
683    </p>
684
685    <pre class="definition">
686... loaded WaveCodecCtr.dll
687
688... put some ADPCM buffer and corresponding ADPCMINFO in memory,
689... ADPCM is byte ordered.. not endian sensitive.
690
691s16 *pcm = (u8*)malloc(getBytesForPcmBuffer(samplesToDecode));
692
693if (pcm)
694{
695    // Decode
696    decode(source, pcm, adpcminfo, samplesToDecode);
697
698    ... store decoded PCM buffer to file
699
700    // Free the PCM buffer
701    free(pcm);
702}
703
704... continue
705</pre>
706</div>
707
708<h2><a name="caution"></a>Cautions for Encoding and Playing Looped Wave Files</h2>
709<p>Note the following cautions when encoding looped waveforms and when playing them on the actual hardware.</p>
710<p class="warning">The information relating to encoding also pertains to the use of the <CODE>nn::snd::EncodeAdpcmData</CODE> function for encoding data into DSP ADPCM on the actual hardware.</p>
711
712<ul>
713  <li><a href="#caution_loop">How to Play Regular Looped Waveforms</a></li>
714  <li><a href="#caution_align">Align the Loop Start Position to an 8-byte Boundary</a></li>
715  <li><a href="#caution_loopStart">Noise When the Loop Start Equals the Start of the Waveform</a></li>
716  <li><a href="#caution_loopEnd">Noise When the Loop End Equals the End of the Waveform</a></li>
717</ul>
718
719<div class="subSection">
720<h3><a name="caution_loop"></a>How to Play Regular Looped Waveforms</h3>
721<p>When looping a waveform like the following on the actual hardware:</p>
722<pre class="definition">
723    WS      LS                     LE
724    |-------|&lt;--------------------&gt;|
725
726      WS: Start of waveform
727      LS: Loop start position
728      LE: Loop end position
729</pre>
730<ol>
731    <li><CODE>WaveBuffer</CODE> for playing WS to LE</li>
732    <li><CODE>WaveBuffer</CODE> for playing LS to LE</li>
733</ol>
734<p>Prepare two <CODE>WaveBuffer</CODE> instances (as shown) and set the order as 1. → 2. in <CODE>nn::snd::Voice</CODE>.</p>
735
736
737<pre class="definition">
738    WS                             LE
739 1. |------------------------------|    (When the loopFlag of WaveBuffer is false.)
740
741            LS                     LE
742 2.         |&lt;--------------------&gt;|    (When the loopFlag of WaveBuffer is true.)
743</pre>
744
745<h3><a name="caution_align"></a>Align the Loop Start Position to an 8-byte Boundary</h3>
746<p>In the DSP ADPCM format, 8 bytes (corresponding to 14 samples) are handled as one set of information. For this reason, the <SPAN class="argument">bufferAddress</SPAN> argument of the <CODE>nn::snd::WaveBuffer</CODE> function must specify an address with an 8-byte boundary.</p>
747<p>On the other hand, when creating <a href="#caution_loop"><CODE>WaveBuffer</CODE> as described in 2</a>, LS is not necessarily at an 8-byte (14-sample) boundary.</p>
748<p>If the boundary is not 8 bytes (14 samples), you must displace the LS position to an 8-byte boundary so this restriction is satisfied.</p>
749<p>For example, if LS is at the 16th sample, you could slide it to the next 14-sample boundary (28 samples) and top off the waveforms after LE with the moved part before encoding.</p>
750
751<pre class="definition">
752     LS                  LE
753     |&lt;-----------------&gt;|
754      ^^^^
755756         LS'                   LE'
757     ----|&lt;-------------------&gt;|
758                           ^^^^
759</pre>
760
761
762<h3><a name="caution_loopStart"></a>Noise When the Loop Start Equals the Start of the Waveform</h3>
763<p>Because of encoder limitations, when the loop start position equals the start of a waveform, you cannot play a clean loop without noise.</p>
764<p>If the loop start position equals the start of the waveform, use the technique described in <a href="#caution_align">Align the loop start position to an 8-byte boundary</a> to slide LS' to 14, so you can play the loop cleanly without noise.
765</p>
766
767<h3><a name="caution_loopEnd"></a>Noise When the Loop End Equals the End of the Waveform</h3>
768<p>Because of encoder limitations, when the loop start position equals the end of a waveform, encoding is not stable and noise occurs.</p>
769<p>When waveforms continue beyond LE, for the <SPAN class="argument">samples</SPAN> argument of the <CODE><a href="#encode">encode</a></CODE> function, pass <CODE>WS to end of waveform</CODE> rather than <CODE>WS to LE</CODE>.
770</p>
771<pre class="definition">
772    WS      LS                     LE   WE
773    |-------|&lt;--------------------&gt;|----|
774
775      WS:  Start of waveform
776      WE : End of waveform
777      LS: Loop start position
778      LE: Loop end position
779
780    encode( WS address, dst, cxt, WE-WS );
781</pre>
782
783<p>When waveforms do not continue beyond LE, apply the technique introduced in <a href="#caution_align">Align the loop start position to an 8-byte boundary</a> to use copied waveforms for about 100 samples from LS, and position them after LE.</p>
784<pre class="definition">
785    WS      LS                     LE=WE
786    |-------|&lt;--------------------&gt;|
787             ^^^^^
788789    WS      LS                     LE   WE'
790    |-------|&lt;--------------------&gt;|----|
791                                    ^^^^^
792
793    encode( WS address, dst, cxt, WE'-WS );
794</pre>
795
796
797</div>
798
799    <h2><a name="history"></a>Revision History</h2>
800    <dl class="history">
801      <dt>2011/12/12</dt>
802      <dd>Initial version.<br />
803      </dd>
804    </dl>
805  <hr><p>CONFIDENTIAL</p></body>
806</html>