source: vital-to8-sdk/music/mod/player_module.c @ 1

Last change on this file since 1 was 1, checked in by svn, 5 years ago

Import initial

File size: 21.3 KB
Line 
1/***********************************************************************/
2/* a mod player that will make your ears bleed                         */
3/* corrected a bit and converted for interrupt based interface         */
4/* derives from an unfinished mod to Sparc raw player by               */
5/* Liam Corner - zenith@dcs.warwick.ac.uk                              */
6/* Marc Espie - espie@dmi.ens.fr                                       */
7/***********************************************************************/
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <malloc.h>
12
13
14/**********************************************************/
15/* uS is the number of uSeconds that a byte is played for */
16/* Sparc plays at 8000 bytes/sec  =>  1 byte = 125 uSec   */
17/* VSYNC is the number of bytes played in 1/50 sec        */
18/* ie 0.02/(uS * 10**-6)                                  */
19/* here we replay by default at 44100 Hz                  */
20/**********************************************************/
21
22#define uS ((1.0/44100)*1000000)
23#define VSYNC 882
24#define AUDIO "./out.raw"
25
26
27#define MAX_CHANEL      16
28 
29#define MIN(A,B) ((A)<(B) ? (A) : (B))
30#define MAX(A,B) ((A)>(B) ? (A) : (B))
31 
32 
33typedef struct {    /***********************************/
34  char name[256];
35  signed char *info;       /* Sample                          */
36  int length;       /* Length of sample                */
37  float volume;     /* Fractional volume 0-1 (min-max) */
38  int rep_start;    /* Byte offset of repeat start     */
39  int rep_end;      /* Byte offset of repeat end       */
40} Voice;            /***********************************/
41 
42 
43typedef struct {                 /**************************/
44  unsigned char sample [64][MAX_CHANEL];           /* Sample number          */
45  unsigned char effect [64][MAX_CHANEL];           /* Effect number          */
46  unsigned char params [64][MAX_CHANEL];  /* Effect parameters      */
47  unsigned int period [64][MAX_CHANEL];            /* Period (pitch) of note */
48} Pattern;                       /**************************/
49 
50 
51typedef struct {         /***********************************************/
52  char samp;             /* Sample number of current note               */
53  int pitch;             /* Current channel pitch (index to step_table) */
54  int slide;             /* Step size of pitch slide (if any)           */
55  int doslide;
56  unsigned int pointer;  /* Current sample position                     */
57  unsigned int step;     /* Sample offset increment (gives pitch)       */
58  float volume;          /* Fractional volume of current note           */
59  float volslide;
60  int doslidevol;
61  int doporta;
62  int pitchgoal;
63  int portarate;
64} Channel;               /***********************************************/
65
66typedef struct {
67        int patnum;
68        int curpat;
69        int note;
70        int vbl;
71        int sample;
72        int speed;
73} Playbuf;
74
75
76/****************************************************************************/
77/* Skips the next 'n' input bytes - because fseek won't work on stdin       */
78/****************************************************************************/
79void byteskip (fp, bytes)
80FILE *fp;
81int bytes;
82    {
83    int loop;
84 
85    for (loop = 0; loop < bytes; loop++)
86        getc(fp);
87    }
88 
89 
90 
91char *getstring(f, len)
92FILE *f;
93int len;
94    {
95    static char s[150];
96    int i;
97 
98    for (i = 0; i < len; i++)
99        s[i] = fgetc(f);
100    s[len] = '\0';
101    return s;
102    }
103 
104#define OLD 0
105#define NEW 1
106
107int step_table[1024];
108
109/***********************************************************************/
110/* Creates a table of the byte_step << 16 for a given pitch            */
111/* The step and pointer are stored << 16 to get accuracy without floats*/
112/* eg to get double pitch only play every other byte                   */
113/* so step of 0x10000 is normal pitch, 0x8000 is half,                 */
114/* 0x20000 is double.  Pointer is >> 16 when accessed,                 */
115/* so 0x10000 is 1st byte, 0x20000 2nd etc                             */
116/* I have no idea where the other numbers are from, I copied them from */
117/* a SoundTracker player for the Acorn Archimedes                      */
118/*                                                                     */
119/* Actually, these other numbers are highly dependent on the amiga hw. */
120/***********************************************************************/
121void init_step_table(void) {
122        int loop;
123    float dummy1, dummy2;
124
125    step_table[0] = 0;
126    for (loop = 1; loop < 1024; loop++)
127        {
128        dummy1 = 3575872 / loop;
129        dummy2 = (dummy1 / (1000000 /uS) ) * 60000;
130        step_table[loop] = (int)dummy2;
131        }
132}
133
134/* song data */
135char tune[128];
136Voice voices[32];
137Pattern patterns[128];
138int chanel_nb=4;
139
140/* the playing status */
141Channel ch[MAX_CHANEL];
142Playbuf where;
143
144int type;   /* module type: old or new */
145int nvoices;
146char songlength;
147 
148int load_module(char *filename)
149    {
150    FILE *fp;
151    int loop;
152    int notes, note, channel, vsync;
153    int pat, pat_num;
154    int byte, bytes;
155    int speed=6;                      /* Default speed is 6 */
156    int end_pattern=0;
157    char num_patterns=0;
158    unsigned char ulaw;
159    int effect;
160        char signature[4+1];
161 
162        type = NEW;
163
164 
165    if (type == OLD)
166        nvoices = 15;
167    else
168        nvoices = 31;
169 
170 
171 
172    fp = fopen(filename, "rb");
173   
174    if (fp == NULL)
175        {
176        fprintf(stderr, "unable to open tune file %s\n",
177            filename);
178                        return 0;
179        }
180 
181        /* check for signature at some obscure offset... */
182        fseek(fp,20+31*30+2+128,SEEK_SET);
183        signature[0]=fgetc(fp);
184        signature[1]=fgetc(fp);
185        signature[2]=fgetc(fp);
186        signature[3]=fgetc(fp);
187        signature[4]='\0';
188
189       
190        if (strcmp(signature,"M.K.")==0) {
191        nvoices = 31;
192                chanel_nb=4;
193        } else
194        if (strcmp(signature,"6CHN")==0) {
195        nvoices = 31;
196                chanel_nb=6;
197        } else
198        if (strcmp(signature,"8CHN")==0) {
199        nvoices = 31;
200                chanel_nb=8;
201        } else {
202        nvoices = 15;
203                chanel_nb=4;
204        }
205       
206        printf("Signature %s\n",signature);
207       
208        fseek(fp,0,SEEK_SET);
209       
210        /* read song name */
211    printf("Module : %s\n\n", getstring(fp, 20));
212 
213        /* Reads in the sample-information tables */
214    for (loop = 1; loop <= nvoices; loop++)
215        {
216                sprintf(voices[loop].name,"%s",getstring(fp, 22));
217        // printf("%6d : %s\n", loop, voices[loop].name);
218        voices[loop].length = ( (getc(fp) << 8) | getc(fp) ) * 2;
219        getc(fp);
220        voices[loop].volume = getc(fp);
221        voices[loop].volume = MIN(voices[loop].volume, 64);
222        voices[loop].volume /= 64;   /* Volume is a fraction */
223        voices[loop].rep_start = ( (getc(fp) << 8) | getc(fp) ) * 2;
224        voices[loop].rep_end = ( (getc(fp) << 8) | getc(fp) ) * 2;
225        if (voices[loop].rep_end <= 4)
226            voices[loop].rep_end = 0;
227        else
228            {
229                                voices[loop].rep_end = MIN(voices[loop].rep_end,voices[loop].length);
230            }
231        }
232    voices[0].length = 0;
233 
234    songlength = getc(fp);
235    byteskip(fp, 1);
236 
237        /* Reads in the tune */
238    for (loop = 0; loop < 128; loop++)
239        {
240        tune[loop] = getc(fp);
241        if (tune[loop] > num_patterns)
242            num_patterns = tune[loop];
243        }
244    num_patterns++;
245 
246        /* skip over sig (usually M.K.) */
247    if (type == NEW)
248        byteskip(fp,4);
249 
250        /* Reads in the patterns */
251    for (pat_num = 0; pat_num < num_patterns; pat_num++)
252        {
253            /* 64 notes per pattern  */
254        for (notes = 0; notes < 64; notes++)
255            {
256                /* 4 channels per note   */
257            for (channel = 0; channel < chanel_nb; channel++)
258                {
259                note = (getc(fp) << 24) | (getc(fp) << 16) |
260                    (getc(fp) << 8) | getc(fp);
261                (patterns[pat_num]).effect[notes][channel] =
262                    (note & 0xF00) >> 8;
263                (patterns[pat_num]).params[notes][channel] = note & 0xFF;
264                (patterns[pat_num]).sample[notes][channel] =
265                    ( (note & 0xF000) >> 12) | ( (note >> 24) & 0x10);
266                (patterns[pat_num]).period[notes][channel] =
267                    MIN( (note & 0xFFF0000) >> 16, 1023);
268                }
269            }
270        }
271 
272        /* Stores the samples voices as an array of char */
273    for (loop = 1; loop <= nvoices; loop++)
274        {
275        voices[loop].info = malloc(voices[loop].length);
276        if (voices[loop].info == NULL)
277            {
278            fprintf(stderr, "unable to allocate memory\n");
279            exit(1);
280            }
281        fread(voices[loop].info, 1, voices[loop].length, fp);
282        }
283        return -1;
284}
285
286void
287next_pattern() {
288        int loop;
289        where.curpat = tune[where.patnum];
290    for (loop = 0; loop < chanel_nb; loop++) {
291                ch[loop].samp=0;
292                ch[loop].pointer = 0;
293        ch[loop].step = 0;
294        ch[loop].volume = 0;
295        ch[loop].pitch = 0;
296    }
297    // fprintf(stderr,"New pattern %X %X\n",where.patnum,where.curpat);
298}
299
300void
301next_note() {
302        int samp, pitch, cmd, para;
303        int channel;
304    int end_pattern=0;
305       
306    for (channel = 0; channel < chanel_nb; channel++) {
307                samp = patterns[where.curpat].sample[where.note][channel];
308                pitch = patterns[where.curpat].period[where.note][channel];
309                cmd = patterns[where.curpat].effect[where.note][channel];
310                para = patterns[where.curpat].params[where.note][channel];
311                if (samp)
312                {
313                        ch[channel].samp = samp;
314                        /* load new instrument */
315                        ch[channel].volume = voices[ch[channel].samp].volume;
316                        // fprintf(stderr,"New note %X %X\n",samp,pitch);
317                }
318                                                       
319                /* If sample number=0 and no new period */
320                /* continue last note */
321                if (pitch && cmd != 3) {
322                        ch[channel].pointer = 0;
323                        ch[channel].step = step_table[pitch];
324                        ch[channel].pitch = pitch;
325                }
326                                       
327                ch[channel].doslide = 0;
328                ch[channel].doslidevol = 0;
329                ch[channel].doporta = 0;
330                                       
331                /* Do effects */
332                switch(cmd) {
333                case 0xF :
334                        if (para<=32) {
335                                where.speed = para;
336                        } else {
337                                where.speed = (750)/(para);
338                        }
339                                fprintf(stderr,"speed is %d\n",where.speed);
340                        break;
341                case 0xD :
342                        end_pattern = 1;
343                        break;
344                case 0xC :
345                        ch[channel].volume= MIN(para, 64);
346                        ch[channel].volume /= 64;
347                        break;
348                /* volume_slicur_chunk_indexde */
349                case 0xB :
350                        where.patnum = (para & 0xF) + (10 * (para >> 4));
351                        where.note=0;
352                        break;
353                case 0xA :
354                        ch[channel].doslidevol = 1;
355                        if (para) {
356                                if (para & 15)
357                                        ch[channel].volslide = - para / 64;
358                                else
359                                        ch[channel].volslide = (para >> 4)/64;
360                        }
361                        break;
362                case 0x3 :
363                        ch[channel].doporta = 1;
364                        if (para)
365                                ch[channel].portarate = para;
366                        if (pitch)
367                                ch[channel].pitchgoal = pitch;
368                        break;
369                case 0x2   :
370                        ch[channel].doslide = 1;
371                        if (para)
372                                ch[channel].slide = para;
373                        break;
374                case 0x1   :
375                        ch[channel].doslide = 1;
376                        if (para)
377                                ch[channel].slide = -para;
378                        break;
379                case 0x0   :
380                        break;
381                default  :
382                                                /* printf(" [%d][%d] ", cmd, para); */
383                break;
384                } // of switch effect
385    } // of for channel
386    if (end_pattern) {
387                where.note=63;
388        }
389}
390
391void play_start(void) {
392        int loop;
393       
394    for (loop = 0; loop < chanel_nb; loop++) {
395                ch[loop].samp=0; /* GFE : added this to avoid nasty core dumps :) */
396        ch[loop].pointer = 0;
397        ch[loop].step = 0;
398        ch[loop].volume = 0;
399        ch[loop].pitch = 0;
400    }
401   
402    init_step_table();
403       
404        where.patnum=0;
405        where.curpat=0;
406        where.note=0;
407        where.sample=0;
408        where.vbl=0;
409        where.speed=6;
410        next_pattern();
411        next_note();
412}
413
414void play_prev_pattern(void) {
415        int loop;
416       
417    for (loop = 0; loop < chanel_nb; loop++) {
418                ch[loop].samp=0;
419        ch[loop].pointer = 0;
420        ch[loop].step = 0;
421        ch[loop].volume = 0;
422        ch[loop].pitch = 0;
423    }
424   
425    init_step_table();
426       
427    if (where.patnum>0) {
428                where.patnum--;
429        }
430       
431        where.curpat=0;
432        where.note=0;
433        where.sample=0;
434        where.vbl=0;
435        next_pattern();
436        next_note();
437}
438
439void play_next_pattern(void) {
440        int loop;
441       
442    for (loop = 0; loop < chanel_nb; loop++) {
443                ch[loop].samp=0;
444        ch[loop].pointer = 0;
445        ch[loop].step = 0;
446        ch[loop].volume = 0;
447        ch[loop].pitch = 0;
448    }
449   
450    init_step_table();
451       
452    if (where.patnum<127) {
453                where.patnum++;
454        }
455       
456        where.curpat=0;
457        where.note=0;
458        where.sample=0;
459        where.vbl=0;
460        next_pattern();
461        next_note();
462}
463
464void
465next_vbl(void) {
466        int channel;
467    for (channel = 0; channel < chanel_nb; channel++) {
468                if (ch[channel].doslide) {
469                        ch[channel].pitch += ch[channel].slide;
470                        ch[channel].pitch = MIN(ch[channel].pitch, 1023);
471                        ch[channel].pitch = MAX(ch[channel].pitch, 113);
472                        ch[channel].step = step_table[ch[channel].pitch];
473                }
474                if (ch[channel].doslidevol) {
475                        ch[channel].volume += ch[channel].volslide;
476                        if (ch[channel].volume < 0.0)
477                                ch[channel].volume = 0.0;
478                        else if (ch[channel].volume >= 1.0)
479                                ch[channel].volume = 1.0;
480                }
481                if (ch[channel].doporta) {
482                        if (ch[channel].pitch < ch[channel].pitchgoal) {
483                                ch[channel].pitch += ch[channel].portarate;
484                                if (ch[channel].pitch > ch[channel].pitchgoal)
485                                        ch[channel].pitch = ch[channel].pitchgoal;
486                        }
487                        else if (ch[channel].pitch > ch[channel].pitchgoal) {
488                                ch[channel].pitch -= ch[channel].portarate;
489                                if (ch[channel].pitch < ch[channel].pitchgoal)
490                                        ch[channel].pitch = ch[channel].pitchgoal;
491                        }
492                }
493        }
494}
495
496void build_chunk(int size,int * buf) {
497    int loop;
498        int byte;
499        int channel;
500             
501    for (loop=0;loop<size;loop++) { 
502                if (where.sample==VSYNC) {
503                        where.sample=0;
504                        next_vbl();
505                        where.vbl++;
506                        if (where.vbl>=where.speed) {
507                                where.vbl=0;
508                                where.note++;
509                                if (where.note==64) {
510                                        where.note=0;
511                                        where.patnum++;
512                                        next_pattern();
513                                }
514                                next_note();
515                        }
516                }
517                where.sample++;
518                byte = 0;
519                for (channel = 0; channel < chanel_nb; channel++) {
520                        if (ch[channel].samp == 0)
521                                continue;
522                        /* If at end of sample jump to rep_start position */
523                        if (voices[ch[channel].samp].rep_end) {
524                                if ((ch[channel].pointer >> 16) >= voices[ch[channel].samp].rep_end) {
525                                        ch[channel].pointer = voices[ch[channel].samp].rep_start << 17;
526                                }
527                        }
528                        else
529                        if ((ch[channel].pointer >> 16) >= voices[ch[channel].samp].length)
530                                continue;
531                               
532                        /* byte = sum of (sample byte * volume) for each */
533                        /* of 4 channels which mixes the sounds          */
534                        if ((ch[channel].pointer >> 16) < voices[ch[channel].samp].length) {
535                                byte += (int) ( (voices[ch[channel].samp].info[ch[channel].pointer >> 16])
536                                                                        * (ch[channel].volume));
537                                ch[channel].pointer += ch[channel].step;
538                        }
539                } // of for channel
540               
541                // clip
542                if (byte>128) byte=128;
543                if (byte<-127) byte=-127;
544               
545                // byte=((byte+127)&0xFC)-127;
546               
547                buf[loop]=byte;
548        }
549}
550
551static char song_text[128*12];
552char * get_song_text(void) {
553        int loop;
554        char buf[256];
555        song_text[0]='\0';
556       
557        for (loop=0;loop<128;loop++) {
558                sprintf(buf,"%3d %3d  \n",loop,tune[loop]);
559                strcat(song_text,buf);
560        }
561        return song_text;
562}
563
564int get_song_pattern(int index) {
565        if ((index<0) || (index>127)) return 0;
566        return tune[index];
567}
568
569static char voice_text[32*256];
570char * get_voice_text(void) {
571        int loop;
572        char buf[256];
573        voice_text[0]='\0';
574       
575        for (loop=0;loop<32;loop++) {
576                sprintf(buf,"%3d %3d  \n",loop,tune[loop]);
577                strcat(voice_text,buf);
578        }
579        return voice_text;
580}
581
582
583/*
584period
585sample
586effect
587params
588*/
589
590/*
591          C    C#   D    D#   E    F    F#   G    G#   A    A#   B
592Octave 0:1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907
593Octave 1: 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453
594Octave 2: 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226
595Octave 3: 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113
596Octave 4: 107, 101,  95,  90,  85,  80,  76,  71,  67,  64,  60,  57
597*/
598char notesLabels[2000][5];
599
600void
601init_notes_labels(void) {
602        int loop;
603       
604        // by default (not real amiga notes)
605        for (loop=0;loop<2000;loop++) {
606                sprintf(notesLabels[loop],"%04d",loop);
607        }
608       
609        strcpy(notesLabels[107],"C4  ");
610        strcpy(notesLabels[101],"C#4 ");
611        strcpy(notesLabels[95],"D4  ");
612        strcpy(notesLabels[90],"D#4 ");
613        strcpy(notesLabels[85],"E4  ");
614        strcpy(notesLabels[80],"F4  ");
615        strcpy(notesLabels[76],"F#4 ");
616        strcpy(notesLabels[71],"G4  ");
617        strcpy(notesLabels[67],"G#4 ");
618        strcpy(notesLabels[64],"A4  ");
619        strcpy(notesLabels[60],"A#4 ");
620        strcpy(notesLabels[57],"B4  ");
621
622        strcpy(notesLabels[214],"C3  ");
623        strcpy(notesLabels[202],"C#3 ");
624        strcpy(notesLabels[190],"D3  ");
625        strcpy(notesLabels[180],"D#3 ");
626        strcpy(notesLabels[170],"E3  ");
627        strcpy(notesLabels[160],"F3  ");
628        strcpy(notesLabels[151],"F#3 ");
629        strcpy(notesLabels[143],"G3  ");
630        strcpy(notesLabels[135],"G#3 ");
631        strcpy(notesLabels[127],"A3  ");
632        strcpy(notesLabels[120],"A#3 ");
633        strcpy(notesLabels[113],"B3  ");
634
635        strcpy(notesLabels[428],"C2  ");
636        strcpy(notesLabels[404],"C#2 ");
637        strcpy(notesLabels[381],"D2  ");
638        strcpy(notesLabels[360],"D#2 ");
639        strcpy(notesLabels[339],"E2  ");
640        strcpy(notesLabels[320],"F2  ");
641        strcpy(notesLabels[302],"F#2 ");
642        strcpy(notesLabels[285],"G2  ");
643        strcpy(notesLabels[269],"G#2 ");
644        strcpy(notesLabels[254],"A2  ");
645        strcpy(notesLabels[240],"A#2 ");
646        strcpy(notesLabels[226],"B2  ");
647
648        strcpy(notesLabels[856],"C1  ");
649        strcpy(notesLabels[808],"C#1 ");
650        strcpy(notesLabels[762],"D1  ");
651        strcpy(notesLabels[720],"D#1 ");
652        strcpy(notesLabels[678],"E1  ");
653        strcpy(notesLabels[640],"F1  ");
654        strcpy(notesLabels[604],"F#1 ");
655        strcpy(notesLabels[570],"G1  ");
656        strcpy(notesLabels[538],"G#1 ");
657        strcpy(notesLabels[508],"A1  ");
658        strcpy(notesLabels[480],"A#1 ");
659        strcpy(notesLabels[453],"B1  ");
660
661        strcpy(notesLabels[1712],"C0  ");
662        strcpy(notesLabels[1616],"C#0 ");
663        strcpy(notesLabels[1525],"D0  ");
664        strcpy(notesLabels[1440],"D#0 ");
665        strcpy(notesLabels[1357],"E0  ");
666        strcpy(notesLabels[1281],"F0  ");
667        strcpy(notesLabels[1209],"F#0 ");
668        strcpy(notesLabels[1141],"G0  ");
669        strcpy(notesLabels[1077],"G#0 ");
670        strcpy(notesLabels[1017],"A0  ");
671        strcpy(notesLabels[961 ],"A#0 ");
672        strcpy(notesLabels[907 ],"B0  ");
673       
674}
675
676char curNote[256];
677char* get_pattern_label(int pat,int note,int channel) {
678        int samp = patterns[pat].sample[note][channel];
679    int pitch = patterns[pat].period[note][channel];
680    int cmd = patterns[pat].effect[note][channel];
681    int para = patterns[pat].params[note][channel];
682   
683    if ((samp == 0) && (cmd == 0) && (para == 0)) {
684                strcpy(curNote,"     .. .. ..");
685                return curNote;
686        }
687        sprintf(curNote,"%s %02d %02X %02X",notesLabels[pitch],samp,cmd,para);
688        return curNote;
689}
690
691static char pattern_line_text[1024];
692char *
693get_pattern_line(int patnum,int note) {
694        int chanel;
695        static int first=1;
696        char buf[1024];
697       
698        if (first) {
699                init_notes_labels();
700                first=0;
701        }
702       
703        pattern_line_text[0]='\0';
704        for (chanel=0;chanel<chanel_nb;chanel++) {
705                sprintf(buf,"%s |",get_pattern_label(patnum,note,chanel));
706                strcat(pattern_line_text,buf);
707        }
708        return pattern_line_text;
709}
710
711
712static char pattern_text[64*1024];
713char * get_pattern_text(int patnum) {
714        int loop;
715        int chanel;
716        char buf[1024];
717        static int first=1;
718        pattern_text[0]='\0';
719       
720        if (first) {
721                init_notes_labels();
722                first=0;
723        }
724       
725        for (loop=0;loop<64;loop++) {
726                sprintf(buf,"%2d ",loop);
727                strcat(pattern_text,buf);
728               
729                for (chanel=0;chanel<chanel_nb;chanel++) {
730                        sprintf(buf,"%s |",get_pattern_label(patnum,loop,chanel));
731                        strcat(pattern_text,buf);
732                }
733                sprintf(buf,"\n");
734                strcat(pattern_text,buf);
735        }
736        return pattern_text;
737}
738
739void
740where_am_i(int *songpos,int * patnum,int * notenum) {
741        *songpos=where.patnum;
742        *patnum=where.curpat;
743        *notenum=where.note;
744}
745
746char *
747get_sample_name(int index) {
748        return voices[index].name;
749}
750
751int
752get_sample_size(int index) {
753        return voices[index].length;   
754}
755
756int
757get_sample_hit(int index) {
758        int song_loop;
759        int note_loop;
760        int chanel_loop;
761        int total=0;
762        for (song_loop=0;song_loop<songlength;song_loop++) {
763                for (note_loop=0;note_loop<64;note_loop++) {
764                        for (chanel_loop=0;chanel_loop<chanel_nb;chanel_loop++) {
765                                if (patterns[tune[song_loop]].sample[note_loop][chanel_loop]==index) {
766                                        total++;
767                                }
768                        }
769                }
770        }
771        return total;
772}
773
774int
775get_sample_pitch_hit(int index) {
776        int song_loop;
777        int note_loop;
778        int chanel_loop;
779        int pitch[1024];
780        int total=0;
781       
782        for (note_loop=0;note_loop<1024;note_loop++) {
783                pitch[note_loop]=0;
784        }
785       
786        for (song_loop=0;song_loop<songlength;song_loop++) {
787                for (note_loop=0;note_loop<64;note_loop++) {
788                        for (chanel_loop=0;chanel_loop<chanel_nb;chanel_loop++) {
789                                if (patterns[tune[song_loop]].sample[note_loop][chanel_loop]==index) {
790                                        pitch[patterns[tune[song_loop]].period[note_loop][chanel_loop]]++;
791                                }
792                        }
793                }
794        }
795
796        for (note_loop=0;note_loop<1024;note_loop++) {
797                if (pitch[note_loop]>0) {
798                        total++;
799                }
800        }
801       
802        return total;
803}
804
805int
806get_nb_sample(void) {
807        return nvoices;
808}
809
810/* will range from -1.0 to 1.0 */
811float* get_sample_preview(int index,int size,int step) {
812        float tab[2048];
813        int loop;
814       
815        if (size>2048) return NULL;
816               
817        for (loop=0;loop<size;loop++) {
818                if (loop*step<voices[index].length) {
819                        tab[loop]=voices[index].info[loop*step]/128.0;
820                } else {
821                        tab[loop]=0.0;
822                }
823        }
824        return tab;
825}
Note: See TracBrowser for help on using the repository browser.