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

Разработка программного обеспечения, предназначенного для изменения характеристик исходного звукового сигнала с целью изменения характеристик его звучания. Алгоритмы обработки и фильтрации звукового сигнала, редактирование его, изменение темпа и уровня.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 08.07.2008
Размер файла 1,8 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

ReverseAudio(AudioData, Start, Finish-Start+1);

end;

Status := 'waiting';

end;

procedure TMainForm.NormalizeButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

Normalize(AudioData, Start, Finish-Start+1);

end;

Status := 'waiting';

PaintBox1.Repaint;

end;

procedure TMainForm.SetSpeedButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

SetSpeedOfAudio(AudioData, Start, Finish-Start+1, SpeedEdit.Value/100);

DeleteMarkers;

AudioPosition := Start;

SetMarker;

AudioPosition := Trunc(Start+(Finish-Start)*100/SpeedEdit.Value);

SetMarker;

AudioPosition := Start;

SetAudioPosition;

end;

Status := 'waiting';

end;

procedure TMainForm.ChangePropertie(Sender: TObject);

var

S: String;

Value, Code: Cardinal;

begin

if (Status<>'waiting')and(Status<>'starting') then Exit;

Status := 'editing';

if Sender = AudioOptionsForm.nSamplesPerSecButton then

begin

Val(AudioOptionsForm.nSamplesBox.Text, Value, Code);

SetnSamplesPerSec(AudioData, Value);

end;

if Sender = AudioOptionsForm.nBitsPerSampleButton then

begin

Val(AudioOptionsForm.nBitsBox.Text, Value, Code);

SetnBitsPerSample(AudioData, Value);

end;

if Sender = AudioOptionsForm.nChannelsButton then

begin

SetnChannels(AudioData, AudioOptionsForm.nChannelsBox.ItemIndex+1);

end;

AudioData.Calculate_nBlockAlign;

DeleteMarkers;

AudioPosition := 0;

SetAudioPosition;

Str(AudioData.nChannels, S);

AudioOptionsForm.nChannelsText.Caption := S + ' channels';

Str(AudioData.nBitsPerSample, S);

AudioOptionsForm.nBitsPerSampleText.Caption := S + ' bits';

Str(AudioData.nSamplesPerSec, S);

AudioOptionsForm.nSamplesPerSecText.Caption := S + ' Hz';

Status := 'waiting';

end;

procedure TMainForm.SetVolumeButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

SetVolumeOfAudio(AudioData, Start, Finish-Start+1, VolumeEdit.Value/100);

end;

Status := 'waiting';

end;

procedure TMainForm.AboutButtonClick(Sender: TObject);

begin

MessageBox(MainForm.Handle, 'AudioEditor v02.2006'#13#13'Выполнил Суханов М.А.'#13#13'ИжГТУ, 2006'#13#13'smike@pochta.ru', 'О программе', MB_OK);

end;

procedure TMainForm.HomePageLinkClick(Sender: TObject);

begin

ShellExecute(Handle, 'open', PChar('http://Andrei512.narod.ru'), '', '', SW_Show);

end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);

begin

AudioData.Destroy;

AudioClipBoard.Destroy;

UndoInfo.AudioData.Destroy;

end;

procedure TMainForm.SetSpeedBitBtnClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

SetSpeedOfAudio(AudioData, Start, Finish-Start+1, SpeedEdit.Value/100);

DeleteMarkers;

AudioPosition := Start;

SetMarker;

AudioPosition := Trunc(Start+(Finish-Start)*100/SpeedEdit.Value);

SetMarker;

AudioPosition := Start;

SetAudioPosition;

end;

Status := 'waiting';

end;

procedure TMainForm.ChangeSpeedButtonClick(Sender: TObject);

var

AudioSize, NewCount: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

NewCount := ChangeSpeedOfAudio(AudioData, Start, Finish-Start+1, SpeedEdit.Value/100);

DeleteMarkers;

AudioPosition := Start;

SetMarker;

AudioPosition := Start+NewCount;

SetMarker;

AudioPosition := Start;

SetAudioPosition;

end;

Status := 'waiting';

end;

procedure TMainForm.SetVolumeBitBtnClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

SetVolumeOfAudio(AudioData, Start, Finish-Start+1, VolumeEdit.Value/100);

end;

Status := 'waiting';

PaintBox1.Repaint;

end;

procedure TMainForm.ChangeVolumeBitBtnClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

ChangeVolumeOfAudio(AudioData, Start, Finish-Start+1, VolumeEdit.Value/100);

end;

Status := 'waiting';

PaintBox1.Repaint;

end;

procedure TMainForm.NormalizeBitBtnClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

Normalize(AudioData, Start, Finish-Start+1);

end;

Status := 'waiting';

end;

procedure TMainForm.EffectButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

if Sender = BitBtn13 then Echo(AudioData, Start, Finish-Start+1, EffOptionsForm.nResponsesEdit.Value, EffOptionsForm.ResponseTimeEdit.Value, EffOptionsForm.ResponseVolumeEdit.Value/100);

if Sender = BitBtn14 then Reverberation(AudioData, Start, Finish-Start+1, EffOptionsForm.nEchosEdit.Value, EffOptionsForm.DelayEdit.Value, EffOptionsForm.EchoVolumeEdit.Value/100);

if Sender = BitBtn15 then ChangeVolumeOfAudio(AudioData, Start, Finish-Start+1, 0);

if Sender = BitBtn16 then ReChangeVolumeOfAudio(AudioData, Start, Finish-Start+1, 1);

