Contents of the /dev directory :


pacemaker_source_xxxxxx.zip : The latest PaceMaker plug-in source code.

pacemaker_library_v1.2xx.dll : PaceMaker library files, containing the actual plug-in file (dsp_pacemaker.dll), the library definition file (.lib) and the linker map file (.map).

doc.html : Documentation on how PaceMaker can be used to process sound in own programs

pmsample.zip : A simple example program demonstrating how to use PaceMaker to process sound in o

Functions and data types in dsp_pacemaker.dll :


Contents:


Introduction

There have been some queries if PaceMaker code can be used in own programs, and if so, what about programs not written in C++? Answer to the first question is yes, PaceMaker source code can be used in other programs, as far as they are written and given away in non-profitable purpose (that is, the program licensing model is freeware, shareware with very modest fee or equivalent).

About the second question, there's no reason why PaceMaker algorithms wouldn't work if they were migrated to Visual Basic or Delphi, but as proper implementation of a tempo changer routine is very calculation intensive task, there's a good reason to believe the resulting performance would be somewhat poor.

The PaceMaker itself is compiled with high-performing C++ compiler and contains MMX-optimized hot-spot routines and thus provides somewhat good performance. To harness this in other programs written in other languages and developer tools, the new version of dsp_pacemaker.dll library contains several additional API functions (in addition to the usual plug-in interface to Winamp player) that enable utilizing the PaceMaker's sound processing functionalities in other programs, regardless which developer tool they are made with.

This documentation describes the functions in dsp_pacemaker.dll and briefly discusses how to use the PaceMaker functionalities in own programs.


Using PaceMaker in own programs

Loading the dll library file and resolving function addresses in compiler

Before functions in a dll library can be used, the dll library file has to be loaded in memory and the function addresses be determined. When using a compiling developer tool, like Visual C++, Borland C++ Builder or Delphi, the compiler can automatically resolve the function addresses and load the dll file in beginning of the program execution if the dll's .lib file is included in the project libraries and dll import declarations are added in the program code for each required function.

The PaceMaker source code package contains a C header file 'dll_pacemaker.h' which has the dll import declarations for each PaceMaker API function (the declarations use Visual C++ syntax, they may or may not work with Borland C++ tools). For example, the function "pacemaker_create" can be imported using the following declaration :

__declspec(dllimport) PMHANDLE pacemaker_create();

If using some other language or other compiler then Visual C++, see the compiler manual for correct declaration syntax.

Loading the dll library file and resolving function addresses in run-time

Optional way to access the dll functions is to use the Win32 api function LoadLibrary to load the dll file and GetProcAddress to resolve the function addresses in. In this approach, the developer has to write all the code needed for loading the dll library but on the other case he/she can also control when the dll library is loaded, and in which directories the dll file is searched for.

Creating a pacemaker object instance

PaceMaker can process several concurrent sound streams at the same time. Because of that, the sound processing routines need to make a difference between different streams, and for that purpose a 'pacemaker' object instance has to be created before calling any processing functions.

The 'pacemaker' object instance is created by calling the function pacemaker_create, which returns a handle to the newly created object. This handle can be used for calling the sound processing functions, and when finishing, destroy the handle by calling the function pacemaker_destroy to free resources allocated by the object.

Processing sound

After creating a 'pacemaker' object instance the sound processing functions are ready for use. At first, set the number of sound channels by calling pacemaker_set_channels and the return buffer size by calling pacemaker_set_output_buffer_size.

After that, you can start actual processing by calling pacemaker_evaluate to process a batch of samples and pacemaker_set_tempo/pitch/speed functions to set how PaceMaker modifies the sound.


Data types used by dsp_pacemaker.dll


PMHANDLE

This is a 32 bit integer value used as an instance reference when calling the sound processing functions in the dll.

Actually, this is a pointer to an instance of a C++ class 'pacemaker'. If you use Visual C++, you should be able to access the C++ class "pacemaker" members directly with this handle by including the header file "pacemaker.h" in your source code and typecasting the handle of this type to (pacemaker*).


Standard C data types used by dsp_pacemaker.dll

The following are standard C data types, but here're the descriptions for should someone be unfamiliar with C types :


Functions in dsp_pacemaker.dll


PMHANDLE pacemaker_create()

Creates a new pacemaker object instance. When finishing, destroy the instance by calling pacemaker_destroy.

Returns a handle of the newly created pacemaker object instance, or NULL if fails.


void pacemaker_destroy(PMHANDLE handle)

Destroys a pacemaker instance created with pacemaker_create function.

Parameters :


void pacemaker_clear_buffers(PMHANDLE handle)

Clears the internal buffers.

The pacemaker routines accumulates some sound data into internal buffers in order to being able to carry out the sound processing. That's why it's a good idea to call this function to clear the buffers when changing the song, jumping to a new location in the sound stream etc.

Parameters :


unsigned int pacemaker_flush_buffers(PMHANDLE handle, short *outsamples)

Flushes processed samples from the internal buffers.

PaceMaker stores processed sound samples into an internal buffer where they're then fed to the output in a suitable fashion by maintaining a somewhat constant output sound flow. This function can be called to extract the last few sample chunks when the end of a sound stream is reached and no more samples can be fed to the routines.

Parameters :

Returns number of samples copied to the output buffer.


