//drony@mynet.com
//icq:266148308
{component}
unit ToneGen;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs
,mmsystem,Math;
//default values
const
AttDef=10;
HoldDef=5;
DecDef=20;
SusDef=50;
RelDef=30;
DurDef=100;
FreDef=440;
VolDef=100;
AMLevels=7;
MaxFreq=20000;
MinFreq=20;
type
TTGPercentage = 0..100;
TTGWave = (tgSine,tgSquare,tgTriangle,tgSawtooth,tgNoise);
TTGResolution = (tg16Bit,tg8Bit);
TTGQuality = (tgHiQ,tgLoQ);
TTGAMLevel = (tgAMLevel1,tgAMLevel2,tgAMLevel3,tgAMLevel4,tgAMLevel5,tgAMLevel6,tgAMLevel7,tgAMLevel8);
TToneGen = class(TComponent)
private
{ Private declarations }
HasChanged: bool;
HasADSRChanged: bool;
HasToneChanged: bool;
HasStopped: bool;
Buffer: PChar;
BufferSize: Integer;
fFrequency: Smallint;
fDuration: Smallint;
fWaveform: TTGWave;
fAttack: Smallint;
fHold: Smallint;
fDecay: Smallint;
fSustain: Smallint;
fRelease: Smallint;
fAsync: bool;
fLoop: bool;
fResolution: TTGResolution;
fQuality: TTGQuality;
fLeftVolume: Smallint;
fRightVolume: Smallint;
DeviceID: Integer;
fStereo: bool;
fAMAmplitude: Smallint;
fAMWaveform: TTGWave;
fAMFrequency: Single;
fAMUseMultiplier: bool;
Octave: Integer;
fAMLevel: TTGAMLevel;
AMAmpArray: array[0..AMLevels] of Smallint;
AMWaveArray: array[0..AMLevels] of TTGWave;
AMFreqArray: array[0..AMLevels] of Single;
AMOctaves: array[0..AMLevels] of Integer;
procedure SetFrequency(Freq: Smallint);
procedure SetDuration(Dur: Smallint);
procedure SetWaveform(Wave: TTGWave);
procedure SetAttack(Att: Smallint);
procedure SetHold(Hld: Smallint);
procedure SetDecay(Decy: Smallint);
procedure SetSustain(Sus: Smallint);
procedure SetRelease(Rel: Smallint);
procedure SetResolution(Res: TTGResolution);
procedure SetQuality(Qual: TTGQuality);
function GetVolume: DWORD;
procedure SetVolume;
procedure SetLeftVolume(LVol: Smallint);
procedure SetRightVolume(RVol: Smallint);
function CreateWaveform(DoADSR: bool): bool;
procedure ADSRWaveform(Buf: PChar;BufSize: Integer; DoStereo: bool);
procedure PlayWave;
function LimitValue(lower,upper,val: Smallint):Smallint;
function GetPercentage(PC: Smallint): Smallint;
procedure SetStereo(bstereo: bool);
procedure SetAMLevel(level: TTGAMLevel);
procedure SetAMAmplitude(Amp: Smallint);
procedure SetAMWaveform(Wave: TTGWave);
procedure SetAMFrequency(Freq: Single);
procedure SetAMMultiplier(setit: bool);
//DefineProperties procedures
procedure ReadAMArrayData(Stream: TStream);
procedure WriteAMArrayData(Stream: TStream);
class function InstanceCount: Integer;
class function GetOriginalVolume: DWORD;
protected
{ Protected declarations }
//write array data
procedure DefineProperties(Filer:TFiler);override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Frequency: Smallint read fFrequency write SetFrequency default FreDef;
property Duration: Smallint read fDuration write SetDuration default DurDef;
property Waveform: TTGWave read fWaveform write SetWaveform default tgSine;
property Attack: Smallint read fAttack write SetAttack default AttDef;
property Hold: Smallint read fHold write SetHold default HoldDef;
property Decay: Smallint read fDecay write SetDecay default DecDef;
property Sustain: Smallint read fSustain write SetSustain default SusDef;
property Release: Smallint read fRelease write SetRelease default RelDef;
property Async: bool read fAsync write fAsync default true;
property Loop: bool read fLoop write fLoop default false;
property Resolution: TTGResolution read fResolution write SetResolution default tg16Bit;
property Quality: TTGQuality read fQuality write SetQuality default tgHiQ;
property LeftVolume: Smallint read fLeftVolume write SetLeftVolume default VolDef;
property RightVolume: Smallint read fRightVolume write SetRightVolume default VolDef;
property Stereo: bool read fStereo write SetStereo default false;
property AMLevel: TTGAMLevel read fAMLevel write SetAMLevel default tgAMLevel1;
property AMAmplitude: Smallint read fAMAmplitude write SetAMAmplitude nodefault;
property AMWaveform: TTGWave read fAMWaveform write SetAMWaveform nodefault;
property AMFrequency: Single read fAMFrequency write SetAMFrequency nodefault;
property AMUseMultiplier: bool read fAMUseMultiplier write SetAMMultiplier default true;
procedure Play;
procedure PlayADSR;
procedure Stop;
procedure PresetVolume;
procedure Prepare;
procedure PrepareADSR;
procedure ResetAM;
procedure SetAMParameter(Level: TTGAMLevel;Freq: Single; Amp: Smallint; Wav:TTGWave);
function GetDataBuffer: PChar;
function ExportFile(FileName: String): bool;
function SetNote(NoteString:String): Integer;
function SetAMNote(Level: TTGAMLevel;NoteString:String): Single;
end;
procedure Register;
implementation
type
{ format of WAV file header }
TWavHeader = record { parameter description }
rId : longint; { 'RIFF' 4 characters }
rLen : longint; { length of DATA + FORMAT chunk }
{ FORMAT CHUNK }
wId : longint; { 'WAVE' }
fId : longint; { 'fmt ' }
fLen : longint; { length of FORMAT DATA = 16 }
{ format data }
wFormatTag : word; { $01 = PCM }
nChannels : word; { 1 = mono, 2 = stereo }
nSamplesPerSec : longint; { Sample frequency ie 11025}
nAvgBytesPerSec : longint; { = nChannels * nSamplesPerSec *
(nBitsPerSample/8) }
nBlockAlign : word; { = nChannels * (nBitsPerSAmple / 8 }
wBitsPerSample : word; { 8 or 16 }
{ DATA CHUNK }
dId : longint; { 'data' }
wSampleLength : longint; { length of SAMPLE DATA }
{ sample data : offset 44 }
{ for 8 bit mono = s[0],s[1]... :byte}
{ for 8 bit stereo = sleft[0],sright[0],sleft[1],sright[1]... :byte}
{ for 16 bit mono = s[0],s[1]... :word}
{ for 16 bit stereo = sleft[0],sright[0],sleft[1],sright[1]... :word}
end;
var
TTGCount: Integer=0;
OriginalVolume: DWORD=0;
procedure Register;
begin
RegisterComponents('Plus', [TToneGen]);
end;
//limit value
function TToneGen.LimitValue(lower,upper,val: Smallint):Smallint;
var
msg:String;
begin
if (val>=lower) and (val<=upper) then
begin
Result:=val;
Exit;
end;
//error message?
if csDesigning in ComponentState then
begin
msg:='Value must be between '+IntToStr(lower)+' and '+IntToStr(upper);
MessageBox(0,PChar(msg),'Error',MB_OK or MB_ICONERROR);
end;
if val>upper then
Result:=upper
else
Result:=lower;
end;
//limit values 0 to 100 **********************************************
//if designing give warning
//force to limits
function TToneGen.GetPercentage(PC: Smallint):Smallint;
begin
Result:=LimitValue(0,100,PC);
end;
//preset tone and volume settings **********************************************
procedure TToneGen.Prepare;
begin
//setup volume
SetVolume;
//create wave
CreateWaveform(false);
end;
//set mono or stereo **********************************************
procedure TToneGen.SetStereo(bstereo: bool);
begin
HasChanged:=true;
fStereo:=bstereo;
end;
//preset ADSR and volume settings **********************************************
procedure TToneGen.PrepareADSR;
begin
//setup volume
SetVolume;
//create wave
CreateWaveform(true);
end;
//preset volume levels **********************************************
procedure TToneGen.PresetVolume;
begin
//setup volume
SetVolume;
end;
//play sound **********************************************
procedure TToneGen.PlayWave;
var
Flags: DWORD;
begin
//stop any sounds first
Stop;
//setup volume
SetVolume;
Flags:=SND_SYNC;
if fAsync then Flags:=SND_ASYNC;
if fLoop then Flags:=SND_ASYNC or SND_LOOP;
Flags:=Flags or SND_MEMORY;
//play data in buffer
if Buffer<>nil then
PlaySound(Buffer, 0, Flags);
end;
//play simple tone **********************************************
procedure TToneGen.Play;
begin
if HasChanged or HasToneChanged then
CreateWaveform(false);
HasStopped:=false;
PlayWave;
//flag as having finished?
HasStopped:=not(Async or Loop);
end;
//play enveloped tone **********************************************
procedure TToneGen.PlayADSR;
begin
if HasChanged or HasADSRChanged then
CreateWaveform(true);
HasStopped:=false;
PlayWave;
//flag as having finished?
HasStopped:=not(Async or Loop);
end;
//stop sound **********************************************
procedure TToneGen.Stop;
begin
//stop any sounds
PlaySound(nil, 0, 0);
//flag as having finished
HasStopped:=true;
end;
//get waveform volume **********************************************
function TToneGen.GetVolume: DWORD;
var
vol: DWORD;
wocs: WAVEOUTCAPS;
CanDoLR: bool;
begin
vol:=0;
//can do left & right?
waveOutGetDevCaps(DeviceID,@wocs,sizeof(WAVEOUTCAPS));
if(wocs.dwFormats and WAVECAPS_LRVOLUME)>0 then
CanDoLR:=true
else
CanDoLR:=false;
//get volume?
waveOutGetVolume(DeviceID,@vol);
//copy mono level to right channel?
if not CanDoLR then
vol:=vol+(vol shl $10);
Result:=vol;
end;
//set waveform volume **********************************************
procedure TToneGen.SetVolume;
var
newvol: DWORD;
begin
//combine percentages
newvol:=(($ffff * fLeftVolume) div 100)+((($ffff * fRightVolume) div 100) shl $10);
//set volume
waveOutSetVolume(DeviceID,newvol);
end;
//return original volume setting **********************************************
class function TToneGen.GetOriginalVolume: DWORD;
begin
Result:=OriginalVolume;
end;
//constructor **********************************************
constructor TToneGen.Create(AOwner: TComponent);
var
i: Integer;
begin
Inherited Create(AOwner);
HasChanged:=true;
HasADSRChanged:=true;
HasToneChanged:=true;
HasStopped:=true;
Buffer:=nil;
BufferSize:=0;
fFrequency:=FreDef;
fDuration:=DurDef;
fWaveform:=tgSine;
fAttack:=AttDef;
fHold:=HoldDef;
fDecay:=DecDef;
fSustain:=SusDef;
fRelease:=RelDef;
fAsync:=true;
fLoop:=false;
fResolution:=tg16Bit;
fQuality:=tgHiQ;
fLeftVolume:=VolDef;
fRightVolume:=VolDef;
fStereo:=false;
fAMUseMultiplier:=true;
Octave:=4;
//amplitude modulation settings
fAMLevel:=tgAMLevel1;
ResetAM;
fAMFrequency:=AMFreqArray[Integer(fAMLevel)];
fAMWaveform:=AMWaveArray[Integer(fAMLevel)];
fAMAmplitude:=AMAmpArray[Integer(fAMLevel)];
for i:=0 to AMLevels do
begin
AMOctaves[i]:=Octave;
end;
DeviceID:=0;
//store volume settings
if (InstanceCount=0) and not(csDesigning in ComponentState)then
begin
//store original settings
OriginalVolume:=GetVolume;
//initialise volume
SetVolume;
end;
//increment instance count
Inc(TTGCount);
end;
//destructor **********************************************
destructor TToneGen.Destroy;
var
OV: DWORD;
begin
//stop playing
Stop;
//de-allocate memory
If Buffer<>nil then
begin
FreeMem(Buffer);
Buffer:=nil;
BufferSize:=0;
end;
//decrement instance count
Dec(TTGCount);
//restore volume settings
if (TTGCount=0) and not(csDesigning in ComponentState) then
begin
OV:=GetOriginalVolume;
waveOutSetVolume(DeviceID,OV);
end;
inherited Destroy;
end;
//instance count **********************************************
class function TToneGen.InstanceCount: Integer;
begin
Result:=TTGCount;
end;
//set left volume **********************************************
procedure TToneGen.SetLeftVolume(LVol: Smallint);
begin
fLeftVolume:=GetPercentage(LVol);
//initialise volume
if (csLoading in ComponentState) or HasStopped then
SetVolume;
end;
//set right volume **********************************************
procedure TToneGen.SetRightVolume(RVol: Smallint);
begin
fRightVolume:=GetPercentage(RVol);
//initialise volume
if (csLoading in ComponentState) or HasStopped then
SetVolume;
end;
//set frequency **********************************************
procedure TToneGen.SetFrequency(Freq: Smallint);
begin
HasChanged:=true;
fFrequency:=LimitValue(MinFreq,MaxFreq,Freq);
end;
//duration **********************************************
procedure TToneGen.SetDuration(Dur: Smallint);
begin
HasChanged:=true;
fDuration:=LimitValue(10,$7FFF,Dur);
end;
//wave type **********************************************
procedure TToneGen.SetWaveform(Wave: TTGWave);
begin
HasChanged:=true;
fWaveform:=Wave;
end;
//attack **********************************************
procedure TToneGen.SetAttack(Att: Smallint);
begin
HasADSRChanged:=true;
fAttack:=GetPercentage(Att);
end;
//hold **********************************************
procedure TToneGen.SetHold(Hld: Smallint);
begin
HasADSRChanged:=true;
fHold:=GetPercentage(Hld);
end;
//decay **********************************************
procedure TToneGen.SetDecay(Decy: Smallint);
begin
HasADSRChanged:=true;
fDecay:=GetPercentage(Decy);
end;
//sustain **********************************************
procedure TToneGen.SetSustain(Sus: Smallint);
begin
HasADSRChanged:=true;
fSustain:=GetPercentage(Sus);
end;
//release **********************************************
procedure TToneGen.SetRelease(Rel: Smallint);
begin
HasADSRChanged:=true;
fRelease:=GetPercentage(Rel);
end;
//8 or 16 bit **********************************************
procedure TToneGen.SetResolution(Res: TTGResolution);
begin
HasChanged:=true;
fResolution:=Res;
end;
//quality **********************************************
procedure TToneGen.SetQuality(Qual: TTGQuality);
begin
HasChanged:=true;
fQuality:=Qual;
end;
//create wave header ****************************************
procedure CreateWavHeader( stereo: bool;{ t=stereo f=mono }
hires : bool; { t=16bits, f=8 }
hirate : bool; { sample rate t=44100 f=22050}
datasize: longint; {date block size}
var wh: TWavHeader { Wavheader ref } );
var
resolution,channels: word;
rate: longint;
begin
//stereo/mono?
if stereo=true then
channels:=2
else
channels:=1;
//16bit/8bit?
if hires=true then
resolution:=16
else
resolution:=8;
//44100/22050 bps?
if hirate=true then
rate:=96000
else
rate:=44100;
wh.rId := $46464952; { 'RIFF' }
wh.rLen := datasize+36; { length of sample + format }
wh.wId := $45564157; { 'WAVE' }
wh.fId := $20746d66; { 'fmt ' }
wh.fLen := 16; { length of format chunk }
wh.wFormatTag := 1; { PCM data }
wh.nChannels := channels; { mono/stereo }
wh.nSamplesPerSec := rate; { sample rate }
wh.nAvgBytesPerSec := channels*rate*(resolution div 8);
wh.nBlockAlign := channels*(resolution div 8);
wh.wBitsPerSample := resolution;{ resolution 8/16 }
wh.dId := $61746164; { 'data' }
wh.wSampleLength := datasize; { sample size }
end;
//**********************************************************************
//modify data to ADSR settings
procedure TToneGen.ADSRWaveform(Buf: PChar;BufSize: Integer; DoStereo: bool);
var
Total,i: Cardinal;
Start,Samples,Cnt: Cardinal;
BufValue: Integer;
SampleFactor,SusFactor: Real;
Env,EnvDur: Cardinal;
SusDuration: Cardinal;
iBuffer: ^SmallInt;
ResFactor: Integer;
HoldV,AttackV,DecayV,SustainV,ReleaseV: Integer;
HiRes: bool;
ByteVal: Char;
WordVal: Smallint;
begin
if fResolution=tg16Bit then
begin
HiRes:=true;
end
else
begin
HiRes:=false;
end;
AttackV:=fAttack;
HoldV:=fHold;
DecayV:=fDecay;
SustainV:=fSustain;
ReleaseV:=fRelease;
//1/2 no of samples for 16bit
if HiRes then
ResFactor:=2
else
ResFactor:=1;
//1/2 no of samples for stereo
if DoStereo then
ResFactor:=ResFactor*2;
Total:=AttackV+HoldV+DecayV+ReleaseV;
//normalise percentages
if Total>100 then
begin
AttackV:=AttackV * 100 div Total;
HoldV:=HoldV * 100 div Total;
DecayV:=DecayV * 100 div Total;
ReleaseV:=100-(AttackV+HoldV+DecayV);
SusDuration:=0;
end;
SusDuration:=100-(AttackV+HoldV+DecayV+ReleaseV);
Samples:=SusDuration * BufSize div (100 * ResFactor);
//sustain level
SusFactor:=SustainV/100;
if Samples<1 then
begin
//SustainV:=0;
end;
Start:=0;
if HiRes then
begin
//create 16bit pointer
iBuffer:=Pointer(Buf);
end;
for Env:=0 to 4 do
begin
//envelope entry
case Env of
0://Attack
begin
EnvDur:=AttackV;
Samples:=EnvDur * BufSize div (100 * ResFactor);
if Samples>0 then
SampleFactor:=1/Samples
else
EnvDur:=0;
end;
1: //Hold
begin
EnvDur:=HoldV;
Samples:=EnvDur * BufSize div (100 * ResFactor);
if Samples>0 then
SampleFactor:=1
else
EnvDur:=0;
end;
2://Decay
begin
EnvDur:=DecayV;
Samples:=EnvDur * BufSize div (100 * ResFactor);
if Samples>0 then
SampleFactor:=(100-SustainV)/Samples/100
else
EnvDur:=0;
end;
3://Sustain
begin
EnvDur:=SusDuration;
if ReleaseV=0 then
begin
Samples:=BufSize div ResFactor;
if DoStereo then
Samples:=max(0,Samples-(Start div 2))
else
Samples:=max(0,Samples-Start);
end
else
begin
Samples:=EnvDur * BufSize div (100 * ResFactor);
end;
SampleFactor:=SusFactor;
end;
else//Release
begin
EnvDur:=ReleaseV;
Samples:=BufSize div ResFactor;
if DoStereo then
Samples:=Samples-(Start div 2)
else
Samples:=Samples-Start;
if Samples>0 then
SampleFactor:=SusFactor/Samples
else
begin
EnvDur:=0;
Samples:=0;
end;
end;
end;
//process envelope entry
if EnvDur >0 then
begin
if DoStereo then Samples:=Samples*2;
Cnt:=0;
i:=min(Start,BufSize);
while i<=min(BufSize,Start+Samples) do
begin
if HiRes then //16bit
begin
BufValue:=((iBuffer)^);
end
else//8bit
begin
BufValue:=Integer((Buf+i)^);
BufValue:=BufValue-$80;
end;
case Env of
0://Attack
begin
BufValue:=Trunc(Cnt * BufValue * SampleFactor);
end;
1://Hold
begin
//no change to value
end;
2://Decay
begin
BufValue:=BufValue-Trunc(Cnt * BufValue * SampleFactor);
end;
3://Sustain
begin
BufValue:=Trunc(BufValue * SampleFactor);
end;
4://Release
begin
if DoStereo then
BufValue:=Trunc(((Samples div 2)-Cnt) * BufValue * SampleFactor)
else
BufValue:=Trunc((Samples-Cnt) * BufValue * SampleFactor);
end;
end;
if HiRes then //16bit
begin
WordVal:=SmallInt(BufValue);
(iBuffer)^:=WordVal;
Inc(iBuffer);
//stereo?
if DoStereo then
begin
(iBuffer)^:=WordVal;
Inc(iBuffer);
Inc(i);
end;
end
else//8bit
begin
ByteVal:=Char($80+BufValue);
(Buf+i)^:=Char(ByteVal);
//stereo?
if DoStereo then
begin
Inc(i);
(Buf+i)^:=ByteVal;
end;
end;
Inc(i);
Inc(Cnt);
end;
Start:=Start+Samples+1;
end;
end;
HasADSRChanged:=false;
HasChanged:=false;
HasToneChanged:=true;
end;
//**********************************************************************
//create waveform
function TToneGen.CreateWaveform(DoADSR: bool): bool;
var
wh: TWavHeader;
AllocSize,BufSize,HdrSize,i: Integer;
DataBuf: PChar;
MidValue,MaxVal,MinVal,CalcVal: Real;
BytesPerSample,SampsPerInterval: Cardinal;
DoStereo: bool;
CycleCount,cnt,CycleMidPoint,SamplesPerCycle: Cardinal;
FPSamplesPerCycle,FPVerticalStep,FPVerticalAdd :Real;
HiRes,HiQ: bool;
ByteVal: Integer;
iBuffer: ^SmallInt;
WordVal: Smallint;
AmpPC: Integer;
Levels,Total: Integer;
wFrequency: Smallint;
wWaveform: TTGWave;
OldRandSeed: Longint;
//wfh: Integer;
begin
//same random pattern each time
OldRandSeed:=RandSeed;
RandSeed:=1;
//mono or stereo?
DoStereo:=fStereo;
//size of header record
HdrSize:=sizeof(TWavHeader);
//no of bytes per sample
if fResolution=tg16Bit then
begin
BytesPerSample:=2;
HiRes:=true;
MidValue:=0;
end
else
begin
BytesPerSample:=1;
HiRes:=false;
MidValue:=128;
end;
//no of samples per S/100
if fQuality=tgHiQ then
begin
SampsPerInterval:=960;
HiQ:=true;
end
else
begin
SampsPerInterval:=441;
HiQ:=false;
end;
//buffer size
BufSize:=(BytesPerSample * Duration * SampsPerInterval) div 10;
//twice as big for stereo
if DoStereo then BufSize:=BufSize*2;
//create header
CreateWavHeader(DoStereo,HiRes,HiQ,BufSize,wh);
//allocate memory for data buffer
if Buffer<>nil then
begin
FreeMem(Buffer);
Buffer:=nil;
BufferSize:=0;
end;
//stop any sounds
PlaySound(nil, 0, 0);
try
AllocSize:=BufSize+HdrSize+32;
Buffer:=AllocMem(AllocSize);
except
Result:=false;
Exit;
end;
if (Buffer=nil) or (BufSize=0) then
begin
Result:=false;
Exit;
end;
//initialise
BufferSize:=AllocSize;
FillMemory(Buffer,AllocSize,Trunc(MidValue));
//copy header data to start of buffer
CopyMemory(Buffer,@wh,HdrSize);
//amplitude percentages
Total:=0;
for i:=0 to AMLevels do
begin
Total:=Total+AMAmpArray[i];
end;
//-------------------------------
//start of creation loop
for Levels:=-1 to AMLevels do
begin
if Levels=-1 then //base frequency
begin
AmpPC:=100-Total;
wFrequency:=Frequency;
wWaveform:=fWaveForm;
end
else //AM levels
begin
AmpPC:=AMAmpArray[Levels];
if Total>100 then AmpPC:=AmpPC*100 div Total;
//frequency mutiplier or absolute?
if AMUseMultiplier then
begin
wFrequency:=LimitValue(MinFreq,MaxFreq,Trunc(AMFreqArray[Levels]*fFrequency));
end
else //absolute
begin
wFrequency:=Trunc(AMFreqArray[Levels]);
end;
//waveform
wWaveform:=AMWaveArray[Levels];
end;
//loop again if no amplitude
if (AmpPC<=0) or (wFrequency<=0) then Continue;
if fResolution=tg16Bit then
begin
MaxVal:=65534 * AmpPC /100;
MinVal:=-32767 * AmpPC /100;
end
else
begin
MaxVal:=254 * AmpPC /100;
MinVal:=-127 * AmpPC /100;
end;
//floating point samples per cycle
FPSamplesPerCycle:=(SampsPerInterval*100)/wFrequency;
//samples per cycle
SamplesPerCycle:=Trunc(FPSamplesPerCycle);
//CycleMidPoint of cycle
//CycleMidPoint:=SamplesPerCycle div 2;
CycleMidPoint:=Trunc(FPSamplesPerCycle+0.5) div 2;
//offset to data area
DataBuf:=Buffer+HdrSize;
//counter to step through cycles
CycleCount:=1;
FPVerticalStep:=0;
FPVerticalAdd:=0;
//write wav data to buffer
//sine step values
if wWaveform=tgSine then
begin
FPVerticalStep:=(pi*2)/SamplesPerCycle;
end;
//sq step values
if wWaveform=tgSquare then
begin
MaxVal:=MaxVal / 2;;
end;
//triangle vertical step size
if wWaveform=tgTriangle then
begin
FPVerticalStep:=MinVal;
FPVerticalAdd:=(MaxVal / CycleMidPoint);
end;
//sawtooth vertical step size
if wWaveform=tgSawtooth then
begin
FPVerticalStep:=MinVal;
FPVerticalAdd:=(MaxVal/SamplesPerCycle);
end;
cnt:=0;
i:=0;
while i begin
//select wave type
case wWaveform of
//sine
tgSine:
begin
CalcVal:=Trunc((sin(cnt * FPVerticalStep))/2*MaxVal);
end;
//square
tgSquare:
begin
if cnt CalcVal:=MinVal
else
CalcVal:=MaxVal;
end;
//triangle
tgTriangle:
begin
if cnt begin
CalcVal:=Trunc(FPVerticalStep);
FPVerticalStep:=FPVerticalStep+FPVerticalAdd;
end
else
begin
CalcVal:=Trunc(FPVerticalStep);
FPVerticalStep:=FPVerticalStep-FPVerticalAdd;
if FPVerticalStep //if (CalcVal+MidValue)>MaxVal then CalcVal:=MaxVal+MidValue;
end;
end;
//sawtooth
tgSawtooth:
begin
CalcVal:=Trunc(FPVerticalStep);
FPVerticalStep:=FPVerticalStep+FPVerticalAdd;
end;
//noise
else
CalcVal:=random(Trunc(MaxVal+1))+MinVal
end;
//offset
CalcVal:=MidValue+CalcVal;
//8bit or 16?
if HiRes then
begin
iBuffer:=Pointer(DataBuf+i);
WordVal:=iBuffer^;
WordVal:=WordVal+Trunc(CalcVal);
iBuffer^:=WordVal;
Inc(i,2);
//stereo?
if DoStereo then
begin
iBuffer:=Pointer(DataBuf+i);
(iBuffer)^:=WordVal;
Inc(i,2);
end
end
else //8bit
begin
ByteVal:=Integer((DataBuf+i)^)-Trunc(MidValue);
ByteVal:=ByteVal+Trunc(CalcVal);
(DataBuf+i)^:=Char(ByteVal);
//stereo?
if DoStereo then
begin
(DataBuf+i+1)^:=(DataBuf+i)^;
Inc(i);
end;
Inc(i);
end;
Inc(cnt);
if cnt=SamplesPerCycle then
begin
cnt:=0;
if wWaveform<>tgSine then
begin
FPVerticalStep:=MinVal;
end;
Inc(CycleCount);
//update samples per cycle
SamplesPerCycle:=Trunc((FPSamplesPerCycle*CycleCount)-(Trunc(FPSamplesPerCycle*(CycleCount-1))));
//CycleMidPoint of cycle
//CycleMidPoint:=SamplesPerCycle div 2;
CycleMidPoint:=Trunc(FPSamplesPerCycle+0.5) div 2;
end;
end;
end;
HasADSRChanged:=true;
HasChanged:=false;
HasToneChanged:=false;
//pass to ADSR routine
if DoADSR then
begin
ADSRWaveform(DataBuf,BufSize,DoStereo);
end;
//restore random seed value
RandSeed:=OldRandSeed;
//temporary
{wfh:=FileCreate('c:\test.wav');
if wfh<>-1 then
begin
FileWrite(wfh,Buffer^,BufSize+HdrSize);
FileClose(wfh);
end;}
//******
Result:=true;
end;
//**********************************************************************
//set AM Level selection
procedure TToneGen.SetAMLevel(level: TTGAMLevel);
begin
fAMLevel:=level;
AMAmplitude:=AMAmpArray[Integer(level)];
AMWaveform:=AMWaveArray[Integer(level)];
AMFrequency:=AMFreqArray[Integer(level)];
end;
//**********************************************************************
//AM frequency = multiplier or absolute?
procedure TToneGen.SetAMMultiplier(setit: bool);
begin
fAMUseMultiplier:=setit;
HasChanged:=true;
end;
//**********************************************************************
//set selected AM Amplitude
procedure TToneGen.SetAMAmplitude(Amp: Smallint);
begin
fAMAmplitude:=GetPercentage(Amp);
AMAmpArray[Integer(fAMLevel)]:=fAMAmplitude;
HasChanged:=true;
end;
//**********************************************************************
//AM Waveform
procedure TToneGen.SetAMWaveform(Wave: TTGWave);
begin
fAMWaveform:=Wave;
AMWaveArray[Integer(fAMLevel)]:=fAMWaveform;
HasChanged:=true;
end;
//**********************************************************************
//AM Frequency
procedure TToneGen.SetAMFrequency(Freq: Single);
begin
fAMFrequency:=Freq;
AMFreqArray[Integer(fAMLevel)]:=fAMFrequency;
HasChanged:=true;
end;
//**********************************************************************
//DefineProperties procedures
//register defineproerties proc's
procedure TToneGen.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('AMArrayData', ReadAMArrayData, WriteAMArrayData,true);
end;
//**********************************************************************
//write AM array
procedure TToneGen.WriteAMArrayData(Stream: TStream);
var
i: Integer;
Temp: integer;
STemp: Single;
begin
with Stream do
begin
Temp := AMLevels;
WriteBuffer(Temp, SizeOf(Temp));
for i := 0 to AMLevels do
begin
//amplitude
Temp := AMAmpArray[i];
WriteBuffer(Temp,sizeof(temp));
//waveform
Temp := Integer(AMWaveArray[i]);
WriteBuffer(Temp,sizeof(temp));
//frequency
STemp := AMFreqArray[i];
WriteBuffer(STemp,sizeof(STemp));
end;
end;
end;
//**********************************************************************
//read AM array
procedure TToneGen.ReadAMArrayData(Stream: TStream);
var
i, Temp, Levels: Integer;
STemp: Single;
begin
with Stream do
begin
Levels := 0;
ReadBuffer(Levels, SizeOf(Levels));
for i := 0 to Levels do
begin
//amplitude
Temp := 0;
ReadBuffer(Temp, SizeOf(Temp));
AMAmpArray[i]:=Temp;
//waveform
Temp := 0;
ReadBuffer(Temp, SizeOf(Temp));
AMWaveArray[i]:=TTGWave(Temp);
//frquency
STemp := 0;
ReadBuffer(STemp, SizeOf(STemp));
AMFreqArray[i]:=STemp;
end;
end;
end;
//**********************************************************************
//reset AM parameters to defaults
procedure TToneGen.ResetAM;
var
i: Integer;
begin
for i:=0 to AMLevels do
begin
//amplitude
AMAmpArray[i]:=0;
//wave
AMWaveArray[i]:=tgSine;
//frequency
AMFreqArray[i]:=(i+1.0) / 2;
end;
HasChanged:=true;
end;
//**********************************************************************
//set an AM parameter
procedure TToneGen.SetAMParameter(Level: TTGAMLevel;Freq: Single; Amp: Smallint; Wav:TTGWave);
begin
//frequency
AMFreqArray[Integer(Level)]:=Freq;
//wave
AMWaveArray[Integer(Level)]:=Wav;
//amplitude
AMAmpArray[Integer(Level)]:=Amp;
HasChanged:=true;
end;
//**********************************************************************
//return data buffer pointer
function TToneGen.GetDataBuffer: PChar;
begin
Result:=Buffer;
end;
//**********************************************************************
//export data
function TToneGen.ExportFile(FileName: String): bool;
var
Success,FileHandle: Integer;
begin
Result:=false;
if Buffer=nil then Exit;
FileHandle:=FileCreate(FileName);
if FileHandle<>-1 then
begin
Success:=FileWrite(Filehandle,Buffer^,BufferSize);
FileClose(FileHandle);
if Success<>-1 then Result:=true;
end;
end;
//**********************************************************************
//set frequency to note value
function SetNoteToFreq(NoteString: String;var pOctave: Integer): Integer;
var
i,tOctave,Freq,Base,TempNote,NoteValue,MaxNoteVal: Integer;
begin
Result:=0;
Base:=440;
MaxNoteVal:=121;
NoteValue:=-1;
tOctave:=pOctave;
NoteString:=AnsiUppercase(Trim(NoteString));
//direct note entry 'Nxx'
if AnsiPos('N',NoteString)=1 then
begin
//delete 'N'
Delete(NoteString,1,1);
NoteValue:=StrToIntDef(NoteString,-1);
if NoteValue>MaxNoteVal then NoteValue:=-1;
NoteString:='';
end
else
begin
if AnsiPos('O',NoteString)=1 then //Octave 'Ox'
begin
//delete 'O'
Delete(NoteString,1,1);
tOctave:=StrToIntDef(NoteString[1],-1);
if tOctave=-1 then Exit;
//delete 'x'
Delete(NoteString,1,1);
end
// > or <
else if (AnsiPos('<',NoteString)=1) or (AnsiPos('>',NoteString)=1) then
begin
while(AnsiPos('<',NoteString)=1) or (AnsiPos('>',NoteString)=1) do
begin
if AnsiPos('<',NoteString)=1 then
begin
Dec(tOctave);
if tOctave<0 then tOctave:=0;
end
else
begin
Inc(tOctave);
if tOctave>9 then tOctave:=9;
end;
Delete(NoteString,1,1);
end;
end;
//extract note
for i:=0 to 6 do
begin
//search for note (A - G)
if AnsiPos(Char(Integer('A')+i),NoteString)=1 then
begin
NoteValue:=i;
//delete note character
Delete(NoteString,1,1);
Break;
end;
end;
//accidental # + -
if NoteValue>-1 then
begin
//insert semitones
TempNote:=NoteValue*2;
//correct for BC & EF
if NoteValue>4 then
Dec(TempNote);
if NoteValue>1 then
Dec(TempNote);
NoteValue:=TempNote;
//# or +
if (AnsiPos('+',NoteString)=1) or (AnsiPos('#',NoteString)=1) then
begin
Delete(NoteString,1,1);
//B or E
if (NoteValue=2) or (NoteValue=7) then
NoteValue:=-1
else
Inc(NoteValue);
end
//-
else if AnsiPos('-',NoteString)=1 then
begin
Delete(NoteString,1,1);
//C or F
if (NoteValue=3) or (NoteValue=8) then
NoteValue:=-1
else
begin
Dec(NoteValue);
//A- = G# in previous octave
if NoteValue<0 then
begin
NoteValue:=11;//G#
Dec(tOctave);
if tOctave<0 then NoteValue:=-1;
end;
end;
end;
end;
if NoteValue>-1 then
begin
NoteValue:=12*tOctave+NoteValue;
end;
end;
//should be empty now
if Length(NoteString)>0 then NoteValue:=-1;
if NoteValue>-1 then
begin
pOctave:=tOctave;
NoteValue:=NoteValue-48;
Freq:=Trunc(Base * Power(2,NoteValue/12)+0.5);
if (Freq>=MinFreq) and (Freq<=MaxFreq) then
begin
Result:=Freq;
end;
end;
end;
//**********************************************************************
//set frequency to note value
function TToneGen.SetNote(NoteString: String): Integer;
var
Freq,pOctave: Integer;
begin
Result:=0;
pOctave:=Octave;
Freq:=SetNoteToFreq(NoteString,pOctave);
if Freq>0 then
begin
Frequency:=Freq;
Octave:=pOctave;
HasChanged:=true;
Result:=Freq;
end;
end;
//**********************************************************************
//set AM frequency to note value
function TToneGen.SetAMNote(Level: TTGAMLevel;NoteString:String): Single;
var
Freq,pOctave: Integer;
fFreq: Single;
begin
Result:=0;
pOctave:=AMOctaves[Integer(Level)];
Freq:=SetNoteToFreq(NoteString,pOctave);
fFreq:=Freq;
if Freq>0 then
begin
//absolute or multiply?
if fAMUseMultiplier then
fFreq:=fFreq/fFrequency;
AMFreqArray[Integer(Level)]:=fFreq;
AMOctaves[Integer(Level)]:=pOctave;
HasChanged:=true;
Result:=fFreq;
end;
end;
end.
{=============================================================================}
//samples
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,ExtCtrls, ComCtrls,Math, Buttons, ToneGen;
type
//data used for demos
DemoData=record
Wave: TTGWave;
Dur: Integer;
Freq: Integer;
A,H,D,S,R: Integer;
Reps: Integer;
AMEntries: Integer;
AMFreq: array[0..7] of Single;
AMWave: array[0..7] of TTGWave;
AMAmp: array[0..7] of Smallint;
end;
TForm1 = class(TForm)
RadioGroup1: TRadioGroup;
RadioGroup2: TRadioGroup;
UpDown1: TUpDown;
Edit1: TEdit;
Label1: TLabel;
RadioGroup3: TRadioGroup;
Edit2: TEdit;
UpDown2: TUpDown;
Label2: TLabel;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
TrackBar3: TTrackBar;
TrackBar4: TTrackBar;
Label7: TLabel;
Panel1: TPanel;
Label3: TLabel;
Panel2: TPanel;
Label4: TLabel;
Panel3: TPanel;
Label5: TLabel;
Panel4: TPanel;
TrackBar5: TTrackBar;
TrackBar6: TTrackBar;
Label6: TLabel;
Button6: TButton;
Button7: TButton;
Button8: TButton;
Button9: TButton;
Button10: TButton;
Button11: TButton;
Timer2: TTimer;
Button12: TButton;
Timer3: TTimer;
Button13: TButton;
Button14: TButton;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
Label9: TLabel;
Label8: TLabel;
Bevel1: TBevel;
Bevel3: TBevel;
Label10: TLabel;
Bevel2: TBevel;
Button1: TButton;
Button2: TButton;
CheckBox3: TCheckBox;
ToneGen1: TToneGen;
Label11: TLabel;
Panel5: TPanel;
TrackBar7: TTrackBar;
Bevel4: TBevel;
WaveTTG: TToneGen;
TrackBar8: TTrackBar;
Label12: TLabel;
Label13: TLabel;
Bevel5: TBevel;
Label14: TLabel;
Panel6: TPanel;
TrackBar9: TTrackBar;
Panel7: TPanel;
TrackBar10: TTrackBar;
RadioGroup4: TRadioGroup;
Bevel6: TBevel;
Label15: TLabel;
Panel8: TPanel;
TrackBar11: TTrackBar;
Panel9: TPanel;
TrackBar12: TTrackBar;
RadioGroup5: TRadioGroup;
Bevel7: TBevel;
Label16: TLabel;
Panel10: TPanel;
TrackBar13: TTrackBar;
Panel11: TPanel;
TrackBar14: TTrackBar;
RadioGroup6: TRadioGroup;
Bevel8: TBevel;
Label17: TLabel;
Panel12: TPanel;
TrackBar15: TTrackBar;
Panel13: TPanel;
TrackBar16: TTrackBar;
RadioGroup7: TRadioGroup;
Bevel9: TBevel;
Label18: TLabel;
Panel14: TPanel;
TrackBar17: TTrackBar;
Panel15: TPanel;
TrackBar18: TTrackBar;
RadioGroup8: TRadioGroup;
Bevel10: TBevel;
Label19: TLabel;
Panel16: TPanel;
TrackBar19: TTrackBar;
Panel17: TPanel;
TrackBar20: TTrackBar;
RadioGroup9: TRadioGroup;
Bevel11: TBevel;
Label20: TLabel;
Panel18: TPanel;
TrackBar21: TTrackBar;
Panel19: TPanel;
TrackBar22: TTrackBar;
RadioGroup10: TRadioGroup;
Bevel12: TBevel;
Label21: TLabel;
Panel20: TPanel;
TrackBar23: TTrackBar;
Panel21: TPanel;
TrackBar24: TTrackBar;
RadioGroup11: TRadioGroup;
Bevel13: TBevel;
Label22: TLabel;
Bevel14: TBevel;
Label23: TLabel;
Button4: TButton;
Button5: TButton;
Button15: TButton;
Button16: TButton;
Button17: TButton;
Button18: TButton;
Button19: TButton;
Button20: TButton;
Button21: TButton;
Button22: TButton;
Button23: TButton;
Button24: TButton;
TrackBar25: TTrackBar;
Panel22: TPanel;
Button25: TButton;
Edit3: TEdit;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Button26: TButton;
Button27: TButton;
GroupBox3: TGroupBox;
Button3: TButton;
Button28: TButton;
procedure Button1Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TrackBar5Change(Sender: TObject);
procedure TrackBar6Change(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button9Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure Button10Click(Sender: TObject);
procedure Button11Click(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Button12Click(Sender: TObject);
procedure Timer3Timer(Sender: TObject);
procedure Button13Click(Sender: TObject);
procedure Button14Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure RadioGroup3Click(Sender: TObject);
procedure TrackBar8Change(Sender: TObject);
procedure RadioGroup4Click(Sender: TObject);
procedure TrackBar9Change(Sender: TObject);
procedure TrackBar10Change(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure TrackBar25Change(Sender: TObject);
procedure Button25Click(Sender: TObject);
procedure Button26Click(Sender: TObject);
procedure Button27Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button28Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
DD: array [0 .. 9] of DemoData;
Demo: Integer;
PanRight: bool;
//tune data
notevals: array [0..13] of String=('A','A','E','E','F#','F#','E','D','D','C#','C#','B','B','A');
//note intervals
interval: array[0..13] of Smallint=(1,1,1,1,1,1,2,1,1,1,1,1,1,1);
notepos: Integer;
WaveCount: Integer=5;
DoRedraw: bool=true;
//AM controls
AMWav: array[0..7] of TRadioGroup;
AMFreq: array[0..7] of TTrackBar;
AMAmp: array[0..7] of TTrackBar;
AMAmpV: array[0..7] of TPanel;
AMFreqV: array[0..7] of TPanel;
procedure SetupTone;
implementation
{$R *.DFM}
//exit
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
//return wave type from index
function WaveIndex(Index: Integer):TTGWave;
begin
case Index of
0: Result:=tgSine;
1: Result:=tgSquare;
2: Result:=tgTriangle;
3: Result:=tgSawtooth;
else Result:=tgNoise;
end;
end;
//draw envelope & wave graphic
procedure RedrawADSR;
var
i,bleft,btop,apos,hpos,dpos,spos,rpos,wdth,hgt,total: Integer;
xs,xe,ys,ye: Integer;
fmc: TCanvas;
Buf: PChar;
wavdata: Char;
begin
if DoRedraw=false then exit;
with Form1 do
begin
fmc:=Form1.Canvas;
//ADSR
wdth:=Bevel1.Width-1;
hgt:=Bevel1.Height-4;
bleft:=Bevel1.Left+1;
btop:=Bevel1.Top+2;
apos:=100-trackbar1.Position;
hpos:=100-trackbar7.Position;
dpos:=100-trackbar2.Position;
spos:=trackbar3.Position;
rpos:=100-trackbar4.Position;
total:=apos+hpos+dpos+rpos;
if total>100 then
begin
apos:=apos * 100 div total;
hpos:=hpos * 100 div total;
dpos:=dpos * 100 div total;
rpos:=rpos * 100 div total;
end;
//attack
fmc.Pen.Color:=clRed;
xs:=bleft;
xe:=bleft+(wdth * apos div 100);
ys:=btop+hgt;
ye:=btop;
fmc.MoveTo(xs,ys);
fmc.LineTo(xe,ye);
//hold
fmc.Pen.Color:=clPurple;
xe:=xe+(wdth * hpos div 100);
ye:=btop;
fmc.LineTo(xe,ye);
//decay
fmc.Pen.Color:=clBlue;
xe:=xe+(wdth * dpos div 100);
ye:=btop+(hgt * spos div 100);
fmc.LineTo(xe,ye);
//sustain
fmc.Pen.Color:=clGreen;
if total<100 then
begin
xe:=(bleft+wdth)-(wdth * rpos div 100);
fmc.LineTo(xe,ye);
end;
//release
fmc.Pen.Color:=clNavy;
xe:=bleft+wdth;
ye:=btop+hgt;
fmc.LineTo(xe,ye);
//Waveform
Buf:=WaveTTG.GetDataBuffer;
if Buf<>nil then
begin
Buf:=Buf+44;//offset to data
bleft:=Bevel4.Left+1;
btop:=Bevel4.Top+2;
fmc.Pen.Color:=clBlue;
wavdata:=Buf^;
fmc.MoveTo(bleft,(Integer(wavdata) div 2) + btop);
Inc(Buf);
for i:=1 to Bevel4.Width-2 do
begin
wavdata:=Buf^;
fmc.LineTo(bleft+i,(Integer(wavdata) div 2) + btop);
Inc(Buf);
end;
end;
end;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
//reset AM parameters
WaveTTG.ResetAM;
ToneGen1.ResetAM;
//draw wave
TrackBar8Change(nil);
//draw envelope
TrackBar1Change(nil);
//do am text
TrackBar10Change(nil);
SetupTone;
Tonegen1.Prepare;
end;
//set async state from loop
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
CheckBox2.Enabled:=not CheckBox1.Checked;
end;
//set ADSR
procedure TForm1.TrackBar1Change(Sender: TObject);
var
tb1,tb2,tb3,tb4,tb5,Total: Integer;
begin
tb1:=100-TrackBar1.Position;
tb2:=100-TrackBar2.Position;
tb3:=100-TrackBar3.Position;
tb4:=100-TrackBar4.Position;
tb5:=100-TrackBar7.Position;
Total:=tb1+tb2+tb4+tb5;
with ToneGen1 do
begin
Attack:=tb1;
Hold:=tb5;
Decay:=tb2;
Sustain:=tb3;
Release:=tb4;
end;
if Total>100 then
begin
tb1:=tb1 * 100 div Total;
tb2:=tb2 * 100 div Total;
tb4:=tb4 * 100 div Total;
tb5:=tb5 * 100 div Total;
end;
Panel1.Caption:=IntToStr(tb1)+'%';
Panel2.Caption:=IntToStr(tb2)+'%';
Panel3.Caption:=IntToStr(tb3)+'%';
Panel4.Caption:=IntToStr(tb4)+'%';
Panel5.Caption:=IntToStr(tb5)+'%';
//update graphic
if Doredraw then Form1.Bevel2.Invalidate;
Update;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
RedrawADSR;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//set volume
TrackBar5.Position:=100-ToneGen1.LeftVolume;
TrackBar6.Position:=100-ToneGen1.RightVolume;
Randomize;
//initialise demo records
//morse
with DD[0] do
begin
Freq:=440;
Dur:=100;
Wave:=tgSine;
A:=0;
H:=0;
D:=0;
S:=100;
R:=0;
AMEntries:=0;
end;
//alarm
with DD[1] do
begin
Freq:=1500;
Dur:=200;
Wave:=tgTriangle;
A:=0;
H:=10;
D:=20;
S:=80;
R:=0;
AMEntries:=1;
AMFreq[0]:=2.5;
AMAmp[0]:=38;
AMWave[0]:=tgSawtooth;
end;
//pan
with DD[2] do
begin
Freq:=100;
Dur:=100;
Wave:=tgSquare;
A:=10;
H:=5;
D:=15;
S:=75;
R:=0;
AMEntries:=0;
end;
//tune
with DD[3] do
begin
Freq:=500;
Dur:=500;
Wave:=tgSawtooth;
A:=10;
H:=21;
D:=15;
S:=75;
R:=55;
AMEntries:=2;
AMAmp[0]:=45;
AMFreq[0]:=3.0;
AMWave[0]:=tgSquare;
AMAmp[1]:=45;
AMFreq[1]:=4.0;
AMWave[1]:=tgSine;
end;
//bell
with DD[5] do
begin
Freq:=3130;
Dur:=450;
Wave:=tgTriangle;
A:=0;
H:=10;
D:=65;
S:=30;
R:=20;
AMEntries:=2;
AMAmp[0]:=40;
AMFreq[0]:=0.1;
AMWave[0]:=tgSine;
AMAmp[1]:=5;
AMFreq[1]:=3.0;
AMWave[1]:=tgSquare;
end;
//C maj
with DD[6] do
begin
Freq:=523;
Dur:=900;
Wave:=tgTriangle;
A:=0;
H:=10;
D:=40;
S:=30;
R:=40;
AMEntries:=2;
AMAmp[0]:=33;
AMFreq[0]:=1.3;
AMWave[0]:=tgTriangle;
AMAmp[1]:=33;
AMFreq[1]:=1.5;
AMWave[1]:=tgTriangle;
end;
//C min
with DD[7] do
begin
Freq:=523;
Dur:=900;
Wave:=tgTriangle;
A:=0;
H:=10;
D:=40;
S:=30;
R:=40;
AMEntries:=2;
AMAmp[0]:=33;
AMFreq[0]:=1.2;
AMWave[0]:=tgTriangle;
AMAmp[1]:=33;
AMFreq[1]:=1.5;
AMWave[1]:=tgTriangle;
end;
//setup AM control arrays
//wave
AMWav[0]:=Form1.RadioGroup4;
AMWav[1]:=Form1.RadioGroup5;
AMWav[2]:=Form1.RadioGroup6;
AMWav[3]:=Form1.RadioGroup7;
AMWav[4]:=Form1.RadioGroup8;
AMWav[5]:=Form1.RadioGroup9;
AMWav[6]:=Form1.RadioGroup10;
AMWav[7]:=Form1.RadioGroup11;
//frequency
AMFreq[0]:=Form1.TrackBar10;
AMFreq[1]:=Form1.TrackBar12;
AMFreq[2]:=Form1.TrackBar14;
AMFreq[3]:=Form1.TrackBar16;
AMFreq[4]:=Form1.TrackBar18;
AMFreq[5]:=Form1.TrackBar20;
AMFreq[6]:=Form1.TrackBar22;
AMFreq[7]:=Form1.TrackBar24;
//frequency display
AMFreqV[0]:=Form1.Panel7;
AMFreqV[1]:=Form1.Panel9;
AMFreqV[2]:=Form1.Panel11;
AMFreqV[3]:=Form1.Panel13;
AMFreqV[4]:=Form1.Panel15;
AMFreqV[5]:=Form1.Panel17;
AMFreqV[6]:=Form1.Panel19;
AMFreqV[7]:=Form1.Panel21;
//amplitude
AMAmp[0]:=Form1.TrackBar9;
AMAmp[1]:=Form1.TrackBar11;
AMAmp[2]:=Form1.TrackBar13;
AMAmp[3]:=Form1.TrackBar15;
AMAmp[4]:=Form1.TrackBar17;
AMAmp[5]:=Form1.TrackBar19;
AMAmp[6]:=Form1.TrackBar21;
AMAmp[7]:=Form1.TrackBar23;
//amplitude display
AMAmpV[0]:=Form1.Panel6;
AMAmpV[1]:=Form1.Panel8;
AMAmpV[2]:=Form1.Panel10;
AMAmpV[3]:=Form1.Panel12;
AMAmpV[4]:=Form1.Panel14;
AMAmpV[5]:=Form1.Panel16;
AMAmpV[6]:=Form1.Panel18;
AMAmpV[7]:=Form1.Panel20;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
end;
//left volume
procedure TForm1.TrackBar5Change(Sender: TObject);
begin
ToneGen1.LeftVolume:=100-TrackBar5.Position;
WaveTTG.LeftVolume:=100-TrackBar5.Position;
end;
//right volume
procedure TForm1.TrackBar6Change(Sender: TObject);
begin
ToneGen1.RightVolume:=100-TrackBar6.Position;
WaveTTG.RightVolume:=100-TrackBar6.Position;
end;
//set component parameters from controls
procedure SetupTone;
begin
with Form1.Tonegen1 do
begin
Loop:=Form1.CheckBox1.Checked;
Async:=Form1.CheckBox2.Checked;
Frequency:=StrToIntDef(Form1.Edit2.Text,440);
Duration:=StrToIntDef(Form1.Edit1.Text,440);
Stereo:=Form1.CheckBox3.Checked;
if Form1.RadioGroup2.ItemIndex=0 then
Quality:=tgHiQ
else
Quality:=tgLoQ;
if Form1.RadioGroup1.ItemIndex=0 then
Resolution:=tg16Bit
else
Resolution:=tg8Bit;
Waveform:=WaveIndex(Form1.RadioGroup3.ItemIndex);
end;
end;
//play tone
procedure TForm1.Button6Click(Sender: TObject);
begin
SetupTone;
ToneGen1.Play;
//Tonegen1.ExportFile('c:\test.wav');
end;
//set volume
procedure TForm1.Button7Click(Sender: TObject);
begin
ToneGen1.PresetVolume;
end;
//stop sound
procedure TForm1.Button9Click(Sender: TObject);
begin
Timer2.Enabled:=false;
Timer3.Enabled:=false;
ToneGen1.Stop;
end;
//play ADSR
procedure TForm1.Button8Click(Sender: TObject);
begin
SetupTone;
ToneGen1.PlayADSR;
//Tonegen1.ExportFile('c:\test.wav');
end;
//setup demo parameters
procedure SetDemo(ID:Integer);
var
ttg: TToneGen;
i,al,amp: Integer;
level:TTGAMLevel;
freq: Single;
wav: TTGWave;
begin
DoRedraw:=false;
//set data
Form1.Tonegen1.AMUseMultiplier:=true;
Form1.RadioButton2.Checked:=true;
ttg:=Form1.ToneGen1;
for i:=0 to 1 do
begin
with ttg do
begin
Frequency:=DD[ID].Freq;
Duration:=DD[ID].Dur;
Waveform:=DD[ID].Wave;
Attack:=DD[ID].A;
Hold:=DD[ID].H;
Decay:=DD[ID].D;
Sustain:=DD[ID].S;
Release:=DD[ID].R;
//AM setup
level:=tgAMLevel1;
for al:=0 to 7 do
begin
if al>=DD[ID].AMEntries then
begin
amp:=0;
freq:=0;
wav:=tgSine;
end
else
begin
amp:=DD[ID].AMAmp[al];
freq:=DD[ID].AMFreq[al];
wav:=DD[ID].AMWave[al];
end;
ttg.SetAMParameter(level,freq,amp,wav);
//set AM controls
if ttg=Form1.WaveTTG then
begin
AMWav[al].ItemIndex:=Integer(wav);
AMAmp[al].Position:=50-amp;
if al=7 then
begin
DoRedraw:=true;
Form1.TrackBar9Change(nil);
end;
if freq>5.0 then freq:=5.0;
if freq<=0.1 then
AMFreq[al].Position:=50
else
begin
AMFreq[al].Position:=50-Trunc(freq*10+0.5);
end;
Inc(level);
end;
end;
if ID<>4 then
begin
Loop:=false;
Form1.Checkbox1.Checked:=Loop;
Async:=true;
Form1.Checkbox2.Checked:=Async;
end
else
begin
Loop:=Form1.Checkbox1.Checked;
Async:=Form1.Checkbox2.Checked;
end;
end;
ttg:=Form1.WaveTTG;
end;
Form1.WaveTTG.Loop:=false;
Form1.WaveTTG.Async:=true;
//setup controls
with Form1 do
begin
Edit2.Text:=IntToStr(DD[ID].Freq);
Edit1.Text:=IntToStr(DD[ID].Dur);
Trackbar1.Position:=100-DD[ID].A;
Trackbar2.Position:=100-DD[ID].D;
Trackbar3.Position:=100-DD[ID].S;
Trackbar4.Position:=100-DD[ID].R;
Trackbar7.Position:=100-DD[ID].H;
Radiogroup3.ItemIndex:=Integer(DD[ID].Wave);
end;
Form1.Timer2.Enabled:=false;
Form1.Timer3.Enabled:=false;
//chords?
if (ID=6) or (ID=7) then
begin
Form1.ToneGen1.SetNote('C');
Form1.ToneGen1.SetAMNote(tgAMLevel1,'E');
if ID=6 then
Form1.ToneGen1.SetAMNote(tgAMLevel2,'G')//major
else
Form1.ToneGen1.SetAMNote(tgAMLevel2,'F#');//minor
Form1.ToneGen1.PlayADSR;
Exit;
end;
//random
if ID<>4 then
begin
Form1.Timer2.Enabled:=true;
end;
if ((ID=4) and Form1.Tonegen1.Loop) or (ID<>4) then
Form1.Timer3.Enabled:=true;
Form1.Timer3.Interval:=5000;
//tune
if ID=3 then
Form1.Timer3.Interval:=10000;
DoRedraw:=true;
end;
//random
procedure TForm1.Button10Click(Sender: TObject);
var
i: Integer;
begin
Demo:=4;
with DD[Demo] do
begin
Freq:=(10+random(1000))*10;
Dur:=(10+random(90))*10;
Wave:=TTGWave(random(5));
A:=random(101);
H:=random(101);
D:=random(101);
S:=random(101);
R:=random(101);
AMEntries:=random(9);
if AMEntries>0 then
begin
for i:=0 to AMEntries-1 do
begin
AMFreq[i]:=random(51)/10;
AMAmp[i]:=random(50 div AMEntries);
AMWave[i]:=TTGWave(random(6));
end;
end;
end;
//loop?
if random(2)>0 then
Checkbox1.Checked:=true
else
Checkbox1.Checked:=false;
SetDemo(Demo);
Tonegen1.PlayADSR;
end;
//morse
procedure TForm1.Button11Click(Sender: TObject);
begin
Demo:=0;
Timer2.Interval:=100+Random(300);
SetDemo(Demo);
end;
//demo timer
procedure TForm1.Timer2Timer(Sender: TObject);
begin
//morse
if Demo=0 then
begin
Timer2.Interval:=50+Random(300);
end;
//pan
if Demo=2 then
begin
with Tonegen1 do
begin
if PanRight then
begin
if RightVolume<100 then
RightVolume:=RightVolume+50
else
if LeftVolume>0 then
LeftVolume:=LeftVolume-50
else
PanRight:=false;
end
else
begin
if LeftVolume<100 then
LeftVolume:=LeftVolume+50
else
if RightVolume>0 then
RightVolume:=RightVolume-50
else
PanRight:=true;
end;
PresetVolume;
Trackbar5.Position:=100-LeftVolume;
Trackbar6.Position:=100-RightVolume;
end;
end;
//tune
if Demo=3 then
begin
if Notepos>13 then Exit;
//set note frequency
Tonegen1.SetNote(notevals[Notepos]);
Tonegen1.PlayADSR;
Timer2.Interval:=interval[notepos]*400;
Notepos:=Notepos+1;
end;
Tonegen1.PlayADSR;
end;
//alarm
procedure TForm1.Button12Click(Sender: TObject);
begin
Demo:=1;
Timer2.Interval:=400;
SetDemo(Demo);
end;
//demo overall duration
procedure TForm1.Timer3Timer(Sender: TObject);
begin
Timer3.Enabled:=false;
Timer2.Enabled:=false;
with Tonegen1 do
begin
Stop;
//set volume after pan
if Demo=2 then
begin
LeftVolume:=100;
RightVolume:=100;
WaveTTG.LeftVolume:=100;
WaveTTG.RightVolume:=100;
Trackbar5.Position:=100-LeftVolume;
Trackbar6.Position:=100-RightVolume;
end;
end;
end;
//pan
procedure TForm1.Button13Click(Sender: TObject);
begin
Tonegen1.LeftVolume:=100;
Tonegen1.RightVolume:=0;
Tonegen1.PresetVolume;
Demo:=2;
SetDemo(Demo);
PanRight:=true;
Timer2.Interval:=200;
Timer2.Enabled:=true;
end;
//tune
procedure TForm1.Button14Click(Sender: TObject);
begin
Demo:=3;
Notepos:=0;
SetDemo(Demo);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Application.HelpFile := ExtractFilePath(Application.ExeName)+'TTonegen.hlp';
Application.HelpCommand(HELP_CONTENTS, 0);
end;
procedure TForm1.RadioGroup3Click(Sender: TObject);
begin
Form1.WaveTTG.Waveform:=WaveIndex(Form1.RadioGroup3.ItemIndex);
WaveTTG.Prepare;
if DoRedraw then Bevel4.Invalidate;
Update;
end;
procedure TForm1.TrackBar8Change(Sender: TObject);
begin
WaveCount:=20-Trackbar8.Position;
WaveTTG.Frequency:=(44100*WaveCount) div Bevel4.Width-2;
WaveTTG.Prepare;
//if DoRedraw then Bevel4.Invalidate;
Bevel4.Invalidate;
Bevel4.Update;
end;
//set all parameters from controls
procedure SetAMParameters;
var
level: TTGAMLevel;
i,amp,tf,Total: Integer;
freq: Single;
wav: TTGWave;
mul: bool;
begin
if DoRedraw=false then Exit;
level:=tgAMLevel1;
//proportion factor from display
Total:=0;
for i:=0 to 7 do
Total:=Total+50-AMAmp[i].Position;
if Total<100 then Total:=100;
//step through AM levels
for i:=0 to 7 do
begin
Form1.WaveTTG.AMLevel:=level;
//waveform
wav:=WaveIndex(AMWav[i].ItemIndex);
//amplitude
amp:=50-AMAmp[i].Position;
//update display values
AMAmpV[i].Caption:=IntToStr(amp * 100 div Total)+'%';
//frequency
mul:=Form1.RadioButton2.Checked;
Form1.Tonegen1.AMUseMultiplier:=mul;
tf:=50-AMFreq[i].Position;
//absolute?
if not mul then
begin
if tf=0 then
freq:=20
else
freq:=tf*100;
AMFreqV[i].Caption:=IntToStr(Trunc(freq));
//modify frequency for display component (always useAMmultiplier)
tf:=StrToIntDef(Form1.Edit2.Text,440);
//freq:=tf/freq;
freq:=freq/tf;
end
else //multiplier
begin
if tf=0 then
freq:=0.1
else
freq:=tf / 10;
AMFreqV[i].Caption:='x'+FloatToStrF(freq,ffFixed,4,1);
end;
//setup wave display component this way
Form1.WaveTTG.AMLevel:=level;
Form1.WaveTTG.AMWaveform:=wav;
Form1.WaveTTG.AMAmplitude:=amp;
Form1.WaveTTG.AMFrequency:=freq;
//setup play component the alternative way
Form1.Tonegen1.SetAMParameter(level,freq,amp,wav);
Inc(level);
end;
//draw wave
Form1.TrackBar8Change(nil);
end;
procedure TForm1.RadioGroup4Click(Sender: TObject);
begin
SetAMParameters;
end;
procedure TForm1.TrackBar9Change(Sender: TObject);
begin
SetAMParameters;
end;
procedure TForm1.TrackBar10Change(Sender: TObject);
begin
SetAMParameters;
end;
//set note frequency
procedure TForm1.Button4Click(Sender: TObject);
var
freq:Integer;
btn: TButton;
begin
btn:=TButton(Sender);
freq:=ToneGen1.SetNote('O'+IntToStr(TrackBar25.Position)+btn.Caption);
if freq>0 then
begin
Edit2.Text:=IntToStr(freq);
SetupTone;
Tonegen1.PlayADSR;
//Tonegen1.Play;
end;
end;
procedure TForm1.TrackBar25Change(Sender: TObject);
var
en: bool;
pos: Integer;
begin
pos:=TrackBar25.Position;
Panel22.Caption:=IntToStr(pos);
//do buttons
if pos=9 then
en:=false
else
en:=true;
Button20.Enabled:=en;
Button21.Enabled:=en;
Button22.Enabled:=en;
Button23.Enabled:=en;
Button24.Enabled:=en;
end;
procedure TForm1.Button25Click(Sender: TObject);
begin
SetupTone;
//Tonegen1.Prepare;
Tonegen1.PrepareADSR;
if Tonegen1.ExportFile(Edit3.Text)=false then
begin
Beep();
Application.MessageBox('Could Not Save File','Error',0);
end;
end;
//reset AM parameters
procedure TForm1.Button26Click(Sender: TObject);
var
i: Integer;
begin
DoRedraw:=false;
Tonegen1.ResetAM;
WaveTTG.ResetAM;
for i:=0 to 7 do
begin
if i=7 then DoRedraw:=true;
AMWav[i].ItemIndex:=0;
AMFreq[i].Position:=50-((i+1)*5);
AMAmp[i].Position:=50;
end;
end;
//bell
procedure TForm1.Button27Click(Sender: TObject);
begin
Demo:=5;
Timer2.Interval:=900;
SetDemo(Demo);
end;
//C maj
procedure TForm1.Button3Click(Sender: TObject);
begin
Demo:=6;
SetDemo(Demo);
end;
procedure TForm1.Button28Click(Sender: TObject);
begin
Demo:=7;
SetDemo(Demo);
end;
end.
//form .dfm
object Form1: TForm1
Left = 180
Top = 146
BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
Caption = 'ToneGen Demo'
ClientHeight = 573
ClientWidth = 792
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnActivate = FormActivate
OnCreate = FormCreate
OnDestroy = FormDestroy
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 13
object Bevel14: TBevel
Left = 110
Top = 315
Width = 572
Height = 256
Shape = bsFrame
end
object Bevel5: TBevel
Left = 112
Top = 157
Width = 570
Height = 152
Shape = bsFrame
end
object Bevel3: TBevel
Left = 112
Top = 8
Width = 569
Height = 142
Shape = bsFrame
end
object Label1: TLabel
Left = 21
Top = 273
Width = 65
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Duration (mS)'
end
object Label2: TLabel
Left = 15
Top = 312
Width = 80
Height = 14
Alignment = taCenter
AutoSize = False
Caption = 'Frequency (Hz)'
end
object Label7: TLabel
Left = 129
Top = 17
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Attack'
Font.Charset = DEFAULT_CHARSET
Font.Color = clRed
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label3: TLabel
Left = 225
Top = 17
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Decay'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label4: TLabel
Left = 272
Top = 17
Width = 36
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Sustain'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGreen
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label5: TLabel
Left = 320
Top = 17
Width = 38
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Release'
Font.Charset = DEFAULT_CHARSET
Font.Color = clNavy
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label6: TLabel
Left = 35
Top = 93
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Left'
Font.Charset = DEFAULT_CHARSET
Font.Color = clMaroon
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel1: TBevel
Left = 382
Top = 19
Width = 287
Height = 122
Style = bsRaised
end
object Label10: TLabel
Left = 124
Top = 3
Width = 51
Height = 13
Caption = ' Envelope '
end
object Bevel2: TBevel
Left = 378
Top = 16
Width = 295
Height = 128
end
object Label11: TLabel
Left = 177
Top = 17
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Hold'
Font.Charset = DEFAULT_CHARSET
Font.Color = clPurple
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel4: TBevel
Left = 150
Top = 172
Width = 526
Height = 131
end
object Label12: TLabel
Left = 116
Top = 168
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'More'
Font.Charset = DEFAULT_CHARSET
Font.Color = clTeal
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label13: TLabel
Left = 114
Top = 291
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Less'
Font.Charset = DEFAULT_CHARSET
Font.Color = clTeal
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label14: TLabel
Left = 124
Top = 152
Width = 92
Height = 13
Alignment = taCenter
Caption = ' Waveform Display '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel6: TBevel
Left = 121
Top = 328
Width = 68
Height = 221
Shape = bsFrame
end
object Label15: TLabel
Left = 125
Top = 322
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 1 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel7: TBevel
Left = 190
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label16: TLabel
Left = 194
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 2 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel8: TBevel
Left = 258
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label17: TLabel
Left = 262
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 3 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel9: TBevel
Left = 327
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label18: TLabel
Left = 331
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 4 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel10: TBevel
Left = 396
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label19: TLabel
Left = 400
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 5 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel11: TBevel
Left = 465
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label20: TLabel
Left = 469
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 6 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel12: TBevel
Left = 533
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label21: TLabel
Left = 537
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 7 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Bevel13: TBevel
Left = 601
Top = 329
Width = 68
Height = 221
Shape = bsFrame
end
object Label22: TLabel
Left = 605
Top = 323
Width = 41
Height = 13
Alignment = taCenter
Caption = ' Level 8 '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label23: TLabel
Left = 124
Top = 309
Width = 107
Height = 13
Alignment = taCenter
Caption = ' Amplitude Modulation '
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object GroupBox1: TGroupBox
Left = 685
Top = 220
Width = 105
Height = 219
Caption = ' Demo '
TabOrder = 28
object Button27: TButton
Left = 12
Top = 158
Width = 81
Height = 25
Caption = 'Bell'
TabOrder = 0
OnClick = Button27Click
end
object Button3: TButton
Left = 12
Top = 186
Width = 40
Height = 25
Caption = 'C maj'
TabOrder = 1
OnClick = Button3Click
end
object Button28: TButton
Left = 53
Top = 186
Width = 40
Height = 25
Caption = 'C min'
TabOrder = 2
OnClick = Button28Click
end
end
object GroupBox3: TGroupBox
Left = 1
Top = 419
Width = 106
Height = 43
Caption = ' Octave '
TabOrder = 95
end
object GroupBox2: TGroupBox
Left = 24
Top = 4
Width = 81
Height = 147
Caption = ' Volume '
TabOrder = 29
object Label9: TLabel
Left = 7
Top = 15
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Left'
Font.Charset = DEFAULT_CHARSET
Font.Color = clMaroon
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object Label8: TLabel
Left = 41
Top = 15
Width = 31
Height = 13
Alignment = taCenter
AutoSize = False
Caption = 'Right'
Font.Charset = DEFAULT_CHARSET
Font.Color = clMaroon
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
end
object RadioGroup1: TRadioGroup
Left = 688
Top = 3
Width = 97
Height = 68
Caption = ' Resolution '
ItemIndex = 0
Items.Strings = (
'16 bit'
'8 bit')
TabOrder = 0
end
object RadioGroup2: TRadioGroup
Left = 688
Top = 75
Width = 97
Height = 72
Caption = ' Sample Rate '
ItemIndex = 0
Items.Strings = (
'96000'
'44100')
TabOrder = 1
end
object UpDown1: TUpDown
Left = 78
Top = 288
Width = 16
Height = 21
Associate = Edit1
Min = 10
Max = 1000
Increment = 10
Position = 100
TabOrder = 2
Thousands = False
end
object Edit1: TEdit
Left = 21
Top = 288
Width = 57
Height = 21
TabOrder = 3
Text = '100'
end
object RadioGroup3: TRadioGroup
Left = 9
Top = 153
Width = 97
Height = 118
Caption = ' Base Waveform '
ItemIndex = 0
Items.Strings = (
'Sine'
'Square'
'Triangle'
'Sawtooth'
'Noise')
TabOrder = 4
OnClick = RadioGroup3Click
end
object Edit2: TEdit
Left = 21
Top = 329
Width = 57
Height = 21
TabOrder = 5
Text = '440'
OnChange = TrackBar10Change
end
object UpDown2: TUpDown
Left = 78
Top = 329
Width = 16
Height = 21
Associate = Edit2
Min = 20
Max = 20000
Increment = 10
Position = 440
TabOrder = 6
Thousands = False
end
object CheckBox1: TCheckBox
Left = 710
Top = 175
Width = 49
Height = 17
Caption = 'Loop'
TabOrder = 7
OnClick = CheckBox1Click
end
object CheckBox2: TCheckBox
Left = 710
Top = 151
Width = 51
Height = 17
Caption = 'Async'
Checked = True
State = cbChecked
TabOrder = 8
end
object TrackBar1: TTrackBar
Left = 135
Top = 54
Width = 25
Height = 93
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 90
TabOrder = 9
ThumbLength = 15
OnChange = TrackBar1Change
end
object TrackBar2: TTrackBar
Left = 233
Top = 54
Width = 25
Height = 93
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 80
TabOrder = 10
ThumbLength = 15
OnChange = TrackBar1Change
end
object TrackBar3: TTrackBar
Left = 281
Top = 54
Width = 25
Height = 93
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 50
TabOrder = 11
ThumbLength = 15
OnChange = TrackBar1Change
end
object TrackBar4: TTrackBar
Left = 330
Top = 54
Width = 25
Height = 93
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 90
TabOrder = 12
ThumbLength = 15
OnChange = TrackBar1Change
end
object Panel1: TPanel
Left = 128
Top = 32
Width = 32
Height = 20
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '100%'
Color = clWhite
TabOrder = 13
end
object Panel2: TPanel
Left = 225
Top = 32
Width = 32
Height = 20
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '100%'
Color = clWhite
TabOrder = 14
end
object Panel3: TPanel
Left = 274
Top = 32
Width = 32
Height = 20
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '100%'
Color = clWhite
TabOrder = 15
end
object Panel4: TPanel
Left = 322
Top = 32
Width = 32
Height = 20
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '100%'
Color = clWhite
TabOrder = 16
end
object TrackBar5: TTrackBar
Left = 37
Top = 31
Width = 25
Height = 92
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 60
TabOrder = 17
ThumbLength = 15
OnChange = TrackBar5Change
end
object TrackBar6: TTrackBar
Left = 72
Top = 31
Width = 25
Height = 92
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 80
TabOrder = 18
ThumbLength = 15
OnChange = TrackBar6Change
end
object Button6: TButton
Left = 10
Top = 510
Width = 89
Height = 25
Caption = 'Play Tone'
TabOrder = 19
OnClick = Button6Click
end
object Button7: TButton
Left = 34
Top = 123
Width = 64
Height = 23
Caption = 'Preset'
TabOrder = 20
OnClick = Button7Click
end
object Button8: TButton
Left = 10
Top = 478
Width = 89
Height = 25
Caption = 'Play ADSR'
TabOrder = 21
OnClick = Button8Click
end
object Button9: TButton
Left = 10
Top = 542
Width = 89
Height = 25
Caption = 'Stop'
TabOrder = 22
OnClick = Button9Click
end
object Button10: TButton
Left = 697
Top = 238
Width = 81
Height = 25
Caption = 'Random'
TabOrder = 23
OnClick = Button10Click
end
object Button11: TButton
Left = 697
Top = 350
Width = 81
Height = 25
Caption = 'Morse'
TabOrder = 24
OnClick = Button11Click
end
object Button12: TButton
Left = 697
Top = 322
Width = 81
Height = 25
Caption = 'Alarm'
TabOrder = 25
OnClick = Button12Click
end
object Button13: TButton
Left = 697
Top = 294
Width = 81
Height = 25
Caption = 'Volume Pan'
TabOrder = 26
OnClick = Button13Click
end
object Button14: TButton
Left = 697
Top = 266
Width = 81
Height = 25
Caption = 'Tune'
TabOrder = 27
OnClick = Button14Click
end
object Button1: TButton
Left = 696
Top = 483
Width = 81
Height = 25
Cancel = True
Caption = 'E&xit'
TabOrder = 30
OnClick = Button1Click
end
object Button2: TButton
Left = 695
Top = 450
Width = 81
Height = 25
Caption = '&Help'
TabOrder = 31
OnClick = Button2Click
end
object CheckBox3: TCheckBox
Left = 710
Top = 200
Width = 49
Height = 17
Caption = 'Stereo'
Checked = True
State = cbChecked
TabOrder = 32
end
object Panel5: TPanel
Left = 177
Top = 32
Width = 32
Height = 20
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '100%'
Color = clWhite
TabOrder = 33
end
object TrackBar7: TTrackBar
Left = 184
Top = 54
Width = 25
Height = 93
LineSize = 5
Max = 100
Orientation = trVertical
PageSize = 10
Frequency = 10
Position = 90
TabOrder = 34
ThumbLength = 15
OnChange = TrackBar1Change
end
object TrackBar8: TTrackBar
Left = 122
Top = 180
Width = 25
Height = 113
LineSize = 5
Max = 19
Orientation = trVertical
PageSize = 10
Frequency = 2
Position = 14
TabOrder = 35
ThumbLength = 15
OnChange = TrackBar8Change
end
object Panel6: TPanel
Left = 124
Top = 339
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 36
end
object TrackBar9: TTrackBar
Left = 129
Top = 359
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 37
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel7: TPanel
Left = 156
Top = 339
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 38
end
object TrackBar10: TTrackBar
Left = 160
Top = 359
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 45
ShowHint = True
TabOrder = 39
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup4: TRadioGroup
Left = 126
Top = 442
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 40
OnClick = RadioGroup4Click
end
object Panel8: TPanel
Left = 193
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 41
end
object TrackBar11: TTrackBar
Left = 198
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 42
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel9: TPanel
Left = 225
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 43
end
object TrackBar12: TTrackBar
Left = 229
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 40
ShowHint = True
TabOrder = 44
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup5: TRadioGroup
Left = 195
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 45
OnClick = RadioGroup4Click
end
object Panel10: TPanel
Left = 261
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 46
end
object TrackBar13: TTrackBar
Left = 266
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 47
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel11: TPanel
Left = 293
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 48
end
object TrackBar14: TTrackBar
Left = 297
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 35
ShowHint = True
TabOrder = 49
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup6: TRadioGroup
Left = 263
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 50
OnClick = RadioGroup4Click
end
object Panel12: TPanel
Left = 330
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 51
end
object TrackBar15: TTrackBar
Left = 335
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 52
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel13: TPanel
Left = 362
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 53
end
object TrackBar16: TTrackBar
Left = 366
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 30
ShowHint = True
TabOrder = 54
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup7: TRadioGroup
Left = 332
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 55
OnClick = RadioGroup4Click
end
object Panel14: TPanel
Left = 399
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 56
end
object TrackBar17: TTrackBar
Left = 404
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 57
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel15: TPanel
Left = 431
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 58
end
object TrackBar18: TTrackBar
Left = 435
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 25
ShowHint = True
TabOrder = 59
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup8: TRadioGroup
Left = 401
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 60
OnClick = RadioGroup4Click
end
object Panel16: TPanel
Left = 468
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 61
end
object TrackBar19: TTrackBar
Left = 473
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 62
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel17: TPanel
Left = 500
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 63
end
object TrackBar20: TTrackBar
Left = 504
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 20
ShowHint = True
TabOrder = 64
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup9: TRadioGroup
Left = 470
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 65
OnClick = RadioGroup4Click
end
object Panel18: TPanel
Left = 536
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 66
end
object TrackBar21: TTrackBar
Left = 541
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 67
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel19: TPanel
Left = 568
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 68
end
object TrackBar22: TTrackBar
Left = 572
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 15
ShowHint = True
TabOrder = 69
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup10: TRadioGroup
Left = 538
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 70
OnClick = RadioGroup4Click
end
object Panel20: TPanel
Left = 604
Top = 340
Width = 29
Height = 20
Hint = 'Amplitude'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '0%'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 71
end
object TrackBar23: TTrackBar
Left = 609
Top = 360
Width = 25
Height = 89
Hint = 'Amplitude'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 50
ShowHint = True
TabOrder = 72
ThumbLength = 15
OnChange = TrackBar9Change
end
object Panel21: TPanel
Left = 636
Top = 340
Width = 29
Height = 20
Hint = 'Frequency'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = 'x0.1'
Color = clWhite
ParentShowHint = False
ShowHint = True
TabOrder = 73
end
object TrackBar24: TTrackBar
Left = 640
Top = 360
Width = 25
Height = 89
Hint = 'Frequency'
LineSize = 5
Max = 50
Orientation = trVertical
ParentShowHint = False
PageSize = 10
Frequency = 5
Position = 10
ShowHint = True
TabOrder = 74
ThumbLength = 15
OnChange = TrackBar10Change
end
object RadioGroup11: TRadioGroup
Left = 606
Top = 443
Width = 58
Height = 102
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ItemIndex = 0
Items.Strings = (
'Sin'
'Sq'
'Tri'
'Saw'
'Noise')
ParentFont = False
TabOrder = 75
OnClick = RadioGroup4Click
end
object Button4: TButton
Left = 5
Top = 364
Width = 25
Height = 19
Caption = 'A'
TabOrder = 76
OnClick = Button4Click
end
object Button5: TButton
Left = 30
Top = 364
Width = 25
Height = 19
Caption = 'A#'
TabOrder = 77
OnClick = Button4Click
end
object Button15: TButton
Left = 55
Top = 364
Width = 25
Height = 19
Caption = 'B'
TabOrder = 78
OnClick = Button4Click
end
object Button16: TButton
Left = 80
Top = 364
Width = 25
Height = 19
Caption = 'C'
TabOrder = 79
OnClick = Button4Click
end
object Button17: TButton
Left = 5
Top = 382
Width = 25
Height = 19
Caption = 'C#'
TabOrder = 80
OnClick = Button4Click
end
object Button18: TButton
Left = 30
Top = 382
Width = 25
Height = 19
Caption = 'D'
TabOrder = 81
OnClick = Button4Click
end
object Button19: TButton
Left = 55
Top = 382
Width = 25
Height = 19
Caption = 'D#'
TabOrder = 82
OnClick = Button4Click
end
object Button20: TButton
Left = 80
Top = 382
Width = 25
Height = 19
Caption = 'E'
TabOrder = 83
OnClick = Button4Click
end
object Button21: TButton
Left = 5
Top = 400
Width = 25
Height = 19
Caption = 'F'
TabOrder = 84
OnClick = Button4Click
end
object Button22: TButton
Left = 30
Top = 400
Width = 25
Height = 19
Caption = 'F#'
TabOrder = 85
OnClick = Button4Click
end
object Button23: TButton
Left = 55
Top = 400
Width = 25
Height = 19
Caption = 'G'
TabOrder = 86
OnClick = Button4Click
end
object Button24: TButton
Left = 80
Top = 400
Width = 25
Height = 19
Caption = 'G#'
TabOrder = 87
OnClick = Button4Click
end
object TrackBar25: TTrackBar
Left = 3
Top = 435
Width = 81
Height = 25
Hint = 'Octave'
Max = 9
ParentShowHint = False
Position = 4
ShowHint = True
TabOrder = 88
ThumbLength = 10
OnChange = TrackBar25Change
end
object Panel22: TPanel
Left = 83
Top = 436
Width = 18
Height = 19
Hint = 'Octave'
BevelInner = bvLowered
BevelOuter = bvLowered
Caption = '4'
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 89
end
object Button25: TButton
Left = 687
Top = 544
Width = 103
Height = 26
Caption = 'Export File'
TabOrder = 90
OnClick = Button25Click
end
object Edit3: TEdit
Left = 687
Top = 521
Width = 101
Height = 21
TabOrder = 91
Text = 'c:\test.wav'
end
object RadioButton1: TRadioButton
Left = 607
Top = 553
Width = 65
Height = 14
Caption = 'Absolute'
TabOrder = 92
OnClick = TrackBar10Change
end
object RadioButton2: TRadioButton
Left = 535
Top = 553
Width = 65
Height = 14
Caption = 'Multiply'
Checked = True
TabOrder = 93
TabStop = True
OnClick = TrackBar10Change
end
object Button26: TButton
Left = 123
Top = 551
Width = 52
Height = 16
Caption = 'Reset'
TabOrder = 94
OnClick = Button26Click
end
object Timer2: TTimer
Enabled = False
Interval = 150
OnTimer = Timer2Timer
Left = 638
Top = 22
end
object Timer3: TTimer
Enabled = False
Interval = 5000
OnTimer = Timer3Timer
Left = 606
Top = 22
end
object ToneGen1: TToneGen
Frequency = 100
Hold = 10
AMAmplitude = 30
AMWaveform = tgSine
AMFrequency = 0.300000011920929000
Left = 574
Top = 22
AMArrayData = {
070000001E000000000000009A99993E00000000000000000000C03F00000000
000000000000A04100000000000000000000A04100000000000000000000A041
00000000000000000000A04100000000000000000000A0410000000002000000
0000A041}
end
object WaveTTG: TToneGen
Frequency = 800
Duration = 50
Resolution = tg8Bit
Quality = tgLoQ
AMAmplitude = 30
AMWaveform = tgSquare
AMFrequency = 4.000000000000000000
Left = 544
Top = 22
AMArrayData = {
070000001E00000001000000000080400A000000010000000000003F00000000
040000000000C03F000000000000000000000040000000000000000000002040
0000000000000000000040400000000000000000000060400000000000000000
00008040}
end
end