Hello everybody.
Here the first one night shot of
United OpenLib of Sound.
Only load, init, open and play are ready.
But this first shot work only for a single handle.
The next step is to enhance UOS_Open(soundfile : string) with
UOS_Open(soundfile : string; UOA_Handle : pointer) to have the possibility to create many handles.
Each handle needs : a proper Tinfo, a proper Tstream and of course a THandle.
I want a procedure, for example UOS_CreateHandle() who creates a
a proper Tinfo, a proper Tstream and of course a THandle.
But how to do it ?
By the way, here the code of a demo using UOS :
http://fredvs.github.io/uos/Here the first UOS code for single playing.

unit U_OS;
{*******************************************************************************
* United Openlibraries of Sound ( U_OS ) *
* -------------------------------------- *
* *
* United procedures to access Open Sound libraries *
* *
* *
* Lazarus Forum / Fred van Stappen / Fiens@hotmail.com *
* *
********************************************************************************
* first realease latest changes: 2012-07-20 *
*******************************************************************************}
interface
uses
Forms, SysUtils, LazDyn_PortAudio, LazDyn_LibSndFile, LazDyn_Mpg123;
const
///// error
noError = 0;
FilePAError = 10;
LoadPAError = 11;
FileSFError = 20;
LoadSFError = 21;
FileMPError = 30;
LoadMPError = 31;
//////// UOS_load() flag
LoadAll = 0; // load all PortAudio + SndFile + MPG123
LoadPA = 1; // load only PortAudio
LoadSF = 2; // load only SndFile
LoadMP = 3; // load only MPG123
LoadPA_SF = 4; // load only PortAudio + SndFile
LoadPA_MP = 5; // load only PortAudio + MPG123
LoadSF_MP = 6; // load only SndFile + MPG123
type
TResult = record
PAloadERROR : shortint;
SFloadERROR : shortint;
MPloadERROR : shortint;
PAinitError : integer;
MPinitError : integer;
MPOpenERROR : shortint;
SFOpenERROR : shortint;
end;
type
Tinfo= record
filename : string;
channels : integer;
format : integer;
frames : integer;
samplerate : integer;
sections : integer;
seekable : integer;
encoding : integer;
end;
var
UOSStopStream : shortint;
UOSloadflag : shortint ;
UOSresult : TResult;
UOSDefOut : PaDeviceIndex;
UOSDEVinfo : PPaDeviceInfo;
UOSAPIinfo : PPaHostApiInfo;
UOS_HANDLE : pointer;
UOSsoundfile : String;
sfInfo : TSF_INFO;
UOSOpenInfo : Tinfo;
mhErr : integer;
Stream : PPaStream;
NumSampleBlocks :integer;
SFoutbuf : array [0..2047] of byte; //1023 for stereo only !
MPoutbuf : array [0..65535] of byte;
OutputParameters : PaStreamParameters;
BufFrames : Tsf_count_t;
OutFrames : Tsf_count_t;
procedure UOS_Load(PA_FileName,SF_FileName,MP_FileName : AnsiString ; flag : shortint );
procedure UOS_UnLoad() ;
procedure UOS_Init() ;
procedure UOS_Open(UOSsoundfile:ansistring) ;
procedure UOS_Play() ;
//procedure UOS_Pause() ; // to do ....
//procedure UOS_Resume():TResult ; // to do ....
//procedure UOS_Stop():TResult ; // to do ....
implementation
procedure UOS_Play() ;
begin
UOSStopStream := 0 ;
if (UOSresult.SFOpenError = 0) or (UOSresult.MPOpenError = 0) then
begin
OutputParameters.Device := UOSDefOut;
OutputParameters.channelCount:= UOSOpenInfo.channels;
OutputParameters.SampleFormat := paint16 ;
OutputParameters.SuggestedLatency :=
(Pa_GetDeviceInfo( OutputParameters.device)^.defaultHighOutputLatency) * 1;
OutputParameters.HostApiSpecificStreamInfo := nil;
Pa_OpenStream(@Stream, nil, @OutputParameters, UOSOpenInfo.samplerate ,
64, paClipOff, nil,nil) ;
Pa_StartStream(stream) ;
NumSampleBlocks:= 0;
if UOSresult.SFOpenError = 0 then
BufFrames:= length( SFoutbuf) else
if UOSresult.MPOpenError = 0 then
BufFrames:= length(MPoutbuf) ;
OutFrames :=0;
repeat
if UOSresult.SFOpenError = 0 then
OutFrames:= sf_read_short(UOS_HANDLE, @SFoutbuf[0], BufFrames)
else if UOSresult.MPOpenError = 0 then
mpg123_read( UOS_HANDLE, @MPoutbuf[0], BufFrames, OutFrames);
if UOSresult.SFOpenError = 0 then
Pa_WriteStream(stream,@SFoutbuf[0],OutFrames div 2)
else if UOSresult.MPOpenError = 0 then
Pa_WriteStream(stream,@MPoutbuf[0],OutFrames div 4);
inc( NumSampleBlocks);
application.ProcessMessages; //////////// important if we want to do something else in the program !
until (OutFrames < BufFrames) or (UOSStopStream <> 0);
//////////////////////////////////////////////////////////
Pa_StopStream(stream) ;
Pa_CloseStream(stream) ;
end;
end;
procedure UOS_Open(UOSsoundfile:ansistring) ;
begin
UOSresult.MPOpenError := - 1;
UOSresult.SFOpenError := - 1;
if (UOSresult.SFloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadSF) or (UOSloadflag = LoadPA_SF) or
(UOSloadflag = LoadSF_MP)) then begin
UOS_HANDLE := sf_open(pchar(UOSsoundfile),SFM_READ,sfInfo) ; (* try to open the file *)
If UOS_HANDLE = NIL then
begin
UOSresult.SFOpenError := 1 ;
end
else
////////////////////// have to add more info of course .......
begin
UOSresult.SFOpenError := 0;
UOSOpenInfo.filename := UOSsoundfile ;
UOSOpenInfo.channels := SFinfo.channels;
UOSOpenInfo.format := SFinfo.format;
UOSOpenInfo.frames := SFinfo.frames;
UOSOpenInfo.samplerate := SFinfo.samplerate;
UOSOpenInfo.sections := SFinfo.sections;
UOSOpenInfo.seekable := SFinfo.seekable;
end;
end;
if ((UOSresult.SFOpenError = 1) or (UOSresult.SFOpenError = -1)) and (UOSresult.MPloadERROR = 0)
and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadMP) or (UOSloadflag = LoadPA_MP) or
(UOSloadflag = LoadSF_MP)) then begin
mhErr := -1;
UOS_HANDLE:= mpg123_new( NIL, mhErr);
if mhErr = 0 then mhErr := mpg123_open( UOS_HANDLE,pchar(UOSsoundfile))
else UOSresult.MPOpenError := 1 ;
if mhErr = 0 then mhErr := mpg123_getformat( UOS_HANDLE, UOSOpenInfo.samplerate , UOSOpenInfo.channels, UOSOpenInfo.encoding) ;
if mhErr = 0 then begin
UOSresult.MPOpenError := 0;
UOSOpenInfo.filename := UOSsoundfile ;
end else
begin
UOSresult.MPOpenError := 2 ;
end;
end;
end;
procedure UOS_Unload() ;
begin
UOSStopStream := 1 ;
application.ProcessMessages;
if (UOSresult.SFOpenError = 0 ) then sf_close(UOS_HANDLE) ;
Sf_Unload();
if (UOSresult.MPOpenError = 0) then mpg123_close(UOS_HANDLE) ;
Mp_Unload();
Pa_Unload();
end;
procedure UOS_Init() ;
begin
if (UOSresult.MPloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadMP) or (UOSloadflag = LoadPA_MP) or
(UOSloadflag = LoadSF_MP)) then if mpg123_init()=MPG123_OK then UOSresult.MPinitError := 0 else UOSresult.MPinitError := 1;
IF (UOSresult.PAloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadPA) or
(UOSloadflag = LoadPA_SF) or (UOSloadflag = LoadPA_MP)) Then begin
UOSresult.PAinitError := Pa_Initialize();
if UOSresult.PAinitError = 0 then begin
UOSDefOut := Pa_GetDefaultOutputDevice(); /////////////////// at the moment only default device but i gonna fix it
UOSDEVinfo:= Pa_GetDeviceInfo(UOSDefOut);
UOSAPIinfo:= Pa_GetHostApiInfo(UOSDEVinfo^.hostApi);
end;
end;
end;
procedure UOS_Load( PA_FileName,SF_FileName,MP_FileName : AnsiString ; flag : shortint ) ;
begin
UOSloadflag := flag ;
case flag of
LoadAll : begin
if not fileexists(PA_FileName) then UOSresult.PAloadERROR:= 1 else
if Pa_Load (PA_FileName) then UOSresult.PAloadERROR:= 0 else UOSresult.PAloadERROR:= 2 ;
if not fileexists(SF_FileName) then UOSresult.SFloadERROR:= 1 else
if Sf_Load (SF_FileName) then UOSresult.SFloadERROR:= 0 else UOSresult.SFloadERROR:= 2 ;
if not fileexists(MP_FileName) then UOSresult.MPloadERROR := 1 else
if mp_Load (Mp_FileName) then UOSresult.MPloadERROR := 0 else UOSresult.MPloadERROR := 2 ;
end;
LoadPA : begin
if not fileexists(PA_FileName) then UOSresult.PAloadERROR:= 1 else
if Pa_Load (PA_FileName) then UOSresult.PAloadERROR:= 0 else UOSresult.PAloadERROR:= 2 ;
end;
LoadSF : begin
if not fileexists(SF_FileName) then UOSresult.SFloadERROR:= 1 else
if Sf_Load (SF_FileName) then UOSresult.SFloadERROR:= 0 else UOSresult.SFloadERROR:= 2 ;
end;
LoadMP : begin
if not fileexists(MP_FileName) then UOSresult.MPloadERROR := 1 else
if mp_Load (Mp_FileName) then UOSresult.MPloadERROR := 0 else UOSresult.MPloadERROR := 2 ;
end;
LoadPA_SF : begin
if not fileexists(PA_FileName) then UOSresult.PAloadERROR:= 1 else
if Pa_Load (PA_FileName) then UOSresult.PAloadERROR:= 0 else UOSresult.PAloadERROR:= 2 ;
if not fileexists(SF_FileName) then UOSresult.SFloadERROR:= 1 else
if Sf_Load (SF_FileName) then UOSresult.SFloadERROR:= 0 else UOSresult.SFloadERROR:= 2 ;
end;
LoadPA_MP : begin
if not fileexists(MP_FileName) then UOSresult.MPloadERROR := 1 else
if MP_Load (Mp_FileName) then UOSresult.MPloadERROR := 0 else UOSresult.MPloadERROR := 2 ;
if not fileexists(PA_FileName) then UOSresult.PAloadERROR:= 1 else
if Pa_Load (PA_FileName) then UOSresult.PAloadERROR:= 0 else UOSresult.PAloadERROR:= 2 ;
end;
LoadSF_MP : begin
if not fileexists(SF_FileName) then UOSresult.SFloadERROR:= 1 else
if SF_Load (SF_FileName) then UOSresult.SFloadERROR:= 0 else UOSresult.SFloadERROR:= 2 ;
if not fileexists(MP_FileName) then UOSresult.MPloadERROR := 1 else
if mp_Load (Mp_FileName) then UOSresult.MPloadERROR := 0 else UOSresult.MPloadERROR := 2 ;
end;
end;
end;
initialization
UOSresult.PAloadERROR:= -1 ;
UOSresult.SFloadERROR := -1 ;
UOSresult.MPloadERROR := -1 ;
UOSresult.PAinitError := -1 ;
UOSresult.MPinitError := -1 ;
UOSStopStream := 0 ;
end.