{case EffectBox.ItemIndex of

0: ChangeVolumeOfAudio(AudioData, Start, Finish-Start+1, 0);

1: ReChangeVolumeOfAudio(AudioData, Start, Finish-Start+1, 1);

2: Echo(AudioData, Start, Finish-Start+1, nResponsesEdit.Value, ResponseTimeEdit.Value, ResponseVolumeEdit.Value/100);

3: Reverberation(AudioData, Start, Finish-Start+1, nEchosEdit.Value, DelayEdit.Value, EchoVolumeEdit.Value/100);

end;}

end;

Status := 'waiting';

PaintBox1.Repaint;

end;

procedure TMainForm.PaintAudioGraph;

var

PaintPos, MaxPaintPos: Cardinal;

AudioPos, {SamplesPerPoint,} LeftSamples, MaxAmplitude: Cardinal;

numChannels, Channel, i: Word;

Smp, Smp1: Integer;

begin

with PaintBox1.Canvas do

begin

Pen.Color := clBlack;

MoveTo(Round(PaintBox1.Width/2),0);

LineTo(Round(PaintBox1.Width/2), Round(PaintBox1.Height));

MoveTo(0, Round(PaintBox1.Height/2));

LineTo(PaintBox1.Width, Round(PaintBox1.Height/2));

Pen.Color := clGreen;

end;

MaxPaintPos := PaintBox1.Width;

if AudioPosition-PaintBox1.Width*SamplesPerPoint >= 0 then

begin

AudioPos := AudioPosition-PaintBox1.Width*SamplesPerPoint;

PaintPos := 0;

end

else

begin

AudioPos := 0;

PaintPos := PaintBox1.Width - Trunc(AudioPosition/SamplesPerPoint);

end;

numChannels := AudioData.nChannels;

MaxAmplitude := 1;

for i := 1 to AudioData.nBitsPerSample do

MaxAmplitude := MaxAmplitude*2;

Smp := 0;

for Channel := 0 to numChannels-1 do

begin

AudioData.ReadSample(AudioPos, Channel, Smp1);

Smp := Smp + Smp1;

end;

Smp := Round(Smp/numChannels);

PaintBox1.Canvas.MoveTo(PaintPos-Round(PaintBox1.Width/2), Round(PaintBox1.Height/2-Smp/MaxAmplitude*PaintBox1.Height));

LeftSamples := SamplesPerPoint;

while PaintPos<=(MaxPaintPos+Round(PaintBox1.Width/2)) do

begin

Smp := 0;

for Channel := 0 to numChannels-1 do

begin

AudioData.ReadSample(AudioPos, Channel, Smp1);

Smp := Smp + Smp1;

end;

if (Selection.StartExists)and(Selection.FinishExists)and

(AudioPos>Selection.Start)and(AudioPos<Selection.Finish)

then PaintBox1.Canvas.Pen.Color := clRed

else PaintBox1.Canvas.Pen.Color := clGreen;

Smp := Round(Smp/numChannels);

PaintBox1.Canvas.LineTo(PaintPos-Round(PaintBox1.Width/2), Round(PaintBox1.Height/2-Smp/MaxAmplitude*PaintBox1.Height));

Inc(AudioPos);

Dec(LeftSamples);

if LeftSamples = 0 then

begin

Inc(PaintPos);

LeftSamples := SamplesPerPoint;

end;

end;

end;

procedure TMainForm.PaintBox1Paint(Sender: TObject);

begin

PaintAudioGraph;

end;

procedure TMainForm.WaveOutButtonClick(Sender: TObject);

begin

ShellExecute(Handle, 'open', PChar('sndvol32.exe'), '', '', SW_Show);

end;

procedure TMainForm.WaveInButtonClick(Sender: TObject);

begin

ShellExecute(Handle, 'open', PChar('sndvol32.exe'), PChar('/r'), '', SW_Show);

end;

procedure TMainForm.CopyToFileButtonClick(Sender: TObject);

var

FileName, Ext, EncMode, StereoMode, BitRate: String;

i: Byte;

TempAudio: TAudioData;

Code: Integer;

PCM: TPCMFile;

MP3: TMP3File;

EM1: TEM1File;

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

if SaveDialog.Execute then

FileName := SaveDialog.FileName else Exit;

Ext := ExtractFileExt(FileName);

with AudioData do

AudioSize := Data.Size div nBlockAlign;

TempAudio := TAudioData.Create;

with Selection do

begin

if not StartExists or not FinishExists then

begin

DeleteMarkers;

Start := 0;

Finish := AudioSize-1;

end;

CopyAudio(AudioData, TempAudio, Start, Finish);

end;

for i := 1 to Length(Ext) do Ext[i] := UpCase(Ext[i]);

if Ext = '.WAV' then

begin

PCM := TPCMFile.Create(FileName, TempAudio);

PCM.Destroy;

end;

if Ext = '.MP3' then

begin

if RadioButton1.Checked then

begin

BitRate := MP3OptionsForm.ConstantBitRateComboBox.Text;

EncMode := '-b';

end;

if RadioButton2.Checked then

begin

BitRate := MP3OptionsForm.AverageBitRateComboBox.Text;

EncMode := '--abr';

end;

if RadioButton3.Checked then

begin

Str(MP3OptionsForm.VariableBitrateComboBox.ItemIndex, BitRate);

EncMode := '-V';

end;

case MP3OptionsForm.StereoModeComboBox.ItemIndex of

