Implements Module Player working in Form
* Implements Embedding .xm music in Final Application
This commit is contained in:
389
UOS/examples/uos_portaudio.pas
Normal file
389
UOS/examples/uos_portaudio.pas
Normal file
@@ -0,0 +1,389 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading version of PortAudio Pascal Wrapper.
|
||||
Load library with pa_load() and release with pa_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com
|
||||
Reference counting added by Max Karpushin / homeplaner@yandex.ru}
|
||||
|
||||
unit uos_portaudio;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs, CTypes;
|
||||
|
||||
const
|
||||
libpa=
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
'libportaudio.2.dylib';
|
||||
{$ELSE}
|
||||
'libportaudio.so.2';
|
||||
{$ENDIF}
|
||||
{$ELSE}
|
||||
'portaudio.dll';
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
PaError = CInt32;
|
||||
PaErrorCode =(
|
||||
paNotInitialized := -10000,
|
||||
paUnanticipatedHostError,
|
||||
paInvalidChannelCount,
|
||||
paInvalidSampleRate,
|
||||
paInvalidDevice,
|
||||
paInvalidFlag,
|
||||
paSampleFormatNotSupported,
|
||||
paBadIODeviceCombination,
|
||||
paInsufficientMemory,
|
||||
paBufferTooBig,
|
||||
paBufferTooSmall,
|
||||
paNullCallback,
|
||||
paBadStreamPtr,
|
||||
paTimedOut,
|
||||
paInternalError,
|
||||
paDeviceUnavailable,
|
||||
paIncompatibleHostApiSpecificStreamInfo,
|
||||
paStreamIsStopped,
|
||||
paStreamIsNotStopped,
|
||||
paInputOverflowed,
|
||||
paOutputUnderflowed,
|
||||
paHostApiNotFound,
|
||||
paInvalidHostApi,
|
||||
paCanNotReadFromACallbackStream,
|
||||
paCanNotWriteToACallbackStream,
|
||||
paCanNotReadFromAnOutputOnlyStream,
|
||||
paCanNotWriteToAnInputOnlyStream,
|
||||
paIncompatibleStreamHostApi,
|
||||
paBadBufferPtr,
|
||||
paNoError := 0
|
||||
);
|
||||
|
||||
PaDeviceIndex = CInt32;
|
||||
|
||||
PaHostApiIndex = CInt32;
|
||||
|
||||
PaHostApiTypeId =(paInDevelopment := 0,
|
||||
paDirectSound := 1,
|
||||
paMME := 2,
|
||||
paASIO := 3,
|
||||
paSoundManager := 4,
|
||||
paCoreAudio := 5,
|
||||
paOSS := 7,
|
||||
paALSA := 8,
|
||||
paAL := 9,
|
||||
paBeOS := 10,
|
||||
paWDMKS := 11,
|
||||
paJACK := 12,
|
||||
paWASAPI := 13,
|
||||
paAudioScienceHPI := 14
|
||||
);
|
||||
|
||||
PaHostApiInfo = record
|
||||
structVersion : CInt32;
|
||||
_type : PaHostApiTypeId ;
|
||||
_name : Pchar;
|
||||
deviceCount : CInt32;
|
||||
defaultInputDevice : PaDeviceIndex;
|
||||
defaultOutputDevice : PaDeviceIndex;
|
||||
end;
|
||||
PPaHostApiInfo = ^PaHostApiInfo;
|
||||
|
||||
PaHostErrorInfo = record
|
||||
hostApiType : PaHostApiTypeId;
|
||||
errorCode : CLong;
|
||||
errorText : PChar;
|
||||
end;
|
||||
PPaHostErrorInfo = ^PaHostErrorInfo;
|
||||
|
||||
PaTime = CDouble;
|
||||
|
||||
PaSampleFormat = pCULongLong;
|
||||
|
||||
PaDeviceInfo = record
|
||||
structVersion : CInt32;
|
||||
_name : PChar;
|
||||
hostApi : PaHostApiIndex;
|
||||
maxInputChannels : CInt32;
|
||||
maxOutputChannels : CInt32;
|
||||
defaultLowInputLatency : PaTime;
|
||||
defaultLowOutputLatency : PaTime;
|
||||
defaultHighInputLatency : PaTime;
|
||||
defaultHighOutputLatency : PaTime;
|
||||
defaultSampleRate : CDouble;
|
||||
end;
|
||||
PPaDeviceInfo = ^PaDeviceInfo;
|
||||
|
||||
PaStreamParameters = record
|
||||
device : PaDeviceIndex;
|
||||
channelCount : CInt32;
|
||||
sampleFormat : PaSampleFormat;
|
||||
suggestedLatency : PaTime;
|
||||
hostApiSpecificStreamInfo : Pointer;
|
||||
end;
|
||||
PPaStreamParameters = ^PaStreamParameters;
|
||||
|
||||
// ************************* Streaming types *************************
|
||||
|
||||
PaStream = Pointer;
|
||||
PPaStream = ^PaStream;
|
||||
PPPaStream = ^PPaStream;
|
||||
|
||||
PaStreamFlags = CULong;
|
||||
|
||||
PaStreamCallbackTimeInfo = record
|
||||
inputBufferAdcTime : PaTime;
|
||||
currentTime : PaTime;
|
||||
outputBufferDacTime : PaTime;
|
||||
end;
|
||||
PPaStreamCallbackTimeInfo = ^PaStreamCallbackTimeInfo;
|
||||
|
||||
PaStreamCallbackFlags = CULong;
|
||||
|
||||
PaStreamCallbackResult =(
|
||||
paContinue := 0,
|
||||
paComplete := 1,
|
||||
paAbort := 2);
|
||||
|
||||
PaStreamCallback = function(
|
||||
input : Pointer;
|
||||
output : Pointer;
|
||||
frameCount : CULong;
|
||||
timeInfo : PPaStreamCallbackTimeInfo;
|
||||
statusFlags : PaStreamCallbackFlags;
|
||||
userData : Pointer) : CInt32;
|
||||
PPaStreamCallback = ^PaStreamCallback;
|
||||
|
||||
PaStreamFinishedCallback = procedure(userData : Pointer);
|
||||
PPaStreamFinishedCallback = ^PaStreamFinishedCallback;
|
||||
|
||||
PaStreamInfo = record
|
||||
structVersion : CInt32;
|
||||
inputLatency : PaTime;
|
||||
outputLatency : PaTime;
|
||||
sampleRate : CDouble;
|
||||
end;
|
||||
PPaStreamInfo = ^PaStreamInfo;
|
||||
|
||||
const
|
||||
paFormatIsSupported = 0;
|
||||
paFramesPerBufferUnspecified = 0;
|
||||
paNoDevice = PaDeviceIndex(-1);
|
||||
paUseHostApiSpecificDeviceSpecification = PaDeviceIndex(-2);
|
||||
paFloat32 = PaSampleFormat($00000001);
|
||||
paInt32 = PaSampleFormat($00000002);
|
||||
paInt24 = PaSampleFormat($00000004);
|
||||
paInt16 = PaSampleFormat($00000008);
|
||||
paInt8 = PaSampleFormat($00000010);
|
||||
paUInt8 = PaSampleFormat($00000020);
|
||||
paCustomFormat = PaSampleFormat($00010000);
|
||||
paNonInterleaved = PaSampleFormat($80000000);
|
||||
paNoFlag = PaStreamFlags(0);
|
||||
paClipOff = PaStreamFlags($00000001);
|
||||
paDitherOff = PaStreamFlags($00000002);
|
||||
paNeverDropInput = PaStreamFlags($00000004);
|
||||
paPrimeOutputBuffersUsingStreamCallback = PaStreamFlags($00000008);
|
||||
paPlatformSpecificFlags = PaStreamFlags($FFFF0000);
|
||||
paInputUnderflow = PaStreamCallbackFlags($00000001);
|
||||
paInputOverflow = PaStreamCallbackFlags($00000002);
|
||||
paOutputUnderflow = PaStreamCallbackFlags($00000004);
|
||||
paOutputOverflow = PaStreamCallbackFlags($00000008);
|
||||
paPrimingOutput = PaStreamCallbackFlags($00000010);
|
||||
|
||||
////// Dynamic load : Vars that will hold our dynamically loaded functions...
|
||||
|
||||
// *************************** functions *******************************
|
||||
|
||||
var Pa_GetVersion: function():CInt32 ; cdecl;
|
||||
|
||||
var Pa_GetVersionText: function():PChar ; cdecl;
|
||||
|
||||
var Pa_GetErrorText: function(errorCode : PaError):PChar ; cdecl;
|
||||
|
||||
var Pa_Initialize: function():PaError ; cdecl;
|
||||
|
||||
var Pa_Terminate: function():PaError ; cdecl;
|
||||
|
||||
var Pa_GetHostApiCount: function():PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultHostApi: function():PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_GetHostApiInfo: function(hostApi : PaHostApiIndex):PPaHostApiInfo ; cdecl;
|
||||
|
||||
var Pa_HostApiTypeIdToHostApiIndex: function(_type : PaHostApiTypeId):PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_HostApiDeviceIndexToDeviceIndex: function(hostApi : PaHostApiIndex;hostApiDeviceIndex : CInt32):PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetLastHostErrorInfo: function():PPaHostErrorInfo ; cdecl;
|
||||
|
||||
// ************** Device enumeration and capabilities ******************
|
||||
|
||||
var Pa_GetDeviceCount: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultInputDevice: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultOutputDevice: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDeviceInfo: function(device : PaDeviceIndex):PPaDeviceInfo ; cdecl;
|
||||
|
||||
var Pa_IsFormatSupported: function(inputParameters,outputParameters : PPaStreamParameters; sampleRate : CDouble):PaError ; cdecl;
|
||||
|
||||
// *********************** Stream function *****************************
|
||||
|
||||
var Pa_OpenStream: function(stream : PPPaStream;
|
||||
inputParameters : PPaStreamParameters;
|
||||
outputParameters : PPaStreamParameters;
|
||||
sampleRate : CDouble;
|
||||
framesPerBuffer : CULong;
|
||||
streamFlags : PaStreamFlags;
|
||||
streamCallback : PPaStreamCallback;
|
||||
userData : Pointer):PaError ; cdecl;
|
||||
|
||||
var Pa_OpenDefaultStream: function(stream : PPPaStream;
|
||||
numInputChannels : CInt32;
|
||||
numOutputChannels : CInt32;
|
||||
sampleFormat : PaSampleFormat;
|
||||
sampleRate : CDouble;
|
||||
framesPerBuffer : CULong;
|
||||
streamCallback : PPaStreamCallback;
|
||||
userData : Pointer):PaError ; cdecl;
|
||||
|
||||
var Pa_CloseStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_SetStreamFinishedCallback: function(stream : PPaStream;
|
||||
streamFinishedCallback : PPaStreamFinishedCallback):PaError ; cdecl;
|
||||
|
||||
var Pa_StartStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_StopStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_AbortStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_IsStreamStopped: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_IsStreamActive: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_GetStreamInfo: function(stream : PPaStream):PPaStreamInfo ; cdecl;
|
||||
|
||||
var Pa_GetStreamTime: function(stream : PPaStream):Patime ; cdecl;
|
||||
|
||||
var Pa_GetStreamCpuLoad: function(stream : PPaStream):CDouble ; cdecl;
|
||||
|
||||
var Pa_ReadStream: function(stream : PPaStream; buffer : pcfloat ;frames : CULong):PaError ; cdecl;
|
||||
|
||||
var Pa_WriteStream: function(stream : PPaStream; buffer : pcfloat ;frames : CULong):PaError ; cdecl;
|
||||
|
||||
var Pa_GetStreamReadAvailable: function(stream : PPaStream):CSLong ; cdecl;
|
||||
|
||||
var Pa_GetStreamWriteAvailable: function(stream : PPaStream):CSLong ; cdecl;
|
||||
|
||||
// ****************** Miscellaneous utilities **************************
|
||||
|
||||
var Pa_GetSampleSize: function(format : PaSampleFormat):PaError ; cdecl;
|
||||
|
||||
var Pa_Sleep: function(msec : CLong) : integer; cdecl;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
{Special function for dynamic loading of lib ...}
|
||||
|
||||
var Pa_Handle:TLibHandle=dynlibs.NilHandle; // this will hold our handle for the lib; it functions nicely as a mutli-lib prevention unit as well...
|
||||
|
||||
var ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function Pa_IsLoaded : boolean; inline;
|
||||
|
||||
Function Pa_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure Pa_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
implementation
|
||||
|
||||
function Pa_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (Pa_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Function Pa_Load (const libfilename:string) :boolean;
|
||||
var
|
||||
thelib: string;
|
||||
begin
|
||||
Result := False;
|
||||
if Pa_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then thelib := libpa else thelib := libfilename;
|
||||
Pa_Handle:=DynLibs.SafeLoadLibrary(thelib); // obtain the handle we want
|
||||
if Pa_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
Pointer(Pa_GetVersion):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetVersion'));
|
||||
Pointer(Pa_GetVersionText):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetVersionText'));
|
||||
Pointer(Pa_GetErrorText):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetErrorText'));
|
||||
Pointer(Pa_Initialize):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Initialize'));
|
||||
Pointer(Pa_Terminate):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Terminate'));
|
||||
Pointer(Pa_GetHostApiCount):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetHostApiCount'));
|
||||
Pointer(Pa_GetDefaultHostApi):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultHostApi'));
|
||||
Pointer(Pa_GetHostApiInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetHostApiInfo'));
|
||||
Pointer(Pa_HostApiTypeIdToHostApiIndex):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_HostApiTypeIdToHostApiIndex'));
|
||||
Pointer(Pa_HostApiDeviceIndexToDeviceIndex):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_HostApiDeviceIndexToDeviceIndex'));
|
||||
Pointer(Pa_GetLastHostErrorInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetLastHostErrorInfo'));
|
||||
//////////////////
|
||||
Pointer(Pa_GetDeviceCount):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDeviceCount'));
|
||||
Pointer(Pa_GetDefaultInputDevice):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultInputDevice'));
|
||||
Pointer(Pa_GetDefaultOutputDevice):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultOutputDevice'));
|
||||
Pointer(Pa_GetDeviceInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDeviceInfo'));
|
||||
Pointer(Pa_IsFormatSupported):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsFormatSupported'));
|
||||
//////////////////////
|
||||
Pointer(Pa_OpenStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_OpenStream'));
|
||||
Pointer(Pa_OpenDefaultStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_OpenDefaultStream'));
|
||||
Pointer(Pa_CloseStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_CloseStream'));
|
||||
Pointer(Pa_SetStreamFinishedCallback):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_SetStreamFinishedCallback'));
|
||||
Pointer(Pa_StartStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_StartStream'));
|
||||
Pointer(Pa_StopStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_StopStream'));
|
||||
Pointer(Pa_AbortStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_AbortStream'));
|
||||
Pointer(Pa_IsStreamStopped):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsStreamStopped'));
|
||||
Pointer(Pa_IsStreamActive):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsStreamActive'));
|
||||
Pointer(Pa_GetStreamInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamInfo'));
|
||||
Pointer(Pa_GetStreamTime):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamTime'));
|
||||
Pointer(Pa_GetStreamCpuLoad):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamCpuLoad'));
|
||||
Pointer(Pa_ReadStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_ReadStream'));
|
||||
Pointer(Pa_WriteStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_WriteStream'));
|
||||
Pointer(Pa_GetStreamReadAvailable):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamReadAvailable'));
|
||||
Pointer(Pa_GetStreamWriteAvailable):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamWriteAvailable'));
|
||||
Pointer(Pa_GetSampleSize):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetSampleSize'));
|
||||
Pointer(Pa_Sleep):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Sleep'));
|
||||
end;
|
||||
Result := Pa_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Procedure Pa_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if Pa_IsLoaded then
|
||||
begin
|
||||
Pa_Terminate();
|
||||
DynLibs.UnloadLibrary(Pa_Handle);
|
||||
Pa_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user