Смекни!
smekni.com

Система обработки аудиоинформации Подсистема фильтрации и обработки сигнала (стр. 20 из 24)

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

AddBrainWave(AudioData, Start, Finish-Start+1, BWFreqEdit1.Value, BWFreqEdit2.Value);

end;

Status := 'waiting';

end;

procedure TMainForm.Left10ButtonClick(Sender: TObject);

var

AudioSize, Smp10ms: Cardinal;

begin

if Status<>'waiting' then Exit;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

Smp10ms := Round(AudioData.nSamplesPerSec/100);

if Sender = Left10Button then

if AudioPosition < Smp10ms then AudioPosition := 0 else AudioPosition := AudioPosition - Smp10ms

else

if AudioPosition + Smp10ms >= AudioSize then AudioPosition := AudioSize - 1 else AudioPosition := AudioPosition + Smp10ms;

SetAudioPosition;

end;

procedure TMainForm.SSelButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

if Sender = {SSelButton}BitBtn3 then

if Selection.StartExists then AudioPosition := Selection.Start else AudioPosition := 0

else

if Selection.FinishExists then AudioPosition := Selection.Finish else AudioPosition := AudioSize - 1;

SetAudioPosition;

end;

procedure TMainForm.HelpButtonClick(Sender: TObject);

begin

HelpForm.Visible := True;

HelpForm.Show;

end;

procedure TMainForm.UndoCheckBoxClick(Sender: TObject);

begin

if UndoCheckBox.Checked then

UndoButton.Enabled := True

else

begin

UndoButton.Enabled := False;

UndoInfo.AudioData.Data.Clear;

end;

end;

procedure TMainForm.N4Click(Sender: TObject);

begin

MainForm.Close;

end;

procedure TMainForm.N43Click(Sender: TObject);

begin

AudioOptionsForm.Visible := True;

AudioOptionsForm.Show;

end;

procedure TMainForm.MP31Click(Sender: TObject);

begin

MP3OptionsForm.Visible := True;

MP3OptionsForm.Show;

end;

procedure TMainForm.N44Click(Sender: TObject);

begin

EffOptionsForm.Visible := True;

EffOptionsForm.Show;

end;

procedure TMainForm.ButtonZoomInClick(Sender: TObject);

begin

SamplesPerPoint := SamplesPerPoint div 2;

if (SamplesPerPoint<1) then SamplesPerPoint:=1;

PaintBox1.Repaint;

end;

procedure TMainForm.ButtonZoomOutClick(Sender: TObject);

begin

SamplesPerPoint := SamplesPerPoint * 2;

PaintBox1.Repaint;

end;

procedure TMainForm.AudioOptionsButtonClick(Sender: TObject);

begin

AudioOptionsForm.Visible := True;

AudioOptionsForm.Show;

end;

procedure TMainForm.MP3OptionsButtonClick(Sender: TObject);

begin

MP3OptionsForm.Visible := True;

MP3OptionsForm.Show;

end;

procedure TMainForm.EffOptionsButtonClick(Sender: TObject);

begin

EffOptionsForm.Visible := True;

EffOptionsForm.Show;

end;

end.

П. 1.2. ТЕКСТ МОДУЛЯ PCM_FORMAT.PAS

unit PCM_Format;

interface

uses

SysUtils, AudioFormat;

type

TPCMFile = class(TAudioFile)

public

RIFFLabel: String;

RIFFSize: LongWord;

fccType: String;

fmt_Label: String;

fmtSize: LongWord;

formatTag: Word;

nChannels: Word;

nSamplesPerSec: LongWord;

nAvgBytesPerSec: LongWord;

nBlockAlign: Word;

nBitsPerSample: Word;

DataID: String;

AdvDataBegin: LongWord; //*

DataSize: LongWord;

DataLabel: String;

SndDataBegin: LongWord; //*

nDataBytes: LongWord;

constructor Open(FileName: string);

function ReadSample(Number, Channel: LongInt): Integer;

procedure WriteSample(Number, Channel: LongInt; Value: Integer);

procedure ReadAudioData(var AudioData: TAudioData);

constructor Create(FileName: string; var AudioData: TAudioData);

private

{ Private declarations }

end;

implementation

constructor TPCMFile.Open(FileName: String);

begin

inherited Open(FileName);

ReadString(RIFFLabel, 4);

Read(RIFFSize, 4);

ReadString(fccType, 4);

ReadString(fmt_Label, 4);

Read(fmtSize, 4);

