How to access BASS library functionalities directly |
|
For some of its many features, Active Sound Recorder 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 and BASS_ChannelGetLevel functions exported by BASS.DLL: In order to access these functions directly from your code, you will need to declare them 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); DWORD BASSDEF (BASS_ChannelGetLevel)(DWORD handle);
|
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; ActiveSoundRecorder1.BassModuleGet (MODULE_BASS, &hBass);
#define LOADBASSFUNCTION(f) *((void**)&f)=GetProcAddress(HMODULE (hBass),#f)
LOADBASSFUNCTION(BASS_ChannelSetAttribute); LOADBASSFUNCTION(BASS_ChannelGetLevel);
|
That's all: we can now call the BASS function directly from our code: if for example we should need to lower a playback stream to half its volume, we could simply use the following code:
HSTREAM hStreamPlay = NULL; ActiveSoundRecorder1.BassStreamGet (FALSE, hStreamPlay); BASS_ChannelSetAttribute (hStreamPlay, BASS_ATTRIB_VOL, 0.5f);
|
or if we should need to get the volume level of a recording stream we could do the following:
HSTREAM hStreamRec = NULL; ActiveSoundRecorder1.BassStreamGet (TRUE, hStreamRec); DWORD dwLevel = BASS_ChannelGetLevel (hStreamRec); WORD wLeft = WORD (dwLevel); WORD wRight = WORD (dwLevel >> 16);
|
This brings another interesting point: on the first code snippets above we are acting on a playback stream, identified by the hStreamPlay variable and on the second code snippet we are acting on a recording stream, identified by the hStreamRec variable: how can we obtain those streams? This is quite simple: In case you should need to have direct access to the handle (HSTREAM or HRECORD) of a playback or recording stream created through BASS, you could use the BassStreamGet method.
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 and recording streams of type HSTREAM and HRECORD: 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 HSTREAM and HRECORD streams with these plugins.
As mentioned before, Active Sound Recorder already embeds some external BASS plugin that supports the decoding of specific audio formats like WMA, MP4, AC3 and others: from time to time developers belonging to the BASS community deliver new plugins for supporting other audio formats; also if not directly embedded inside the component, functions exported by the plugin for creating the 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 the StartFromFile, StartFromMemory or StartFromURL methods 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 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.