Mercurial > hg > dmlib
annotate testpl.c @ 55:e0e470c3fc8e
Initial round of cleaning up the player code a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 01 Oct 2012 06:28:29 +0300 |
parents | 033c660c25f5 |
children | b51c7fc264ab |
rev | line source |
---|---|
0 | 1 #include "jss.h" |
2 #include "jssmod.h" | |
3 #include "jssmix.h" | |
4 #include "jssplr.h" | |
5 #include <errno.h> | |
6 #include <string.h> | |
7 #include <unistd.h> | |
8 #include <SDL.h> | |
9 | |
10 | |
11 static const char patNoteTable[12][3] = | |
12 { | |
13 "C-", "C#", "D-", | |
14 "D#", "E-", "F-", | |
15 "F#", "G-", "G#", | |
16 "A-", "A#", "B-" | |
17 }; | |
18 | |
19 | |
20 #define jmpNMODEffectTable (36) | |
21 static const char jmpMODEffectTable[jmpNMODEffectTable] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
22 | |
23 | |
24 void printRow(FILE * f, JSSPattern * p, int row) | |
25 { | |
26 int j, k; | |
27 char c; | |
28 JSSNote *n; | |
29 | |
30 if (!p) | |
31 return; | |
32 | |
33 n = &(p->data[p->nchannels * row]); | |
34 | |
35 fprintf(f, "%.2x: ", row); | |
36 | |
37 k = p->nchannels < 5 ? p->nchannels : 5; | |
38 | |
39 for (j = 0; j < k; j++) | |
40 { | |
41 switch (n->note) | |
42 { | |
43 case jsetNotSet: | |
44 fprintf(f, "... "); | |
45 break; | |
46 case jsetNoteOff: | |
47 fprintf(f, "=== "); | |
48 break; | |
49 default: | |
50 fprintf(f, "%s%i ", patNoteTable[n->note % 12], n->note / 12); | |
51 break; | |
52 } | |
53 | |
54 if (n->instrument != jsetNotSet) | |
55 fprintf(f, "%.2x ", n->instrument + 1); | |
56 else | |
57 fprintf(f, ".. "); | |
58 | |
59 if (n->volume == jsetNotSet) | |
60 fprintf(f, ".. "); | |
61 else if (n->volume >= 0x00 && n->volume <= 0x40) | |
62 fprintf(f, "%.2x ", n->volume); | |
63 else | |
64 { | |
65 switch (n->volume & 0xf0) | |
66 { | |
67 case 0x50: c = '-'; break; | |
68 case 0x60: c = '+'; break; | |
69 case 0x70: c = '/'; break; | |
70 case 0x80: c = '\\'; break; | |
71 case 0x90: c = 'S'; break; | |
72 case 0xa0: c = 'V'; break; | |
73 case 0xb0: c = 'P'; break; | |
74 case 0xc0: c = '<'; break; | |
75 case 0xd0: c = '>'; break; | |
76 case 0xe0: c = 'M'; break; | |
77 default: c = '?'; break; | |
78 } | |
79 fprintf(f, "%c%x ", c, (n->volume & 0x0f)); | |
80 } | |
81 | |
82 if (n->effect >= 0 && n->effect < jmpNMODEffectTable) | |
83 fprintf(f, "%c", jmpMODEffectTable[n->effect]); | |
84 else if (n->effect == jsetNotSet) | |
85 fprintf(f, "."); | |
86 else | |
87 fprintf(f, "?"); | |
88 | |
89 if (n->param != jsetNotSet) | |
90 fprintf(f, "%.2x|", n->param); | |
91 else | |
92 fprintf(f, "..|"); | |
93 | |
94 n++; | |
95 } | |
96 } | |
97 | |
98 | |
99 void audioCallback(void *userdata, Uint8 *stream, int len) | |
100 { | |
101 JSSMixer *d = (JSSMixer *) userdata; | |
102 | |
103 if (d != NULL) | |
104 { | |
105 jvmRenderAudio(d, stream, len / jvmGetSampleSize(d)); | |
106 } | |
107 } | |
108 | |
109 | |
110 int main(int argc, char *argv[]) | |
111 { | |
112 SDL_AudioSpec *a_desired, *a_obtained; | |
113 DMResource *inFile; | |
114 char *sname = NULL; | |
115 int result = -1; | |
116 JSSModule *m; | |
117 JSSMixer *d; | |
118 JSSPlayer *p; | |
119 int buflen = 4096; | |
120 | |
121 if (argc > 1) | |
122 sname = argv[1]; | |
123 | |
124 // Open the files | |
125 if (sname == NULL) | |
126 inFile = dmf_create_stdio_stream(stdin); | |
127 else if ((inFile = dmf_create_stdio(sname)) == NULL) | |
128 { | |
129 fprintf(stderr, "Error opening input file '%s'. (%s)\n", sname, strerror(errno)); | |
130 return 1; | |
131 } | |
132 | |
133 // Initialize miniJSS | |
134 fprintf(stderr, "Initializing miniJSS\n"); | |
135 jssInit(); | |
136 | |
137 | |
138 // Read module file | |
139 fprintf(stderr, "Reading file: %s\n", sname); | |
140 #ifdef JSS_SUP_XM | |
141 fprintf(stderr, "* Trying XM...\n"); | |
142 result = jssLoadXM(inFile, &m); | |
143 #endif | |
144 #ifdef JSS_SUP_JSSMOD | |
145 if (result != 0) | |
146 { | |
8
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
147 size_t bufgot, bufsize = dmfsize(inFile); |
0 | 148 Uint8 *buf = dmMalloc(bufsize); |
8
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
149 dmfseek(inFile, 0L, SEEK_SET); |
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
150 fprintf(stderr, "* Trying JSSMOD (%d bytes, %p)...\n", bufsize, buf); |
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
151 if ((bufgot = dmfread(buf, 1, bufsize, inFile)) != bufsize) |
0 | 152 { |
8
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
153 fprintf(stderr, "Error reading file (not enough data %d), #%d: %s\n", |
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
154 bufgot, dmferror(inFile), dmErrorStr(dmferror(inFile))); |
0 | 155 return 2; |
156 } | |
157 result = jssLoadJSSMOD(buf, bufsize, &m); | |
158 dmFree(buf); | |
159 } | |
160 #endif | |
161 dmf_close(inFile); | |
162 | |
8
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
163 if (result != DMERR_OK) |
0 | 164 { |
8
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
165 fprintf(stderr, "Error loading module file, %d: %s\n", |
fc097f7717df
Fix JSSMod loading in viewmod and testpl.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
166 result, dmErrorStr(result)); |
0 | 167 return 3; |
168 } | |
169 | |
49
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
170 // Try to convert it |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
171 if ((result = jssConvertModuleForPlaying(m)) != DMERR_OK) |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
172 { |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
173 fprintf(stderr, "Could not convert module for playing, %d: %s\n", |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
174 result, dmErrorStr(result)); |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
175 return 3; |
033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
176 } |
0 | 177 |
178 // Initialize SDL audio | |
179 fprintf(stderr, "Pre-initializing params\n"); | |
180 a_desired = dmMalloc(sizeof(SDL_AudioSpec)); | |
181 a_obtained = dmMalloc(sizeof(SDL_AudioSpec)); | |
182 if (!a_desired || !a_obtained) | |
183 { | |
184 fprintf(stderr, "Could not allocate SDL shit\n"); | |
185 return 3; | |
186 } | |
187 | |
188 a_desired->freq = 48000; | |
189 a_desired->format = AUDIO_S16SYS; | |
190 a_desired->channels = 2; | |
191 | |
192 // Initialize mixing device | |
193 fprintf(stderr, "Initializing miniJSS mixer with: %d, %d, %d\n", | |
194 JSS_AUDIO_S16, a_desired->channels, a_desired->freq); | |
195 | |
196 d = jvmInit(JSS_AUDIO_S16, a_desired->channels, a_desired->freq, JMIX_AUTO); | |
197 if (!d) { | |
198 fprintf(stderr, "jvmInit() returned NULL\n"); | |
199 return 3; | |
200 } | |
201 | |
202 a_desired->samples = buflen; | |
203 a_desired->callback = audioCallback; | |
204 a_desired->userdata = (void *) d; | |
205 | |
206 // Open the audio device | |
207 fprintf(stderr, "Trying to init SDL with: %d, %d, %d\n", | |
208 a_desired->format, a_desired->channels, a_desired->freq); | |
209 | |
210 if (SDL_OpenAudio(a_desired, a_obtained) < 0) | |
211 { | |
212 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); | |
213 return 4; | |
214 } | |
215 | |
216 fprintf(stderr, "Got: %d, %d, %d\n", | |
217 a_obtained->format, a_obtained->channels, a_obtained->freq); | |
218 | |
219 if ((a_obtained->format != a_desired->format) || | |
220 (a_obtained->channels != a_desired->channels) || | |
221 (a_obtained->freq != a_desired->freq)) | |
222 { | |
223 fprintf(stderr, "Could not get wanted audio parameters from SDL!\n"); | |
224 return 8; | |
225 } | |
226 | |
227 free(a_desired); | |
228 | |
229 // Initialize player | |
230 p = jmpInit(d); | |
231 if (!p) | |
232 { | |
233 fprintf(stderr, "jmpInit() returned NULL\n"); | |
234 return 4; | |
235 } | |
236 | |
237 // Set callback | |
238 jvmSetCallback(d, jmpExec, p); | |
239 | |
240 // Initialize playing | |
241 jmpSetModule(p, m); | |
242 jmpPlayOrder(p, 0); | |
243 jvmSetGlobalVol(d, 60); | |
244 | |
245 // okay, main loop here ... "play" module and print out info | |
246 printf("----------------------------------------------------\n"); | |
247 SDL_PauseAudio(0); | |
248 while (p->isPlaying) | |
249 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
49
diff
changeset
|
250 int r = p->row; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
49
diff
changeset
|
251 while (r == p->row && p->isPlaying) |
0 | 252 SDL_Delay(50); |
253 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
49
diff
changeset
|
254 printRow(stdout, p->pattern, p->row); |
0 | 255 printf("\n"); |
256 } | |
257 | |
258 printf("----------------------------------------------------\n"); | |
259 | |
260 // Free module data | |
261 jmpClose(p); | |
262 jvmClose(d); | |
263 jssFreeModule(m); | |
264 m = NULL; | |
265 | |
266 return 0; | |
267 } |