Using routines in a production/demo/game etc
- the essence/gutts of the playback routines are in the following files. So firstly, copy them over to your source code directory:
COPYING -> COPYING.FunktrackerGOLD INSTALL -> README.FunktrackerGOLD
dsp_mixxer.c
dsp_mixxer.h
funkload.c
funkload.h
funktracker.c
funktracker.h
funktracker_defs.h
options.h
- Then write a playback routine for your song. There are two ways you can implement playback- either in foreground as a program, or threaded (background).
- For games like Nighthawk (an X11 game i maintain, my recommendation (and most game/demo writters of Linux X/Svgalib do this), is to contain your effects and playback code in a separate program, and have your main game program talk to it via a pipe: issuing playback and effects commands to it via the pipe. In this instance, the routines run as foreground:
---$-------------
.
#include "funktracker_defs.h"
#include "dsp_mixxer.h"
#include "funktracker.h"
#include "funkload.h"
int main(....)
{
/This value is 128, which is the maximum patterns for the format.
you may like to optimise this for the particular song (songs) you are
playing./
funk_info.funk_pd_size = MAXIMUM_PATTERNS;
/*Opens up the /dev/dsp device, and configures it's output.
set these as required:
sample_rate........... Output sampling rate from 6000 to 44100
sample_precision ..... 8 or 16 bit precision (values 8 or 16)
stereo_flag ........ 0 for mono, 1 for stereo
*/
if(open_dsp(,
<sample_rate>,
<sample_precision>,
<stereo_flag>))
{
load_funk_module("song.fnk");
if(ferr_val == FERR_OK)
{
funk_info.trek_status = PLAY;
funk_init_for_play();
while(funk_info.trek_status == PLAY)
{
/the thing that runs the playback routines, mixxes the channels and
sends the output to /dev/dsp/
virtualmixxer();
/put your pipe mechanics code is in here. You can have a look
at my Nighthawk source code to see how i did this if you like./
}
}
dealloc_funk_mem();
}
close_dsp();
return 1;
}
---$-------------
- For pthreads, (that this funktracker distribution uses): we can implement it as follows:
---$-------------
.
#include <pthreads.h>
#include "funktracker_defs.h"
#include "dsp_mixxer.h"
#include "funktracker.h"
#include "funkload.h"
void *bg_loop(void *arg)
{
while(funk_info.trek_status == PLAY)
virtualmixxer();
return NULL;
}
int main(....)
{
funk_info.funk_pd_size = MAXIMUM_PATTERNS;
if(open_dsp(,
<sample_rate>,
<sample_precision>,
<stereo_flag))
{
load_funk_module("song.fnk");
if(ferr_val == FERR_OK)
{
pthread_t th_a;
funk_info.trek_status = PLAY;
funk_init_for_play();
if(pthread_create(&th_a,NULL,bg_loop,NULL) == 0)
{
void *retval;
while(funk_info.trek_status == PLAY)
{
/ do foreground processing in here/
}
pthread_join(th_a,&retval);
}
}
dealloc_funk_mem();
}
close_dsp();
return 1;
}
---$-------------
- Nb/ the reason why i didn't use pthreads in the game is because X pthreads seems to upset X11 causing X11 to halt the program (probably use to two processes sharing a display id etc). Nb/ that pthreads is safe for curses applications. It's highly likely that it's safe for SVgalib programs as well.
- include or incorporate options.h into your own header files of your game/makefile etc
- if you do use these routines please credit funktracker and me. thanks.
:Jason Nunn