Read(formatTag, 2);

Read(nChannels, 2);

Read(nSamplesPerSec, 4);

Read(nAvgBytesPerSec, 4);

Read(nBlockAlign, 2);

Read(nBitsPerSample, 2);

Position := $14 + fmtSize;

ReadString(DataLabel, 4);

if DataLabel <> 'data' then

begin

DataId := DataLabel;

Read(DataSize, 4);

AdvDataBegin := Position;

Position := Position + DataSize;

ReadString(DataLabel, 4);

end

else

begin

DataID := '';

DataSize := 0;

end;

Read(nDataBytes, 4);

SndDataBegin := Position;

end;

function TPCMFile.ReadSample(Number, Channel: LongInt): Integer;

var

i: Byte;

Value, Mult: LongWord;

begin

Position := SndDataBegin + Number*nBlockAlign + Channel*Trunc(nBlockAlign/nChannels);

Value := 0;

Read(Value, Trunc(nBlockAlign/nChannels));

Mult := 1;

for i := 0 to Trunc(nBlockAlign/nChannels)-1 do Mult := Mult*256;

if nBitsPerSample>8 then

if Value >= Mult/2 then ReadSample := Value - Mult else ReadSample := Value

else

ReadSample := Value-128;

end;

procedure TPCMFile.WriteSample(Number, Channel: LongInt; Value: Integer);

begin

Position := SndDataBegin + Number*nBlockAlign + Channel*Trunc(nBlockAlign/nChannels);

if nBitsPerSample<=8 then Value := Value+128;

Write(Value, Trunc(nBlockAlign/nChannels));

end;

procedure TPCMFile.ReadAudioData(var AudioData: TAudioData);

const

MaxBufSize = 65536;

var

i: Cardinal;

BufSize: Cardinal;

Buf: array [0..MaxBufSize] of Byte;

begin

AudioData.Data.Clear;

Position := SndDataBegin;

while Position<Size do

begin

if Size-Position>=MaxBufSize then BufSize := MaxBufSize else BufSize := Size-Position;

Read(Buf, BufSize);

AudioData.Data.Write(Buf, BufSize);

end;

AudioData.nChannels := nChannels;

AudioData.nSamplesPerSec := nSamplesPerSec;

AudioData.nBitsPerSample := nBitsPerSample;

AudioData.Calculate_nBlockAlign;

end;

constructor TPCMFile.Create(FileName: string; var AudioData: TAudioData);

const

MaxBufSize = 65536;

var

i: Cardinal;

BufSize: Cardinal;

Buf: array [0..MaxBufSize] of Byte;

begin

inherited Create(FileName);

RIFFLabel := 'RIFF';

RIFFSize := AudioData.Data.Size+4*3+2*2+4*2+2*2+4*2;

fccType := 'WAVE';

fmt_Label := 'fmt ';

fmtSize := 16;

formatTag := 1; //???

nChannels := AudioData.nChannels;

nSamplesPerSec := AudioData.nSamplesPerSec;

nBlockAlign := AudioData.nBitsPerSample div 8;

if AudioData.nBitsPerSample mod 8 <> 0 then Inc(nBlockAlign);

nBlockAlign := nBlockAlign*nChannels;

nAvgBytesPerSec := nSamplesPerSec*nBlockAlign;

nBitsPerSample := AudioData.nBitsPerSample;

DataLabel := 'data';

nDataBytes := AudioData.Data.Size;

WriteString(RIFFLabel, 4);

Write(RIFFSize, 4);

WriteString(fccType, 4);

WriteString(fmt_Label, 4);

Write(fmtSize, 4);

Write(formatTag, 2);

Write(nChannels, 2);

Write(nSamplesPerSec, 4);

Write(nAvgBytesPerSec, 4);

Write(nBlockAlign, 2);

Write(nBitsPerSample, 2);

WriteString(DataLabel, 4);

Write(nDataBytes, 4);

DataID := '';

DataSize := 0;

SndDataBegin := Position;

AudioData.Data.Position := 0;

while AudioData.Data.Position < AudioData.Data.Size do

begin

with AudioData.Data do

begin

if Size-Position>=MaxBufSize then BufSize := MaxBufSize else BufSize := Size-Position;

Read(Buf, BufSize);

end;

Write(Buf, BufSize);

end;

end;

end.

П. 1.3. ТЕКСТ МОДУЛЯ MP3_FORMAT.PAS

unit MP3_Format;

interface

uses