0: StereoMode := 's';

1: StereoMode := 'j';

2: StereoMode := 'f';

3: StereoMode := 'd';

4: StereoMode := 'm';

end;

MP3 := TMP3File.Create(FileName, TempAudio, BitRate, EncMode, StereoMode);

MP3.Destroy;

end;

if Ext = '.EM1' then

begin

EM1 := TEM1File.Create(FileName, TempAudio);

EM1.Destroy;

end;

TempAudio.Destroy;

end;

procedure TMainForm.SaveUndoInfo;

begin

if not UndoCheckBox.Checked then Exit;

UndoInfo.AudioPosition := AudioPosition;

UndoInfo.Selection.Start := Selection.Start;

UndoInfo.Selection.Finish := Selection.Finish;

UndoInfo.Selection.StartExists := Selection.StartExists;

UndoInfo.Selection.FinishExists := Selection.FinishExists;

UndoInfo.AudioData.Data.Clear;

CopyAudio(AudioData, UndoInfo.AudioData, 0, AudioData.Data.Size div AudioData.nBlockAlign - 1);

end;

procedure TMainForm.UndoButtonClick(Sender: TObject);

begin

if Status<>'waiting' then Exit;

if UndoInfo.AudioData.Data.Size = 0 then Exit;

Status := 'undo';

DeleteMarkers;

AudioData.Data.Clear;

CopyAudio(UndoInfo.AudioData, AudioData, 0, UndoInfo.AudioData.Data.Size div UndoInfo.AudioData.nBlockAlign - 1);

if UndoInfo.Selection.StartExists then

begin

AudioPosition := UndoInfo.Selection.Start;

SetMarker;

end;

if UndoInfo.Selection.FinishExists then

begin

AudioPosition := UndoInfo.Selection.Finish;

SetMarker;

end;

AudioPosition := UndoInfo.AudioPosition;

SetAudioPosition;

UndoInfo.AudioData.Data.Clear;

Status := 'waiting';

end;

procedure TMainForm.EMailButtonClick(Sender: TObject);

begin

ShellExecute(Handle, 'open', PChar('mailto:Andrei512@narod.ru'), PChar(''), '', SW_Show);

end;

procedure TMainForm.BrainWaveButtonClick(Sender: TObject);

var

AudioSize: Cardinal;

begin

if Status<>'waiting' then Exit;

Status := 'deformation';

SaveUndoInfo;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

with Selection do

begin

if not StartExists or not FinishExists then

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')+'\';

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);

procedure AddBrainWave(var AudioData: TAudioData; Start, Count, Freq1, Freq2: Integer);

procedure SetSpeedOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Speed: Real);

function ChangeSpeedOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Speed: Real): Cardinal;

procedure SetnSamplesPerSec(var AudioData: TAudioData; Value: Cardinal);

procedure SetnBitsPerSample(var AudioData: TAudioData; Value: Cardinal);

procedure SetnChannels(var AudioData: TAudioData; Value: Cardinal);

procedure SetVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

procedure Echo(var AudioData: TAudioData; Start, Count, Number, Delay: Cardinal; Volume: Real);

procedure Reverberation(var AudioData: TAudioData; Start, Count, Number, Delay: Cardinal; Volume: Real);

procedure ChangeVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

procedure ReChangeVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

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

implementation

constructor TAudioData.Create;

var

TempDir, FileName: String;

i: Word;

begin

inherited Create;

TempDir := GetEnvironmentVariable('TEMP')+'\';

i := 0;

FileName := TempDir + '\' + '0.TAD';

while FileExists(FileName) do

begin

Inc(i);

Str(i, FileName);

FileName := TempDir + '\' + FileName + '.TAD';

end;

Name := FileName;

Data := TFile.Create(FileName);

end;

procedure TAudioData.Calculate_nBlockAlign;

begin

nBlockAlign := nBitsPerSample div 8;

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

nBlockAlign := nBlockAlign*nChannels;

end;

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

var

i: Byte;

Mult, AbsValue: LongWord;

begin

Calculate_nBlockAlign;

Data.Position := Number*nBlockAlign + Channel*(nBlockAlign div nChannels);

AbsValue := 0;

Data.Read(AbsValue, nBlockAlign div nChannels);

Mult := 1;

for i := 1 to nBlockAlign div nChannels do

Mult := Mult*256;

if nBitsPerSample>8 then

if AbsValue >= Trunc(Mult/2) then Value := AbsValue - Mult else Value := AbsValue

else Value := AbsValue-128;

end;

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

var

K: Byte;

N: Cardinal;

begin

Calculate_nBlockAlign;

Data.Position := Number*nBlockAlign + Channel*(nBlockAlign div nChannels);

if Data.Position>Data.Size then

begin

K := 0;

N := Data.Position + nBlockAlign div nChannels;

Data.Position := Data.Size;

while Data.Position<=N do Data.Write(K, 1);

Data.Position := Number*nBlockAlign + Channel*(nBlockAlign div nChannels);

end;

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

Data.Write(Value, nBlockAlign div nChannels);

end;

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

var

Smp1, Smp, Smp2: Integer;

begin

if (Number = 0) or (Number + 1 = Data.Size div nBlockAlign) then

begin

Extremum := True;

Exit;

end;

ReadSample(Number-1, Channel, Smp1);

ReadSample(Number, Channel, Smp);

ReadSample(Number+1, Channel, Smp2);

if (Smp1<Smp)and(Smp>Smp2) or (Smp1>Smp)and(Smp<Smp2) then

