APlayer uses add-ons to both the players and agents. To create an add-on will not be mentioned in this document, but it's provided by Be in the BeBook. This document will only describe which function you should have and what they has to do.
The whole interface is object orientated. You need to create your own class, which derives from the APAddOnPlayer or APAddOnAgent, dependent if you creating a player or agent. These two classes derive from the APAddOn class. In this class are some functions that are common to both players and agents. The class you create can then override some virtual functions. Some of these functions has to be overriden, like the GetName() function, but as a general rule, you only need to override the functions you change the default behavior on.
In the constructor of your AddOn class, you need to do something. This is required, else your add-on won't work probably. You has to fill out 3 member variables with some constants. These variables holds the version number of the add-on interface the time you compiled your add-on. APlayer can then see which interface to use. Here is a code snap of what you have to do:
addOnVersion = AP_ADDON_VERSION; playerVersion = AP_PLAYER_VERSION; agentVersion = AP_AGENT_VERSION;
Your add-on needs 3 global functions, which are the Load(), Unload() and GetInstance() functions. In a section below will describe what you have to put in these functions.
Note that all classes starting with a P, like PString and PFile are classes in the PolyKit library. To see the documentation for these classes, download the PolyKit library. Use as many of these classes as you can, because it will then be more easier to port your add-on to another platform.
A player is an add-on that produces some sound. APlayer supports two kinds of players, module and sample player. A module player is a player like a mod or xm player. They parse the data from a module and tells APlayer what to play. They use the APChannel class to do so. There will be an instance of the APChannel class for each channel the player use. These instances can the player get from the virtChannel variable stored in the APAddOnPlayer class.
A sample player is just a player that returns a stream of sample data, e.g. a MP3 or RIFF-WAVE player. APlayer will then play the data as it is.
An agent can be anything. You can plug-in different places in APlayer, even more than one place! An agent can be a scope, a module converter, sound effect generator, e.g. echo or normalizer. See the examples to see how to create different kinds of agents.
All settings is stored in one global settings file. This file is built like the Microsoft Windows registry, with keys and values in it. To access this file, you need to use the PRegistry class in the PolyKit library. See the documentation for this class there.
APlayer has its own tree of keys. In this section I will try to explain how this thee is built and how to use it. In the root key are stored the following keys:
APlayer Players Agents
In the APlayer key all the main settings are stored. These entries are private and should not be used.
The Players key have all the entries for the players which need some. You has to create a subkey in this key with the name of the player, e.g. /Players/SidPlay/ and store your entries in this subkey. If you have a window, you should also store the position and size in the registry when the window is closed and retrieve them again when it opens. The user can then place the windows as he/she want and the windows will open the same places the next time the user uses APlayer. The number of values and subkeys in the player subkey can be as many you want.
The last key, the Agents key, is the same as the Players key, except that it's for agents instead.
You don't need to load the setting file by yourself. APlayer will load it when it starts. There will then be created 2 instances of the PRegistry class in the APGlobalData class. The first one is used as a "use" registry and the second as a "save" registry. You should only use the "use" registry for both read and writes. APlayer will handle the "save" registry by itself, but if you really want to use the "save" registry, you can do it. The diffence is that it will only be the "save" registry that will be written to disk. If you create an entry in the "use" registry, the next time the user starts APlayer, it will be gone. If you instead create the entry in the "save" registry, it will still be there, both in the "use" and "save" registry the next time APlayer is started. If have used the Amiga before, you probably know what I talk about and if not, just use the "use" registry.
void Load(APGlobalData *global);
After your add-on has been loaded into memory, this function will be called. This function is required in your add-on. If you don't have it, an error will show up and your add-on will not be used. You will probably use this function to allocate and initialize some memory. Players will probably initialize the moduletypes it have with the InstallModType() function.
The argument is a pointer to the global data class, where you can find some information and functions you can use. Remember to lock the class with the Lock(), when you access the variables in it. It isn't necessary to lock it if you call the functions in it. You can read about the global class here.
void Unload(APGlobalData *global);
Just before your add-on will be unloaded, this function will be called. You will probally delete the memory you have allocated in the Load() function. The argument is a pointer to the global data class.
APAddOn *GetInstance(APGlobalData *global);
This function is also required. It has to return a pointer to your own add-on class. You have to call the new operator in this function and return the pointer. APlayer will then call the delete operator on the pointer when it's no longer needed. Do NOT make a global instance of your class and then return a pointer to it. You have to dynamic allocate it in this function.
The reason is, that your class can be called several times, e.g. if you have created a player and its playing right now by APlayer. The user will then load another module in the same format. APlayer will then call this function while your player is running. If you create a new instance everytime, you won't have any conflict.
virtual ConfigInfo *GetConfigInfo(void);
If your add-on have a configuration window, you has to override this function. It returns a pointer to a configuration structure. This structure tells APlayer how to show the window. This is different for each platform.
BeOS:
The structure is shown below:
typedef struct ConfigInfo { BView * view; PString regKey; } ConfigInfo;
The view field is a pointer the the view where your whole config window are stored. You usually create a top view with all the buttons as siblings. This view will then be attached to a window. You have to create a new instance with the new operator everytime this function is called. APlayer will then delete the instance when the window is closed.
The regKey field, is a string that tells APlayer where to read and write your settings. This string is only used by APlayer, so it can handle the use, save and cancel buttons in the window. The string can e.g. be "/Players/SidPlay/". All your settings will then be stored in the SidPlay key. See the "Where to store your settings" section above.
virtual uint32 GetCount(void);
This function has to return the number of add-ons you have in your library file. This can be used if you have e.g. more than one player. See the ModTracker example to see how to use this. The default implementation returns 1.
virtual PString GetDescription(uint32 index) = 0;
You has to override this function. It has to return a description of your add-on at the index given. The description will be shown in the settings window, so the user can see what the add-on does. The index starts at 0 and increments by 1 at the time. The number of times this function will be called, depends on the GetCount() function.
virtual PString GetName(uint32 index) = 0;
You has to override this function. It has to return the name of your add-on at the index given. The index starts at 0 and increments by 1 at the time. The number of times this function will be called, depends on the GetCount() function.
virtual ShowInfo *GetShowInfo(void);
Not implemented yet!
virtual uint32 GetSupportFlags(void);
This function has to return some flags that indicates what your add-on supports. This can be if your player support rewind/forward or where your agent what to plug-in. Below is a table over the different flags. Every flag can be or'ed together.
Name | Description |
appSamplePlayer | Set this flag if you create a sample player. If you don't set this flag, a module player is presumed. |
appLoadAddOn | Set this flag if your player is written in C and not 100% C++ or if you have a lot of global variables. This makes sure that your player will be loaded everytime it's needed. If you don't set this flag, your player will only be loaded once, but it can be used a lot more. |
appUseRingBuffer | If your player use a long time to decode the music data, e.g. a MP3 player, it would be a good idea to use a ring buffer. APlayer have one you can use, just set this flag. APlayer will then put the data you return into the ring buffer and administrate the whole thing. |
appDontCloseFile | If you create a sample player and you don't want to read the whole sample into the memory before playing it, you need to use the file pointer to the file. If you set this flag, APlayer won't close the file, which means you can use the file pointer everywhere in your player. APlayer will first close the file when the module is ejected from the memory. |
appRewind | Set this if you support rewind. Your Rewind() function will then be called. |
appForward | Set this if you support forward. Your Forward() function will then be called. |
appSetPosition | If you support both rewind and forward and you can set the position to any position you want, set this flag. The SetSongPosition() function will be called. |
Name | Description |
apaInfoButton | Only one agent can attach here. It will be the first one found. You're agent will be called through the Run() function when the user presses the Info button in the main window. |
apaListEditorButton | Only one agent can attach here. It will be the first one found. You're agent will be called through the Run() function when the user presses the Module List Editor button in the main window. |
apaSampleButton | Only one agent can attach here. It will be the first one found. You're agent will be called through the Run() function when the user presses the Sample button in the main window. |
apaModuleInfoChange | Any number of agents can plug-in here. All the agents will be called everytime the module information changes. The Plugin_ModuleInfoChanged() function will be called when the information change. |
apaAfterInit | Any number of agents can plug-in here. All the agents will be called right after a player has initialized a module. The Plugin_AfterInit() function will be called. |
apaAfterFree | Any number of agents can plug-in here. All the agents will be called right after a module has been thrown out of the memory. The Plugin_AfterFree() function will be called. |
apaAfterInitSong | Any number of agents can plug-in here. All the agents will be called everytime a new subsong has been initialized. The Plugin_AfterInitSong() function will be called. |
apaAfterAddingFiles | Any number of agents can plug-in here. All the agents will be called right after one or more files has been added to the module list. The Plugin_AfterAddingFiles() function will be called. |
apaAfterRemovingFiles | Any number of agents can plug-in here. All the agents will be called right after one or more files has been removed from the module list. The Plugin_AfterRemovingFiles() function will be called. |
apaBeforeCheck | Any number of agents can plug-in here. All the agents will be called just before the module check begins. Module converters and/or depackers usually plug-in here and then convert/depack the module. The Plugin_BeforeCheck() function will be called. |
apaVirtualMixer | If you want a virtual mixer allocated for you, just set this flag. You then need to override the Plugin_InitMixer(), Plugin_EndMixer() and Plugin_DoMixing() functions too. |
virtual float GetVersion(void);
Override this function if you have a version. The function has to return the version as a floating point number. This version number is shown in the settings window under the Players or Agents tab. Here can the user see the versions of the different add-ons. The default implementation returns 0.0.
virtual PString GetModTypeString(uint32 index);
This function will return the module type as a string. This string is not the same on the different platforms. On BeOS, the string is a mimetype, e.g. audio/x-mod. The default implementation returns an empty string. To associate an icon to the module type, use the InstallModType() function in the APGlobalData class.
virtual void EndPlayer(void);
This function will only be called once, just before the module will be freed from the memory. You can cleanup what you have made in the InitPlayer() function. The default implementation does nothing.
virtual void EndSound(void);
This function is called every time a new song has to be stopped, e.g. just before a new subsong is started. The default implementation does nothing.
virtual ap_result ExtraLoad(PString fileName);
If your player require some extra files to be loaded, e.g. if the module is splitted in two or more files, you can override this function. The argument is the filename of the file the user have selected with full path. You can use the OpenExtraFile() function to help you to find the other files needed. If you could locate and load the extra files without any problems, return AP_OK, else return AP_ERROR. The default implementation does nothing, it just returns AP_OK.
virtual bool Forward(void);
Not implemented yet!
virtual PString GetAuthor(void);
If you can get the author of the module in your player, you can override this function. It returns the author of the module as a string. If you return an empty string, APlayer will try to scan all the sample names after a possible author and if found show it, else the Module Info window will show "Unknown" instead. However, this functionality isn't implemented yet, but will as soon the sample info is implemented. The default implementation returns an empty string.
virtual uint32 GetInfoCount(void);
If you want to show some extra information in the module info window, you can override this function together with the GetInfoString() function. This extra information can e.g. be the length of the song, the sample rate used etc. This function has to return the number of lines of extra information you have. The default implementation returns 0.
virtual uint32 GetInstrumentCount(void);
If your player have support for instruments and you want to show them to the user in the sample info window, you can override this function together with the GetInstrumentInfo() function. This function have to return the number of instrument the current module loaded have. The GetInstrumentInfo() function will then be called for each instrument. The default implementation returns 0.
virtual void GetInstrumentInfo(uint32 num, APInstInfo *info);
If your player have support for instruments and you want to show them to the user in the sample info window, you can override this function together with the GetInstrumentCount() function. This function will be called for each instrument you have. An APInstInfo structure is allocated and your function is called. You then need to fill out this structure with the instrument information according to the number to get as the argument. The structure have these fields:
Name | Type | Description |
name | PString | This is the name of the instrument. If the instrument doesn't have any name, empty the string. |
flags | uint32 | Set this to one or more of the flags defined. At the moment there isn't defined any flags, so write 0 it this field. |
notes | int16[10*12] | Fill out this array with sample numbers. Each element in the array is the same as a single note. If the instrument supports more than one sample per instrument, this can be useful. You can also store -1, which means that the current note isn't used. |
virtual PString GetInfoString(uint32 line, ap_infoType type);
If you want to show some extra information in the module info window, you can override this function together with the GetInfoCount() function. This extra information can e.g. be the length of the song, the sample rate used etc. This function has to return a string with the information.
The information to return, is indicated by the arguments. The first argument is the line starting from 0 and the last argument is the type of the string. The type can be apDescription or apValue. If type is apDescription, you has to return a string that describe the information, e.g. "Song length:". If type is apValue, you has to return what the value of the current line is, e.g. "42".
virtual uint16 GetModuleChannels(void);
This function has to return the number of channels the module uses. You don't need this function and if you don't override it, the default implementation will return the number of channels returned by the GetVirtualChannels() function. The ImpulseTracker player uses this function, because it have the New Note Action system.
virtual PString GetModuleName(void);
If you can get the name of the module in your player, you can override this function. It returns the name of the module as a string. If you return an empty string, the Module Info window will just show the filename instead. The default implementation returns an empty string.
virtual uint32 GetSampleCount(void);
If your player have support for samples and you want to show them to the user in the sample info window, you can override this function together with the GetSampleInfo() function. This function have to return the number of samples the current module loaded have. The GetSampleInfo() function will then be called for each sample. The default implementation returns 0.
virtual void GetSampleInfo(uint32 num, APSampleInfo *info);
If your player have support for samples and you want to show them to the user in the sample info window, you can override this function together with the GetSampleCount() function. This function will be called for each sample you have. An APSampInfo structure is allocated and your function is called. You then need to fill out this structure with the sample information according to the number to get as the argument. The structure have these fields:
Name | Type | Description |
name | PString | This is the name of the sample. If the sample doesn't have any name, empty the string. |
flags | uint32 | Set this to one or more of the flags defined. See below for the flags you can use. |
type | APSampType | This is the type of the sample. At the moment, you can use one of these types: apSample, apAM, apFM, apHybrid and apAdlib. |
bitSize | uint8 | This is the number of bits the sample is in. Only 8 and 16 is supported at the moment. |
middleC | uint32 | This is the frequency of the middle C, also known as the C-4. Include finetune calculation when you calculate this value. |
volume | uint16 | Set this to the volume the sample is played with as default. The value can be between 0 and 256. |
panning | int16 | Set this to the panning the sample is played with as default. The value can be between 0 and 256. If your player doesn't support panning, store -1 in this field. |
address | void * | This is the address to the sample in memory. |
length | uint32 | Set this to the length of your sample in samples, not bytes. |
loopStart | uint32 | Set this to the loop start point in the sample. The offset has to be stored in samples, not bytes. |
loopLength | uint32 | This is the number of samples to loop. Note that it's has to be stored in samples, not bytes. |
In the flag field in the above structure, you can use one of more of these values. You can just or them together.
Flag | Description |
APSAMP_LOOP | Set this if the sample is looping. |
APSAMP_PINGPONG | Set this if the sample have ping-pong looping. Note that you also need to set the APSAMP_LOOP together with this one if you want to enable the looping. |
virtual void GetSamplePlayerInfo(SamplePlayerInfo *sampInfo);
You only need this function if you making a sample player. APlayer will call this function after the InitPlayer() function. You have to fill out the structure given by the argument. The structure have this format:
Name | Type | Description |
bitSize | uint16 | Set this to the bit size of the stream you return. Only 8 and 16 are supported at the moment. |
frequency | uint32 | This is the frequency to play the stream with. If you got an Amiga period, you can use this formula to convert it to a frequency: frequency = 3546895 / period. |
See the APChannel class to see how to tell APlayer what to play. The default implementation of this function, does nothing.
virtual int16 GetSongLength(void);
This function has to return the length of the current subsong. The default implementation returns 0.
If you create a sample player, you can still return a length. You can take the size of the file and divide it with the buffer size you use. The GetSongPosition() function can then return where in the file the player is in buffers.
virtual int16 GetSongPosition(void);
This function has to return the current playing position of the current subsong. The default implementation returns -1, which means it can't be told.
virtual uint16 *GetSubSongs(void);
This function has to return a pointer to an array with 2 uint16. The first element is the number of subsongs there are in the module and the last element is the subsong to start playing counting from 0. The default implementation will return 1 subsong.
virtual uint16 GetVirtualChannels(void);
This function has to return the number of virtual channels you would like to be allocated for you. The default implementation returns 4 channels, because this is the one used most on the Amiga and lot of the players are from the Amiga.
virtual bool InitPlayer(void);
This function will only be called once, exactly after the module has been loaded into the memory. You can make one time initializing code here, like allocate memory etc. You have to return true is every things goes well and false if not. You have to show a PAlert message by yourself to show exactly what went wrong. If you return false, the EndPlayer() function will not be called. The default implementation does nothing, just returns true.
virtual void InitSound(uint16 songNum);
This function is called every time a new song has to be played. The argument is the subsong number starting from 0. If you don't have any subsongs, just ignore the argument. It will always be 0 then. The number of subsongs you have, is returned by the GetSubSongs() function. The default implementation does nothing.
virtual ap_result LoadModule(uint32 index, PFile *file) = 0;
If you returned AP_OK in the ModuleCheck() function, this function will then be called. It has to load the module into the memory. Do not just load the module as one big block, because you don't know how the current CPU aligns structures. Create the structures used by the module and load one field at the time from the file into the structures. There is a lot of helper functions to do that in the PFile class.
The arguments are the index of the player to use. The index starts at 0 and increments by 1 at the time. The last argument is a pointer to a file object, where the current file is opened for reading. You don't need to seek to the start of the file. APlayer does that for you, just before it calls this function.
virtual ap_result ModuleCheck(uint32 index, PFile *file) = 0;
You need to override this function. It has to check the current file to see if it's a supported module type. If it is, return AP_OK and if it isn't, return AP_UNKNOWN. If something went wrong, return AP_ERROR. The arguments are the current player index. The index starts at 0 and increments by 1 at the time. The number of times this function will be called, depends on the GetCount() function. The last argument is a pointer to a file object, where the current file is opened for reading. Remember to seek to the position you want to check, even if it's the start of the file.
virtual void Play(void) = 0;
This is your main player function. In this function you have to parse the module file and play the nodes etc. You must not feed the hardware or call any OS functions to play the sound. Instead you have to use the APChannel class to tell APlayer what to play. APlayer will then feed the hardware.
If you create a module player, your function will be called for every tick, which is with normal speed about 50 times per second. If you create a sample player, your function will be called when a new buffer has to be returned. See the APChannel for more information on how to tell APlayer what to play.
virtual bool Rewind(void);
Not implemented yet!
virtual void SetSongPosition(int16 pos);
If you support rewind and forward, you can override this function. It will get a position between 0 and the song length - 1 as argument and you have to set the position to that. The default implementation does nothing.
void CloseExtraFile(PFile *file); throw (PFileException);
Use this function to close a file opened with the OpenExtraFile() function. It will close the file and cleanup some other stuff. If it failed for some reason, it will throw an exception. The argument is the file returned by the OpenExtraFile() function.
void ChangeModuleInfo(uint32 line, ap_infoType type, PString newString);
If you for some reason want to change some of the information in the Info window, you can call this function. The arguments are the line number you want to change, which type of information (apDescription or apValue) and the string to change the line to.
void ChangePosition(void);
If you create a player with position change, call this function everytime you change the position. APlayer will then call the GetSongPosition() function to get the position and show it in the main window.
uint16 GetBPMTempo(void) const;
This function will calculate the BPM from the playFreq variable. Also see the SetBPMTempo() function.
uint32 GetExtraFilesSize(void);
This function will return the total number of bytes of the extra files loaded.
uint32 GetMixingFrequency(void) const;
If you need the mixing frequency the user has selected in the settings window, you can call this function. This is normally used in sample players.
PFile *OpenExtraFile(PString fileName, PString extension); throw (PFileException);
This function can be used in the ExtraLoad() function if you have any. It will try to open the file with different forms of extensions or prefixes. The arguments are the name of the file to open with full path and the extension to try with. The extension is tried as an extension, but also as a prefix. If it found the file, it will return a pointer to a PFile object. Use this object to read from the file and call the CloseExtraFile() function to close it. If it failed, an exception will be thrown.
void SetBPMTempo(uint16 bpm);
If you have a BPM (Beats Per Minute) value and not a frequency required to change the tempo via the playFreq variable, you can use this function. It will calculate the frequency from the BPM value you give and store it in the playFreq variable.
bool endReached;
If you create a player, it would be nice if you can tell APlayer when the module begins over. To do that, set this variable to true. APlayer then know it's time to load the next module in the list.
float playFreq;
This is the frequency the player runs in. It indicates how often your play function will be called per second. The initialized value is 50. To change the frequency, just store the new value in this variable. If you have a BPM value, you can call the SetBPMTempo() function instead. It will calculate the frequency and store it in this variable.
APChannel **virtChannels;
This is a pointer to a pointer array. Each pointer in this array points to an APChannel object. Use these objects to play the sound. Each object is a channel. The number of channel objects allocated depends on what you returned in the GetVirtualChannels() function in your player.
virtual void EndAgent(void);
This function will only be called once. It will be called just before the instance of your agent will be deleted. You can cleanup anything you have initialized in the InitAgent() function if any. The default implementation does nothing.
virtual int8 GetPluginPriority(uint32 pluginFlag);
If you like your agent to be called before or after other agents, you can use this function to set the priority in the call order. A heigher value means it will be called before all other agents with a lower value. If you don't override this function, your agent will be plugged in with priority 0. The argument is one of the plug-in flags (apaXXXXX) and only one of them at the time. If you plug-in more than one place, you can simply make a switch/case statement on the argument and then return the proper value. The returned priority can be between -128 and +127.
virtual bool InitAgent(void);
This function will only be called once. You can allocate some memory needed, initialize the settings, create your windows or whatever you want to do. The function is called right after the add-on is loaded and an instance is created. Return true if everything went ok and false if not. You have to show a PAlert by yourself if something went wrong. The default implementation just returns true.
virtual void OpenWindows(void);
If you have any windows in your agent, override this function. In this function you open the windows. Remember to only open the windows if the user has them opened when he/she exited APlayer the last time. You can remember this state in the settings.
virtual void Run(void);
This function will be called if you plug-in on a button or menu item. When the user presses that button, e.g. the module info button, this function will be called. Here you probably will open the window if you have any or do whatever you have to do. The default implementation does nothing.
virtual void Plugin_AfterAddingFiles(void);
When one or more files has been added to the module list, all agents which has plugged-in at this location, will be called via this function. The default implementation does nothing.
virtual void Plugin_AfterFree(void);
After a module has been freed from the memory, all agents which has plugged-in at this location, will be called via this function. The default implementation does nothing.
virtual void Plugin_AfterInit(void);
After a module has been loaded and initialized, all agents which has plugged-in at this location, will be called via this function. The default implementation does nothing.
virtual void Plugin_AfterInitSong(void);
After a subsong has been initialized, all agents which has plugged-in at this location, will be called via this function. The default implementation does nothing.
virtual ap_result Plugin_BeforeCheck(BeforeCheckInfo *info);
After a module needs to be loaded into the memory, a test must be made to recognize the module. Before this test is made, all agents which has plugged-in at this location, will be called. This can e.g. be a module converter which will convert the module into another format. It has to return either AP_OK or AP_ERROR. The structure given has these fields:
Name | Type | Description |
moduleFile | PFile * | This is a pointer to the file to check. Do only read this field, do not write any new values in it. |
newModuleFile | PFile * | If you have converted the module, allocate a new PFile object with the new operator and store it in this field. The converted module has to be written into this file. Normally, a memory file is used. If you haven't changed anything, store NULL in this field. |
modKind | PString | Put the name of the module you converted from in this field. This can e.g. be FastTracker II, ScreamTracker etc. |
modType | PString | Put the module type you converted from. This is a mimestring, like audio/x-xm. |
Notice that all agents will be called that has plugged in. One agent can convert a module and then another agent converts the converted module into another format. If you want to be sure your agent is called before someone elses, you can change the plug-in priority with the GetPluginPriority() function.
virtual void Plugin_AfterRemovingFiles(void);
When one or more files has been removed from the module list, all agents which has plugged-in at this location, will be called via this function. The default implementation does nothing.
virtual bool Plugin_DoMixing(APChannel **channels);
If you have told APlayer you want a virtual mixer, this function will called when it's time to mix your data with the rest of the data. As the argument, you get a pointer to an array holding pointers to the channel objects. To play some sound, you just need to call the member functions in these objects, just like a player will do it. The return value indicate if you want to enable the mixing or not. This can be used, so you only use CPU power when really needed, e.g. in the sample info window, this function will only return true when the user play a sample. Thereby it won't use any extra CPU power just by sitting there.
virtual void Plugin_EndMixer(void);
If you have told APlayer you want a virtual mixer, this function will called when it's time to cleanup your mixer. You need to deallocate and cleanup the things you have initialized in the Plugin_InitMixer() function.
virtual uint16 Plugin_InitMixer(void);
If you have told APlayer you want a virtual mixer, this function will called every time a new module is loaded a it's time to initialize the mixers. You have to do all the mixer related things in this function and then return the number of channels you want to be allocated for you. If you return 0, your mixer won't be allocated. This is the same as telling APlayer that something went wrong.
virtual void Plugin_ModuleInfoChanged(uint32 line, ap_infoType type, PString newString);
This function will be called everytime something in the module information has changed. This can e.g. be used to update a window that show the informations, like the module info agent. The arguments are the line number to change, the type (apDescription or apValue) and what to change the information to. The default implementation does nothing.
void FreeModule(void);
If you call this function, the current playing module will be stopped and deleted from the memory. If no module is playing, nothing will happend.
void LoadModule(int32 index);
Call this function if you want to load and play a new module. The index is the index number in the module list of the module to load. The index is starting from 0.