unsigned int pacemaker_evaluate(PMHANDLE handle, short *outsamples, short *insamples, unsigned int numsamples)

Processes a batch of samples. The routine takes the input samples and outputs a chunk of processed samples, if any ready.

Notice that the routine collects sound samples into internal buffer before processing them, and thus the samples outputted aren't the same ones as feed to the function at the same function call. In addition, when beginning a new song or sound stream, the routine may return no samples at all for first few calls in the beginning. When the processing buffers have enough samples for processing, the routine tries to output a comparable amount of samples than are fed to input.

Parameters :

Returns the number of processed samples returned in the outsamples buffer.


char * pacemaker_get_license_text(void)

Returns the PaceMaker license text that can be shown on the client program's about box etc.

Returns a pointer to the null-terminated character buffer having the license text.


unsigned int pacemaker_get_revision(void)

Returns the revision number of the dll library. The revision number is intended for preventing version conflict issues should there be new PaceMaker releases with new capabilities some day in the future.

The currently available revision numbers are:

PaceMaker release Revision number
v1.2b4 0
v1.2b5 (still unreleased) 1
v1.2 ...to be decided

Returns the pacemaker.dll revision number.


void pacemaker_set_channels(PMHANDLE handle, unsigned int numchannels)

Sets number of channels in input sound data.

Changing the number of channels in the middle of a song will most likely cause disturbances. To prevent disturbances, either call pacemaker_clear_buffers to clear the internal buffers when changing the number of channels, or make the change during a quiet sequence.

Parameters :


void pacemaker_set_samplerate(PMHANDLE handle, unsigned int samplerate)

Sets sample rate of the in input sound data.

This parameter affects the tempo changing routine. Using an illegal sample rate value may cause distorts in the resulting sound.

Parameters :


void pacemaker_set_output_buffer_size(PMHANDLE handle, unsigned int size_in_bytes)

Sets the output buffer, where the processed samples are returned, size in bytes. As the sound samples are 16 bit integers with either one or two channels, a single sample may occupy either 2 (for mono sound) or 4 (for stereo sound) bytes of memory.

Notice that when tempo or speed of sound is lowered from the original, the sound is stretched so that the outputted sound is longer than the ingoing sound, and thus the size of the output buffer should be in proportion to the smalled allowed temp or sound adjustment.

For example, to slow the tempo down to half of the original, the output buffer should be at least twice the size of the average chunks of sample data (in bytes) that are fed to the 'evaluate' routine, for being able to output all the processed data at the same rate than new data is feed to the input. In other words, if the 'evaluate' function is feed (on average) with 512 stereo samples each call, and the tempo is allowed to be slowed down to 50% of the original, the buffer size should be at least 512 * 2 * 4 = 4096 bytes. It's yet recommended to use a bit larger buffer than that, just to leave some slack.

Parameters :

See also :


void pacemaker_set_speed_absolute(PMHANDLE handle, float new_speed)

Sets new 'speed' control value for the sound processor. The speed value of 1.0 corresponds to the original speed, values less than that result in deeper and slower sound and values larger than 1.0 result in higher and faster sound.

For examples, a value of 0.5 would correspond to playing the sound at half of the original speed, value of 2.0 at twice the original speed and so on.

Parameters :


void pacemaker_set_tempo_absolute(PMHANDLE handle, float new_tempo)

Sets new 'tempo' control value for the sound processor. The value of 1.0 corresponds to the original speed, values less than that result in slower tempo and values larger than 1.0 result in faster tempo.

For examples, a value of 0.5 would correspond to playing the sound at half of the original tempo, value of 2.0 at twice the original tempo and so on.

Parameters :


void pacemaker_set_pitch_absolute(PMHANDLE handle, float new_pitch)

Sets new 'pitch' control value for the sound processor. The value of 1.0 corresponds to the original pitch, values less than that result in lower pitch (deeper sound) and values larger than 1.0 result in higher pitches.

For examples, a value of 0.5 would correspond to lowering the sound frequencies to half of the original (that is, lowering pitch by one octave), value of 2.0 to raising the sound frequencies to two times the original (that is, raising the pitch by one octave) and so on.

Notice that because of the nature of human ear, it's often more recommended to use octave or semitone scale rather than absolute scale for changing the pitch (see the other pitch functions below).

Parameters :

See also :


void pacemaker_set_pitch_octaves(PMHANDLE handle, float new_pitch)

Sets new 'pitch' control value for the sound processor using octave scale. Value of -1.0 corresponds to lowering pitch by one octave, +1.0 by raising the pitch by one octave and so on.

Parameters :

See also :


void pacemaker_set_pitch_semitones(PMHANDLE handle, int steps)

Sets new 'pitch' control value for the sound processor using semitones where one octave is divided in 12 steps. A value of -12 corresponds to lowering pitch by one octave, +12 to raising the pitch by one octave and so on.

Parameters :

See also :


winampDSPHeader *winampDSPGetHeader2()

This is the interface function provided for WinAmp to access the plug-in routines. You may disregard this one unless you wish to imitate WinAmp for some reason (in that case, see the WinAmp DSP sdk for further details).


Contact the author at <oparviai@iki.fi>

wn programs. The program reads sound data from a file and writes the processed sound to another one.


updated 12.08.2001