Extremum := True

else

Extremum := False;

end;

destructor TAudioData.Destroy;

begin

Data.Destroy;

DeleteFile(Name);

inherited Destroy;

end;

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

var

i: Cardinal;

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

begin

AudioGeter.Data.Clear;

AudioGeter.nChannels := AudioSource.nChannels;

AudioGeter.nSamplesPerSec := AudioSource.nSamplesPerSec;

AudioGeter.nBitsPerSample := AudioSource.nBitsPerSample;

AudioGeter.Calculate_nBlockAlign;

AudioSource.Data.Position := Start*AudioSource.nBlockAlign;

for i := 1 to Abs(Finish-Start) do

begin

AudioSource.Data.Read(Buf, AudioSource.nBlockAlign);

AudioGeter.Data.Write(Buf, AudioSource.nBlockAlign);

end;

AudioGeter.nChannels := AudioSource.nChannels;

AudioGeter.nSamplesPerSec := AudioSource.nSamplesPerSec;

AudioGeter.nBitsPerSample := AudioSource.nBitsPerSample;

end;

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

var

i: Cardinal;

Buf: Byte;

begin

if AudioSource.Data.Size = 0 then Exit;

AudioGeter.Data.Insert(Start*AudioGeter.nBlockAlign, AudioSource.Data.Size);

AudioSource.Data.Position := 0;

AudioGeter.Data.Position := Start*AudioGeter.nBlockAlign;

for i := 1 to AudioSource.Data.Size do

begin

AudioSource.Data.Read(Buf, 1);

AudioGeter.Data.Write(Buf, 1);

end;

end;

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

begin

AudioData.Data.Delete(Start*AudioData.nBlockAlign, Abs(Finish-Start)*AudioData.nBlockAlign);

end;

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

var

i: Cardinal;

Buf: Byte;

begin

if AudioSource.Data.Size = 0 then Exit;

AudioSource.Data.Position := 0;

AudioGeter.Data.Position := Start*AudioGeter.nBlockAlign;

for i := 1 to AudioSource.Data.Size do

begin

AudioSource.Data.Read(Buf, 1);

AudioGeter.Data.Write(Buf, 1);

end;

end;

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

var

i, Channel, AudioSize: Cardinal;

Value, MaxValue: Int64;

Samp1, Samp2: Integer;

begin

if AudioSource.Data.Size = 0 then Exit;

AudioSize := AudioGeter.Data.Size div AudioGeter.nBlockAlign;

MaxValue := 1; for i := 1 to AudioGeter.nBitsPerSample-1 do MaxValue := MaxValue*2;

for i := 0 to AudioSource.Data.Size div AudioGeter.nBlockAlign - 1 do

for Channel := 0 to AudioGeter.nChannels-1 do

begin

AudioSource.ReadSample(i, Channel, Samp1);

if Start+i<AudioSize then

AudioGeter.ReadSample(Start+i, Channel, Samp2)

else

Samp2 := 0;

Value := Samp1 + Samp2;

if (Value < -MaxValue)or(Value >= MaxValue) then

Value := Trunc((Value)/2);

AudioGeter.WriteSample(Start+i, Channel, Value);

end;

end;

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

var

i, AbsStart, AbsFinish, AbsCount: Cardinal;

BufferStart: Cardinal;

Buf: Int64;

TempAudio: TAudioData;

begin

TempAudio := TAudioData.Create;

AbsStart := Start*AudioData.nBlockAlign;

AbsCount := Count*AudioData.nBlockAlign;

AbsFinish := AbsStart+AbsCount;

i := AbsFinish;

repeat

if i-AbsStart>=MaxSizeOfBuffer then

BufferStart := i - MaxSizeOfBuffer

else

BufferStart := AbsStart;

AudioData.Data.Position := BufferStart;

AudioData.Data.Read(Buf, 1);

while i>BufferStart do

begin

i := i - AudioData.nBlockAlign;

AudioData.Data.Position := i;

AudioData.Data.Read(Buf, AudioData.nBlockAlign);

TempAudio.Data.Write(Buf, AudioData.nBlockAlign);

end;

until i=AbsStart;

AudioData.Data.Position := AbsStart;

TempAudio.Data.Position := 0;

for i := 1 to Count do

begin

TempAudio.Data.Read(Buf, AudioData.nBlockAlign);

AudioData.Data.Write(Buf, AudioData.nBlockAlign);

end;

TempAudio.Destroy;

end;

procedure AddBrainWave(var AudioData: TAudioData; Start, Count, Freq1, Freq2: Integer);

var

i, MaxAmplitude: Cardinal;

T, TL, TR: Real;

Freq: Integer;

SampL, SampR: Integer;

begin

if AudioData.nChannels = 1 then Exit;

MaxAmplitude := 1;

for i := 1 to AudioData.nBitsPerSample-1 do

MaxAmplitude := MaxAmplitude*2;

for i := Start to Start+Count-1 do

begin

Freq := Freq1 + Round((i-Start)*(Freq2-Freq1)/Count);

T := 2*Pi/(AudioData.nSamplesPerSec/(Freq/100));

TL := 2*Pi/(AudioData.nSamplesPerSec/(50+50*Freq/100));

TR := 2*Pi/(AudioData.nSamplesPerSec/(50+50*Freq/100+Freq/100));

AudioData.ReadSample(i, 0, SampL);

AudioData.ReadSample(i, 1, SampR);

SampL := Trunc(0.6*SampL+0.4*MaxAmplitude*Sin(i*TL));

