1 
2 /*
3  * The Real SoundTracker - General support routines
4  *
5  * Copyright (C) 1998-2019 Michael Krause
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include <pthread.h>
23 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <glib.h>
28 
29 #include "st-subs.h"
30 #include "xm.h"
31 
32 int st_init_pattern_channels(XMPattern* p,
33     unsigned length,
34     int num_channels)
35 {
36     int i;
37 
38     p->length = p->alloc_length = length;
39     for (i = 0; i < num_channels; i++) {
40         if (!(p->channels[i] = calloc(1, length * sizeof(XMNote)))) {
41             st_free_pattern_channels(p);
42             return 0;
43         }
44     }
45 
46     return 1;
47 }
48 
49 void st_free_pattern_channels(XMPattern* pat)
50 {
51     int i;
52 
53     for (i = 0; i < 32; i++) {
54         free(pat->channels[i]);
55         pat->channels[i] = NULL;
56     }
57 }
58 
59 void st_free_all_pattern_channels(XM* xm)
60 {
61     int i;
62 
63     for (i = 0; i < 256; i++)
64         st_free_pattern_channels(&xm->patterns[i]);
65 }
66 
67 int st_copy_pattern(XMPattern* dst,
68     XMPattern* src)
69 {
70     XMNote* oldchans[32];
71     int i;
72 
73     for (i = 0; i < 32; i++) {
74         oldchans[i] = dst->channels[i];
75         if (src->channels[i]) {
76             if (!(dst->channels[i] = st_dup_track(src->channels[i], src->length))) {
77                 // Out of memory, restore previous pattern, return error
78                 for (; i >= 0; i--) {
79                     free(dst->channels[i]);
80                     dst->channels[i] = oldchans[i];
81                 }
82                 return 0;
83             }
84         } else {
85             dst->channels[i] = NULL;
86         }
87     }
88 
89     for (i = 0; i < 32; i++)
90         free(oldchans[i]);
91 
92     dst->length = dst->alloc_length = src->length;
93 
94     return 1;
95 }
96 
97 XMPattern*
98 st_dup_pattern(XMPattern* p)
99 {
100     XMPattern* r;
101 
102     r = g_new0(XMPattern, 1);
103     if (!r)
104         return NULL;
105 
106     if (!st_copy_pattern(r, p)) {
107         g_free(r);
108         return NULL;
109     }
110 
111     return r;
112 }
113 
114 XMNote*
115 st_dup_track(XMNote* n,
116     int length)
117 {
118     XMNote* r;
119 
120     if (!n)
121         return NULL;
122 
123     r = malloc(length * sizeof(XMNote));
124     if (r) {
125         memcpy(r, n, length * sizeof(XMNote));
126     }
127 
128     return r;
129 }
130 
131 /* Duplicate part of a track, wrap-around at end is handled */
132 XMNote*
133 st_dup_track_wrap(XMNote* n,
134     int tracklength,
135     int copystart,
136     int copylength)
137 {
138     XMNote* r;
139 
140     if (!n || copylength > tracklength || copystart >= tracklength)
141         return NULL;
142 
143     if (copylength > tracklength - copystart) {
144         r = malloc(copylength * sizeof(XMNote));
145         if (r) {
146             memcpy(r, n + copystart, (tracklength - copystart) * sizeof(XMNote));
147             memcpy(r + tracklength - copystart, n, (copylength - (tracklength - copystart)) * sizeof(XMNote));
148         }
149     } else {
150         r = st_dup_track(n + copystart, copylength);
151     }
152 
153     return r;
154 }
155 
156 void st_clear_track(XMNote* n,
157     int length)
158 {
159     if (!n)
160         return;
161 
162     memset(n, 0, length * sizeof(*n));
163 }
164 
165 /* Clear part of a track, wrap-around at end is handled */
166 void st_clear_track_wrap(XMNote* n,
167     int tracklength,
168     int clearstart,
169     int clearlength)
170 {
171     if (!n || clearlength > tracklength || clearstart >= tracklength)
172         return;
173 
174     if (clearlength > tracklength - clearstart) {
175         st_clear_track(n + clearstart, tracklength - clearstart);
176         st_clear_track(n, clearlength - (tracklength - clearstart));
177     } else {
178         st_clear_track(n + clearstart, clearlength);
179     }
180 }
181 
182 void st_paste_track_into_track_wrap(XMNote* from,
183     XMNote* to,
184     int tolength,
185     int insertstart,
186     int fromlength)
187 {
188     if (!from || !to || tolength < fromlength || insertstart >= tolength)
189         return;
190 
191     if (fromlength > tolength - insertstart) {
192         memcpy(to + insertstart, from, (tolength - insertstart) * sizeof(XMNote));
193         memcpy(to, from + tolength - insertstart, (fromlength - (tolength - insertstart)) * sizeof(XMNote));
194     } else {
195         memcpy(to + insertstart, from, fromlength * sizeof(XMNote));
196     }
197 }
198 
199 void st_clear_pattern(XMPattern* p)
200 {
201     int i;
202 
203     for (i = 0; i < 32; i++) {
204         st_clear_track(p->channels[i], p->alloc_length);
205     }
206 }
207 
208 void st_pattern_delete_track(XMPattern* p,
209     int t)
210 {
211     int i;
212     XMNote* a;
213 
214     a = p->channels[t];
215     g_assert(a != NULL);
216 
217     for (i = t; i < 31 && p->channels[i + 1] != NULL; i++) {
218         p->channels[i] = p->channels[i + 1];
219     }
220 
221     p->channels[i] = a;
222     st_clear_track(a, p->alloc_length);
223 }
224 
225 void st_pattern_insert_track(XMPattern* p,
226     int t)
227 {
228     int i;
229     XMNote* a;
230 
231     a = p->channels[31];
232 
233     for (i = 31; i > t; i--) {
234         p->channels[i] = p->channels[i - 1];
235     }
236 
237     if (!a) {
238         if (!(a = calloc(1, p->alloc_length * sizeof(XMNote)))) {
239             g_assert_not_reached();
240         }
241     }
242 
243     p->channels[t] = a;
244     st_clear_track(a, p->alloc_length);
245 }
246 
247 gboolean
248 st_instrument_used_in_song(XM* xm,
249     int instr)
250 {
251     int i, j, k;
252     XMPattern* p;
253     XMNote* c;
254 
255     for (i = 0; i < xm->song_length; i++) {
256         p = &xm->patterns[(int)xm->pattern_order_table[i]];
257         for (j = 0; j < xm->num_channels; j++) {
258             c = p->channels[j];
259             for (k = 0; k < p->length; k++) {
260                 if (c[k].instrument == instr)
261                     return TRUE;
262             }
263         }
264     }
265 
266     return FALSE;
267 }
268 
269 int st_instrument_num_samples(STInstrument* instr)
270 {
271     int i, n;
272 
273     for (i = 0, n = 0; i < ST_NUM_SAMPLES(instr); i++) {
274         if (instr->samples[i].sample.length != 0)
275             n++;
276     }
277     return n;
278 }
279 
280 int st_instrument_num_save_samples(STInstrument* instr)
281 {
282     int i, n;
283 
284     for (i = 0, n = 0; i < ST_NUM_SAMPLES(instr); i++) {
285         if (instr->samples[i].sample.length != 0 || instr->samples[i].utf_name[0] != 0)
286             n = i + 1;
287     }
288     return n;
289 }
290 
291 gsize
292 st_get_instrument_size(STInstrument* instr)
293 {
294     gint i;
295     gsize s;
296 
297     for (i = 0, s = 0; i < ST_NUM_SAMPLES(instr); i++)
298         /* Length in samples which are internally in 2-bytes format */
299         s += instr->samples[i].sample.length * sizeof(instr->samples[i].sample.data[0]);
300 
301     return s + sizeof(STInstrument);
302 }
303 
304 int st_num_save_instruments(XM* xm)
305 {
306     int i, n;
307 
308     for (i = 0, n = 0; i < ST_NUM_INSTRUMENTS(xm); i++) {
309         if (st_instrument_num_save_samples(&xm->instruments[i]) != 0 || xm->instruments[i].utf_name[0] != 0)
310             n = i + 1;
311     }
312     return n;
313 }
314 
315 int st_num_save_patterns(XM* xm)
316 {
317     int i, n;
318 
319     for (i = 0, n = 0; i < 256; i++) {
320         if (!st_is_empty_pattern(&xm->patterns[i]))
321             n = i;
322     }
323 
324     return n + 1;
325 }
326 
327 void st_copy_instrument(STInstrument* src, STInstrument* dest)
328 {
329     int i;
330     guint32 length;
331     GMutex lock[ST_NUM_SAMPLES(src)];
332 
333     st_clean_instrument(dest, NULL);
334 
335     for (i = 0; i < ST_NUM_SAMPLES(dest); i++)
336         lock[i] = dest->samples[i].sample.lock; /* Preserve GMutex'es from modification */
337     memcpy(dest, src, sizeof(STInstrument));
338     for (i = 0; i < ST_NUM_SAMPLES(dest); i++) {
339         if ((length = dest->samples[i].sample.length * sizeof(dest->samples[i].sample.data[0]))) {
340             dest->samples[i].sample.data = malloc(length);
341             memcpy(dest->samples[i].sample.data, src->samples[i].sample.data, length);
342         }
343         dest->samples[i].sample.lock = lock[i];
344     }
345 }
346 
347 void st_clean_instrument_full(STInstrument* instr,
348     const char* name, const gboolean modify_name)
349 {
350     int i;
351 
352     for (i = 0; i < ST_NUM_SAMPLES(instr); i++)
353         st_clean_sample_full(&instr->samples[i], NULL, NULL, modify_name);
354 
355     if (modify_name) {
356         if (!name) {
357             memset(instr->name, 0, sizeof(instr->name));
358             memset(instr->utf_name, 0, sizeof(instr->utf_name));
359             instr->needs_conversion = FALSE;
360         } else {
361             g_utf8_strncpy(instr->utf_name, name, sizeof(instr->name) - 1);
362             instr->needs_conversion = TRUE;
363         }
364     }
365     memset(instr->samplemap, 0, sizeof(instr->samplemap));
366     memset(&instr->vol_env, 0, sizeof(instr->vol_env));
367     memset(&instr->pan_env, 0, sizeof(instr->pan_env));
368     instr->vol_env.num_points = 1;
369     instr->vol_env.points[0].val = 64;
370     instr->pan_env.num_points = 1;
371     instr->pan_env.points[0].val = 32;
372 }
373 
374 void st_set_sample_name(STSample* s,
375     const char* name)
376 {
377     g_utf8_strncpy(s->utf_name, name, sizeof(s->name) - 1);
378     s->needs_conversion = TRUE;
379 }
380 
381 void st_clean_sample_full(STSample* s,
382     const char* utf_name, const char* name,
383     const gboolean clear_name)
384 {
385     free(s->sample.data);
386     s->sample.data = NULL;
387     s->sample.looptype = 0;
388     s->sample.length = 0;
389     s->sample.loopend = 1;
390     s->sample.loopstart = 0;
391     s->volume = 0;
392     s->finetune = 0;
393     s->panning = 0;
394     s->relnote = 0;
395     s->treat_as_8bit = 0;
396 
397     if (clear_name) {
398         if (utf_name) {
399             g_utf8_strncpy(s->utf_name, utf_name, sizeof(s->name) - 1);
400             if (!name)
401                 s->needs_conversion = TRUE;
402             else {
403                 strncpy(s->name, name, sizeof(s->name) - 1);
404                 s->needs_conversion = FALSE;
405             }
406         } else {
407             memset(s->utf_name, 0, sizeof(s->utf_name));
408             memset(s->name, 0, sizeof(s->name));
409             s->needs_conversion = FALSE;
410         }
411     }
412 }
413 
414 void st_copy_sample(STSample* src_smp, STSample* dest_smp)
415 {
416     guint32 length;
417     GMutex lock = dest_smp->sample.lock;
418 
419     if (dest_smp->sample.data)
420         g_free(dest_smp->sample.data);
421     memcpy(dest_smp, src_smp, sizeof(STSample));
422     dest_smp->sample.lock = lock;
423     length = sizeof(dest_smp->sample.data[0]) * dest_smp->sample.length;
424     dest_smp->sample.data = malloc(length);
425     memcpy(dest_smp->sample.data, src_smp->sample.data, length);
426 }
427 
428 void st_clean_song(XM* xm)
429 {
430     int i;
431 
432     st_free_all_pattern_channels(xm);
433 
434     xm->song_length = 1;
435     xm->restart_position = 0;
436     xm->num_channels = 8;
437     xm->tempo = 6;
438     xm->bpm = 125;
439     xm->flags = 0;
440     memset(xm->pattern_order_table, 0, sizeof(xm->pattern_order_table));
441 
442     for (i = 0; i < 256; i++)
443         st_init_pattern_channels(&xm->patterns[i], 64, xm->num_channels);
444 }
445 
446 void st_set_num_channels(XM* xm,
447     int n)
448 {
449     int i, j;
450     XMPattern* pat;
451 
452     for (i = 0; i < ST_NUM_PATTERNS(xm); i++) {
453         pat = &xm->patterns[i];
454         for (j = 0; j < n; j++) {
455             if (!pat->channels[j]) {
456                 pat->channels[j] = calloc(1, sizeof(XMNote) * pat->alloc_length);
457             }
458         }
459     }
460 
461     xm->num_channels = n;
462 }
463 
464 void st_set_pattern_length(XMPattern* pat,
465     int l)
466 {
467     int i;
468     XMNote* n;
469 
470     if (l > pat->alloc_length) {
471         for (i = 0; i < 32 && pat->channels[i] != NULL; i++) {
472             n = calloc(1, sizeof(XMNote) * l);
473             memcpy(n, pat->channels[i], sizeof(XMNote) * pat->length);
474             free(pat->channels[i]);
475             pat->channels[i] = n;
476         }
477         pat->alloc_length = l;
478     }
479 
480     pat->length = l;
481 }
482 
483 void st_sample_fix_loop(STSample* sts)
484 {
485     st_mixer_sample_info* s = &sts->sample;
486 
487     if (s->loopend > s->length)
488         s->loopend = s->length;
489     else if (!s->loopend)
490         s->loopend = 1;
491     if (s->loopstart >= s->loopend)
492         s->loopstart = s->loopend - 1;
493 }
494 
495 int st_find_first_unused_and_empty_pattern(XM* xm)
496 {
497     int i;
498 
499     for (i = 0; i < ST_NUM_PATTERNS(xm); i++) {
500         if (!st_is_pattern_used_in_song(xm, i) && st_is_empty_pattern(&xm->patterns[i])) {
501             return i;
502         }
503     }
504 
505     return -1;
506 }
507 
508 gboolean
509 st_is_empty_pattern(XMPattern* p)
510 {
511     int i;
512 
513     for (i = 0; i < 32; i++) {
514         if (p->channels[i]) {
515             if (!st_is_empty_track(p->channels[i], p->length)) {
516                 return 0;
517             }
518         }
519     }
520 
521     return 1;
522 }
523 
524 gboolean
525 st_is_empty_track(XMNote* notes,
526     int length)
527 {
528     for (; length > 0; length--, notes++) {
529         if (notes->note != 0 || notes->instrument != 0 || notes->volume != 0
530             || notes->fxtype != 0 || notes->fxparam != 0) {
531             return 0;
532         }
533     }
534 
535     return 1;
536 }
537 
538 gboolean
539 st_is_pattern_used_in_song(XM* xm,
540     int patnum)
541 {
542     int i;
543 
544     for (i = 0; i < xm->song_length; i++)
545         if (xm->pattern_order_table[i] == patnum)
546             return 1;
547 
548     return 0;
549 }
550 
551 void st_exchange_patterns(XM* xm,
552     int p1,
553     int p2)
554 {
555     XMPattern tmp;
556     int i;
557 
558     memcpy(&tmp, &xm->patterns[p1], sizeof(XMPattern));
559     memcpy(&xm->patterns[p1], &xm->patterns[p2], sizeof(XMPattern));
560     memcpy(&xm->patterns[p2], &tmp, sizeof(XMPattern));
561 
562     for (i = 0; i < xm->song_length; i++) {
563         if (xm->pattern_order_table[i] == p1)
564             xm->pattern_order_table[i] = p2;
565         else if (xm->pattern_order_table[i] == p2)
566             xm->pattern_order_table[i] = p1;
567     }
568 }
569 
570 gboolean
571 st_check_if_odd_are_not_empty(XMPattern* p)
572 {
573     int i, j;
574 
575     for (i = 0; i < 32 && p->channels[i]; i++)
576         for (j = 1; j < p->length; j += 2)
577             if ((p->channels[i][j].note && p->channels[i][j].instrument) || (p->channels[i][j].volume > 15) || p->channels[i][j].fxtype || p->channels[i][j].fxparam)
578                 return TRUE;
579 
580     return FALSE;
581 }
582 
583 void st_shrink_pattern(XMPattern* p)
584 {
585     int i, j, length = p->length;
586 
587     for (i = 0; i < 32 && p->channels[i]; i++) {
588         for (j = 1; j <= (length - 1) / 2; j++)
589             memcpy(&p->channels[i][j], &p->channels[i][2 * j], sizeof(XMNote));
590         for (; j < p->alloc_length; j++) { /* clear the rest of the pattern */
591             p->channels[i][j].note = 0;
592             p->channels[i][j].instrument = 0;
593             p->channels[i][j].volume = 0;
594             p->channels[i][j].fxtype = 0;
595             p->channels[i][j].fxparam = 0;
596         }
597     }
598 
599     st_set_pattern_length(p, (length - 1) / 2 + 1);
600 }
601 
602 void st_expand_pattern(XMPattern* p)
603 {
604     int i, j, length = MIN(p->length * 2, 256);
605 
606     st_set_pattern_length(p, length);
607 
608     for (i = 0; i < 32 && p->channels[i]; i++) {
609         for (j = length / 2 - 1; j >= 0; j--) {
610             /* copy to even positions and clear odd */
611             memcpy(&p->channels[i][2 * j], &p->channels[i][j], sizeof(XMNote));
612             p->channels[i][2 * j + 1].note = 0;
613             p->channels[i][2 * j + 1].instrument = 0;
614             p->channels[i][2 * j + 1].volume = 0;
615             p->channels[i][2 * j + 1].fxtype = 0;
616             p->channels[i][2 * j + 1].fxparam = 0;
617         }
618     }
619 }
620 
621 void st_convert_sample(void* src,
622     void* dst,
623     int srcformat,
624     int dstformat,
625     int count)
626 {
627     gint16* d16;
628     gint8* d8;
629 
630     if (srcformat == dstformat) {
631         memcpy(dst, src, count * (srcformat / 8));
632     } else {
633         if (dstformat == 16) {
634             /* convert to 16 bit */
635             d16 = dst;
636             d8 = src;
637             while (count--)
638                 *d16++ = (*d8++ << 8);
639         } else {
640             /* convert to 8 bit */
641             d8 = dst;
642             d16 = src;
643             while (count--)
644                 *d8++ = (*d16++ >> 8);
645         }
646     }
647 }
648 
649 void st_sample_8bit_signed_unsigned(gint8* data,
650     int count)
651 {
652     while (count) {
653         *data++ += 128;
654         count--;
655     }
656 }
657 
658 void st_sample_16bit_signed_unsigned(gint16* data,
659     int count)
660 {
661     while (count) {
662         *data++ += 32768;
663         count--;
664     }
665 }
666