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>Table of Contents</h2>
156      <ul>
157        <li><a href="#overview">Overview</a>
158        <li><a href="#api">Exported Functions</a>
159        <li><a href="#sampleCode">Sample Code</a>
160        <li><a href="#caution">Precautions for Encoding and Playing Back Looped Wave Files</a>
161        <li><a href="#history">Revision History</a>
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 is a single-threaded DLL.
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.</h4>
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. (See <CODE><a href="#getBytesForAdpcmSamples">getBytesForAdpcmSamples</a></CODE> below.)</p>
212    <p>
213    Use this function before you conduct encoding, in order to secure memory for storing the encoding 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 will need to 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>The offset for the ADPCM nibble in the frame header.</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>The 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> Therefore, when the loop starts from the first sample, the offset is <CODE>0</CODE>. If the loop starts from the 101st sample, then the offset is <CODE>100</CODE>.</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>This is the pointer to the buffer where the DSP ADPCM encoded data are output.<br> The application needs to allocate memory for this buffer.  You need to 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 (<CODE>gain</CODE>, <CODE>yn1</CODE>, <CODE>yn2</CODE>) 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 in order 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 need to 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>The 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 the buffer secured for storing the decoded 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 coefficients and data in the initial state corresponding to the sampling data being decoded.</td>
467        </tr>
468        <tr>
469          <td>in</td>
470          <th>samples</th>
471          <td>The 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>     <h4>引数</h4>     <table class="arguments">       <thead> <tr> <td width="15"> </td><th>名前</th> <td>説明</td> </tr> </thead>       <tbody>         <tr>           <td>in</td>           <th></th>           <td></td>         </tr>       </tbody>     </table>     <h4>返り値</h4>     <h4>説明</h4> -->
482
483    </div>
484
485
486    <h2><a name="sampleCode"></a>Sample Code</h2>
487    <p><CODE>WaveCodecCtr.dll</CODE> has been created for use with Win32 applications. A number of samples are given below.</p>
488    <ul>
489      <li><a href="#usage_init">Initialization</a></li>
490      <li><a href="#usage_encode">Encoding</a></li>
491      <li><a href="#usage_decode">Decoding</a></li>
492    </ul>
493
494    <div class="subSection">
495    <h3><a name="usage_init"></a>Initialization</h3>
496    <p>Applications that call DLLs must comply with Win32 rules when calling <CODE>WaveCodecCtr.dll</CODE>.
497    </p>
498<pre class="definition">
499typedef signed short   s16;
500typedef unsigned char u8;
501typedef unsigned short u16;
502typedef unsigned long  u32;
503
504/* ---------------------------------------------------------------
505
506  Import the <CODE>WaveCodecCtr.dll</CODE> API
507
508 ---------------------------------------------------------------- */
509typedef struct
510{
511    // start context
512    s16 coef[16];
513    u16 gain;
514    u16 pred_scale;
515    s16 yn1;
516    s16 yn2;
517
518    // loop context
519    u16 loop_pred_scale;
520    s16 loop_yn1;
521    s16 loop_yn2;
522
523} ADPCMINFO;
524
525static HINSTANCE hDll;
526typedef u32 (*lpFunc1)(u32);
527typedef u32 (*lpFunc2)(void);
528typedef void (*lpFunc3)(s16*, u8*, ADPCMINFO*, u32);
529typedef void (*lpFunc4)(u8*, s16*, ADPCMINFO*, u32);
530typedef void (*lpFunc5)(u8*, ADPCMINFO*, u32);
531lpFunc1 getBytesForAdpcmBuffer;
532lpFunc1 getBytesForAdpcmSamples;
533lpFunc1 getBytesForPcmBuffer;
534lpFunc1 getBytesForPcmSamples;
535lpFunc1 getSampleForAdpcmNibble;
536lpFunc1 getNibbleAddress;
537lpFunc2 getBytesForAdpcmInfo;
538lpFunc3 encode;
539lpFunc4 decode;
540lpFunc5 getLoopContext;
541
542/*--------------------------------------------------------------------------*/
543void clean_up(void)
544{
545    if (hDll)
546        FreeLibrary(hDll);
547}
548
549/*--------------------------------------------------------------------------*/
550int getDll(void)
551{
552    hDll = LoadLibrary(&quot;WaveCodecCtr.dll&quot;);
553    if (hDll)
554    {
555        if (!(getBytesForAdpcmBuffer =
556                (lpFunc1)GetProcAddress(
557                             hDll,
558                             &quot;getBytesForAdpcmBuffer&quot;
559                             ))) return 1;
560        if (!(getBytesForAdpcmSamples =
561                (lpFunc1)GetProcAddress(
562                             hDll,
563                             &quot;getBytesForAdpcmSamples&quot;
564                             ))) return 1;
565        if (!(getBytesForPcmBuffer =
566                (lpFunc1)GetProcAddress(
567                             hDll,
568                             &quot;getBytesForPcmBuffer&quot;
569                             ))) return 1;
570        if (!(getBytesForPcmSamples =
571                (lpFunc1)GetProcAddress(
572                             hDll,
573                             &quot;getBytesForPcmSamples&quot;
574                             ))) return 1;
575        if (!(getNibbleAddress =
576                (lpFunc1)GetProcAddress(
577                             hDll,
578                             &quot;getNibbleAddress&quot;
579                             ))) return 1;
580        if (!(getSampleForAdpcmNibble =
581                (lpFunc1)GetProcAddress(
582                             hDll,
583                             &quot;getSampleForAdpcmNibble&quot;
584                             ))) return 1;
585        if (!(getBytesForAdpcmInfo =
586                (lpFunc2)GetProcAddress(
587                             hDll,
588                             &quot;getBytesForAdpcmInfo&quot;
589                             ))) return 1;
590        if (!(encode =
591                (lpFunc3)GetProcAddress(
592                            hDll,
593                            &quot;encode&quot;
594                            ))) return 1;
595        if (!(decode =
596                (lpFunc4)GetProcAddress(
597                            hDll,
598                            &quot;decode&quot;
599                            ))) return 1;
600        if (!(getLoopContext =
601                (lpFunc5)GetProcAddress(
602                             hDll,
603                             &quot;getLoopContext&quot;
604                             ))) return 1;
605        return(0);
606    }
607    return(1);
608}
609
610
611/*--------------------------------------------------------------------------*/
612int _tmain(int argc, _TCHAR* argv[])
613{
614    if (getDll())
615    {
616        clean_up();
617        exit(1);
618    }
619
620    // do stuff here
621
622    clean_up();
623}
624</pre>
625
626    <h3><a name="usage_encode"></a>Encoding</h3>
627    <p>
628    The encoding function assumes that the data are 16-bit little-endian PCM data (as used for Windows WAV files). If you want the application to encode big-endian data, you will need to flip the endianness before encoding.</p>
629    <pre class="definition">
630//... loaded WaveCodecCtr.dll
631
632//... put some PCM buffer in memory, reverse the endian if you have to
633u8 *adpcm = (u8*)malloc(getBytesForAdpcmBuffer(samplesToEncode));
634
635if (adpcm)
636{
637    ADPCMINFO adpcminfo;
638
639    // ok.. lets encode it!
640    encode(source, adpcm, &amp;adpcminfo, samplesToEncode);
641
642    // get ADPCM loop context if sample is looped
643    if (samplesToLoopStart)
644            getLoopContext(adpcm, &amp;adpcminfo, samplesToLoopStart);
645
646    // see how many bytes to store the encoded data stream
647    u32 nBytesToStore = getBytesForAdpcmSamples(samplesToEncode);
648
649    ... store encoded ADPCM data stream to file
650
651    ... store ADPCM context to file
652
653    u32 nibbleStartOffset   = getNibbleAddress(0);
654    u32 nibbleLoopStartOffset = getNibbleAddress(samplesToLoopStart);
655    u32 nibbleEndAddress  = getNibbleAddress(samplesToEncode);
656
657    ... store nibble addressing to file
658
659    // don't need the ADPCM buffer anymore
660    free(adpcm);
661}
662
663... continue
664    </pre>
665
666    <h3><a name="usage_decode"></a>Decoding</h3>
667    <p>
668    The decoding result is output as 16-bit little-endian PCM data.
669    </p>
670
671    <pre class="definition">
672... loaded WaveCodecCtr.dll
673
674... put some ADPCM buffer and corresponding ADPCMINFO in memory,
675... ADPCM is byte ordered.. not endian sensitive.
676
677s16 *pcm = (u8*)malloc(getBytesForPcmBuffer(samplesToDecode));
678
679if (pcm)
680{
681    // ok.. lets decode it!
682    decode(source, pcm, adpcminfo, samplesToDecode);
683
684    ... store decoded PCM buffer to file
685
686    // don&rsquo;t need the PCM buffer anymore
687    free(pcm);
688}
689
690... continue
691</div>
692
693<h2><a name="caution"></a>Precautions for Encoding and Playing Back Looped Wave Files</h2>
694<p>
695The following precautions should be noted when encoding looped waveforms and when playing them back on the actual hardware.</p>
696<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.
697</p>
698
699<ul>
700  <li><a href="#caution_loop">How to play regular looped waveforms</a></li>
701  <li><a href="#caution_align">Align the loop start position to an 8-byte boundary</a></li>
702  <li><a href="#caution_loopStart">There is noise when loop start = start of waveform </a></li>
703  <li><a href="#caution_loopEnd">There is noise when loop end = end of waveform </a></li>
704</ul>
705
706<div class="subSection">
707<h3><a name="caution_loop"></a>How to play regular looped waveforms</h3>
708<p>When looping a waveform like the one shown below on the actual hardware:
709<pre class="definition">
710    WS      LS                     LE
711    |-------|&lt;--------------------&gt;|
712
713      WS : Start of waveform
714      LS : Loop start position
715      LE : Loop end position
716</pre>
717<ol>
718    <li><CODE>WaveBuffer</CODE> for playing WS to LE</li>
719    <li><CODE>WaveBuffer</CODE> for playing LS to LE</li>
720</ol>
721<p>Prepare two <CODE>WaveBuffer</CODE> (as shown above) and set the order as 1. → 2. in <CODE>nn::snd::Voice</CODE>.</p>
722
723
724<pre class="definition">
725    WS                             LE
726 1. |------------------------------|    (When <CODE>WaveBuffer</CODE> loopFlag is false)
727
728            LS                     LE
729 2.         |&lt;--------------------&gt;|    (When <CODE>WaveBuffer</CODE> loopFlag is true)
730</pre>
731
732<h3><a name="caution_align"></a>Align the loop start position to an 8-byte boundary</h3>
733<p>In the DSP ADPCM format, 8 bytes (corresponding to 14 samples) are handled as one set of information.
734
735For 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.
736</p>
737<p>On the other hand, when creating <a href="#caution_loop"><CODE>WaveBuffer</CODE> as described in 2. above</a>, LS is not necessarily at an 8-byte (14-sample) boundary.
738</p>
739<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.
740</p>
741<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.
742</p>
743
744<pre class="definition">
745     LS                     LE
746     |&lt;-----------------&gt;|
747      ^^^^
748749         LS'                   LE'
750     ----|&lt;-------------------&gt;|
751                           ^^^^
752</pre>
753
754
755<h3><a name="caution_loopStart"></a>There is noise when loop start = start of waveform </h3>
756<p>Due to encoder limitations, when the loop start position equals the start of a waveform, you cannot play a clean loop without noise.
757</p>
758<p>If the loop start position is at the start of the waveform, apply the technique described in &quot;<a href="#caution_align">Align the loop start position to an 8-byte boundary</a>&quot; to slide <CODE>LS'</CODE> to 14 so you can play the loop cleanly without noise.
759
760
761
762</p>
763
764<h3><a name="caution_loopEnd"></a>There is noise when loop end = end of waveform </h3>
765<p>Due to encoder limitations, when the loop start position equals the end of a waveform, encoding is not stable and noise occurs.
766</p>
767<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 &quot;WS to end of waveform&quot; rather than &quot;WS to LE.&quot;
768
769
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>If waveforms do not continue beyond LE, apply the technique introduced in &quot;<a href="#caution_align">Align the loop start position to an 8-byte boundary</a>&quot; to copy the waveforms for about 100 samples from LS and position them after LE.
784
785
786 </p>
787<pre class="definition">
788    WS      LS                     LE=WE
789    |-------|&lt;--------------------&gt;|
790             ^^^^^
791792    WS      LS                     LE   WE'
793    |-------|&lt;--------------------&gt;|----|
794                                    ^^^^^
795
796    encode( WS address, dst, cxt, WE'-WS );
797</pre>
798
799
800
801</div>
802
803    <h2><a name="history"></a>Revision History</h2>
804    <dl class="history">
805      <dt>2011/12/12</dt>
806      <dd>Initial version.<br />
807      </dd>
808    </dl>
809  <hr><p>CONFIDENTIAL</p></body>
810</html>