SampR := Trunc(0.6*SampR+0.4*MaxAmplitude*Sin(i*TR));

AudioData.WriteSample(i, 0, SampL);

AudioData.WriteSample(i, 1, SampR);

end;

end;

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

var

i, MaxAmplitude, MaxVolume: Cardinal;

Volume: Integer;

K: Real;

Channel: Word;

begin

MaxAmplitude := 1;

for i := 1 to AudioData.nBitsPerSample-1 do

MaxAmplitude := MaxAmplitude*2;

for Channel := 0 to AudioData.nChannels-1 do

begin

MaxVolume := 0;

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Volume);

if Abs(Volume) > MaxVolume then MaxVolume := Abs(Volume);

end;

K := MaxAmplitude/MaxVolume;

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Volume);

Volume := Round(Volume*K);

AudioData.WriteSample(i, Channel, Volume);

end;

end;

end;

procedure SetSpeedOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Speed: Real);

var

i, j, k, n, NewCount: Cardinal;

Channel: Byte;

Smp1, Smp2: Integer;

Interval: Real;

TempAudio: TAudioData;

Buf: Int64;

begin

if (Speed = 1) or (Speed = 0) then Exit;

TempAudio := TAudioData.Create;

TempAudio.nChannels := AudioData.nChannels;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := AudioData.nBitsPerSample;

TempAudio.nBlockAlign := AudioData.nBlockAlign;

NewCount := Round(Count/Speed);

if Speed > 1 then

begin

i := NewCount;

Interval := Speed;

AudioData.Data.Position := Start*AudioData.nBlockAlign;

while i<>0 do

begin

AudioData.Data.Read(Buf, AudioData.nBlockAlign);

TempAudio.Data.Write(Buf, AudioData.nBlockAlign);

AudioData.Data.Position := AudioData.Data.Position - AudioData.nBlockAlign + Trunc(Interval)*AudioData.nBlockAlign;

Interval := Interval-Trunc(Interval)+Speed;

Dec(i);

end;

end

else

begin

Speed := 1/Speed;

for Channel := 0 to AudioData.nChannels-1 do

begin

i := 0;

j := 0;

Interval := Speed;

while i<>Count do

begin

AudioData.ReadSample(Start+i, Channel, Smp1);

if i+1<>Count then

AudioData.ReadSample(Start+i+1, Channel, Smp2)

else

Smp2 := Smp1;

k := Trunc(Interval);

for n := 0 to k-1 do

TempAudio.WriteSample(j+n, Channel, Round(Smp1+(Smp2-Smp1)/k*n));

Interval := Interval-Trunc(Interval)+Speed;

Inc(i);

Inc(j, k);

end;

end;

end;

DeleteAudio(AudioData, Start, Start+Count-1);

InsertAudio(TempAudio, AudioData, Start);

TempAudio.Destroy;

end;

function ChangeSpeedOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Speed: Real): Cardinal;

var

i, j, k, n: Cardinal;

Channel: Byte;

Smp1, Smp2: Integer;

Interval, FinalSpeed: Real;

TempAudio: TAudioData;

Buf: Int64;

begin

if (Speed = 1) or (Speed = 0) then Exit;

TempAudio := TAudioData.Create;

TempAudio.nChannels := AudioData.nChannels;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := AudioData.nBitsPerSample;

TempAudio.nBlockAlign := AudioData.nBlockAlign;

FinalSpeed := Speed;

if Speed > 1 then

begin

Speed := 1;

Interval := Speed;

AudioData.Data.Position := Start*AudioData.nBlockAlign;

while AudioData.Data.Position div AudioData.nBlockAlign < Start+Count do

begin

AudioData.Data.Read(Buf, AudioData.nBlockAlign);

TempAudio.Data.Write(Buf, AudioData.nBlockAlign);

AudioData.Data.Position := AudioData.Data.Position - AudioData.nBlockAlign + Trunc(Interval)*AudioData.nBlockAlign;

Interval := Interval-Trunc(Interval)+Speed;

Speed := Speed+Trunc(Interval)*(FinalSpeed-1)/Count;

end;

end

else

begin

FinalSpeed := 1/FinalSpeed;

for Channel := 0 to AudioData.nChannels-1 do

begin

i := 0;

j := 0;

Speed := 1;

Interval := Speed;

while i<>Count do

begin

AudioData.ReadSample(Start+i, Channel, Smp1);

if i+1<>Count then

AudioData.ReadSample(Start+i+1, Channel, Smp2)

else

Smp2 := Smp1;

k := Trunc(Interval);

for n := 0 to k-1 do

TempAudio.WriteSample(j+n, Channel, Round(Smp1+(Smp2-Smp1)/k*n));

Interval := Interval-Trunc(Interval)+Speed;

Inc(i);

Inc(j, k);

Speed := Speed+(FinalSpeed-1)/Count;

end;

end;

end;

DeleteAudio(AudioData, Start, Start+Count-1);

InsertAudio(TempAudio, AudioData, Start);

ChangeSpeedOfAudio := TempAudio.Data.Size div TempAudio.nBlockAlign;

TempAudio.Destroy;

end;

procedure SetnSamplesPerSec(var AudioData: TAudioData; Value: Cardinal);

var

AudioSize: Cardinal;

begin

if AudioData.nSamplesPerSec = Value then Exit;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

if AudioSize <> 0 then SetSpeedOfAudio(AudioData, 0, AudioSize, AudioData.nSamplesPerSec/Value);

