304 lines
6.0 KiB
ObjectPascal

(*
this file is a part of audio components suite
see the license file for more details.
you can contact me at mail@z0m3ie.de
this is an sample unit for an driver
*)
unit driver;
interface
uses
ACS_Audio,SysUtils, Classes, ACS_Types, ACS_Classes, ACS_Strings;
const
LATENCY = 25;
type
TOwnAudioOut = class(TACSBaseAudioOut)
private
EndOfInput, StartInput : Boolean;
FDeviceNumber : Integer;
FDeviceCount : Integer;
procedure SetDevice(Ch : Integer);override;
function GetDeviceInfo : TACSDeviceInfo;override;
function GetDeviceCount : Integer;override;
protected
procedure Done; override;
function DoOutput(Abort : Boolean):Boolean; override;
procedure Prepare; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Pause;override;
procedure Resume;override;
end;
TOwnAudioIn = class(TACSBaseAudioIn)
private
FDeviceNumber : Integer;
FDeviceCount : Integer;
FBPS, FChan, FFreq : Integer;
FOpened : Integer;
FRecTime : Integer;
procedure SetDevice(i : Integer);override;
procedure OpenAudio;
procedure CloseAudio;
function GetBPS : Integer; override;
function GetCh : Integer; override;
function GetSR : Integer; override;
function GetTotalTime : real; override;
procedure SetRecTime(aRecTime : Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetData(Buffer : Pointer; BufferSize : Integer): Integer; override;
procedure Init; override;
procedure Flush; override;
end;
implementation
procedure TOwnAudioOut.Prepare;
begin
FInput.Init;
FBuffer := AllocMem(FBufferSize);
StartInput := True;
EndOfInput := False;
//Init your output device here
end;
procedure TOwnAudioOut.Done;
begin
//Flush your output device here
Finput.Flush;
FreeMem(FBuffer);
end;
function TOwnAudioOut.DoOutput(Abort : Boolean):Boolean;
var
Len, offs, lb : Integer;
Stat : LongWord;
Res : HRESULT;
PlayTime, CTime : LongWord;
begin
Result := True;
if not Busy then Exit;
if not CanOutput then
begin
Result := False;
Exit;
end;
if StartInput then
begin
Len := 0;
while Len < FBufferSize do
begin
offs := FInput.GetData(@FBuffer^[Len], FBufferSize-Len);
if offs = 0 then
begin
EndOfInput := True;
Break;
end;
Inc(Len, offs);
end;
//Do Output Len bytes from FBuffer^
StartInput := False;
end;
if Abort then
begin
//Stop your output device
CanOutput := False;
Result := False;
Exit;
end;
if EndOfInput then
begin
CanOutput := False;
//Stop your output device
Result := False;
Exit;
end;
end;
constructor TOwnAudioOut.Create;
begin
inherited Create(AOwner);
FBufferSize := $40000;
//enumerate devices and set Devicecount
FDeviceCount := 0;
end;
destructor TOwnAudioOut.Destroy;
begin
//Wahtever
end;
procedure TOwnAudioOut.Pause;
begin
if EndOfInput then Exit;
//Pause
end;
procedure TOwnAudioOut.Resume;
begin
if EndOfInput then Exit;
//waht schoud i say ?
end;
procedure TOwnAudioOut.SetDevice(Ch: Integer);
begin
FBaseChannel := Ch;
end;
function TOwnAudioOut.GetDeviceInfo: TACSDeviceInfo;
begin
if (FBaseChannel >= FDeviceCount) then
exit;
//return an Deviceinfo
end;
function TOwnAudioOut.GetDeviceCount: Integer;
begin
Result := FDeviceCount;
end;
constructor TOwnAudioIn.Create;
begin
inherited Create(AOwner);
FBPS := 8;
FChan := 1;
FFreq := 8000;
FSize := -1;
BufferSize := $2000;
//enumerate devices and set Devicecount
FDeviceCount := 0;
end;
destructor TOwnAudioIn.Destroy;
begin
//whatever
inherited Destroy;
end;
procedure TOwnAudioIn.OpenAudio;
var
Res : HResult;
BufSize : Integer;
begin
BufSize := BufferSize;
if FOpened = 0 then
begin
//Init your In put device
end;
Inc(FOpened);
end;
procedure TOwnAudioIn.CloseAudio;
begin
if FOpened = 1 then
begin
//Flush your Input device
end;
if FOpened > 0 then Dec(FOpened);
end;
function TOwnAudioIn.GetBPS : Integer;
begin
Result := FBPS;
end;
function TOwnAudioIn.GetCh : Integer;
begin
Result := FChan;
end;
function TOwnAudioIn.GetSR : Integer;
begin
Result := FFreq;
end;
procedure TOwnAudioIn.Init;
begin
if Busy then raise EACSException.Create(strBusy);
if (FDeviceNumber >= FDeviceCount) then raise EACSException.Create(Format(strChannelnotavailable,[FDeviceNumber]));
if FRecTime > 0 then FBytesToRead := FRecTime*FFreq*FChan*(FBPS div 8);
BufEnd := 0;
BufStart := 1;
FPosition := 0;
Busy := True;
FSize := FBytesToRead;
OpenAudio;
end;
procedure TOwnAudioIn.Flush;
begin
CloseAudio;
Busy := False;
end;
function TOwnAudioIn.GetData(Buffer : Pointer; BufferSize : Integer): Integer;
var
l : Integer;
begin
if not Busy then raise EACSException.Create(strStreamnotopen);
if (FBytesToRead >=0) and (FPosition >= FBytesToRead) then
begin
Result := 0;
Exit;
end;
if BufStart >= BufEnd then
begin
BufStart := 0;
//Read Buffersize bytes from your input device and convert to PCM
//l is the real readed size maybe you cant ead the full buffer jet
BufEnd := l;
end;
if BufferSize < (BufEnd - BufStart)
then Result := BufferSize
else Result := BufEnd - BufStart;
Move(FBuffer[BufStart], Buffer^, Result);
Inc(BufStart, Result);
Inc(FPosition, Result);
end;
procedure TOwnAudioIn.SetRecTime;
begin
FRecTime := aRecTime;
if FRecTime > 0 then
FBytesToRead := FRecTime*FFreq*FChan*(FBPS div 8)
else
FBytesToRead := -1;
end;
procedure TOwnAudioIn.SetDevice(i : Integer);
begin
FDeviceNumber := i
end;
function TOwnAudioIn.GetTotalTime : real;
var
BytesPerSec : Integer;
begin
BytesPerSec := FFreq*FChan*(FBPS div 8);
Result := FBytesToRead/BytesPerSec;
end;
initialization
RegisterAudioOut('My Drivers Name',TOwnAudioOut,LATENCY);
RegisterAudioIn('My Drivers Name',TOwnAudioIn,LATENCY);
finalization
end.