How to access BASS library functionalities directly |
|
For some of its many features, Active DJ Studio embeds the well known BASS library and some of its plugins which allow decoding and playing a number of different audio formats; in some case you could have the need to drive BASS directly in order to perform some particular task not available from the component itself; for achieving this possibility you would have to load and eventually free BASS or its plugins through the LoadLibrary or LoadLibraryEx and the FreeLibrary Windows API functions.
Due to the fact that BASS.DLL and some of its plugins are already embedded inside this component, you don't need to redistribute them with your application because you can get direct access to the module loaded in memory through its handle (HMODULE) returned by an internal call to the LoadLibrary Windows API: this handle, for usage with your own code, can be obtained through the BassModuleGet method.
Through this method you have the possibility to access instances already loaded in memory by the multimedia engine AdjMmsEng.dll: indeed, by knowing the HMODULE of BASS.DLL or of some of its plugins, you could get the pointer to all of the functions exported by the various BASS modules through the GetProcAddress Windows API.
For details about dynamic loading of functions exported by the various BASS modules you can refer to the official documentation of BASS.
IMPORTANT NOTE: Calls to the BASS_Init and BASS_Free functions of BASS.DLL are already managed internally by multimedia engine AdjMmsEng.dll so it's recommended avoiding their usage in order to avoid compatibility issues.
Let's see a small example in C code (Visual Basic 6 is not such friendly when dealing with function pointers loaded dynamically) where we need to access, directly from our code, the BASS_ChannelSetAttribute function exported by BASS.DLL: In order to access this functions directly from your code, you will need to declare it inside you code like this:
#include "Bass.h"
#undef BASSDEF #define BASSDEF(f) (WINAPI *f) // define the functions as pointers
BOOL BASSDEF (BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value);
|
the syntax above is in pure C and is the exact copy of the statements available inside the Bass.h header file. The BASSDEF macro needs to be undefined and redefined with a small variation which allows declaring the calling convention of the exported functions as WINAPI * , which means "pointer to __stdcall". For further details about dynamic loading of functions exported by the various BASS modules you can refer to the official documentation of BASS.
At this point we can proceed with the effective loading of the function pointers in this way:
HMODULE hBass = NULL; Amp3dj1.BassModuleGet (MODULE_BASS, &hBass);
#define LOADBASSFUNCTION(f) *((void**)&f)=GetProcAddress(HMODULE (hBass),#f)
LOADBASSFUNCTION(BASS_ChannelSetAttribute);
|
That's all: we can now call the BASS function directly from our code: if for example we should need to lower a stream to half its volume, we could simply use the following code:
HSTREAM hStream = NULL; Amp3dj1.BassStreamGet (0, &hStream); BASS_ChannelSetAttribute (hStream, BASS_ATTRIB_VOL, 0.5f);
|
This brings another interesting point: on the function call above we are acting on a playback stream, identified by the hStream variable: how can we obtain that stream? This is quite simple: In case you should need to have direct access to the handle (HSTREAM) of a playback stream created through BASS after calling the LoadSound, StreamMixerCreate and similar methods, you can use the BassStreamGet method. In order to initialize this variable you could catch the SoundLoaded event or, as seen on the code snippet above, call the BassStreamGet method when needed.
A second feature brought by the BassStreamGet method is the possibility to apply custom DSP effects implemented by third-party plugins which work on playback streams of type HSTREAM: some of these plugins, such as BASS_WA, BASS_WINAMP, BASS_SFX and others, are available on the BASS web site: please, refer to the respective documentations for knowing how to use the HSTREAM playback stream with these plugins.
As mentioned before, Active DJ Studio already embeds some external BASS plugin that supports the decoding of specific audio formats like WMA, MP4, AC3 and others: from time to time someone belonging to the BASS community delivers new plugins for supporting other audio formats; also if not directly embedded inside the component, functions exported by the plugin for creating the playback audio stream can be in any case accessed by the component through a previous call to the BassPluginStreamCreateFunc method which allows loading the plugin and the specific function dynamically at runtime.
After calling the BassPluginStreamCreateFunc method, when methods beginning with the "Load".prefix (like LoadSound or LoadSoundFromMemory) are invoked, the function exported by the plugin will be automatically used for trying to load the sound file or the Internet stream.
At the moment the component supports the dynamic loading of functions for creating playback streams from the following entities:
• | Sound files: the related function is usually exported by the plugin with the name BASS_xxx_StreamCreateFile where "xxx" indicates the managed audio format, for example BASS_AIX_StreamCreateFile or BASS_TTA_StreamCreateFile; the exported function must use the following C syntax: |
HSTREAM BASS_xxx_StreamCreateFile ( BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags );
|
• | Internet streams: the related function is usually exported by the plugin with the name BASS_xxx_StreamCreateURL where "xxx" indicates the managed audio format, for example BASS_AIX_StreamCreateURL; the exported function must use the following C syntax: |
HSTREAM BASS_xxx_StreamCreateURL ( const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user );
|
It's important to note that you don't need calling the LoadLibrary and FreeLibrary functions on the DLL of the plugin: these functions are already called internally by the component when the BassPluginStreamCreateFunc method is invoked: you simply need to provide the pathname of the plugin and the component will take care of the needed operations.