AudioData.nSamplesPerSec := Value;

end;

procedure SetnBitsPerSample(var AudioData: TAudioData; Value: Cardinal);

var

AudioSize, Max1, Max2, i: Cardinal;

Channel: Word;

Smp: Integer;

Mult: Real;

TempAudio: TAudioData;

begin

if AudioData.nBitsPerSample = Value then Exit;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

TempAudio := TAudioData.Create;

TempAudio.nChannels := AudioData.nChannels;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := Value;

TempAudio.Calculate_nBlockAlign;

Max1 := 1; for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do Max1 := Max1*256;

Max2 := 1; for i := 1 to TempAudio.nBlockAlign div TempAudio.nChannels do Max2 := Max2*256;

Mult := Max2/Max1;

if AudioSize<>0 then

begin

for Channel := 0 to AudioData.nChannels-1 do

for i := 0 to AudioSize-1 do

begin

AudioData.ReadSample(i, Channel, Smp);

Smp := Trunc(Smp*Mult);

TempAudio.WriteSample(i, Channel, Smp);

end;

AudioData.Data.Clear;

OverwriteAudio(TempAudio, AudioData, 0);

end;

TempAudio.Destroy;

AudioData.nBitsPerSample := Value;

AudioData.Calculate_nBlockAlign;

end;

procedure SetnChannels(var AudioData: TAudioData; Value: Cardinal);

var

AudioSize: Cardinal;

TempAudio: TAudioData;

i: Integer;

Channel: Cardinal;

Smp: Integer;

begin

if AudioData.nChannels = Value then Exit;

with AudioData do

AudioSize := Data.Size div nBlockAlign;

TempAudio := TAudioData.Create;

TempAudio.nChannels := Value;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := AudioData.nBitsPerSample;

TempAudio.Calculate_nBlockAlign;

for i := 0 to AudioSize-1 do

for Channel := 0 to Value-1 do

begin

if Channel < AudioData.nChannels then

AudioData.ReadSample(i, Channel, Smp)

else

AudioData.ReadSample(i, AudioData.nChannels-1, Smp);

TempAudio.WriteSample(i, Channel, Smp);

end;

AudioData.Data.Clear;

AudioData.nChannels := Value;

AudioData.Calculate_nBlockAlign;

OverWriteAudio(TempAudio, AudioData, 0);

TempAudio.Destroy;

end;

procedure SetVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

var

MaxValue: Cardinal;

Value: Integer;

i: Cardinal;

Channel: Word;

begin

MaxValue := 1;

for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do

MaxValue := MaxValue*256;

MaxValue := MaxValue div 2 - 1;

for Channel := 0 to AudioData.nChannels-1 do

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Value);

//Value := Trunc(Value*Exp(Volume/20));

Value := Trunc(Value*Volume);

if Abs(Value)>MaxValue then

if Value<0 then Value := -MaxValue

else Value := MaxValue;

AudioData.WriteSample(i, Channel, Value);

end;

end;

procedure Echo(var AudioData: TAudioData; Start, Count, Number, Delay: Cardinal; Volume: Real);

var

TempAudio: TAudioData;

i, j, DelaySmp: Cardinal;

SummSmp: Int64;

Mult: Real;

Smp: Integer;

Channel: Word;

MaxValue: Cardinal;

begin

for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do

MaxValue := MaxValue*256;

MaxValue := MaxValue div 2 - 1;

TempAudio := TAudioData.Create;

TempAudio.nChannels := AudioData.nChannels;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := AudioData.nBitsPerSample;

TempAudio.Calculate_nBlockAlign;

DelaySmp := Round(Delay*AudioData.nSamplesPerSec/1000);

for Channel := 0 to AudioData.nChannels-1 do

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Smp);

SummSmp := Smp;

Mult := Volume;

for j := 1 to Number do

begin

if i-Start < DelaySmp*j then

Smp := 0

else

AudioData.ReadSample(i-DelaySmp*j, Channel, Smp);

SummSmp := SummSmp + Round(Mult*Smp);

Mult := Mult*Volume;

end;

Smp := Round(SummSmp/(Number+1));

if Abs(Smp)>MaxValue then

if Smp<0 then Smp := -MaxValue

else Smp := MaxValue;

TempAudio.WriteSample(i-Start, Channel, Smp);

end;

OverwriteAudio(TempAudio, AudioData, Start);

TempAudio.Destroy;

Normalize(AudioData, Start, Count);

end;

procedure Reverberation(var AudioData: TAudioData; Start, Count, Number, Delay: Cardinal; Volume: Real);

var

TempAudio: TAudioData;

i, j, k, DelaySmp: Cardinal;

SummSmp: Int64;

SmpBuf: array[0..64] of Int64;

Mult: Real;

Smp: Integer;

Channel: Word;

MaxValue: Cardinal;

begin

for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do

MaxValue := MaxValue*256;

MaxValue := MaxValue div 2 - 1;

TempAudio := TAudioData.Create;

TempAudio.nChannels := AudioData.nChannels;

TempAudio.nSamplesPerSec := AudioData.nSamplesPerSec;

TempAudio.nBitsPerSample := AudioData.nBitsPerSample;

TempAudio.Calculate_nBlockAlign;

DelaySmp := Round(Delay*AudioData.nSamplesPerSec/1000);

for Channel := 0 to AudioData.nChannels-1 do

for i := Start to Start+Count-1 do

begin

for j := Number downto 0 do

begin

if i-Start < DelaySmp*j then