SysUtils, ShellApi, Windows, Classes, AudioFormat, PCM_Format;

type

TMP3File = class(TAudioFile)

public

constructor Open(FileName: string);

constructor Create(FileName: string; var AudioData: TAudioData; BitRate, EncMode, StereoMode: String);

procedure ReadAudioData(var AudioData: TAudioData);

private

Name: String;

end;

implementation

{$R Lame.res}

var

Res: TResourceStream;

TempDir: String;

LameFile: String;

LameParameters: String;

constructor TMP3File.Open(FileName: string);

begin

inherited Open(FileName);

Name := FileName;

end;

constructor TMP3File.Create(FileName: string; var AudioData: TAudioData; BitRate, EncMode, StereoMode: String);

var

TempWaveFile: String;

PCM: TPCMFile;

StartupInfo: TStartupInfo;

ProcessInformation: TProcessInformation;

begin

TempWaveFile := TempDir+'TempWave.wav';

PCM := TPCMFile.Create(TempWaveFile, AudioData);

PCM.Destroy;

LameParameters := LameFile+' -m '+StereoMode+' '+EncMode+' '+BitRate+' "'+TempWaveFile+'" "'+FileName+'"';

FillChar(StartupInfo, SizeOf(StartupInfo), 0 );

StartupInfo.cb := SizeOf(StartupInfo);

StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

StartupInfo.wShowWindow := SW_HIDE;

CreateProcess(nil, PChar(LameParameters), nil, nil, False, CREATE_DEFAULT_ERROR_MODE+HIGH_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInformation);

WaitForSingleObject(ProcessInformation.hProcess, infinite);

DeleteFile(PChar(TempWaveFile));

inherited Open(FileName);

Name := FileName;

end;

procedure TMP3File.ReadAudioData(var AudioData: TAudioData);

var

TempWaveFile: String;

PCM: TPCMFile;

Result: Word;

StartupInfo: TStartupInfo;

ProcessInformation: TProcessInformation;

begin

TempWaveFile := TempDir+'TempWave.wav';

LameParameters := LameFile+' --decode '+'"'+Name+'" "'+TempWaveFile+'"';

FillChar(StartupInfo, SizeOf(StartupInfo), 0 );

StartupInfo.cb := SizeOf(StartupInfo);

StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

StartupInfo.wShowWindow := SW_HIDE;

CreateProcess(nil, PChar(LameParameters), nil, nil, False, CREATE_DEFAULT_ERROR_MODE+HIGH_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInformation);

WaitForSingleObject(ProcessInformation.hProcess, infinite);

PCM := TPCMFile.Open(TempWaveFile);

PCM.ReadAudioData(AudioData);

PCM.Destroy;

DeleteFile(PChar(TempWaveFile));

end;

initialization

TempDir := GetEnvironmentVariable('TEMP')+'&bsol;';

Res := TResourceStream.Create(Hinstance, 'Lame', 'ExeFile');

LameFile := TempDir+'Lame.exe';

Res.SaveToFile(LameFile);

Res.Destroy;

end.

П. 1.4. ТЕКСТ МОДУЛЯ EM1_FORMAT.PAS

unit EM1_Format;

interface

uses

SysUtils, AudioFormat;

type

TEM1File = class(TAudioFile)

public

EM1Label: String;

nChannels: Word;

nSamplesPerSec: LongWord;

nBytesPerSample: Word;

nSamples: LongWord;

procedure ReadAudioData(var AudioData: TAudioData);

constructor Create(FileName: string; var AudioData: TAudioData);

constructor Open(FileName: string);

end;

implementation

constructor TEM1File.Create(FileName: string; var AudioData: TAudioData);

var

Channel: Word;

NumberOfBit, NumberOfSample, NumberOfSample0, i: Cardinal;

Sample: Integer;

Bit: Byte;

begin

inherited Create(FileName);

EM1Label := 'EM1 ';

nChannels := AudioData.nChannels;

nSamplesPerSec := AudioData.nSamplesPerSec;

nBytesPerSample := AudioData.nBitsPerSample div 8;

nSamples := AudioData.Data.Size div AudioData.nBlockAlign;

WriteString(EM1Label, 4);

Write(nChannels, 2);

Write(nSamplesPerSec, 4);

Write(nBytesPerSample, 2);

Write(nSamples, 4);

for Channel := 0 to nChannels-1 do

begin

NumberOfBit := Position*8;

NumberOfSample0 := 0;

NumberOfSample := 1;

Bit := 0;

while NumberOfSample < nSamples do

