unit threadedencode; interface uses Classes,lamenc_nice_interface,windows,id3,sysutils,global,forms; type tmp3encode = class(TThread) private { Private declarations } mes : string; c : dword; cmax : integer; size : dword; ftracknumber : integer; finfile, foutfile : string; ftrackname,falbumname,fartistname : string; ffinished : boolean; protected procedure Execute; override; procedure log; procedure setprogsize; procedure stopmpifnec; procedure progvis; procedure prognotvis; procedure writethetag; public property tracknumber : integer read ftracknumber write ftracknumber; property infile : string read finfile write finfile; property outfile : string read foutfile write foutfile; property trackname : string read ftrackname write ftrackname; property albumname : string read falbumname write falbumname; property artistname : string read fartistname write fartistname; property finished : boolean read ffinished; property position : dword read c write c; end; implementation uses empripmain,main,jukeboxform; { Important: Methods and properties of objects in VCL can only be used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure mp3encode.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; } { mp3encode } procedure tmp3encode.writethetag; var ti : tid3tag; begin ti.track:=ftrackname; ti.artist:=fartistname; ti.album:=falbumname; ti.genre:=#0#0; ti.field:='TAG'; writetag(foutfile,ti); end; procedure tmp3encode.progvis; begin //ripmain.encprogress.visible:=true; end; procedure tmp3encode.prognotvis; begin //ripmain.encprogress.visible:=false; //ripmain.encprogress.position:=1; //ripmain.encprogress.max:=1; end; procedure tmp3encode.stopmpifnec; var key : word; o : thandle; begin if uppercase(mainform.mp.filename)=uppercase(foutfile) then begin logent('Track in use, rejecting current track'); {mainform.stopclick(nil); mainform.mp.close; mainform.mp.filename:=cachepath+'\blank.mp3'; mainform.mp.open;} key:=VK_MULTIPLY; jukebox.FormKeydown(nil,key,[]); o:=CreateFile(pchar(foutfile),GENERIC_READ,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,FILE_FLAG_SEQUENTIAL_SCAN); if o=INVALID_HANDLE_VALUE then begin mainform.mp.close; mainform.mp.filename:=cachepath+'\blank.mp3'; mainform.mp.open; end else closehandle(o); end; end; procedure tmp3encode.log; begin logent(' '+mes); end; procedure tmp3encode.setprogsize; begin //ripmain.encprogress.position:=0; //ripmain.encprogress.max:=cmax; end; procedure tmp3encode.Execute; var hand : THBESTREAM; bc : Tbeconfig; bufsize,samples : dword; ibuf,obuf : pointer; written : dword; i,o : thandle; res : dword; done : dword; IsWritten,toread,isread : dword; success : boolean; progressunit : real; tknm : integer; begin returnvalue:=0; progressunit:=0; ffinished:=false; success:=true; tknm:=ftracknumber; mes:='Encoding data for track '+inttostr(tknm)+' "'+ftrackname+'"'; synchronize(log); i:=createfile(pchar(finfile),GENERIC_READ,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_TEMPORARY,0); if (i=INVALID_HANDLE_VALUE) then begin mes:='Error opening extracted wave file:'+finfile; synchronize(log); //cancelop:=true; ffinished:=true; synchronize(prognotvis); exit; end; //Check mp does not have file and close if necesay synchronize(stopmpifnec); o:=CreateFile(pchar(foutfile),GENERIC_WRITE,0,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); if (o=INVALID_HANDLE_VALUE) then begin mes:='Error creating output file:'+finfile; synchronize(log); //cancelop:=true; ffinished:=true; closehandle(i); synchronize(prognotvis); exit; end; bc.format.dwconfig:=BE_CONFIG_MP3; bc.format.mp3.dwSampleRate:=44100; bc.format.mp3.byMode:=BE_MP3_MODE_STEREO; bc.format.mp3.wbitrate:=config.bitrate; bc.format.mp3.bcopyright:=false; bc.format.mp3.bCRC:=true; bc.format.mp3.bOriginal:=false; bc.format.mp3.bPrivate:=false; res:=beInitStream(bc,samples,bufsize,hand); if res=BE_ERR_SUCCESSFUL then begin getmem(ibuf,(bufsize*2)); getmem(obuf,(samples*2)); size:=getfilesize(i,nil); cmax:=100; if size<>0 then progressunit := cmax / size; c:=0; synchronize(setprogsize); synchronize(progvis); done:=0; while(done<>size) do begin if (done+(samples*2)<size) then toread:=samples*2 else toRead:=size-done; readfile(i,ibuf^,toRead,isRead,nil); //isRead:=i.Read(ibuf^,toRead); if isread<>toread then begin mes:='Error reading input file: "'+ftrackname; synchronize(log); success:=false; break; end; if beEncodeChunk(hand,(toread div 2),ibuf,obuf,written) <> BE_ERR_SUCCESSFUL then begin mes:='Error encoding data: track '+inttostr(tknm)+' "'+ftrackname+'"'; synchronize(log); success:=false; break; end; WriteFile(o,obuf^,written,IsWritten,nil); if terminated=true then begin mes:='Aborting encoding data: "'+ftrackname+'"'; synchronize(log); success:=false; break; end; //IsWritten:=o.Write(obuf^,written); //Combing signed and unisigned error so typecast to dword if IsWritten<>dword(written) then begin mes:='Error writing output file: "'+ftrackname+'"'; synchronize(log); success:=false; break; end; done:=done+toread; c:=round(done*progressunit); end; beDeinitStream(hand,obuf,written); WriteFile(o,obuf^,written,dword(IsWritten),nil); beCloseStream(hand); freemem(ibuf); freemem(obuf); if success=false then begin mes:='Aborted encoding data for '+inttostr(tknm)+' "'+ftrackname+'"'; synchronize(log); end; ffinished:=true; end else begin mes:='Error Initalizing Encoder'; synchronize(log); end; c:=cmax; closehandle(o); closehandle(i); //Tag MP3 files if success=true then begin synchronize(writethetag); end; deletefile(finfile); if success=false then deletefile(foutfile); synchronize(prognotvis); c:=0; ffinished:=true; end; end.