304 lines
6.0 KiB
ObjectPascal
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.
|