Mercurial > hg > dmlib
comparison jssmod.c @ 0:32250b436bca
Initial re-import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 28 Sep 2012 01:54:23 +0300 |
parents | |
children | 048536ad01e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:32250b436bca |
---|---|
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 * sdata, const size_t srcSize, const int ops) | |
36 { | |
37 size_t ssize = srcSize; | |
38 Sint8 t, value = 0; | |
39 | |
40 while (ssize--) | |
41 { | |
42 t = *sdata; | |
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 *(sdata++) = t; | |
55 } | |
56 | |
57 return TRUE; | |
58 } | |
59 | |
60 | |
61 /* Decodes a given 16-bit sample | |
62 */ | |
63 BOOL jssEncodeSample16(Uint16 * srcData, const size_t srcSize, 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 ssize, bufSize = srcSize * sizeof(Sint16); | |
70 Uint8 *bp1, *bp2; | |
71 Sint16 t, *sdata, *tmpBuf = dmMalloc(bufSize); | |
72 if (tmpBuf == NULL) return FALSE; | |
73 | |
74 sdata = tmpBuf; | |
75 bp1 = (Uint8 *) srcData; | |
76 bp2 = bp1 + srcSize; | |
77 ssize = srcSize; | |
78 | |
79 while (ssize--) | |
80 { | |
81 t = (*sdata++); | |
82 *bp1++ = t >> 8; | |
83 *bp2++ = t & 0xff; | |
84 } | |
85 | |
86 memcpy(srcData, tmpBuf, bufSize); | |
87 dmFree(tmpBuf); | |
88 | |
89 return jssEncodeSample8((Uint8 *) srcData, bufSize, ops); | |
90 } | |
91 else | |
92 { | |
93 Sint16 t, p, value = 0, *sdata = (Sint16 *) srcData; | |
94 size_t ssize = srcSize; | |
95 | |
96 while (ssize--) | |
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 #endif | |
121 | |
122 | |
123 /* Decodes a given 8-bit sample | |
124 */ | |
125 BOOL jssDecodeSample8(Uint8 * sdata, const size_t srcSize, const int ops) | |
126 { | |
127 size_t ssize = srcSize; | |
128 Sint8 t, value = 0; | |
129 | |
130 while (ssize--) | |
131 { | |
132 t = *sdata; | |
133 | |
134 if (ops & jsampDelta) | |
135 t = value = t + value; | |
136 | |
137 if (ops & jsampFlipSign) | |
138 t ^= 0x80; | |
139 | |
140 *(sdata++) = t; | |
141 } | |
142 return TRUE; | |
143 } | |
144 | |
145 | |
146 /* Decodes a given 16-bit sample | |
147 */ | |
148 BOOL jssDecodeSample16(Uint16 * srcData, const size_t srcSize, const int ops) | |
149 { | |
150 if (ops & jsampSplit) | |
151 { | |
152 size_t ssize, bufSize = srcSize * sizeof(Uint16); | |
153 Uint8 *bp1, *bp2; | |
154 Sint16 *tmpBuf, *sdata; | |
155 | |
156 if (!jssDecodeSample8((Uint8 *) srcData, bufSize, ops)) | |
157 return FALSE; | |
158 | |
159 tmpBuf = dmMalloc(bufSize); | |
160 if (tmpBuf == NULL) return FALSE; | |
161 memcpy(tmpBuf, srcData, bufSize); | |
162 | |
163 sdata = (Sint16 *) srcData; | |
164 bp1 = (Uint8 *) tmpBuf; | |
165 bp2 = bp1 + srcSize; | |
166 ssize = srcSize; | |
167 while (ssize--) | |
168 { | |
169 *sdata++ = (*bp1++ << 8) | (*bp2++ & 0xff); | |
170 } | |
171 | |
172 dmFree(tmpBuf); | |
173 } | |
174 else | |
175 { | |
176 Sint16 t, p, value = 0, *sdata = (Sint16 *) srcData; | |
177 size_t ssize = srcSize; | |
178 while (ssize--) | |
179 { | |
180 if (ops & jsampSwapEndianess) | |
181 { | |
182 p = *sdata; | |
183 t = ((p >> 8) & 0xff) | ((p & 0xff) << 8); | |
184 } else | |
185 t = *sdata; | |
186 | |
187 if (ops & jsampDelta) | |
188 t = value = t + value; | |
189 | |
190 if (ops & jsampFlipSign) | |
191 t ^= 0x8000; | |
192 | |
193 *(sdata++) = t; | |
194 } | |
195 } | |
196 return TRUE; | |
197 } | |
198 | |
199 | |
200 /* Allocates a new module structure or returns errorvalue if failed. | |
201 * Memory is allocated only for the basic structure. Sample- and pattern | |
202 * areas must be allocated separately with appropriate routines. | |
203 */ | |
204 JSSModule *jssAllocateModule(void) | |
205 { | |
206 int i; | |
207 JSSModule *module; | |
208 | |
209 // Allocate module structure | |
210 module = dmMalloc0(sizeof(JSSModule)); | |
211 if (module == NULL) | |
212 return NULL; | |
213 | |
214 // Initialize structure | |
215 for (i = 0; i < jsetNChannels; i++) | |
216 module->defPanning[i] = jchPanMiddle; | |
217 | |
218 for (i = 0; i < jsetMaxOrders; i++) | |
219 module->orderList[i] = jsetOrderEnd; | |
220 | |
221 // Allocate mutex | |
222 #ifdef JSS_SUP_THREADS | |
223 module->mutex = dmCreateMutex(); | |
224 #endif | |
225 | |
226 return module; | |
227 } | |
228 | |
229 | |
230 /* Frees a given module structure, freeing all memory areas | |
231 * that were allocated for it (including patterns, samples, etc.) | |
232 */ | |
233 int jssFreeModule(JSSModule * module) | |
234 { | |
235 int i; | |
236 | |
237 if (module == NULL) | |
238 return DMERR_NULLPTR; | |
239 | |
240 // Free strings | |
241 #ifndef JSS_LIGHT | |
242 dmFree(module->moduleName); | |
243 dmFree(module->trackerName); | |
244 #endif | |
245 | |
246 // Free patterns | |
247 for (i = 0; i < module->npatterns; i++) | |
248 { | |
249 if (module->patterns[i]) | |
250 { | |
251 JSSPattern *pat = module->patterns[i]; | |
252 dmFree(pat->data); | |
253 dmFree(pat); | |
254 module->patterns[i] = NULL; | |
255 } | |
256 } | |
257 | |
258 // Free instruments | |
259 for (i = 0; i < module->ninstruments; i++) | |
260 { | |
261 if (module->instruments[i]) | |
262 { | |
263 JSSInstrument *inst = module->instruments[i]; | |
264 #ifndef JSS_LIGHT | |
265 dmFree(inst->desc); | |
266 #endif | |
267 dmFree(inst->data); | |
268 dmFree(inst); | |
269 module->instruments[i] = NULL; | |
270 } | |
271 } | |
272 | |
273 // Free extended instruments | |
274 for (i = 0; i < module->nextInstruments; i++) | |
275 { | |
276 if (module->extInstruments[i]) | |
277 { | |
278 JSSExtInstrument *ext = module->extInstruments[i]; | |
279 #ifndef JSS_LIGHT | |
280 dmFree(ext->desc); | |
281 #endif | |
282 dmFree(ext); | |
283 module->extInstruments[i] = NULL; | |
284 } | |
285 } | |
286 | |
287 // Free mutex | |
288 #ifdef JSS_SUP_THREADS | |
289 dmDestroyMutex(module->mutex); | |
290 #endif | |
291 | |
292 // Free the module structure | |
293 memset(module, 0, sizeof(JSSModule)); | |
294 dmFree(module); | |
295 | |
296 return DMERR_OK; | |
297 } | |
298 | |
299 | |
300 /* Allocates and initializes a internal pattern structure. | |
301 */ | |
302 JSSPattern *jssAllocatePattern(int nrows, int nchannels) | |
303 { | |
304 int i, j; | |
305 JSSPattern *res; | |
306 JSSNote *pnote; | |
307 | |
308 // Check arguments | |
309 if (nrows <= 0 || nchannels <= 0) | |
310 JSSERROR(DMERR_INVALID_ARGS, NULL, "Invalid nrows=%i or nchannels=%i.\n", nrows, nchannels); | |
311 | |
312 // Allocate a pattern structure | |
313 res = dmMalloc0(sizeof(JSSPattern)); | |
314 if (res == NULL) | |
315 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern structure.\n"); | |
316 | |
317 // Allocate notedata | |
318 res->data = dmCalloc(nrows * nchannels, sizeof(JSSNote)); | |
319 if (res->data == NULL) | |
320 { | |
321 dmFree(res); | |
322 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate pattern data (nrows=%i, nchannels=%i).\n", nrows, | |
323 nchannels); | |
324 } | |
325 | |
326 // Initialize | |
327 res->nrows = nrows; | |
328 res->nchannels = nchannels; | |
329 | |
330 pnote = res->data; | |
331 for (j = 0; j < nrows; j++) | |
332 { | |
333 for (i = 0; i < nchannels; i++) | |
334 { | |
335 pnote->note = pnote->instrument = pnote->volume = | |
336 pnote->effect = pnote->param = jsetNotSet; | |
337 | |
338 pnote++; | |
339 } | |
340 } | |
341 | |
342 // OK, return pointer to struct | |
343 return res; | |
344 } | |
345 | |
346 | |
347 /* Allocates and initializes internal "normal" instrument structure. | |
348 */ | |
349 JSSInstrument *jssAllocateInstrument(void) | |
350 { | |
351 JSSInstrument *res; | |
352 | |
353 // Allocate a instrument structure | |
354 res = dmMalloc0(sizeof(JSSInstrument)); | |
355 if (res == NULL) | |
356 return NULL; | |
357 | |
358 return res; | |
359 } | |
360 | |
361 | |
362 /* Allocates and initializes "extended" instrument structure. | |
363 */ | |
364 JSSExtInstrument *jssAllocateExtInstrument(void) | |
365 { | |
366 int i; | |
367 JSSExtInstrument *res; | |
368 | |
369 // Allocate a instrument structure | |
370 res = dmMalloc0(sizeof(JSSExtInstrument)); | |
371 if (res == NULL) | |
372 return NULL; | |
373 | |
374 for (i = 0; i < jsetNNotes; i++) | |
375 { | |
376 res->sNumForNotes[i] = jsetNotSet; | |
377 } | |
378 | |
379 return res; | |
380 } |