Because of limitation of characters, here next part of the code (see earlier topic)
procedure TUOS_Player.AddFromFile(InName: string; Filename: string; OutName: string; SampleFormat: shortint);
////////// InName : name of new input
////////// FileName : filename of audio file
////////// OutName : name of existing Output // (if multi-output then OutName = name of each output separeted by ';')
////////// SampleFormat : -1 default : Int16 (0: Float32, 1:Int32, 2:Int16)
////////// example : AddFromFile('Input1','/usr/home/test.ogg','Output1;Output2',-1);
var
x, err: integer;
sfInfo: TSF_INFO;
mpinfo: Tmpg123_frameinfo;
mpid3v1: Tmpg123_id3v1;
begin
if not fileexists(FileName) then MessageDlg(FileName + ' do not exists...', mtWarning, [mbYes], 0)
else
begin
x := 0;
err := -1;
while (x < (Length(StreamIn))) and (err <> 0) do
begin
if (StreamIn[x].Name = InName) then ////// seeking for same Input
begin
if (StreamIn[x].HandleSt <> nil) then
case StreamIn[x].info.LibOpen of
0: sf_close(StreamIn[x].HandleSt);
1: mpg123_close(StreamIn[x].HandleSt);
end;
err := 0;
end;
if err <> 0 then inc(x);
end;
if err = -1 then
begin
x := 0;
while (x < Length(StreamIn)) and (err <> 0) do ///// seeking for some empty input
begin
if (StreamIn[x].Name = '') then
begin
StreamIn[x].Name := InName;
err := 0;
end;
if err <> 0 then Inc(x);
end;
end;
if err = -1 then ///// creating a new input
begin
SetLength(StreamIn, Length(StreamIn) + 1);
StreamIn[Length(StreamIn) - 1] := TUOS_InStream.Create;
StreamIn[Length(StreamIn) - 1].Name := InName;
err := 0;
x := Length(StreamIn) - 1;
end;
if err <> -1 then
begin
err := -1;
StreamIn[x].info.LibOpen := -1;
StreamIn[x].info.Isopen := False;
if (UOSloadresult.SFloadERROR = 0) and
((UOSloadflag = LoadAll) or (UOSloadflag = LoadSF) or
(UOSloadflag = LoadPA_SF) or (UOSloadflag = LoadSF_MP)) then
begin
StreamIn[x].HandleSt := sf_open(PChar(FileName), SFM_READ, sfInfo);
(* try to open the file *)
if StreamIn[x].HandleSt = nil then
begin
StreamIn[x].info.LibOpen := -1;
end
else
begin
StreamIn[x].info.LibOpen := 0;
StreamIn[x].info.typeIn := 0;
StreamIn[x].Info.filename := FileName;
StreamIn[x].Info.channels := SFinfo.channels;
StreamIn[x].Info.format := SFinfo.format;
StreamIn[x].Info.frames := SFinfo.frames;
StreamIn[x].Info.samplerate := SFinfo.samplerate;
StreamIn[x].Info.samplerateroot := SFinfo.samplerate;
StreamIn[x].Info.sections := SFinfo.sections;
StreamIn[x].Info.seekable := SFinfo.seekable;
StreamIn[x].Info.Wantframes := length(StreamIn[x].InBuffer) div StreamIn[x].Info.Channels;
StreamIn[x].Info.copyright := sf_get_string(StreamIn[x].HandleSt, SF_STR_COPYRIGHT);
StreamIn[x].Info.software := sf_get_string(StreamIn[x].HandleSt, SF_STR_SOFTWARE);
StreamIn[x].Info.comment := sf_get_string(StreamIn[x].HandleSt, SF_STR_COMMENT);
StreamIn[x].Info.date := sf_get_string(StreamIn[x].HandleSt, SF_STR_DATE);
StreamIn[x].Info.Lengthst := sf_Seek(StreamIn[x].HandleSt, 0, SEEK_END);
sf_seek(StreamIn[x].HandleSt, 0, SEEK_SET);
StreamIn[x].Enabled := False;
err := 0;
end;
end;
if ((StreamIn[x].info.LibOpen = -1)) and (UOSLoadresult.MPloadERROR = 0) and
((UOSloadflag = LoadAll) or (UOSloadflag = LoadMP) or
(UOSloadflag = LoadPA_MP) or (UOSloadflag = LoadSF_MP)) then
begin
Err := -1;
StreamIn[x].HandleSt := mpg123_new(nil, Err);
if Err = 0 then begin
mpg123_open(StreamIn[x].HandleSt, PChar(FileName)) ;
end
else
StreamIn[x].info.LibOpen := -1;
if Err = 0 then
Err := mpg123_getformat(StreamIn[x].HandleSt,
StreamIn[x].info.samplerate, StreamIn[x].info.channels,
StreamIn[x].info.encoding);
if Err = 0 then
begin
StreamIn[x].info.filename := filename;
StreamIn[x].Info.Wantframes :=
length(StreamIn[x].InBuffer) div StreamIn[x].info.channels;
mpg123_info(StreamIn[x].HandleSt, MPinfo);
mpg123_id3(StreamIn[x].HandleSt, @mpid3v1, nil); ////////////// to do : add id2v2
StreamIn[x].info.title := trim(mpid3v1.title);
StreamIn[x].info.artist := mpid3v1.artist;
StreamIn[x].info.album := mpid3v1.album;
StreamIn[x].info.date := mpid3v1.year;
StreamIn[x].info.comment := mpid3v1.comment;
StreamIn[x].info.tag := mpid3v1.tag;
StreamIn[x].info.genre := mpid3v1.genre;
StreamIn[x].info.samplerateroot := MPinfo.rate;
StreamIn[x].info.samplerate := MPinfo.rate;
StreamIn[x].info.Format := MPinfo.layer;
StreamIn[x].info.frames := MPinfo.framesize;
StreamIn[x].info.lengthst := mpg123_length(StreamIn[x].HandleSt);
StreamIn[x].info.LibOpen := 1;
end
else
StreamIn[x].info.LibOpen := -1;
end;
if err <> 0 then
begin
MessageDlg('Cannot Open ' + FileName + '...', mtWarning, [mbYes], 0);
exit;
end
else
begin
StreamIn[x].Name := InName;
StreamIn[x].info.Status := 1;
StreamIn[x].info.isOpen := True;
StreamIn[x].Enabled := True;
StreamIn[x].Info.Position := 0;
StreamIn[x].info.OutFrames := 0;
StreamIn[x].Output := OutName ;
StreamIn[x].Info.Poseek := -1 ;
case StreamIn[x].info.LibOpen of
0 :
begin
StreamIn[x].info.ratio := StreamIn[x].info.Channels;
if SampleFormat = -1 then StreamIn[x].info.SampleFormat := 2
else StreamIn[x].info.SampleFormat := SampleFormat ;
end;
1 : begin
StreamIn[x].info.ratio := 2 * StreamIn[x].info.Channels;
StreamIn[x].info.SampleFormat := 2 ; /////// how to set mpg123 to float ?
// mpg123_param(StreamIn[x].HandleSt, 2, MPG123_FORCE_FLOAT,0); ///// do not work
end;
end;
end;
end;
end;
end;
procedure TUOS_Player.Execute;
var
// pf: PArFloat;
ps: PArShort;
pl: PArLong;
x, x2, x3 : integer;
begin
repeat
for x := 0 to high(StreamIn) do
begin
RTLeventWaitFor(evPause); ///// is there a pause waiting ?
RTLeventSetEvent(evPause);
if (StreamIn[x].HandleSt <> nil) and (StreamIn[x].info.Status = 1) and
(StreamIn[x].Enabled = True) then
begin
if StreamIn[x].Info.Poseek > -1 then begin ////// is there a seek waiting ?
case StreamIn[x].info.LibOpen of
0: sf_seek(StreamIn[x].HandleSt, StreamIn[x].Info.Poseek, SEEK_SET);
1: mpg123_seek(StreamIn[x].HandleSt, StreamIn[x].Info.Poseek, SEEK_SET);
end;
StreamIn[x].Info.Poseek := -1 ;
end;
StreamIn[x].Info.OutFrames := 0 ;
case StreamIn[x].info.LibOpen of ///// get current position
0: StreamIn[x].info.position := sf_seek(StreamIn[x].HandleSt, 0, SEEK_CUR);
1: StreamIn[x].info.position := mpg123_tell(StreamIn[x].HandleSt);
end;
//////// DSPin StreamIn[x].DSP[y].BeforeBuffProc
if (StreamIn[x].info.Status = 1) and (length(StreamIn[x].DSP) > 0) then
for x2 := 0 to high(StreamIn[x].DSP) do
if (StreamIn[x].DSP[x2].Enabled = true) and (StreamIn[x].DSP[x2].BefProc <> nil) then
StreamIn[x].DSP[x2].BefProc(StreamIn[x].HandleSt,StreamIn[x].InBuffer,StreamIn[x].DSP[x2].BefProcParam1,
StreamIn[x].DSP[x2].BefProcParam2,StreamIn[x].info.SampleFormat,StreamIn[x].info.Position,StreamIn[x].info.LibOpen) ;
///// end DSP BeforeProc
RTLeventWaitFor(evPause); ///// is there a pause waiting ?
RTLeventSetEvent(evPause);
case StreamIn[x].info.LibOpen of //////////// Here we are, reading the data and store it in buffer
0: case StreamIn[x].info.SampleFormat of
0 : StreamIn[x].Info.OutFrames := sf_read_float(StreamIn[x].HandleSt, @StreamIn[x].InBuffer[0],StreamIn[x].info.Wantframes);
1 : StreamIn[x].Info.OutFrames := sf_read_int(StreamIn[x].HandleSt, @StreamIn[x].InBuffer[0],StreamIn[x].info.Wantframes);
2 : StreamIn[x].Info.OutFrames := sf_read_short(StreamIn[x].HandleSt, @StreamIn[x].InBuffer[0],StreamIn[x].info.Wantframes);
end;
1: mpg123_read(StreamIn[x].HandleSt, @StreamIn[x].InBuffer[0],StreamIn[x].Info.wantframes, StreamIn[x].Info.outframes);
/////// To do : allow float32 and int32 for mpg123
end;
if StreamIn[x].Info.OutFrames < 1 then StreamIn[x].Info.status := 0; //////// no more data then close the stream
//////// DSPin AfterBuffProc
if (StreamIn[x].info.Status = 1) and (length(StreamIn[x].DSP) > 0) then
for x2 := 0 to high(StreamIn[x].DSP) do
if (StreamIn[x].DSP[x2].Enabled = true) and (StreamIn[x].DSP[x2].AftProc <> nil) then
StreamIn[x].InBuffer :=
StreamIn[x].DSP[x2].AftProc(StreamIn[x].HandleSt,StreamIn[x].InBuffer,StreamIn[x].DSP[x2].AftProcParam1,
StreamIn[x].DSP[x2].AftProcParam2,StreamIn[x].info.SampleFormat,StreamIn[x].info.Position,StreamIn[x].info.LibOpen) ;
///// End DSPin AftterBuffProc
end;
end; ////////
////////////////// Seeking if InStream is terminated
if status > 0 then
begin
status := 0 ;
for x := 0 to high(StreamIn) do if(StreamIn[x].HandleSt <> nil) and (StreamIn[x].info.Status = 1) then status := 1;
end;
//////////////////////// Give Buffer to Output
RTLeventWaitFor(evPause);
RTLeventSetEvent(evPause);
if status = 1 then for x := 0 to high(StreamOut) do
if (StreamOut[x].HandleSt <> nil) and (StreamOut[x].Enabled = True) then
begin
for x2 := 0 to high(StreamOut[x].outBuffer) do StreamOut[x].OutBuffer[x2] := 0; ////// clear output
for x2 := 0 to high(StreamIn) do if (StreamIn[x2].HandleSt <> nil) and (StreamIn[x2].Enabled = True)
and (pos(StreamOut[x].Name,StreamIn[x2].Output) > 0) then
//////// copy buffer-in into buffer-out
for x3 := 0 to high(StreamIn[x2].InBuffer) do StreamOut[x].OutBuffer[x3] := StreamOut[x].OutBuffer[x3] + StreamIn[x2].InBuffer[x3];
//////// DSPOut AfterBuffProc
if (length(StreamOut[x].DSP) > 0) then
for x3 := 0 to high(StreamOut[x].DSP) do
if (StreamOut[x].DSP[x3].Enabled = true) and (StreamOut[x].DSP[x3].AftProc <> nil) then
StreamOut[x].DSP[x3].AftProc(StreamOut[x].HandleSt,StreamOut[x].OutBuffer,StreamOut[x].DSP[x3].AftProcParam1,
StreamOut[x].DSP[x3].AftProcParam2,StreamOut[x].SampleFormat,-1,-1) ;
///// end DSPOut AfterBuffProc
///////// Finally give buffer to output
Pa_WriteStream(StreamOut[x].HandleSt, @StreamOut[x].OutBuffer[0],StreamIn[x2].Info.outframes div StreamIn[x2].Info.ratio);
end;
until status = 0;
////////////////////////////////////////////////////////// end of loop
////////////////////////// Terminate Thread
if status = 0 then
begin
for x := 0 to high(StreamOut) do
if (StreamOut[x].HandleSt <> nil) then
begin
Pa_StopStream(StreamOut[x].HandleSt);
Pa_CloseStream(StreamOut[x].HandleSt);
end;
for x := 0 to high(StreamIn) do
if (StreamIn[x].HandleSt <> nil) then
case StreamIn[x].info.LibOpen of
0: sf_close(StreamIn[x].HandleSt);
1: mpg123_close(StreamIn[x].HandleSt);
end;
if EndProc <> nil then EndProc; ///// Execute EndProc procedure
Terminate;
end;
end;
constructor TUOS_Player.Create(CreateSuspended: boolean; const StackSize: SizeUInt);
begin
inherited Create(CreateSuspended, StackSize);
FreeOnTerminate := True;
evPause := RTLEventCreate;
Enabled := False;
status := 2;
setlength(StreamIn, 1);
setlength(StreamOut, 1);
StreamIn[0] := TUOS_InStream.Create;
StreamOut[0] := TUOS_OutStream.Create;
StreamIn[0].Name := '';
StreamOut[0].Name := '';
StreamOut[0].HandleSt := nil;
StreamIn[0].HandleSt := nil;
end;
destructor TUOS_Player.Destroy;
var
x : integer;
begin
RTLeventdestroy(evPause);
for x := 0 to high(StreamOut) do StreamOut[x].Free;
for x := 0 to high(StreamIn) do StreamIn[x].Free;
inherited Destroy;
end;
destructor TUOS_InStream.Destroy;
var
x : integer;
begin
for x := 0 to high(DSP) do DSP[x].Free;
inherited Destroy;
end;
destructor TUOS_OutStream.Destroy;
var
x : integer;
begin
for x := 0 to high(DSP) do DSP[x].Free;
inherited Destroy;
end;
procedure TUOS_Init.UnLoadLib();
begin
Sf_Unload();
Mp_Unload();
Pa_Unload();
end;
procedure TUOS_Init.InitLib();
begin
if (LoadResult.MPloadERROR = 0) and ((flag = LoadAll) or (flag = LoadMP) or
(flag = LoadPA_MP) or (flag = LoadSF_MP)) then
if mpg123_init() = MPG123_OK then
LoadResult.MPinitError := 0
else
LoadResult.MPinitError := 1;
if (LoadResult.PAloadERROR = 0) and ((flag = LoadAll) or (flag = LoadPA) or
(flag = LoadPA_SF) or (flag = LoadPA_MP)) then
begin
LoadResult.PAinitError := Pa_Initialize();
if LoadResult.PAinitError = 0 then
begin
DefOut := Pa_GetDefaultOutputDevice();
DEVinfo := Pa_GetDeviceInfo(DefOut);
APIinfo := Pa_GetHostApiInfo(DEVinfo^.hostApi);
end;
end;
end;
procedure TUOS_Init.LoadLib();
begin
case flag of
LoadAll:
begin
if not fileexists(PA_FileName) then
LoadResult.PAloadERROR := 1
else
if Pa_Load(PA_FileName) then
LoadResult.PAloadERROR := 0
else
LoadResult.PAloadERROR := 2;
if not fileexists(SF_FileName) then
LoadResult.SFloadERROR := 1
else
if Sf_Load(SF_FileName) then
LoadResult.SFloadERROR := 0
else
LoadResult.SFloadERROR := 2;
if not fileexists(MP_FileName) then
LoadResult.MPloadERROR := 1
else
if mp_Load(Mp_FileName) then
LoadResult.MPloadERROR := 0
else
LoadResult.MPloadERROR := 2;
end;
LoadPA:
begin
if not fileexists(PA_FileName) then
LoadResult.PAloadERROR := 1
else
if Pa_Load(PA_FileName) then
LoadResult.PAloadERROR := 0
else
LoadResult.PAloadERROR := 2;
end;
LoadSF:
begin
if not fileexists(SF_FileName) then
LoadResult.SFloadERROR := 1
else
if Sf_Load(SF_FileName) then
LoadResult.SFloadERROR := 0
else
LoadResult.SFloadERROR := 2;
end;
LoadMP:
begin
if not fileexists(MP_FileName) then
LoadResult.MPloadERROR := 1
else
if mp_Load(Mp_FileName) then
LoadResult.MPloadERROR := 0
else
LoadResult.MPloadERROR := 2;
end;
LoadPA_SF:
begin
if not fileexists(PA_FileName) then
LoadResult.PAloadERROR := 1
else
if Pa_Load(PA_FileName) then
LoadResult.PAloadERROR := 0
else
LoadResult.PAloadERROR := 2;
if not fileexists(SF_FileName) then
LoadResult.SFloadERROR := 1
else
if Sf_Load(SF_FileName) then
LoadResult.SFloadERROR := 0
else
LoadResult.SFloadERROR := 2;
end;
LoadPA_MP:
begin
if not fileexists(MP_FileName) then
LoadResult.MPloadERROR := 1
else
if MP_Load(Mp_FileName) then
LoadResult.MPloadERROR := 0
else
LoadResult.MPloadERROR := 2;
if not fileexists(PA_FileName) then
LoadResult.PAloadERROR := 1
else
if Pa_Load(PA_FileName) then
LoadResult.PAloadERROR := 0
else
LoadResult.PAloadERROR := 2;
end;
LoadSF_MP:
begin
if not fileexists(SF_FileName) then
LoadResult.SFloadERROR := 1
else
if SF_Load(SF_FileName) then
LoadResult.SFloadERROR := 0
else
LoadResult.SFloadERROR := 2;
if not fileexists(MP_FileName) then
LoadResult.MPloadERROR := 1
else
if mp_Load(Mp_FileName) then
LoadResult.MPloadERROR := 0
else
LoadResult.MPloadERROR := 2;
end;
end;
end;
constructor TUOS_Init.Create;
begin
flag := 0;
LoadResult.PAloadERROR := -1;
LoadResult.SFloadERROR := -1;
LoadResult.MPloadERROR := -1;
LoadResult.PAinitError := -1;
LoadResult.MPinitError := -1;
end;
end.