Mercurial > hg > dmlib
annotate tests/plrtest.c @ 2530:aacf3bd1cceb
Cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 16 May 2020 06:38:52 +0300 |
parents | 186cf6a7d634 |
children | 9807ae37ad69 |
rev | line source |
---|---|
0 | 1 #include "jss.h" |
2 #include "jssmod.h" | |
3 #include "jssmix.h" | |
4 #include "jssplr.h" | |
5 #include <string.h> | |
6 #include <unistd.h> | |
7 #include <SDL.h> | |
8 | |
9 | |
10 static const char patNoteTable[12][3] = | |
11 { | |
12 "C-", "C#", "D-", | |
13 "D#", "E-", "F-", | |
14 "F#", "G-", "G#", | |
15 "A-", "A#", "B-" | |
16 }; | |
17 | |
18 | |
19 #define jmpNMODEffectTable (36) | |
20 static const char jmpMODEffectTable[jmpNMODEffectTable] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
21 | |
22 | |
1603 | 23 void printRow(FILE * fh, const JSSPattern * pat, const int row) |
0 | 24 { |
1603 | 25 const JSSNote *note = &(pat->data[pat->nchannels * row]); |
26 int width = pat->nchannels < 5 ? pat->nchannels : 5; | |
0 | 27 |
1603 | 28 fprintf(fh, "%.2x: ", row); |
0 | 29 |
1603 | 30 for (int channel = 0; channel < width; channel++) |
0 | 31 { |
1603 | 32 switch (note->note) |
0 | 33 { |
34 case jsetNotSet: | |
1603 | 35 fprintf(fh, "... "); |
0 | 36 break; |
37 case jsetNoteOff: | |
1603 | 38 fprintf(fh, "=== "); |
0 | 39 break; |
40 default: | |
1603 | 41 fprintf(fh, "%s%d ", |
42 patNoteTable[note->note % 12], | |
43 note->note / 12); | |
0 | 44 break; |
45 } | |
46 | |
1603 | 47 if (note->instrument != jsetNotSet) |
48 fprintf(fh, "%.2x ", note->instrument + 1); | |
0 | 49 else |
1603 | 50 fprintf(fh, ".. "); |
0 | 51 |
1603 | 52 if (note->volume == jsetNotSet) |
53 fprintf(fh, ".. "); | |
54 else | |
55 if (note->volume >= 0x00 && note->volume <= 0x40) | |
56 fprintf(fh, "%.2x ", note->volume); | |
0 | 57 else |
58 { | |
1603 | 59 char ch; |
60 switch (note->volume & 0xf0) | |
0 | 61 { |
1603 | 62 case 0x50: ch = '-'; break; |
63 case 0x60: ch = '+'; break; | |
64 case 0x70: ch = '/'; break; | |
65 case 0x80: ch = '\\'; break; | |
66 case 0x90: ch = 'S'; break; | |
67 case 0xa0: ch = 'V'; break; | |
68 case 0xb0: ch = 'P'; break; | |
69 case 0xc0: ch = '<'; break; | |
70 case 0xd0: ch = '>'; break; | |
71 case 0xe0: ch = 'M'; break; | |
72 default: ch = '?'; break; | |
0 | 73 } |
1603 | 74 fprintf(fh, "%c%x ", |
75 ch, note->volume & 0x0f); | |
0 | 76 } |
77 | |
1603 | 78 if (note->effect >= 0 && note->effect < jmpNMODEffectTable) |
79 fprintf(fh, "%c", jmpMODEffectTable[note->effect]); | |
0 | 80 else |
1603 | 81 fprintf(fh, "%c", note->effect == jsetNotSet ? '.' : '?'); |
0 | 82 |
1603 | 83 if (note->param != jsetNotSet) |
84 fprintf(fh, "%.2x|", note->param); | |
0 | 85 else |
1603 | 86 fprintf(fh, "..|"); |
0 | 87 |
1603 | 88 note++; |
0 | 89 } |
90 } | |
91 | |
92 | |
93 void audioCallback(void *userdata, Uint8 *stream, int len) | |
94 { | |
95 JSSMixer *d = (JSSMixer *) userdata; | |
96 | |
97 if (d != NULL) | |
98 { | |
99 jvmRenderAudio(d, stream, len / jvmGetSampleSize(d)); | |
100 } | |
101 } | |
102 | |
103 | |
104 int main(int argc, char *argv[]) | |
105 { | |
67 | 106 SDL_AudioSpec afmt; |
107 DMResource *file = NULL; | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
667
diff
changeset
|
108 char *inFilename = NULL; |
2530 | 109 int res = -1; |
67 | 110 JSSModule *mod = NULL; |
111 JSSMixer *dev = NULL; | |
112 JSSPlayer *plr = NULL; | |
0 | 113 |
114 if (argc > 1) | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
667
diff
changeset
|
115 inFilename = argv[1]; |
0 | 116 |
117 // Open the files | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
667
diff
changeset
|
118 if (inFilename == NULL) |
2530 | 119 res = dmf_open_stdio_stream(stdin, &file); |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
667
diff
changeset
|
120 else |
2530 | 121 res = dmf_open_stdio(inFilename, "rb", &file); |
2046 | 122 |
2530 | 123 if (res != DMERR_OK) |
0 | 124 { |
2530 | 125 dmErrorMsg("Error opening input file '%s': %s\n", |
126 inFilename, dmErrorStr(res)); | |
127 goto exit; | |
0 | 128 } |
2046 | 129 |
0 | 130 // Initialize miniJSS |
2530 | 131 printf("Initializing miniJSS\n"); |
0 | 132 jssInit(); |
133 | |
134 // Read module file | |
2530 | 135 printf("Reading file: %s\n", inFilename); |
0 | 136 #ifdef JSS_SUP_XM |
2530 | 137 if (mod == NULL) |
138 { | |
139 printf("* Trying XM...\n"); | |
140 dmfreset(file); | |
141 if ((res = jssLoadXM(file, &mod, TRUE)) == DMERR_OK) | |
142 { | |
143 dmfreset(file); | |
144 res = jssLoadXM(file, &mod, FALSE); | |
145 } | |
146 } | |
1204
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
147 #endif |
0 | 148 #ifdef JSS_SUP_JSSMOD |
2530 | 149 if (mod == NULL) |
0 | 150 { |
2530 | 151 printf("* Trying JSSMOD ...\n"); |
1204
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
152 dmfreset(file); |
2530 | 153 if ((res = jssLoadJSSMOD(file, &mod, TRUE)) == DMERR_OK) |
154 { | |
155 dmfreset(file); | |
156 res = jssLoadJSSMOD(file, &mod, FALSE); | |
157 } | |
1204
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
158 } |
794
319792b2af4a
Fix non-fallback loading of JSSMod.
Matti Hamalainen <ccr@tnsp.org>
parents:
793
diff
changeset
|
159 #endif |
67 | 160 dmf_close(file); |
0 | 161 |
1204
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
162 // Check for errors, we still might have some data tho |
2530 | 163 if (res != DMERR_OK) |
0 | 164 { |
2530 | 165 dmErrorMsg( |
166 "Error loading module file: %s\n", | |
167 dmErrorStr(res)); | |
1204
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
168 } |
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
169 |
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
170 // Check if we have anything |
0d173edbabe2
Do the file probing stuff here as well.
Matti Hamalainen <ccr@tnsp.org>
parents:
797
diff
changeset
|
171 if (mod == NULL) |
2530 | 172 { |
173 res = dmError(DMERR_INIT_FAIL, | |
174 "Could not load module file.\n"); | |
175 goto exit; | |
176 } | |
0 | 177 |
49
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
178 // Try to convert it |
2530 | 179 if ((res = jssConvertModuleForPlaying(mod)) != DMERR_OK) |
49
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
180 { |
2530 | 181 dmErrorMsg("Could not convert module for playing: %s\n", |
182 dmErrorStr(res)); | |
183 goto exit; | |
49
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
184 } |
0 | 185 |
186 // Initialize SDL audio | |
67 | 187 afmt.freq = 48000; |
188 afmt.format = AUDIO_S16SYS; | |
189 afmt.channels = 2; | |
303 | 190 |
0 | 191 // Initialize mixing device |
2530 | 192 printf("Initializing miniJSS mixer with: %d, %d, %d\n", |
67 | 193 JSS_AUDIO_S16, afmt.channels, afmt.freq); |
0 | 194 |
67 | 195 dev = jvmInit(JSS_AUDIO_S16, afmt.channels, afmt.freq, JMIX_AUTO); |
196 if (dev == NULL) | |
197 { | |
2530 | 198 res = dmError(DMERR_INIT_FAIL, |
199 "jvmInit() returned NULL\n"); | |
200 goto exit; | |
0 | 201 } |
2046 | 202 |
303 | 203 afmt.samples = afmt.freq / 4; |
67 | 204 afmt.callback = audioCallback; |
205 afmt.userdata = (void *) dev; | |
0 | 206 |
207 // Open the audio device | |
2530 | 208 |
209 fprintf(stderr, | |
210 "Trying to init SDL with: %d, %d, %d\n", | |
67 | 211 afmt.format, afmt.channels, afmt.freq); |
2046 | 212 |
67 | 213 if (SDL_OpenAudio(&afmt, NULL) < 0) |
0 | 214 { |
2530 | 215 res = dmError(DMERR_INIT_FAIL, |
216 "Couldn't open audio: %s\n", | |
217 SDL_GetError()); | |
218 goto exit; | |
0 | 219 } |
2046 | 220 |
0 | 221 // Initialize player |
67 | 222 if ((plr = jmpInit(dev)) == NULL) |
0 | 223 { |
2530 | 224 res = dmError(DMERR_INIT_FAIL, |
225 "jmpInit() returned NULL\n"); | |
226 goto exit; | |
0 | 227 } |
2046 | 228 |
0 | 229 // Initialize playing |
67 | 230 jvmSetCallback(dev, jmpExec, plr); |
231 jmpSetModule(plr, mod); | |
232 jmpPlayOrder(plr, 0); | |
1603 | 233 jvmSetGlobalVol(dev, 100); |
0 | 234 |
235 // okay, main loop here ... "play" module and print out info | |
236 printf("----------------------------------------------------\n"); | |
292 | 237 SDL_LockAudio(); |
0 | 238 SDL_PauseAudio(0); |
292 | 239 SDL_UnlockAudio(); |
240 BOOL playing = TRUE; | |
241 while (playing) | |
0 | 242 { |
793
21ad08cdf408
Fix a potential NULL pointer usage.
Matti Hamalainen <ccr@tnsp.org>
parents:
777
diff
changeset
|
243 JSSPattern *pattern = NULL; |
292 | 244 int currRow, prevRow; |
245 | |
246 JSS_LOCK(plr); | |
247 currRow = prevRow = plr->row; | |
248 JSS_UNLOCK(plr); | |
249 | |
250 while (currRow == prevRow && playing) | |
251 { | |
252 JSS_LOCK(plr); | |
253 currRow = plr->row; | |
254 playing = plr->isPlaying; | |
255 pattern = plr->pattern; | |
256 JSS_UNLOCK(plr); | |
0 | 257 SDL_Delay(50); |
292 | 258 } |
0 | 259 |
793
21ad08cdf408
Fix a potential NULL pointer usage.
Matti Hamalainen <ccr@tnsp.org>
parents:
777
diff
changeset
|
260 if (playing && pattern != NULL) |
292 | 261 { |
262 printRow(stdout, pattern, currRow); | |
263 printf("\n"); | |
264 } | |
0 | 265 } |
2046 | 266 |
0 | 267 printf("----------------------------------------------------\n"); |
268 | |
2530 | 269 exit: |
292 | 270 SDL_LockAudio(); |
67 | 271 SDL_PauseAudio(1); |
272 jmpClose(plr); | |
273 jvmClose(dev); | |
274 jssFreeModule(mod); | |
275 SDL_UnlockAudio(); | |
276 | |
277 SDL_Quit(); | |
0 | 278 |
69
7b97df6f8a97
Add jssClose() in the shutdown.
Matti Hamalainen <ccr@tnsp.org>
parents:
67
diff
changeset
|
279 jssClose(); |
7b97df6f8a97
Add jssClose() in the shutdown.
Matti Hamalainen <ccr@tnsp.org>
parents:
67
diff
changeset
|
280 |
2530 | 281 return res; |
0 | 282 } |