Smp := 0

else

AudioData.ReadSample(i-DelaySmp*j, Channel, Smp);

SmpBuf[j] := Smp;

end;

Mult := Volume;

for j := 1 to Number do

begin

for k := 1 to Number do

SmpBuf[k-1] := SmpBuf[k-1] + Round(SmpBuf[k]*Mult);

Mult := Mult*Volume;

end;

Smp := Round(SmpBuf[0]/(Number+1));

if Abs(Smp)>MaxValue then

if Smp<0 then Smp := -MaxValue

else Smp := MaxValue;

TempAudio.WriteSample(i-Start, Channel, Smp);

end;

OverwriteAudio(TempAudio, AudioData, Start);

TempAudio.Destroy;

Normalize(AudioData, Start, Count);

end;

procedure ChangeVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

var

MaxValue: Cardinal;

Value: Integer;

i: Cardinal;

FinalVolume: Real;

Channel: Word;

begin

MaxValue := 1;

for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do

MaxValue := MaxValue*256;

MaxValue := MaxValue div 2 - 1;

FinalVolume := Volume;

for Channel := 0 to AudioData.nChannels-1 do

begin

Volume := 1;

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Value);

//Value := Trunc(Value*Exp(Volume/20));

Value := Trunc(Value*Volume);

if Abs(Value)>MaxValue then

if Value<0 then Value := -MaxValue

else Value := MaxValue;

AudioData.WriteSample(i, Channel, Value);

Volume := Volume + (FinalVolume-1)/Count;

end;

end;

end;

procedure ReChangeVolumeOfAudio(var AudioData: TAudioData; Start, Count: Cardinal; Volume: Real);

var

MaxValue: Cardinal;

Value: Integer;

i: Cardinal;

FinalVolume: Real;

Channel: Word;

begin

MaxValue := 1;

for i := 1 to AudioData.nBlockAlign div AudioData.nChannels do

MaxValue := MaxValue*256;

MaxValue := MaxValue div 2 - 1;

FinalVolume := Volume;

for Channel := 0 to AudioData.nChannels-1 do

begin

Volume := 0;

for i := Start to Start+Count-1 do

begin

AudioData.ReadSample(i, Channel, Value);

//Value := Trunc(Value*Exp(Volume/20));

Value := Trunc(Value*Volume);

if Abs(Value)>MaxValue then

if Value<0 then Value := -MaxValue

else Value := MaxValue;

AudioData.WriteSample(i, Channel, Value);

Volume := Volume + FinalVolume/Count;

end;

end;

end;

end.

ПРИЛОЖЕНИЕ 2

РУКОВОДСТВО ПРОГРАММИСТА

П. 2.1. НАЗНАЧЕНИЕ ПРОГРАММЫ

Программа обработки и фильтрации звуковых сигналов имеет идентификатор AudioEditor и предназначена для обработки звуковых сигналов, записанных в файлах одного из следующих форматов: Microsoft RIFF/WAVE (*.wav), MP3 (*.mp3), Elecronic Music (*.em1). Программа AudioEditor выполняет следующие функции:

1) возможность открытия и анализа файлов форматов Microsoft Wave, MP3 и Electronic Music;

2) отображение структуры звукового сигнала, записанного в файле, в графическом виде с возможностью изменения масштаба;

3) обеспечение возможности основных операций редактирования: выделение части сигнала, ее удаление, копирование и вставку. Обеспечение возможности вставки звукового сигнала из другого файла;

4) возможность изменения основных параметров цифрового звука: частоты дискретизации, битрейта, числа каналов;

5) изменение темпа (скорости) звукового сигнала, уровня громкости, обращение звукового сигнала;

6) применение звуковых эффектов к сигналу (эха, реверберации, возрастания, затухания) с указанием необходимых для них параметров.

Программа AudioEditor входит в состав системы обработки аудиоинформации. Эта система позволяет получить преобразованный звуковой сигнал с заданными характеристиками звучания, а также осуществить сжатие измененного звукового файла для уменьшения занимаемого им размера без значительной потери качества его звучания.

П. 2.2. УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ

Программа AudioEditor предъявляет следующие требования к техническим средствам:

1) стандартный x86-совместимый ПК;

2) тактовая частота процессора не менее 900 МГц;

3) объем оперативной памяти не менее 128 Мб;

4) разрешение экрана монитора не менее 1024x768.

Программа AudioEditor предъявляет следующие требования к программным средствам:

1) операционная система семейства Windows (Windows 9x/ME/NT/2000/XP);

2) среда для разработки приложений Borland Delphi 7.

П. 2.3. ХАРАКТЕРИСТИКА ПРОГРАММЫ

Программа AudioEditor требует для своего функционирования наличия в проекте файлов, содержащих звуковые сигналы, записанные в файлах следующих форматов: Microsoft RIFF/WAVE (*.wav), MP3 (*.mp3), Elecronic Music (*.em1). В связи с этим перед запуском данного модуля рекомендуется сформировать соответствующие файлы со звуковыми сигналами.

В состав программы входят следующие файлы, необходимые для ее функционирования:

1) AudioEditor.exe - исполняемый файл, содержащий основной интерфейс программы;

2) borlndmm.dll - менеджер разделяемой памяти от Borland;

3) cc3260mt.dll - многопоточная библиотека от Borland;

4) stlpmt45.dll - библиотека стандартных шаблонов STL от Borland.

Программа является интерактивной, т.е. требующей взаимодействия с пользователем.

