The ARSC DLL is a windows dynamic link library wrapper to the Auditory
Research Soundcard (ARSC) Application Programming Interface (API).
This DLL allows non-C languages to utilize the ARSC API without
requiring a recompile. It has been tested with such languages as
MATLAB, C#, VB, and VBA. Theoretically, any windows language that
has the ability to reference functions from an external windows
DLL should be able to use the ARSC library.
For a comprehensive list of functions, see the ARSC API documentation. The
functions listed below are DLL functions which are distinct from the ARSC API.
Calling conventions for any DLL function are specific to the language in
question. Consult the examples for details.
Ordinarily the calling program polls to see when a segment
has finished. This function provides a different methodology
where the looping is done internal to the DLL, then control is
released to the calling program only after the segment is
finished.
Because this function resides within a windows DLL, an escape
mechanism has been provided. Specifically, hit the ESC key
any time the sound engine is running to stop.
WIN32DLL_API int32 STDCALL ar_out_prepare_vb (
int32 dev, // device identifier
void *out_data, // pointer to output data
int32 size[], // array of segment sizes
int32 nseg, // number of segments
int32 nswp // number of sweeps
)
VB.NET (and other languages) doesn't seem able to send
a pointer to an array or a pointer to a pointer. I tried using
Tom's VarPtr trick, but this didn't work since VarPtr is different
in VB.NET than in prior releases of VB. The pinning memory model
method didn't seem to give valid pointers.
This wrapper assumes a pointer to a single block of memory
then re-defines it to the ar_io_prepare() arguments. This
has been tested and works well with VB.NET, MatLab, and
even C#.
A visual interpretation may help to clarify how this works.
Consider a scenario of 3 segments (0,1,2) and 2 channels (0,1)
and that we are considering output only. The first segment
is 1024; the second is 2048; the third is 1024 samples.
seg 0 seg 1 seg2
-------- ---------------- --------
| ch 0 | | ch 0 | | ch 0 |
-------- ---------------- --------
| ch 1 | | ch 1 | | ch 1 |
-------- ---------------- --------
0 1024 0 2048 0 1024
** FIGURE 1 **
Figure 1 shows the segments as separate entities. The underlying
C library only needs pointers, so this layout shows the segments
in a logical train of left to right.
Channels are interleaved in the underlying code. It is useful
to think of channels as being layers of the segment.
This next figure shows how this function takes the data as
one contiguous block.
-------------------------------------------------
| seg 0 | seg 0 | seg 1 | seg 1 | seg 2 | seg 2 |
| ch 0 | ch 1 | ch 0 | ch 1 | ch 0 | ch 1 |
-------------------------------------------------
** FIGURE 2 **
The sizes array is populated with segment lengths. This is
independent of the number of channels. That is, if you have
1 or 1000 channels, the segment length must be the same.
For this example, sizes[3] = { 1024, 2048, 1024 }
WIN32DLL_API char * STDCALL ar_err_msg_matlab (
int32 code // error code
)
MatLab cannot pass anything by reference, so this
function will return the error message for a given code.
This function will work for other languages, but we
recommend using ar_err_msg() when possible.
WIN32DLL_API char * STDCALL ar_dev_name_matlab (
int32 dev // device identifier
)
MatLab cannot pass anything by reference, so this
function will return the device name.
WIN32DLL_API int32 STDCALL ar_version_dll (
char *astrVersionInfo, // pointer to string that holds DLL version information
int32 len // Length of string
)
Returns the DLL version information for the DLL and the underlying ARSC API code.
The size of the passed string should be at least 256 bytes, in fact,
it is required.
The function returns actual size of the returned DLL version content.
WIN32DLL_API int32 STDCALL fill_tone ( int32 *ptrBlock, // Output
int32 aintBlockSize, // Size of memory block in bytes
real64 adblDesiredFrequency, // Frequency in Hz
real64 adblSampleRate, // e.g. 44100.
real64 adblAmplitude );
Fills a memory block with a tone of specified frequency.
The memory block must be allocated in the calling code.
The function returns 1 on success; 0 on failure.
WIN32DLL_API int32 STDCALL ar_set_xfer_stdcall (
int32 dev,
void (STDCALL *in_xfer)(int32),
void (STDCALL *out_xfer)(int32)
);
Most applications that will use the ARSC DLL use the stdcall
calling convention. This includes VB and C#. As such, the
function ar_set_xfer() cannot be used by one of these languages
because the native function uses the cdecl calling convention.
C# requires the use of delegates to pass function pointers to
the DLL. See the C# mixing example for details.
|