begin

while not AudioData.Extremum(NumberOfSample, Channel) do

Inc(NumberOfSample);

Inc(NumberOfSample);

for i := 1 to NumberOfSample-NumberOfSample0 do

begin

WriteBit(NumberOfBit, Bit);

Inc(NumberOfBit);

end;

Bit := 1 - Bit;

NumberOfSample0 := NumberOfSample;

end;

NumberOfSample0 := 0;

NumberOfSample := 1;

while NumberOfSample < nSamples do

begin

while not AudioData.Extremum(NumberOfSample, Channel) do

Inc(NumberOfSample);

AudioData.ReadSample(NumberOfSample, Channel, Sample);

Inc(NumberOfSample);

Write(Sample, nBytesPerSample);

NumberOfSample0 := NumberOfSample;

end;

end;

end;

constructor TEM1File.Open(FileName: String);

begin

inherited Open(FileName);

ReadString(EM1Label, 4);

Read(nChannels, 2);

Read(nSamplesPerSec, 4);

Read(nBytesPerSample, 2);

Read(nSamples, 4);

end;

procedure TEM1File.ReadAudioData(var AudioData: TAudioData);

var

Channel: Word;

NumberOfBit, NumberOfSample, NumberOfSample0, i: Cardinal;

Sample, Sample0, Sample1: Integer;

Bit: Byte;

Value, Mult: LongWord;

begin

AudioData.Data.Clear;

AudioData.nChannels := nChannels;

AudioData.nSamplesPerSec := nSamplesPerSec;

AudioData.nBitsPerSample := nBytesPerSample*8;

AudioData.Calculate_nBlockAlign;

Position := 16;

Mult := 1;

for i := 0 to nBytesPerSample-1 do Mult := Mult*256;

for Channel := 0 to nChannels-1 do

begin

NumberOfBit := Position*8;

for i := 0 to nSamples-1 do

begin

ReadBit(NumberOfBit, Bit);

if Bit = 0 then Sample := -32768 else Sample := 32767;

AudioData.WriteSample(i, Channel, Sample);

Inc(NumberOfBit);

end;

NumberOfSample0 := 0;

NumberOfSample := 0;

Sample0 := 0;

while NumberOfSample < nSamples do

begin

AudioData.ReadSample(NumberOfSample, Channel, Sample1);

Sample := Sample1;

while (Sample = Sample1)and(NumberOfSample < nSamples) do

begin

Inc(NumberOfSample);

if NumberOfSample < nSamples then

AudioData.ReadSample(NumberOfSample, Channel, Sample);

end;

Value := 0;

Read(Value, nBytesPerSample);

if Value >= Mult/2 then Sample := Value - Mult else Sample := Value;

for i := 0 to NumberOfSample-NumberOfSample0-1 do

begin

Sample1 := Sample0 + Round((Sample-Sample0)/2 - (Sample-Sample0)/2*Cos(i*Pi/(NumberOfSample-NumberOfSample0)));

AudioData.WriteSample(NumberOfSample0+i, Channel, Sample1);

end;

NumberOfSample0 := NumberOfSample;

Sample0 := Sample;

end;

end;

end;

end.

П. 1.5. ТЕКСТ МОДУЛЯ AUDIOFORMAT.PAS

unit AudioFormat;

interface

uses

SysUtils, FileUtils;

type

TAudioFile = class(TFile)

end;

type

TAudioData = class(TObject)

public

nChannels: Word;

nSamplesPerSec: LongWord;

nBitsPerSample: Word;

nBlockAlign: Word;

Data: TFile;

constructor Create;

destructor Destroy;

procedure Calculate_nBlockAlign;

procedure ReadSample(Number, Channel: LongInt; var Value: Integer);

procedure WriteSample(Number, Channel: LongInt; Value: Integer);

function Extremum(Number, Channel: LongInt): Boolean;

private

Name: String;

end;

procedure CopyAudio(var AudioSource, AudioGeter: TAudioData; Start, Finish: Cardinal);

procedure DeleteAudio(var AudioData: TAudioData; Start, Finish: Cardinal);

procedure InsertAudio(var AudioSource, AudioGeter: TAudioData; Start: Cardinal);

procedure OverwriteAudio(var AudioSource, AudioGeter: TAudioData; Start: Cardinal);

procedure MixAudio(var AudioSource, AudioGeter: TAudioData; Start: Cardinal);

procedure ReverseAudio(var AudioData: TAudioData; Start, Count: Cardinal);