Вся настройка программы происходит в интерактивном режиме, то есть через специальные диалоги настройки в оболочке самого приложения.

П. 2.4. ОБРАЩЕНИЕ К ПРОГРАММЕ

Для вызова программы необходимо запустить на выполнение файл AudioEditor.exe.

Описание файлов программы:

AudioForm.pas - функции для обработки формы с основными параметрами звукового сигнала;

AudioFormat.pas - функции для изменения основных параметров звука (битрейт, частота дискретизации, число каналов), создания эффектов (реверберации, эха, возрастания, затухания), изменения структуры звукового сигнала, изменения темпа и громкости, обращения;

EffectsForm.pas - функции для обработки формы с параметрами звуковых эффектов;

EM1_Format.pas - функции для работы с файлами формата Electronic Music;

FileUtils.pas - функции для работы с файлами любых типов;

Help.pas - функции для отображения справочной информации по программе;

Main.pas - функции для обработки главного окна программы;

MP3_Format.pas - функции для работы с файлами формата MP3;

MP3Form.pas - функции для обработки формы с параметрами MP3;

PCM_Format.pas - функции для работы с файлами формата Microsoft RIFF/WAVE;

AudioDeformator.res - ресурсы программы;

AudioForm.dfm - файл с описанием формы для изменения основных параметров звукового сигнала (частота дискретизации, битрейт, число каналов);

EffectsForm.dfm - файл с описанием формы для задания параметров звуковых эффектов;

Help.dfm - файл с описанием формы для отображения справочной информации по программе;

Main.dfm - файл с описанием главной формы программы;

MP3Form.dfm - файл с описанием формы для задания параметров MP3.

П. 2.5. ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ

Входными данными являются звуковые сигналы, записанные в файлах одного из следующих форматов: Microsoft RIFF/WAVE (*.wav), MP3 (*.mp3), Elecronic Music (*.em1).

Выходными данными являются измененные звуковые сигналы, записанный в файлах, структура которых аналогична структуре входных.

П. 2.6. СООБЩЕНИЯ

В ходе работы программы на экране могут появиться сообщения, которые приведены в табл.П.2.1.

Таблица П.2.1

Сообщения, появляющиеся в ходе работы программы

Сообщение

Описание

Пожалуйста подождите…

Появляется в случае, когда программой производится выполнение длительной операции (например, открытие файла большого размера или его обработка). Необходимо дождаться исчезновения этого сообщения для дальнейшей работы с программой


Подобные документы

  • Разработка программного обеспечения на языке C. Определение сигнала на выходе цепи, формирование его передаточной характеристики. Расчет длительности переднего фронта входного и выходного сигнала. Выбор структуры, отладка и тестирование программы.

    курсовая работа [83,0 K], добавлен 26.09.2014

  • Понятие звукового микшерного пульта как устройства первичной обработки звуковых сигналов. Технические параметры и функциональные возможности пультов. Смешивание источников сигнала в групповых каналах, дополнительные отводы и использование аттенюаторов.

    реферат [3,2 M], добавлен 09.11.2010

  • Описание архитектуры процессора TMS320C25. Моделирование фильтра в модуле FDATool программной среды Matlab. Алгоритм нерекурсивной фильтрации сигнала. Расчет массива отсчетов входного сигнала. Моделирование фильтра при различных частотах входного сигнала.

    курсовая работа [119,2 K], добавлен 14.06.2015

  • Анализ процесса оцифровки зависимости интенсивности звукового сигнала от времени. Характеристика технологии создания музыкальных звуков в современных электромузыкальных цифровых синтезаторах. Изучение основных звуковых форматов, способов обработки звука.

    курсовая работа [2,3 M], добавлен 23.11.2011

  • Исследования амплитудных и временных параметров электрического сигнала. Классификация осциллографов по назначению и способу вывода измерительной информации, по способу обработки входного сигнала. Классы SignalObject, Ostsilograf, Setka, Signal и Form2.

    курсовая работа [841,8 K], добавлен 08.09.2014

  • Генерирование и сохранение мелодии в виде звукового файла формата wav. Проведение частотного анализа полученного сигнала. Зависимость объема wav-файлов от разрядности кодирования сигнала. Спектр нот записанного wav-файла с заданной разрядностью.

    лабораторная работа [191,0 K], добавлен 30.03.2015

  • Анализ существующих алгоритмов обработки информации человеком и современных моделей памяти. Разработка алгоритмов и математической модели ассоциативного мышления. Имитационная модель обработки информации. Компьютерный эксперимент по тестированию модели.

    курсовая работа [2,3 M], добавлен 19.11.2014

  • Приведение выходного сигнала к аналитическому вид. Программа расчёта характеристик выходного сигнала электрической цепи. Таблица идентификаторов и описаний пользовательских подпрограмм. Построение графиков по массивам входного и выходного сигналов.

    контрольная работа [594,2 K], добавлен 28.09.2012

  • Обработка детерминированного сигнала. Классификация измерительных сигналов. Формула исходного сигнала. Построение спектра амплитуд и спектра фаз. Точность спектрального анализа. Нормальный закон распределения. Спектральный анализ случайного сигнала.

    курсовая работа [616,8 K], добавлен 07.07.2013

  • Задачи цифровой обработки изображений. Методы пороговой сегментации. Создание программы представления рисунка в виде матрицы и применения к нему пороговой обработки. Разработка интерфейса программы загрузки и фильтрации изображения с выбранным порогом.

    курсовая работа [2,0 M], добавлен 12.11.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.