1 /***************************************************************************
2 ****************************************************************************
3 ****************************************************************************
4 *
5 * FunktrackerGOLD - By Jason Nunn
6 * Copyright (C) 1996,1998 Jason Nunn
7 *
8 * FunktrackerGOLD now comes under the GNU General Public License. Please
9 * read the COPYING notice in this distribution.
10 *
11 * ================================================================
12 *
13 ****************************************************************************
14 ****************************************************************************
15 ***************************************************************************/
16 #include <stdio.h>
17 #include <math.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <sys/ioctl.h>
22 #include <sys/soundcard.h>
23 #include "funktracker_defs.h"
24 #include "funktracker.h"
25 #include "funkload.h"
26 
27 tchmix chmix[MAXIMUM_CHANNELS];
28 
29                    /*00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 */
30 int shift_table[] = {-1,-1,-1,-1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3};
31 int dsp_fp;
32 
33 unsigned long mix_buffer_size;
34 sDD *left_mix_buffer = NULL;
35 sDD *right_mix_buffer = NULL;
36 
37 #pragma pack(1)
38 uDB *final_mix_buffer08 = NULL;
39 uDW *final_mix_buffer16 = NULL;
40 uDD *final_mix_buffer32 = NULL;
41 #pragma pack()
42 
43 #ifdef DIGITAL_ECHOING
44 #define echo_dly_factor  256 /* @ 22050hz*/
45 #define echo_buffer_size (512 * 16)
46 #define echo_mask        (echo_buffer_size - 1)
47 int echo_seg;
48 #endif
49 
50 void DAC0816_channel_mixxer(int chan_no,sDD *lbuf,sDD *rbuf);
51 void DAC1616_channel_mixxer(int chan_no,sDD *lbuf,sDD *rbuf);
52 void (*channel_mixxer)(int,sDD *,sDD *) = DAC0816_channel_mixxer;
53 
54 typedef struct
55 {
56   int precision;
57   int stereo;
58   int fram_min;
59   int frag_min;
60   int fram_max;
61   int frag_max;
62 } tcard_caps;
63 
64 tcard_caps card_caps[] = {
65   { 8,0,   8, 6,  16, 7},
66   { 8,1,   8, 7,  18, 8},
67   {16,0,   8, 8,  24, 9},
68   {16,1,   8, 9,  32,10},
69   { 0,0,   0, 0,   0, 0}
70 };
71 
72 /**************************************************************************
73 *
74 **************************************************************************/
calc_mix_buffer(int bpm)75 void calc_mix_buffer(int bpm)
76 {
77   funk_info.hz_rate = 2 * (bpm / 5);
78   mix_buffer_size =
79     (int)(((double)funk_info.sampling_rate / funk_info.hz_rate) + 0.5);
80 }
81 
init_dsp_buffers(void)82 void init_dsp_buffers(void)
83 {
84 #ifdef DIGITAL_ECHOING
85   register int chan;
86 #endif
87   register int x;
88 
89   calc_mix_buffer(funk_info.bpm_rate);
90   ioctl(dsp_fp,SNDCTL_DSP_RESET);
91   for(x = 0;x < mix_buffer_size;x++)
92   {
93     *(left_mix_buffer + x) = 0;
94     *(right_mix_buffer + x) = 0;
95 
96     if(funk_info.precision == 8)
97       if(funk_info.stereo)
98         *(final_mix_buffer16 + x) = 0;
99       else
100         *(final_mix_buffer08 + x) = 0;
101     else
102       if(funk_info.stereo)
103         *(final_mix_buffer32 + x) = 0;
104       else
105         *(final_mix_buffer16 + x) = 0;
106   }
107 #ifdef DIGITAL_ECHOING
108   for(chan = 0;chan < MAXIMUM_CHANNELS;chan++)
109     for(x = 0;x < echo_buffer_size;x++)
110       *(chmix[chan].echo_buffer + x) = 0;
111 #endif
112   if(funk_info.sample_precision == 8)
113     channel_mixxer = DAC0816_channel_mixxer;
114   else
115     channel_mixxer = DAC1616_channel_mixxer;
116 }
117 
dsp_dealloc_bufs(void)118 void dsp_dealloc_bufs(void)
119 {
120 #ifdef DIGITAL_ECHOING
121   register int x;
122 #endif
123 
124   if(left_mix_buffer != NULL) free(left_mix_buffer);
125   if(right_mix_buffer != NULL) free(right_mix_buffer);
126   if(final_mix_buffer08 != NULL) free(final_mix_buffer08);
127   if(final_mix_buffer16 != NULL) free(final_mix_buffer16);
128   if(final_mix_buffer32 != NULL) free(final_mix_buffer32);
129 
130 #ifdef DIGITAL_ECHOING
131   for(x = 0;x < MAXIMUM_CHANNELS;x++)
132     if(chmix[x].echo_buffer != NULL)
133       free(chmix[x].echo_buffer);
134 #endif
135 }
136 
dsp_alloc_bufs(void)137 int dsp_alloc_bufs(void)
138 {
139   register int s = 1;
140 #ifdef DIGITAL_ECHOING
141   register int x;
142 #endif
143 
144   left_mix_buffer = malloc(mix_buffer_size * sizeof(long));
145   right_mix_buffer = malloc(mix_buffer_size * sizeof(long));
146   if(funk_info.precision == 8)
147     if(funk_info.stereo)
148       final_mix_buffer16 = malloc(mix_buffer_size * 2);
149     else
150       final_mix_buffer08 = malloc(mix_buffer_size * 1);
151   else
152     if(funk_info.stereo)
153       final_mix_buffer32 = malloc(mix_buffer_size * 4);
154     else
155       final_mix_buffer16 = malloc(mix_buffer_size * 2);
156 
157 #ifdef DIGITAL_ECHOING
158   for(x = 0;x < MAXIMUM_CHANNELS;x++)
159     chmix[x].echo_buffer = malloc(echo_buffer_size * 4);
160 #endif
161 
162   if(left_mix_buffer == NULL)
163     s = 0;
164   if(right_mix_buffer == NULL)
165     s = 0;
166   if((final_mix_buffer08 == NULL) &&
167      (final_mix_buffer16 == NULL) &&
168      (final_mix_buffer32 == NULL))
169     s = 0;
170 
171 #ifdef DIGITAL_ECHOING
172   for(x = 0;x < MAXIMUM_CHANNELS;x++)
173     if(chmix[x].echo_buffer == NULL)
174       s = 0;
175 #endif
176   return s;
177 }
178 
179 /**************************************************************************
180 * Open up (blocking) /dev/dsp
181 **************************************************************************/
close_dsp(void)182 void close_dsp(void)
183 {
184   if(dsp_fp != -1)
185   {
186     ioctl(dsp_fp,SNDCTL_DSP_RESET);
187     close(dsp_fp);
188   }
189 }
190 
open_dsp(int srate,int prec,int st)191 int open_dsp(int srate,int prec,int st)
192 {
193   register int frames = 8,fragment = 6;
194 
195   funk_info.no_active_channels = 4;
196   funk_info.sample_precision = 8;
197   funk_info.sampling_rate = srate;
198   funk_info.precision = prec;
199   if(prec == 8)
200     funk_info.funk_card_type = FKCARD_VOX08;
201   if(prec == 16)
202     funk_info.funk_card_type = FKCARD_VOX16;
203   funk_info.stereo = st;
204   if(funk_info.sampling_rate < 6000)
205     funk_info.sampling_rate = 6000;
206   if(funk_info.sampling_rate > 44100)
207     funk_info.sampling_rate = 44100;
208   calc_mix_buffer(MIN_BPM_RATE);
209 
210   if((frames != -1) || (fragment != -1))
211   {
212     register int p = 0;
213 
214     for(;;)
215     {
216       if(!card_caps[p].precision)
217         break;
218       if(card_caps[p].precision == funk_info.precision)
219         if(card_caps[p].stereo == funk_info.stereo)
220         {
221           float sr;
222 
223           sr = ((float)funk_info.sampling_rate - 6000) / (44100 - 6000);
224           frames =
225             (int)rint(sr * (float)(card_caps[p].fram_max -
226             card_caps[p].fram_min)) + card_caps[p].fram_min;
227           fragment =
228             (int)rint(sr * (float)(card_caps[p].frag_max -
229             card_caps[p].frag_min)) + card_caps[p].frag_min;
230           break;
231         }
232       p++;
233     }
234   }
235 
236 #ifdef DIGITAL_ECHOING
237   echo_seg = (echo_dly_factor * funk_info.sampling_rate) / 22050;
238   printf("Digital echoing enabled..\n");
239 #endif
240 
241   printf("Mix length: %d (%dhz)\n",
242     (int)mix_buffer_size,funk_info.sampling_rate);
243   if(dsp_alloc_bufs())
244   {
245     printf("Allocated dsp buffers..\n");
246     dsp_fp = open("/dev/dsp",O_WRONLY,0);
247     if(dsp_fp != -1)
248     {
249       int frag;
250 
251       printf("Opened /dev/dsp: %d bit %s, %d Hz (%d frames @ %d bytes)\n",
252         funk_info.precision,
253         funk_info.stereo == 8 ? "mono" : "stereo",
254         funk_info.sampling_rate,
255         frames,1 << fragment);
256       frag = (frames << 16) + fragment;
257       ioctl(dsp_fp,SNDCTL_DSP_SAMPLESIZE,&(funk_info.precision));
258       ioctl(dsp_fp,SNDCTL_DSP_STEREO,&(funk_info.stereo));
259       ioctl(dsp_fp,SNDCTL_DSP_SPEED,&(funk_info.sampling_rate));
260       ioctl(dsp_fp,SNDCTL_DSP_SETFRAGMENT,&frag);
261       return 1;
262     }
263     else
264       printf("Error: Couldn't open /dev/dsp. Program aborted.\n");
265     dsp_dealloc_bufs();
266   }
267   else
268     printf("Error: Allocating dsp buffers. Program aborted.\n");
269   return 0;
270 }
271 
272 /**************************************************************************
273 080808080808080808080808080808080808080808080808080808080808080808080808080
274 080808080808080808080808080808080808080808080808080808080808080808080808080
275 080808080808080808080808080808080808080808080808080808080808080808080808080
276 *
277 * 08 bit into 16bit unit channel DAC buffer Mixer
278 *
279 * 00
280 * ||_____ loop sample
281 * |______ DAC sample play
282 *
283 080808080808080808080808080808080808080808080808080808080808080808080808080
284 080808080808080808080808080808080808080808080808080808080808080808080808080
285 080808080808080808080808080808080808080808080808080808080808080808080808080
286 **************************************************************************/
DAC0816_channel_mixxer(int chan_no,sDD * lbuf,sDD * rbuf)287 void DAC0816_channel_mixxer(int chan_no,sDD *lbuf,sDD *rbuf)
288 {
289   register unsigned long sample_no;
290   register int sam;
291 #ifdef DIGITAL_ECHOING
292   register long sam_reverb;
293   register unsigned int echo_rpos;
294 
295   echo_rpos = chmix[chan_no].echo_delay * echo_seg;
296 #endif
297 
298   for(sample_no = 0;sample_no < mix_buffer_size;sample_no++)
299   {
300     if(chmix[chan_no].funkctrl & 0x2) {
301 #pragma pack(1)
302       sam = *((sDB *)chmix[chan_no].sample_addr +
303             (unsigned long)chmix[chan_no].sample_ptr);
304 #pragma pack()
305     } else
306       sam = 0;
307 
308 #ifdef DIGITAL_ECHOING
309     sam_reverb = *(chmix[chan_no].echo_buffer +
310                  ((chmix[chan_no].echo_ptr - echo_rpos) & echo_mask));
311     *(chmix[chan_no].echo_buffer +
312      (chmix[chan_no].echo_ptr & echo_mask)) =
313       sam + ((sam_reverb * chmix[chan_no].echo_feedback) >> 4);
314     sam += (sam_reverb * chmix[chan_no].echo_decay) >> 4;
315     chmix[chan_no].echo_ptr++;
316 #endif
317 
318     *(lbuf++) += (sam * chmix[chan_no].left_volume) >>
319       shift_table[funk_info.no_active_channels];
320     *(rbuf++) += (sam * chmix[chan_no].right_volume) >>
321       shift_table[funk_info.no_active_channels];
322     chmix[chan_no].sample_ptr += chmix[chan_no].freq;
323     if(chmix[chan_no].sample_ptr >= chmix[chan_no].length)
324     {
325       if(chmix[chan_no].funkctrl & 0x1)
326         chmix[chan_no].sample_ptr = chmix[chan_no].start;
327       else
328         chmix[chan_no].funkctrl = 0;
329     }
330   }
331 }
332 
333 /**************************************************************************
334 161616161616161616161616161616161616161616161616161616161616161616161616161
335 161616161616161616161616161616161616161616161616161616161616161616161616161
336 161616161616161616161616161616161616161616161616161616161616161616161616161
337 *
338 * 16 bit into 16bit unit channel DAC buffer Mixer
339 *
340 * 00
341 * ||_____ loop sample
342 * |______ DAC sample play
343 *
344 161616161616161616161616161616161616161616161616161616161616161616161616161
345 161616161616161616161616161616161616161616161616161616161616161616161616161
346 161616161616161616161616161616161616161616161616161616161616161616161616161
347 **************************************************************************/
DAC1616_channel_mixxer(int chan_no,sDD * lbuf,sDD * rbuf)348 void DAC1616_channel_mixxer(int chan_no,sDD *lbuf,sDD *rbuf)
349 {
350   register unsigned long sample_no;
351   register int sam,shift_t;
352 #ifdef DIGITAL_ECHOING
353   register long sam_reverb;
354   register unsigned int echo_rpos;
355 
356   echo_rpos = chmix[chan_no].echo_delay * echo_seg;
357 #endif
358 
359   shift_t = 8 + shift_table[funk_info.no_active_channels];
360   for(sample_no = 0;sample_no < mix_buffer_size;sample_no++)
361   {
362     if(chmix[chan_no].funkctrl & 0x2) {
363 #pragma pack(1)
364       sam = *((sDW *)chmix[chan_no].sample_addr +
365             (unsigned long)chmix[chan_no].sample_ptr);
366 #pragma pack()
367     } else
368       sam = 0;
369 #ifdef DIGITAL_ECHOING
370     sam_reverb = *(chmix[chan_no].echo_buffer +
371                  ((chmix[chan_no].echo_ptr - echo_rpos) & echo_mask));
372     *(chmix[chan_no].echo_buffer +
373      (chmix[chan_no].echo_ptr & echo_mask)) =
374       sam + ((sam_reverb * chmix[chan_no].echo_feedback) >> 4);
375     sam += (sam_reverb * chmix[chan_no].echo_decay) >> 4;
376     chmix[chan_no].echo_ptr++;
377 #endif
378     *(lbuf++) += (sam * chmix[chan_no].left_volume) >> shift_t;
379     *(rbuf++) += (sam * chmix[chan_no].right_volume) >> shift_t;
380     chmix[chan_no].sample_ptr += chmix[chan_no].freq;
381     if(chmix[chan_no].sample_ptr >= chmix[chan_no].length)
382     {
383       if(chmix[chan_no].funkctrl & 0x1)
384         chmix[chan_no].sample_ptr = chmix[chan_no].start;
385       else
386         chmix[chan_no].funkctrl = 0;
387     }
388   }
389 }
390 
391 /***************************************************************************
392 * post master volume setting
393 ***************************************************************************/
master_volumed(void)394 void master_volumed(void)
395 {
396   register int no,v;
397 
398   v = funk_info.master_volume + 1;
399   for(no = 0;no < mix_buffer_size;no++)
400   {
401     *(left_mix_buffer + no) = (*(left_mix_buffer + no) * v) >> 8;
402     *(right_mix_buffer + no) = (*(right_mix_buffer + no) * v) >> 8;
403   }
404 }
405 
406 /***************************************************************************
407 * mixxer control (x bit samples mixxed into 8 bit mono output..god help us)
408 ***************************************************************************/
DSPx08_mono_mixxer(void)409 void DSPx08_mono_mixxer(void)
410 {
411   register int no;
412 
413   funk_tracker();
414   for(no = 0;no < funk_info.no_active_channels;no++)
415     channel_mixxer(no,left_mix_buffer,right_mix_buffer);
416   master_volumed();
417   for(no = 0;no < mix_buffer_size;no++)
418   {
419     *(final_mix_buffer08 + no) =
420       (uDB)(((*(left_mix_buffer + no) + *(right_mix_buffer + no)) ^ 0x10000)
421       >> 9);
422     *(left_mix_buffer + no) = 0;
423     *(right_mix_buffer + no) = 0;
424   }
425   write(dsp_fp,final_mix_buffer08,mix_buffer_size);
426 }
427 
428 /***************************************************************************
429 * mixxer control (x bit samples mixxed into 16 bit mono output)
430 ***************************************************************************/
DSPx16_mono_mixxer(void)431 void DSPx16_mono_mixxer(void)
432 {
433   register int no;
434 
435   funk_tracker();
436   for(no = 0;no < funk_info.no_active_channels;no++)
437     channel_mixxer(no,left_mix_buffer,right_mix_buffer);
438   master_volumed();
439   for(no = 0;no < mix_buffer_size;no++)
440   {
441     *(final_mix_buffer16 + no) =
442       (*(left_mix_buffer + no) + *(right_mix_buffer + no)) >> 1;
443     *(left_mix_buffer + no) = 0;
444     *(right_mix_buffer + no) = 0;
445   }
446   write(dsp_fp,final_mix_buffer16,mix_buffer_size * 2);
447 }
448 
449 /***************************************************************************
450 * mixxer control (x bit samples mixxed into 8 bit stereo output)
451 ***************************************************************************/
DSPx08_stereo_mixxer(void)452 void DSPx08_stereo_mixxer(void)
453 {
454   register int no;
455 
456   funk_tracker();
457   for(no = 0;no < funk_info.no_active_channels;no++)
458     channel_mixxer(no,left_mix_buffer,right_mix_buffer);
459   master_volumed();
460   for(no = 0;no < mix_buffer_size;no++)
461   {
462     *(final_mix_buffer16 + no) =
463        ((*(left_mix_buffer + no) ^ 0x8000) & 0xff00) +
464        (((*(right_mix_buffer + no) >> 8) ^ 0x80) & 0x00ff);
465     *(left_mix_buffer + no) = 0;
466     *(right_mix_buffer + no) = 0;
467   }
468   write(dsp_fp,final_mix_buffer16,mix_buffer_size * 2);
469 }
470 
471 /***************************************************************************
472 * mixxer control (x bit samples mixxed into 16 bit stereo output)
473 ***************************************************************************/
DSPx16_stereo_mixxer(void)474 void DSPx16_stereo_mixxer(void)
475 {
476   register int no;
477 
478   funk_tracker();
479   for(no = 0;no < funk_info.no_active_channels;no++)
480     channel_mixxer(no,left_mix_buffer,right_mix_buffer);
481   master_volumed();
482   for(no = 0;no < mix_buffer_size;no++)
483   {
484     *(final_mix_buffer32 + no) =
485       (*(left_mix_buffer + no) << 16) + (*(right_mix_buffer + no) & 0xffff);
486     *(left_mix_buffer + no) = 0;
487     *(right_mix_buffer + no) = 0;
488   }
489   write(dsp_fp,final_mix_buffer32,mix_buffer_size * 4);
490 }
491 
492 /**************************************************************************
493 ***************************************************************************
494 * This routines are hardware dependant routines. that translate real freq.
495 * and volume values into the specific card scalarity.
496 ***************************************************************************
497 **************************************************************************/
DSPi_freq_convert(int chan_no,long rfreq)498 void DSPi_freq_convert(int chan_no,long rfreq)
499 {
500   chmix[chan_no].freq = (double)rfreq / funk_info.sampling_rate;
501 }
502 
DSPi_volume_convert(int chan_no,int rvolume,int balance)503 void DSPi_volume_convert(int chan_no,int rvolume,int balance)
504 {
505   chmix[chan_no].right_volume = (rvolume * balance) >> 8;
506   chmix[chan_no].left_volume = (rvolume * (~balance & 0xff)) >> 8;
507 }
508