TI DSP (C5x and C6x) patch by Jim Crichton
[speexdsp.git] / ti / testenc-TI-C5x.c
1 /* Copyright (C) 2005 Psi Systems, Inc.\r
2    File: testenc-TI-C5x.c\r
3    Encoder/Decoder Loop Main file for TI C54xx and C55xx processors\r
4    for use with TI Code Composer (TM) DSP development tools.\r
5    Modified from speexlib/testenc.c\r
6 \r
7 \r
8    Redistribution and use in source and binary forms, with or without\r
9    modification, are permitted provided that the following conditions\r
10    are met:\r
11    \r
12    - Redistributions of source code must retain the above copyright\r
13    notice, this list of conditions and the following disclaimer.\r
14    \r
15    - Redistributions in binary form must reproduce the above copyright\r
16    notice, this list of conditions and the following disclaimer in the\r
17    documentation and/or other materials provided with the distribution.\r
18    \r
19    - Neither the name of the Xiph.org Foundation nor the names of its\r
20    contributors may be used to endorse or promote products derived from\r
21    this software without specific prior written permission.\r
22    \r
23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
24    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
26    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\r
27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
28    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
29    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
30    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
31    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
32    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
33    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
34 */\r
35 \r
36 #ifdef HAVE_CONFIG_H\r
37 #include "config.h"\r
38 #endif\r
39 \r
40 /* Modified from speexlib/testenc.c for Code Composer simulator */\r
41 \r
42 #include <speex/speex.h>\r
43 #include <stdio.h>\r
44 #include <stdlib.h>\r
45 #include <speex/speex_callbacks.h>\r
46 #include <..\libspeex\arch.h>\r
47 \r
48 #undef DECODE_ONLY\r
49 \r
50 #ifdef FIXED_DEBUG\r
51 extern long long spx_mips;\r
52 #endif\r
53 #include <math.h>\r
54 \r
55 #ifdef MANUAL_ALLOC\r
56 #pragma DATA_SECTION(spxHeap, ".myheap"); \r
57 static char spxHeap[SPEEX_PERSIST_STACK_SIZE];\r
58 \r
59 #pragma DATA_SECTION(spxScratch, ".myheap"); \r
60 static char spxScratch[SPEEX_SCRATCH_STACK_SIZE];\r
61 \r
62 char *spxGlobalHeapPtr, *spxGlobalHeapEnd;\r
63 char *spxGlobalScratchPtr, *spxGlobalScratchEnd;\r
64 #endif\r
65 \r
66 void byte2word(short* pInBuf, short* pOutBuf, int nWords)\r
67 {\r
68    short *pIn, *pOut, sNext;\r
69    int i;\r
70    \r
71    pIn = pInBuf;\r
72    pOut = pOutBuf;\r
73    for(i=0;i<nWords;i++)\r
74    {\r
75       sNext = *pIn++;                   // Get low byte\r
76       *pOut++ = (sNext & 0x00ff) | (*pIn++ << 8);       // insert high byte\r
77    }\r
78 }\r
79    \r
80 void word2byte(short* pInBuf, short* pOutBuf, int nWords)\r
81 {\r
82    short *pIn, *pOut;\r
83    int i;\r
84    \r
85    pIn = pInBuf;\r
86    pOut = pOutBuf;\r
87    for(i=0;i<nWords;i++)\r
88    {\r
89       *pOut++ = *pIn & 0x00ff;  // Get low byte\r
90       *pOut++ = (short) ((unsigned short) *pIn++ >> 8);\r
91    }\r
92 }\r
93    \r
94 void main()\r
95 {\r
96    char *outFile, *bitsFile;\r
97    FILE *fout, *fbits=NULL;\r
98 #ifndef DECODE_ONLY\r
99    char *inFile;\r
100    FILE *fin;\r
101 #endif\r
102    short out_short[FRAME_SIZE];\r
103    short inout_byte[2*FRAME_SIZE];\r
104 #ifndef DECODE_ONLY\r
105    short in_short[FRAME_SIZE];\r
106    float sigpow,errpow,snr, seg_snr=0;\r
107    int snr_frames = 0;\r
108    int nbChars;\r
109    int i;\r
110 #endif\r
111    char cbits[22];\r
112    void *st;\r
113    void *dec;\r
114    SpeexBits bits;\r
115    int tmp;\r
116    unsigned int bitCount=0;\r
117    int skip_group_delay;\r
118    SpeexCallback callback;\r
119 \r
120    /* C54xx defaults to max wait states, even for parts like C5416 with \r
121       larger internal memory.  Need to force the wait state register to zero */\r
122 \r
123 #ifdef CONFIG_TI_C54X\r
124    asm("        STM     #0,SWWSR");\r
125 #endif\r
126 \r
127 #ifndef DECODE_ONLY\r
128    sigpow = 0;\r
129    errpow = 0;\r
130 #endif\r
131 \r
132 #ifdef MANUAL_ALLOC\r
133         spxGlobalHeapPtr = spxHeap;\r
134         spxGlobalHeapEnd = spxHeap + sizeof(spxHeap);\r
135 \r
136         spxGlobalScratchPtr = spxScratch;\r
137         spxGlobalScratchEnd = spxScratch + sizeof(spxScratch);\r
138 #endif\r
139    st = speex_encoder_init(&speex_nb_mode);\r
140 #ifdef MANUAL_ALLOC\r
141         spxGlobalScratchPtr = spxScratch;               /* Reuse scratch for decoder */\r
142 #endif\r
143    dec = speex_decoder_init(&speex_nb_mode);\r
144 \r
145    callback.callback_id = SPEEX_INBAND_CHAR;\r
146    callback.func = speex_std_char_handler;\r
147    callback.data = stderr;\r
148    speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\r
149 \r
150    callback.callback_id = SPEEX_INBAND_MODE_REQUEST;\r
151    callback.func = speex_std_mode_request_handler;\r
152    callback.data = st;\r
153    speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);\r
154 \r
155    tmp=0;\r
156    speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);\r
157    tmp=0;\r
158    speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);\r
159    tmp=4;\r
160    speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);\r
161    tmp=1;\r
162    speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);\r
163 \r
164    speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);\r
165    fprintf (stderr, "frame size: %d\n", tmp);\r
166    skip_group_delay = tmp / 2;\r
167 \r
168 #ifdef DECODE_ONLY\r
169    bitsFile = "c:\\speextrunktest\\samples\\malebitsin5x.dat";\r
170    fbits = fopen(bitsFile, "rb");\r
171 #else\r
172    bitsFile = "c:\\speextrunktest\\samples\\malebits.dat";\r
173    fbits = fopen(bitsFile, "wb");\r
174 #endif\r
175    inFile = "c:\\speextrunktest\\samples\\male.snd";\r
176    fin = fopen(inFile, "rb");\r
177    outFile = "c:\\speextrunktest\\samples\\maleout.snd";\r
178    fout = fopen(outFile, "wb+");\r
179  \r
180    speex_bits_init(&bits);\r
181 #ifndef DECODE_ONLY\r
182    while (!feof(fin))\r
183    {\r
184       fread(inout_byte, 2, FRAME_SIZE, fin);\r
185       byte2word(inout_byte, in_short, FRAME_SIZE);  /* C5x has 16-bit char */\r
186 \r
187       if (feof(fin))\r
188          break;\r
189       speex_bits_reset(&bits);\r
190 \r
191       speex_encode_int(st, in_short, &bits);\r
192       nbChars = speex_bits_write(&bits, cbits, sizeof(cbits))/BYTES_PER_CHAR;\r
193       bitCount+=bits.nbBits;\r
194 \r
195       word2byte((short *) cbits, inout_byte, nbChars);\r
196       fwrite(inout_byte, 2, nbChars, fbits);\r
197       speex_bits_rewind(&bits);\r
198 \r
199 #else /* DECODE_ONLY */\r
200    while (!feof(fbits))\r
201    {\r
202       fread(inout_byte, 1, 20, fbits);\r
203 \r
204       if (feof(fbits))\r
205          break;\r
206 \r
207       byte2word(inout_byte, (short *)cbits, 10);\r
208       speex_bits_read_from(&bits, cbits, 20);\r
209       bitCount+=160;\r
210 #endif\r
211       speex_decode_int(dec, &bits, out_short);\r
212       speex_bits_reset(&bits);\r
213 \r
214       word2byte(&out_short[skip_group_delay], inout_byte, FRAME_SIZE-skip_group_delay);\r
215       fwrite(inout_byte, 2, FRAME_SIZE-skip_group_delay, fout);\r
216       skip_group_delay = 0;\r
217 #if 1\r
218    fprintf (stderr, "Bits so far: %u \n", bitCount);\r
219 #endif\r
220    }\r
221    fprintf (stderr, "Total encoded size: %u bits\n", bitCount);\r
222    speex_encoder_destroy(st);\r
223    speex_decoder_destroy(dec);\r
224 \r
225 #ifndef DECODE_ONLY\r
226    rewind(fin);\r
227    rewind(fout);\r
228 \r
229 //   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) \r
230 //           &&\r
231 //           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )\r
232    while ( bitCount > 0 )\r
233    {\r
234         float s=0, e=0;\r
235 \r
236     fread(inout_byte, 2, FRAME_SIZE, fin);\r
237     byte2word(inout_byte, in_short, FRAME_SIZE);\r
238     fread(inout_byte, 2, FRAME_SIZE, fout);\r
239     byte2word(inout_byte, out_short, FRAME_SIZE);\r
240 \r
241     bitCount -= FRAME_SIZE;\r
242         for (i=0;i<FRAME_SIZE;++i) {\r
243             s += (float)in_short[i] * in_short[i];\r
244             e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);\r
245         }\r
246         seg_snr += 10*log10((s+160)/(e+160));\r
247         sigpow += s;\r
248         errpow += e;\r
249         snr_frames++;\r
250    }\r
251    fclose(fin);\r
252 #endif\r
253    fclose(fout);\r
254    fclose(fbits);\r
255 \r
256 #ifndef DECODE_ONLY\r
257    snr = 10 * log10( sigpow / errpow );\r
258    seg_snr /= snr_frames;\r
259    fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);\r
260 \r
261 #ifdef FIXED_DEBUG\r
262    printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));\r
263 #endif\r
264 #endif   \r
265 }\r