comparison minijss/jssmod.c @ 658:c430112449a7

Move miniJSS into a subdirectory.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 16 Apr 2013 07:32:29 +0300
parents jssmod.c@a17e54015bd9
children b136ddc4070b
comparison
equal deleted inserted replaced
657:7e25ec0bbf59 658:c430112449a7
1 /*
2 * miniJSS - Module structure and handling routines
3 * Programmed and designed by Matti 'ccr' Hamalainen
4 * (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
5 */
6 #include "jssmod.h"
7 #include <string.h>
8
9
10 #ifndef JSS_LIGHT
11 /* Take given data until maxlen reached, make a string
12 */
13 char *jssASCIItoStr(char * sdata, const char endByte, const size_t maxLen)
14 {
15 size_t i, k;
16 char *res;
17
18 for (i = 0; sdata[i] && i < maxLen; i++);
19
20 res = (char *) dmMalloc(i + 1);
21 if (res == NULL)
22 return NULL;
23
24 for (k = 0; sdata[k] != endByte && k < i; k++)
25 res[k] = sdata[k];
26
27 res[k] = 0;
28
29 return res;
30 }
31
32
33 /* Encodes a given 8-bit sample
34 */
35 BOOL jssEncodeSample8(Uint8 * data, const size_t len, const int ops)
36 {
37 size_t count = len;
38 Sint8 t, value = 0;
39
40 while (count--)
41 {
42 t = *data;
43
44 if (ops & jsampFlipSign)
45 t ^= 0x80;
46
47 if (ops & jsampDelta)
48 {
49 int n = t - value;
50 value = t;
51 t = n;
52 }
53
54 *(data++) = t;
55 }
56
57 return TRUE;
58 }
59
60
61 /* Decodes a given 16-bit sample
62 */
63 BOOL jssEncodeSample16(Uint16 * data, const size_t len, const int ops)
64 {
65 // "Split" the 16-bit samples into 8-bit halves
66 if (ops & jsampSplit)
67 {
68 // Allocate temporary processing buffer
69 size_t count, bufSize = len * sizeof(Sint16);
70 Uint8 *bp1, *bp2;
71 Sint16 *sdata, *tmpBuf = dmMalloc(bufSize);
72 if (tmpBuf == NULL) return FALSE;
73
74 sdata = tmpBuf;
75 bp1 = (Uint8 *) data;
76 bp2 = bp1 + len;
77 count = len;
78
79 while (count--)
80 {
81 Sint16 t = (*sdata++);
82 *bp1++ = t >> 8;
83 *bp2++ = t & 0xff;
84 }
85
86 memcpy(data, tmpBuf, bufSize);
87 dmFree(tmpBuf);
88
89 return jssEncodeSample8((Uint8 *) data, bufSize, ops);
90 }
91 else
92 {
93 Sint16 t, p, value = 0, *sdata = (Sint16 *) data;
94 size_t count = len;
95
96 while (count--)
97 {
98 if (ops & jsampSwapEndianess)
99 {
100 p = *sdata;
101 t = ((p >> 8) & 0xff) | ((p & 0xff) << 8);
102 } else
103 t = *sdata;
104
105 if (ops & jsampDelta)
106 {
107 int n = t - value;
108 value = t;
109 t = n;
110 }
111
112 if (ops & jsampFlipSign)
113 t ^= 0x8000;
114
115 *(sdata++) = t;
116 }
117 }
118 return TRUE;
119 }
120
121 #endif
122
123
124 /* Decodes a given 8-bit sample
125 */
126 BOOL jssDecodeSample8(Uint8 * data, const size_t len, const int ops)
127 {
128 size_t count = len;
129 Sint8 t, value = 0;
130
131 while (count--)
132 {
133 t = *data;
134
135 if (ops & jsampDelta)
136 t = value = t + value;
137
138 if (ops & jsampFlipSign)
139 t ^= 0x80;
140
141 *(data++) = t;
142 }
143 return TRUE;
144 }
145
146
147 /* Decodes a given 16-bit sample
148 */
149 BOOL jssDecodeSample16(Uint16 * data, const size_t len, const int ops)
150 {
151 if (ops & jsampSplit)
152 {
153 size_t count, bufSize = len * sizeof(Uint16);
154 Uint8 *bp1, *bp2;
155 Sint16 *tmpBuf, *sdata;
156
157 if (!jssDecodeSample8((Uint8 *) data, bufSize, ops))
158 return FALSE;
159
160 tmpBuf = dmMalloc(bufSize);
161 if (tmpBuf == NULL) return FALSE;
162 memcpy(tmpBuf, data, bufSize);
163
164 sdata = (Sint16 *) data;
165 bp1 = (Uint8 *) tmpBuf;
166 bp2 = bp1 + len;
167 count = len;
168 while (count--)
169 {
170 *sdata++ = (*bp1++ << 8) | (*bp2++ & 0xff);
171 }
172
173 dmFree(tmpBuf);
174 }
175 else
176 {
177 Sint16 t, p, value = 0, *sdata = (Sint16 *) data;
178 size_t count = len;
179 while (count--)
180 {
181 if (ops & jsampSwapEndianess)
182 {
183 p = *sdata;
184 t = ((p >> 8) & 0xff) | ((p & 0xff) << 8);
185 } else
186 t = *sdata;
187
188 if (ops & jsampDelta)
189 t = value = t + value;
190
191 if (ops & jsampFlipSign)
192 t ^= 0x8000;
193
194 *(sdata++) = t;
195 }
196 }
197 return TRUE;
198 }
199
200
201 /* Convert sample data from U8 to S16
202 */
203 int jssConvertSampleTo16(void **dst, void * src, const size_t len)
204 {
205 size_t count = len;
206 Uint8 *in = (Uint8 *) src;
207 Sint16 *out;
208
209 *dst = out = dmMalloc(sizeof(Sint16) * len);
210 if (out == NULL)
211 return DMERR_MALLOC;
212
213 while (count--)
214 {
215 *(out++) = (*(in++) * 256) - 32768;
216 }
217
218 return DMERR_OK;
219 }
220
221 /* Converts the given module in preparation for playing it.
222 * This involves sample format conversion (8 to 16 bit, etc.)
223 *
224 * NOTICE! The converted module can only be saved in JSSMOD
225 * format, but this is not recommended.
226 */
227 int jssConvertModuleForPlaying(JSSModule *module)
228 {
229 int i;
230 if (module == NULL)
231 return DMERR_NULLPTR;
232
233 // Convert instruments
234 for (i = 0; i < module->ninstruments; i++)
235 {
236 JSSInstrument *inst = module->instruments[i];
237 if (inst != NULL && inst->data != NULL)
238 {
239 int res;
240 void *data = NULL;
241
242 if (inst->flags & jsf16bit)
243 continue;
244
245 if ((res = jssConvertSampleTo16(&data, inst->data, inst->size)) != DMERR_OK)
246 return res;
247
248 inst->flags |= jsf16bit;
249 dmFree(inst->data);
250 inst->data = data;
251 }
252 }
253
254 return DMERR_OK;
255 }
256
257
258 /* Allocates a new module structure or returns errorvalue if failed.
259 * Memory is allocated only for the basic structure. Sample- and pattern
260 * areas must be allocated separately with appropriate routines.
261 */
262 JSSModule *jssAllocateModule(void)
263 {
264 int i;
265 JSSModule *module;
266
267 // Allocate module structure
268 module = dmMalloc0(sizeof(JSSModule));
269 if (module == NULL)
270 return NULL;
271
272 // Initialize structure
273 for (i = 0; i < jsetNChannels; i++)
274 module->defPanning[i] = jchPanMiddle;
275
276 for (i = 0; i < jsetMaxOrders; i++)
277 module->orderList[i] = jsetOrderEnd;
278
279 // Allocate mutex
280 #ifdef JSS_SUP_THREADS
281 module->mutex = dmCreateMutex();
282 #endif
283
284 return module;
285 }
286
287
288 /* Frees a given module structure, freeing all memory areas
289 * that were allocated for it (including patterns, samples, etc.)
290 */
291 int jssFreeModule(JSSModule * module)
292 {
293 int i;
294
295 if (module == NULL)
296 return DMERR_NULLPTR;
297
298 // Free strings
299 #ifndef JSS_LIGHT
300 dmFree(module->moduleName);
301 dmFree(module->trackerName);
302 #endif
303
304 // Free patterns
305 for (i = 0; i < module->npatterns; i++)
306 {
307 if (module->patterns[i])
308 {
309 JSSPattern *pat = module->patterns[i];
310 dmFree(pat->data);
311 dmFree(pat);
312 module->patterns[i] = NULL;
313 }
314 }
315
316 // Free the "empty" pattern
317 JSSPattern *pat = module->patterns[jsetMaxPatterns];
318 if (pat != NULL)
319 {
320 dmFree(pat->data);
321 dmFree(pat);
322 module->patterns[i] = NULL;
323 }
324
325 // Free instruments
326 for (i = 0; i < module->ninstruments; i++)
327 {
328 if (module->instruments[i])
329 {
330 JSSInstrument *inst = module->instruments[i];
331 #ifndef JSS_LIGHT
332 dmFree(inst->desc);
333 #endif
334 dmFree(inst->data);
335 dmFree(inst);
336 module->instruments[i] = NULL;
337 }
338 }
339
340 // Free extended instruments
341 for (i = 0; i < module->nextInstruments; i++)
342 {
343 if (module->extInstruments[i])
344 {
345 JSSExtInstrument *ext = module->extInstruments[i];
346 #ifndef JSS_LIGHT
347 dmFree(ext->desc);
348 #endif
349 dmFree(ext);
350 module->extInstruments[i] = NULL;
351 }
352 }
353
354 // Free mutex
355 #ifdef JSS_SUP_THREADS
356 dmDestroyMutex(module->mutex);
357 #endif
358
359 // Free the module structure
360 memset(module, 0, sizeof(JSSModule));
361 dmFree(module);
362
363 return DMERR_OK;
364 }
365
366
367 /* Allocates and initializes a internal pattern structure.
368 */
369 JSSPattern *jssAllocatePattern(int nrows, int nchannels)
370 {
371 int i, j;
372 JSSPattern *res;
373 JSSNote *pnote;
374
375 // Check arguments
376 if (nrows <= 0 || nchannels <= 0)
377 JSSERROR(DMERR_INVALID_ARGS, NULL, "Invalid nrows=%i or nchannels=%i.\n", nrows, nchannels);
378
379 // Allocate a pattern structure
380 res = dmMalloc0(sizeof(JSSPattern));
381 if (res == NULL)
382 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern structure.\n");
383
384 // Allocate notedata
385 res->data = dmCalloc(nrows * nchannels, sizeof(JSSNote));
386 if (res->data == NULL)
387 {
388 dmFree(res);
389 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern data (nrows=%i, nchannels=%i).\n", nrows,
390 nchannels);
391 }
392
393 // Initialize
394 res->nrows = nrows;
395 res->nchannels = nchannels;
396
397 pnote = res->data;
398 for (j = 0; j < nrows; j++)
399 {
400 for (i = 0; i < nchannels; i++)
401 {
402 pnote->note = pnote->instrument = pnote->volume =
403 pnote->effect = pnote->param = jsetNotSet;
404
405 pnote++;
406 }
407 }
408
409 // OK, return pointer to struct
410 return res;
411 }
412
413
414 /* Allocates and initializes internal "normal" instrument structure.
415 */
416 JSSInstrument *jssAllocateInstrument(void)
417 {
418 JSSInstrument *res;
419
420 // Allocate a instrument structure
421 res = dmMalloc0(sizeof(JSSInstrument));
422 if (res == NULL)
423 return NULL;
424
425 return res;
426 }
427
428
429 /* Allocates and initializes "extended" instrument structure.
430 */
431 JSSExtInstrument *jssAllocateExtInstrument(void)
432 {
433 int i;
434 JSSExtInstrument *res;
435
436 // Allocate a instrument structure
437 res = dmMalloc0(sizeof(JSSExtInstrument));
438 if (res == NULL)
439 return NULL;
440
441 for (i = 0; i < jsetNNotes; i++)
442 {
443 res->sNumForNotes[i] = jsetNotSet;
444 }
445
446 return res;
447 }