Система обработки аудиоинформации. Подсистема фильтрации и обработки сигнала
Разработка программного обеспечения, предназначенного для изменения характеристик исходного звукового сигнала с целью изменения характеристик его звучания. Алгоритмы обработки и фильтрации звукового сигнала, редактирование его, изменение темпа и уровня.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 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