1 /* OpenCP Module Player
2 * copyright (c) 2009-2010 Stian Skjelstad <stian@nixia.no>
3 *
4 * Unit-test for "dwmixfa.c"
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "config.h"
22 #include "types.h"
23 #include <stdio.h>
24 #include "dwmixfa.h"
25 #include "dev/mcp.h"
26 #include <string.h>
27 #include <stdlib.h>
28 #ifdef I386_ASM
29 #include <unistd.h>
30 #include <sys/mman.h>
31 #include "stuff/pagesize.inc.c"
32 #endif
33
34 static int channelnum;
35
initAsm(void)36 static int initAsm(void)
37 {
38 #ifdef I386_ASM
39 /* Self-modifying code needs access to modify it self */
40 int fd;
41 char file[128]="/tmp/ocpXXXXXX";
42 char *start1, *stop1;
43 int len1;
44 fd=mkstemp(file);
45
46 start1=(void *)start_dwmixfa;
47 stop1=(void *)stop_dwmixfa;
48
49 start1=(char *)(((int)start1)&~(pagesize()-1));
50 len1=((stop1-start1)+pagesize()-1)& ~(pagesize()-1);
51 if (write(fd, start1, len1)!=len1)
52 {
53 close(fd);
54 unlink(file);
55 return 0;
56 }
57 if (mmap(start1, len1, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0)==MAP_FAILED)
58 {
59 perror("mmap()");
60 close(fd);
61 unlink(file);
62 return 0;
63 }
64
65 close(fd);
66 unlink(file);
67 #endif
68
69 return 1;
70 }
71
calcinterpoltab(void)72 static void calcinterpoltab(void)
73 {
74 int i;
75 for (i=0; i<256; i++)
76 {
77 float x1=i/256.0;
78 float x2=x1*x1;
79 float x3=x1*x1*x1;
80 dwmixfa_state.ct0[i]=-0.5*x3+x2-0.5*x1;
81 dwmixfa_state.ct1[i]=1.5*x3-2.5*x2+1;
82 dwmixfa_state.ct2[i]=-1.5*x3+2*x2+0.5*x1;
83 dwmixfa_state.ct3[i]=0.5*x3-0.5*x2;
84 };
85 }
86
OpenPlayer(int chan)87 static void OpenPlayer(int chan)
88 {
89 /*
90 uint32_t currentrate;
91 uint16_t mixfate;
92 */
93 int i;
94
95 /* playsamps=pausesamps=0; not needed, since we don't need to track time */
96
97 /*
98 currentrate=mcpMixProcRate/chan;
99 mixfate=(currentrate>mcpMixMaxRate)?mcpMixMaxRate:currentrate;
100 plrSetOptions(mixfate, mcpMixOpt);
101
102 We don't care about tracking output rate
103 */
104
105 if (!(dwmixfa_state.tempbuf=malloc(sizeof(float)*(MIXF_MIXBUFLEN<<1))))
106 exit(1);
107 /*
108 Don't think I need this
109 if (!mixInit(GetMixChannel, 0, chan, amplify))
110 return 0;
111 */
112
113 for (i=0; i<chan; i++)
114 {
115 dwmixfa_state.voiceflags[i]=0;
116 }
117
118 /*stereo=(plrOpt&PLR_STEREO)?1:0;*/
119 /*bit16=(plrOpt&PLR_16BIT)?1:0;*/
120 /*signedout=(plrOpt&PLR_SIGNEDOUT)?1:0;*/
121 /*reversestereo=!!(plrOpt&PLR_REVERSESTEREO);*/
122 dwmixfa_state.samprate=/*plrRate*/44100;
123 /*
124 bufpos=0;
125 dopause=0;
126 orgspeed=12800;
127 */
128 channelnum=chan;
129 /*
130 mcpNChan=chan;
131 mcpIdle=Idle;
132
133 isstereo=stereo;
134 outfmt=(bit16<<1)|(!signedout);*/
135 dwmixfa_state.nvoices=channelnum;
136
137 prepare_mixer();
138
139 /*calcspeed();*/
140 /*/ playerproc();*/ /* some timing is wrong here! */
141 /* tickwidth=newtickwidth; */
142 /* tickplayed=0; */
143 /* cmdtimerpos=0; */
144 /*
145 if (!pollInit(timerproc))
146 {
147 mcpNChan=0;
148 mcpIdle=0;
149 plrClosePlayer();
150 mixClose();
151 return 0;
152 }
153 {
154 struct mixfpostprocregstruct *mode;
155
156 for (mode=postprocs; mode; mode=mode->next)
157 if (mode->Init) mode->Init(samprate, stereo);
158 }
159 */
160 }
161
ClosePlayer()162 static void ClosePlayer()
163 {
164 /*
165 struct mixfpostprocregstruct *mode;
166
167 mcpNChan=0;
168 mcpIdle=0;
169
170 pollClose();
171
172 plrClosePlayer();
173
174 channelnum=0;
175
176 mixClose();
177
178 for (mode=postprocs; mode; mode=mode->next)
179 if (mode->Close) mode->Close();
180 */
181 free(dwmixfa_state.tempbuf);
182 }
183
main(int argc,char * argv[])184 int main(int argc, char *argv[])
185 {
186 float sample_1[] = {12345.0f, 23451.1234f, 30000.543f, 32767.0f, 1023.09f, -5435.05f, -32768.0f, -16000.02f}; /* normalized around 32767 and -32768 */
187 int16_t output[1024];
188 /* INIT START */
189 initAsm();
190
191 /* volramp=!!(dev->opt&MIXF_VOLRAMP); */
192 /* declick=!!(dev->opt&MIXF_DECLICK); */
193
194 calcinterpoltab();
195
196 /* amplify=65535; */
197 /* relspeed=256; */
198 /* relpitch=256; */
199 /* interpolation=0; */
200 /* mastervol=64; */
201 /* masterbal=0; */
202 /* masterpan=0; */
203 /* mastersrnd=0; */
204 /* channelnum=0; */
205 /* INIT DONE */
206
207 /* LOAD */
208 /* LoadSamples (sampleinfo_1, 1); */
209 /*
210 samples=sampleinfo_1; */
211 /*
212 samplenum=1; */
213
214 prepare_mixer();
215
216 OpenPlayer(1);
217
218 memset(output, 1, sizeof(output));
219 dwmixfa_state.outbuf=output+2;
220 dwmixfa_state.nsamples=308;//508;
221
222 dwmixfa_state.isstereo=0; //1;
223
224 dwmixfa_state.voiceflags[0] = MIXF_PLAYING|MIXF_LOOPED; /* this is so broken! */
225
226 dwmixfa_state.freqf[0]=0x3a987654; /* pitch */
227 dwmixfa_state.freqw[0]=0x00000000; /* pitch */
228
229 dwmixfa_state.fl1[0]=0; /* reset filter */
230 dwmixfa_state.fb1[0]=0; /* reset feilter */
231
232 dwmixfa_state.ffreq[0] = 1; /* filter frequency (0<=x<=1) TODO, needs testing / study */
233 dwmixfa_state.freso[0] = 0; /* filter resonance (0<=x<1) TODO, needs testing / study*/
234
235 dwmixfa_state.smpposf[0]=0;
236 dwmixfa_state.smpposw[0]=sample_1;
237
238 dwmixfa_state.looplen[0]=4;
239 dwmixfa_state.loopend[0]=&sample_1[7];
240
241 dwmixfa_state.volleft[0]=0.125f;
242 dwmixfa_state.volright[0]=0.125f;
243 dwmixfa_state.rampleft[0]=0.0f;
244 dwmixfa_state.rampright[0]=0.0f;
245
246 dwmixfa_state.fadeleft=0.5f;
247 dwmixfa_state.faderight=-0.5f;
248
249 dwmixfa_state.outfmt=2; /* 2 = 16bit, 1 = unsigned, can be or'ed */
250
251 //".long clip_8s, clip_8u, clip_16s, clip_16u\n"
252
253 /*
254 voll=1.0f;
255 volr=1.0f;
256 This is output from getchanvol probably
257 */
258
259 mixer();
260
261 {
262 int i;
263 fprintf(stderr, "output: ");
264 for (i=0;i<512;i++)
265 fprintf(stderr, "[%d %d]", output[i*2], output[i*2+1]);
266 fprintf(stderr, "\n");
267 }
268
269 fprintf(stderr, "smppos: %u.%u\n", (unsigned int)(dwmixfa_state.smpposw[0]-sample_1), dwmixfa_state.smpposf[0]);
270
271 ClosePlayer();
272
273 return 0;
274 }
275