Министерство образования РФ
РОССИЙСКИЙ ГОСУДАРСТВЕННЫЙ СОЦИАЛЬНЫЙ УНИВЕРСИТЕТ ФИЛИАЛ В г. АНАПА
Факультет: Информационных технологий и рекламы
Кафедра: Информатики
Специальность: 230102 АСОИиУ
К У Р С О В А Я Р А Б О Т А
по дисциплине: Объектно-ориентированное программирование
на тему: Использование возможностей Delphi для разработки редактора звуковых файлов.
выполнил ___________________________________
(Ф.И.О. полностью, подпись)
принял __________________________
(должность, уч. степень Ф.И.О. , подпись)
Работа защищена с оценкой
Анапа 2006
СОДЕРЖАНИЕ
ВВЕДЕНИЕ---------------------------------------------------------------------------стр. 3
Изучение предметной области ------------------------------------------------стр. 4
Выбор средств разработки------------------------------------------------------стр. 6
Описание функций и модулей-------------------------------------------------стр. 7
Руководство пользователя------------------------------------------------------стр. 10
Требования к аппаратным и программным частям------------------------стр. 12
ЗАКЛЮЧЕНИЕ -------------------------------------------------------------------стр. 13
СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ------------------------------стр. 14
ЛИСТИНГ ПРОГРАММЫ------------------------------------------------------стр. 15
ВВЕДЕНИЕ
Мультимедиа — это интерактивные системы, обеспечивающие работу с неподвижными изображениями и движущимся видео, анимированной компьютерной графикой и высококачественным звуком.
Применение возможностей мультимедиа, производит революционные изменения в таких областях, как образование, культура, компьютерный тренинг, во многих сферах профессиональной деятельности, науки, искусства, кинематографа, в компьютерных играх и т.д. В данной работе речь пойдёт о записи, хранении, воспроизведении и редактировании цифрового звука (wave form audio), являющегося неотъемлемой частью любого направления мультимедиа технологий.
ЦИФРОВОЕ ПРЕДСТАВЛЕНИЕ ЗВУКА
Звук в природе представляет собой волновые колебания воздуха или другой среды, в которой он распространяется. При записи и хранении звука аналоговая аудиоаппаратура применяет представление звука через напряжение электрического сигнала. Такое же представление имеет и компьютерная аудио периферия (колонки, наушники, микрофон).
U
t
Оцифрованный звук может быть представлен самыми различными способами. В числе наиболее широко применяемого способа цифрового представления звука можно отметить формат PCM - pulse code modulation - импульсно-кодовая модуляция. В контексте нашей тематики под этим термином подразумевается такой способ кодирования данных, при котором каждая выборка (отсчет), произведенная аналого-цифровым преобразователем звуковой карты или другого аудио устройства, представляется в памяти в виде числа, пропорционального по своему значению мгновенной величине сигнала в момент выборки, как показано на рисунке. Скорость выборок или, другими словами, частота выполнения отсчетов (частота дискретизации), прямо связана с максимальной частотой поступающего аналогового сигнала. Если сигнал имеет гармоническую природу и ограничен в некотором диапазоне частот, то для его корректной оцифровки, согласно теореме отсчетов, достаточно иметь частоту дискретизации вдвое превосходящей частоту максимальной гармоники сигнала.
Таким образом, если необходимо без потери качества производить цифровую запись скажем, телефонного разговора, частота сигнала которого находится в диапазоне 300..3400 Гц, то вполне достаточно установить частоту дискретизации 8000 отсчетов/сек. Величина 8000 выбрана из соображений совместимости с различными звуковыми картами и драйверами, поскольку для некоторых из них это является наименьшим возможным значением частоты дискретизации сигнала. Если же необходимо записывать радиопередачи в диапазоне FM (88 - 108 MHz), то понадобится выбрать частоту дискретизации 12500*2=25000 отсчетов/сек, т.к. звуковой диапазон FM-станции 12.5 килогерц.
Запись с компакт-диска для сохранения качества нужно производить с частотой дискретизации 44100 выборок/секунду. Замечу, что это вовсе не гарантирует идеальное качество звучание записи. Звуковая карта вносит некоторые искажения в любом случае.
Кроме частоты дискретизации, цифровой звук имеет ещё один немаловажный параметр – глубина модуляции. Она определяет максимальное количество возможных значений уровня сигнала и, как следствие количество бит информации, необходимых для хранения одной выборки.
ВЫБОР СРЕДСТВ РАЗРАБОТКИ
В данной работе для реализации поставленной задачи использована визуальная среда программирования Borland Delphi 7 использующая язык Object Pascal. Надо отметить, что к моменту выхода продукта обстановка вокруг компании Borland складывалась не лучшим для нее образом. Поговаривали о возможной перепродаже компании, курс акций компании неудержимо катился вниз. Сейчас уже можно без всяких сомнений утверждать, что период трудностей позади. Неверно, конечно, было бы говорить, что только Delphi явился причиной восстановления компании; кроме Delphi, у Borland появились и другие замечательные продукты, так же, как и Delphi, основывающиеся на новых, появившихся недавно у компании Borland, технологиях. На пример новые BDE 2.0, BC++ 4.5, Paradox for Windows 5.0, dBase for Windows 5.0, BC++ 2.0 for OS/2. Тем не менее, именно Delphi стал тем продуктом, на примере которого стало ясно, что у Borland есть еще порох в пороховницах, и что один единственный продукт может настолько удачно сочетать несколько передовых технологий.
Delphi. Основные характеристики продукта.
Delphi - это комбинация нескольких важнейших технологий:
Высокопроизводительный компилятор в машинный код
Объектно-ориентированная модель компонент
Визуальное (а, следовательно, и скоростное) построение приложений из программных прототипов
ОПИСАНИЕ ФУНКЦИЙ И МОДУЛЕЙ
Модуль func.pas содержит процедуры обеспечивающие хранение списка последних открытых файлов
procedure RegisterFile(filename:string);
Добавление пути в список открытых файлов
procedure UpdLastFilesList;
обновление списка открытых файлов в главном меню программы
function CorPath(Path:String):string;
Сокращение пути к файлу для большей информативности
Вот пример хранения списка в файле:
[lastFiles]
N1=C:\Documents and Settings\main\Desktop\OOPKours\Moonlight.wav
ind=5
N2=C:\Documents and Settings\main\Desktop\OOPKours\Not with you.wav
N3=C:\Documents and Settings\main\Desktop\OOPKours\sin.wav
N4=C:\Documents and Settings\main\Desktop\OOPKours\Alizee.wav
N5=C:\Documents and Settings\main\Desktop\OOPKours\Aqua.wav
N6=C:\Documents and Settings\main\Desktop\OOPKours\ля.WAV
Модули vol.pas и selectDev.pas используются формами
Получение списка доступных аудиоустройств и их свойств:
procedure TForm2.FormShow(Sender: TObject);
var caps: TWaveOutCapsA;
i,DevCount:integer;
begin
ListBox1.Clear;
DevCount:=waveOutGetNumDevs;
for i:=0 to devcount-1 do
begin
waveOutGetDevCaps(i, @caps,SizeOf(TWAVEOUTCAPSA));
ListBox1.Items.Add(caps.szPname);
end;
waveOutGetDevCaps(WAVE_MAPPER, @caps,SizeOf(TWAVEOUTCAPSA));
ListBox1.Items.Add(caps.szPname);
end;
Модуль unit1.pas:
Procedure SaveWFile(FileName:String); Сохранение данных из объекта TMemoryStream в файл
Procedure OpenWFile(FileName:String); Загрузка данных из файла посредствам объекта TFileStream в память (TMemoryStream) c проверкой формата и получением данных о звуке (глубина, частота дискретизации, количество каналов), после чего инициализация устройства вывода, подготовка буферов и воспроизведение звука.
procedure waveoutProc(hwi: HWAVEOUT; uMsg, dwInstance,
dwParam1, dwParam2: DWORD); stdcall;
Стандартная callback-функция вызываемая драйвером аудио из вне при завершении проигрывания очередного буфера. При её вызове происходит считывание очередной порции данных и передача их драйверу.
procedure DrawOscio;
Прорисовка осциллограммы текущего аудио фрагмента на поверхности объека TPaintBox.
procedure BuildPeaks;
Подготовка данных для вывода примерной диаграммы всего файла.
procedure TForm1.TrackBar4Change(Sender: TObject);
Событие, вызываемое при перемещении ползунка на линии времени, выполняется изменение текущей позиции в аудио потоке и обновление осциолограммы.
РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
Основные органы управления приложением показаны на рисунке:
Графическое представление аудио данных
Информация о файле
Начать воспроизведение
Остановить воспроизведение
Установить маркеры начала и конца выделения
Выделенный фрагмент времени
Громкость и стереобаланс воспроизведения
Список последних недавно открытых файлов, хранится в конфигурационном файле программы
Копировать выделенный участок в буфер обмена
Совмещает операции копирования и удаления
Вставить звук из буфера обмена начиная с позиции первого маркера
Заменить выделенный участок тишиной
Плавное понижение громкости выделенного участка
Обратно затуханию
Изменить громкость выделенного участка
ТРЕБОВАНИЯ К ПРОГРАММНЫМ И АППАРАТНЫМ ЧАСТЯМ.
Разрабатываемое приложение обеспечивает стабильную работоспособность на следующем аппаратно-программном обеспечении:
IBM совместимый персональный компьютер в типовой конфигурации.
Стандартная мышь.
Не менее 2Mb свободного места на жестком диске.
Предустановленная операционная система MS Windows версии не ниже 95 или NT.
WAVE- совместимое аудиоустройство.
ЗАКЛЮЧЕНИЕ
В данной курсовой проделана работа по созданию приложения для редактирования и проигрывания цифрового звука в среде Delphi. Были изучены основные принципы работы с подсистемой аудио windows, от изучения формата wave файлов до полноценного приложения редактирующего и проигрывающего аудио файлы. Приложение имеет все необходимые средства для комфортного отображения аудио данных в графическом виде. Плюсами являются: Windows подобный интерфейс, двух канальный звук, простота в использовании, информация об аудио данных. Минусами можно назвать: не возможность записи аудио и поддержка только одного формата wave. Также проделана работа по оформлению интерфейса приложения, работа с графическим представлением данных.
СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ
1. Иллюстрированный самоучитель по Delphi 7 для начинающих (электронная версия учебника).
2. Delphi 7 на примерах. Авторы: Пестриков В. Маслобоев А. Москва 2005г.
3. Borland Delphi 7 (электронная версия учебника).
4. Delphi 7. Учебный курс. Автор: Бобровский С.И.
5. Справочная система Microsoft Programming reference, файл MMEDIA, раздел Waveform audio.
Delphi и Windows API – Анатолий Тенцер
Библия программиста в среде Delphi – Михаил Фленов
Программирование в Delphi 7 – П. Дарахвелидзе, Е. Маркова
9. Система управления архивом статей Delphi World версия 6.0 – Н. Акулов
ЛИСТИНГ ПРОГРАММНЫХ МОДУЛЕЙ
Главный модуль
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, mmsystem, inifiles, TeEngine, Series,
ExtCtrls, TeeProcs, Chart, ComCtrls, Buttons, ActnMan,
ActnColorMaps;
type
TWaveHeader = record
idRiff: array [0..3] of char;
RiffLen: longint;
idWave: array [0..3] of char;
idFmt: array [0..3] of char;
InfoLen: longint;
WaveType: smallint;
Ch: smallint;
Freq: longint;
BytesPerSec: longint;
align: smallint;
Bits: smallint;
idData: array[0..3] of char;
DataLen: longint;
end;
TForm1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
N11: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
N14: TMenuItem;
N15: TMenuItem;
N16: TMenuItem;
OpenDialog1: TOpenDialog;
N17: TMenuItem;
N21: TMenuItem;
N31: TMenuItem;
N41: TMenuItem;
N51: TMenuItem;
N61: TMenuItem;
Memo1: TMemo;
PaintBox1: TPaintBox;
TrackBar1: TTrackBar;
TrackBar3: TTrackBar;
GroupBox1: TGroupBox;
TrackBar4: TTrackBar;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
N18: TMenuItem;
N19: TMenuItem;
PaintBox2: TPaintBox;
SpeedButton4: TSpeedButton;
Label1: TLabel;
N20: TMenuItem;
N22: TMenuItem;
N23: TMenuItem;
Label2: TLabel;
SaveDialog1: TSaveDialog;
N5: TMenuItem;
XPColorMap1: TXPColorMap;
procedure Button1Click(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure N17Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar4Change(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure N19Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure N15Click(Sender: TObject);
procedure N20Click(Sender: TObject);
procedure N16Click(Sender: TObject);
procedure N10Click(Sender: TObject);
procedure N14Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure N13Click(Sender: TObject);
procedure TrackBar4KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure N3Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure N5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
LastFilesInd:byte;
ini:tinifile;
WFile,Wmemory,clipBuffer,moveBuffer:Tstream;
Hdr:TWaveHeader;
BlockSize, l, r:integer;
bytedeep:byte;
Pos:int64;
Scale: integer;
PeeksArr:Array of byte;
play,isManualCh:boolean;
wfx:tWAVEFORMATEX;
HWO:HWAVEOUT;
wh: array[0..1] of TWAVEHDR;
Buf: array[0..1] of PChar;
actbuf:byte;
markIn,MarkOut:int64;
path :string;
implementation
uses func, Math, SelectDev, Vol;
{$R *.dfm}
procedure BuildPeaks;
var s:Smallint;
p:int64;
i,j,d,count:integer;
begin
p:=Wmemory.Position ;
if bytedeep=2 then d:=512
else d:=2;
WMemory.Position:=44;
count:=(hdr.Freq div 10)*hdr.Ch*bytedeep;
count:=count+count mod 2;
for i:=0 to length(peeksarr)-1 do
begin
WMemory.Seek(count,soFromCurrent);
WMemory.Read(s,bytedeep);
PeeksArr[i]:=abs(s div d);
end;
Wmemory.Position:=p ;
end;
procedure DrawOscio;
var i,j:word;
s,so: smallint;
p:int64;
begin
form1.PaintBox1.Canvas.MoveTo(0,75);
form1.PaintBox1.Canvas.FillRect(Form1.PaintBox1.Canvas.ClipRect);
p:=WMemory.Position;
WMemory.Position:=pos;
if bytedeep=2 then s:=512
else s:=4;
for i:= 0 to 455 do
begin
WMemory.Read(so,bytedeep);
form1.PaintBox1.Canvas.LineTo(I,75-(so div s));
end;
WMemory.Position:=p;
end;
procedure waveoutProc(hwi: HWAVEOUT; uMsg, dwInstance,
dwParam1, dwParam2: DWORD); stdcall;
begin
if (umsg=wom_done) and play then
begin
pos:=WMemory.Position;
isManualCh:=true;
Form1.TrackBar4.Position:=trunc((pos/WMemory.Size)*10000);
isManualCh:=False;
if
WMemory.Size-Wmemory.Position
begin
play:=false;
exit;
end;
WMemory.ReadBuffer(buf[actbuf]^,BlockSize);
waveOutWrite(HWO,@wh[actbuf],sizeof(Twavehdr));
actbuf:=(actbuf + 1)mod 2;
end;
end;
Procedure OpenWFile(FileName:String);
var i:integer;
s:smallint;
d:Dword;
begin
if not FileExists(filename)then exit;
WFile:=TFileStream.Create(filename,fmOpenRead,fmShareDenyNone);
Wmemory:=TMemoryStream.Create;
moveBuffer:=TMemoryStream.Create;
Wmemory.CopyFrom(Wfile,WFile.Size);
Wfile.Free;
WMemory.Position:=0;
WMemory.Read(Hdr,sizeof(hdr));
form1.Memo1.Lines.clear;
form1.Memo1.Lines.Add('Каналов: '+inttostr(hdr.Ch));
form1.Memo1.Lines.Add('Частота: '+inttostr(hdr.Freq));
form1.Memo1.Lines.Add('Битрейт: '+inttostr(hdr.BytesPerSec));
form1.Memo1.Lines.Add('Глубина: '+inttostr(hdr.Bits));
form1.Memo1.Lines.Add('DataLen: '+inttostr(hdr.DataLen));
form1.Memo1.Lines.Add('InfoLen: '+inttostr(hdr.InfoLen));
form1.Memo1.Lines.Add('Align: '+inttostr(hdr.align));
form1.Memo1.Lines.Add('Длительность: '+inttostr((hdr.RiffLen div hdr.BytesPerSec) div 60)+' : '+inttostr((hdr.RiffLen div hdr.BytesPerSec) mod 60));
BlockSize:=hdr.BytesPerSec div 16;
SetLength(PeeksArr,(hdr.DataLen div hdr.BytesPerSec)*10);
bytedeep:= hdr.Bits div 8;
WMemory.Position:=44;
while not WMemory.Position>=hdr.RiffLen do
begin
WMemory.Read(s,bytedeep);
end;
WMemory.Position:=44;
wfx.nChannels:=hdr.Ch;
wfx.nSamplesPerSec:=hdr.Freq;
wfx.wBitsPerSample:=hdr.Bits;
wfx.wFormatTag:=WAVE_FORMAT_PCM;
wfx.nBlockAlign:=(hdr.Bits div 8)*hdr.Ch;
wfx.nAvgBytesPerSec:=hdr.Freq*wfx.nBlockAlign;
wfx.cbSize:=0;
if hdr.idData<>'data' then begin
ShowMessage('Неподдерживаемый формат файла!');
WMemory.Free;
exit;
end;
waveOutOpen(@HWO, WDeviceInd, @wfx,dword(@waveoutproc) ,0,CALLBACK_FUNCTION);
BuildPeaks;
for i:=0 to 1 do
begin
wh[i].dwLoops:=0;
getmem(buf[i],BlockSize);
WMemory.ReadBuffer(buf[i]^,BlockSize);
wh[i].lpData:=buf[i];
wh[i].dwBufferLength:=BlockSize;
wh[i].dwFlags:=0;
wh[i].dwFlags:=WHDR_INQUEUE;
waveOutPrepareHeader(HWO,@wh[i],sizeof(Twavehdr));
play:=true;
waveOutWrite(HWO,@wh[i],sizeof(Twavehdr));
end;
waveOutGetVolume(hwo,@d);
l:=d shr 16;
r:=d and $f0;
form1.TrackBar1.Position:= 255-(Max(l,r) div 255);
end;
Procedure SaveWFile(FileName:String);
begin
WFile:=TFileStream.Create(filename,fmCreate,fmShareExclusive);
Wmemory.Position:=0;
WFile.Position:=0;
WFile.CopyFrom(Wmemory,Wmemory.Size);
Wfile.Free;
WMemory.Position:=0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
RegisterFile(OpenDialog1.FileName);
OpenWFile(OpenDialog1.FileName);
UpdLastFilesList;
end;
end;
procedure TForm1.N6Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.N17Click(Sender: TObject);
begin
path:=ini.ReadString('lastFiles','N'+inttostr(TmenuItem(sender).Tag),'-');
OpenWFile(path);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
play:=false;
ini.Free;
waveOutClose(HWO);
clipBuffer.Free;
end;
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
Scale:=Scale+1;
end;
procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
Scale:=Scale-1;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
var l,r :byte;
begin
l:=255;
r:=255;
if TrackBar3.Position>32 then
l:=8*(64-TrackBar3.Position)
else
r:=8*(TrackBar3.Position)-1;
waveOutSetVolume(hwo,(((255-TrackBar1.Position)*r) shl 16) or (255-TrackBar1.Position)*l);
end;
procedure TForm1.TrackBar4Change(Sender: TObject);
var i,j,z:integer;
begin
pos:=(trunc((TrackBar4.Position/10000)*WMemory.Size));
pos:=pos+pos mod 2;
if not isManualCh then
WMemory.Position:=pos-44;
Label2.Caption:=inttostr((pos div hdr.BytesPerSec) div 60)+' : '+inttostr((pos div hdr.BytesPerSec) mod 60)+' : '+inttostr((pos div (hdr.BytesPerSec div 100)) mod 100){+' _ '+inttostr(pos)};
DrawOscio;
j:=trunc((length(PeeksArr)-500)*(TrackBar4.Position/10000));
PaintBox2.Canvas.FillRect(PaintBox2.Canvas.ClipRect);
PaintBox2.Canvas.Pen.Color:=clBlack;
for i:=0 to 500 do
begin
PaintBox2.Canvas.MoveTo(i,30-PeeksArr[j+i] div 2);
PaintBox2.Canvas.LineTo(i,30+PeeksArr[j+i] div 2);
end;
PaintBox2.Canvas.Pen.Color:=clred;
PaintBox2.Canvas.MoveTo(0,30);
PaintBox2.Canvas.LineTo(500,30);
z:=trunc((TrackBar4.Position/10000)*500);
PaintBox2.Canvas.Pen.Color:=clGreen;
PaintBox2.Canvas.MoveTo(z,00);
PaintBox2.Canvas.LineTo(z,70);
label2.Left:=z;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
actbuf:=0 ;
play:=true;
waveOutWrite(HWO,@wh[0],sizeof(Twavehdr));
waveOutWrite(HWO,@wh[1],sizeof(Twavehdr));
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
play:=false;
end;
procedure TForm1.FormShow(Sender: TObject);
var t:cardinal;
begin
ini:=tinifile.Create(ExtractFileDir(Application.ExeName)+'\cfg.ini');
UpdLastFilesList;
t:=ini.ReadInteger('Main','DeviceID',13043);
if t=13043 then
begin
form2.ShowMOdal;
ini.WriteString('Main','DeviceID',inttostr(WDeviceInd));
end
else
WDeviceInd:=t;
if paramcount<> 0 then
begin
path:=ParamStr(1);
OpenWFile(path);
end;
end;
procedure TForm1.N19Click(Sender: TObject);
begin
form2.ShowMOdal;
ini.WriteString('Main','DeviceID',inttostr(WDeviceInd));
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
TrackBar4.SelStart:=TrackBar4.Position;
markIn:=pos;
end;
procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
TrackBar4.SelEnd:=TrackBar4.Position;
MarkOut:=pos;
if markin>= markout then begin
TrackBar4.SelStart:=0;
markin:=0;
end ;
Label1.Caption:='C '+inttostr((markin div hdr.BytesPerSec) div 60)+' : '+inttostr((markIn div hdr.BytesPerSec) mod 60)+' по '+inttostr((MarkOut div hdr.BytesPerSec) div 60)+' : '+inttostr((MarkOut div hdr.BytesPerSec) mod 60);
end;
procedure TForm1.N15Click(Sender: TObject);
var i:integer;
z:byte;
begin
play:=false;
z:=0;
Wmemory.Position:=markIn;
for i:=markin to markout do
begin
Wmemory.Write(z,1);
end;
BuildPeaks;
Wmemory.Position:=markIn;
SpeedButton1.Click;
end;
procedure TForm1.N20Click(Sender: TObject);
var i:integer;
z:byte;
count:integer;
s:Smallint;
begin
if sender=N22 then
z:=0 else z:=1;
play:=False;
Wmemory.Position:=markIn;
count:=(MarkOut-markIn) div (hdr.Ch*bytedeep);
for i:=1 to count do
begin
WMemory.Read(s,bytedeep);
wmemory.Seek(-bytedeep,soFromCurrent);
s:=round(s*abs(z-(i/count)));
Wmemory.Write(s,bytedeep);
end;
BuildPeaks;
Wmemory.Position:=markIn;
SpeedButton1.Click;
end;
procedure TForm1.N16Click(Sender: TObject);
begin
play:=false;
Wmemory.Position:=MarkOut;
moveBuffer.CopyFrom(Wmemory,Wmemory.Size-MarkOut);
Wmemory.Position:=markIn;
moveBuffer.Position:= 0;
Wmemory.CopyFrom(moveBuffer,moveBuffer.Size);
Wmemory.Size:=Wmemory.Position;
moveBuffer.Size:=0;
hdr.RiffLen:=hdr.RiffLen-(MarkOut-markIn);
hdr.DataLen:=hdr.DataLen-(MarkOut-markIn);
SetLength(PeeksArr,(hdr.DataLen div hdr.BytesPerSec)*10);
Wmemory.Position:=0;
Wmemory.Write(hdr,sizeof(hdr));
BuildPeaks;
SpeedButton1.Click;
MarkOut:=markIn;
TrackBar4.SelStart:=trunc(markin/Wmemory.Size * 10000);
TrackBar4.SelEnd:=TrackBar4.SelStart;
end;
procedure TForm1.N10Click(Sender: TObject);
begin
Wmemory.Position:=markIn;
clipBuffer.Size:=0;
clipBuffer.CopyFrom(Wmemory,MarkOut-markIn);
clipBuffer.Position:=0;
Wmemory.Position:=markIn;
memo1.Lines.Add('Фрагмент длинной '+ inttostr((clipBuffer.Size div hdr.BytesPerSec) div 60)+' : '+inttostr((clipBuffer.Size div hdr.BytesPerSec) mod 60)+' добавлен в буфер')
end;
procedure TForm1.N14Click(Sender: TObject);
begin
if clipBuffer.Size=0 then exit;
Wmemory.Position:=markIn;
clipBuffer.Position:=0;
Wmemory.CopyFrom(clipBuffer,clipBuffer.Size);
BuildPeaks;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
clipBuffer:=TMemoryStream.Create;
end;
procedure TForm1.N13Click(Sender: TObject);
begin
play:=false;
N10.Click;
N16.Click;
end;
procedure TForm1.TrackBar4KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=vk_home then SpeedButton3.Click;
if Key=vk_end then SpeedButton4.Click;
Key:=0;
end;
procedure TForm1.N3Click(Sender: TObject);
begin
play:=false;
SaveWFile(path);
end;
procedure TForm1.N4Click(Sender: TObject);
begin
SaveDialog1.FileName:=path;
if SaveDialog1.Execute then SaveWFile(SaveDialog1.FileName);
end;
procedure TForm1.N5Click(Sender: TObject);
var i:integer;
count:integer;
s:Smallint;
begin
if form3.ShowModal <>mrOk then exit;
play:=False;
Wmemory.Position:=markIn;
count:=(MarkOut-markIn) div (bytedeep);
for i:=1 to count do
begin
WMemory.Read(s,bytedeep);
wmemory.Seek(-bytedeep,soFromCurrent);
s:=round(s*((4096-form3.Tag)/2048));
Wmemory.Write(s,bytedeep);
end;
BuildPeaks;
form1.Caption:=inttostr(form3.Tag);
Wmemory.Position:=markIn;
end;
end.
Модуль окна выбора устройства
unit SelectDev;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,mmsystem, Buttons;
type
TForm2 = class(TForm)
ListBox1: TListBox;
BitBtn1: TBitBtn;
procedure FormShow(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
WDeviceInd:cardinal;
implementation
{$R *.dfm}
procedure TForm2.FormShow(Sender: TObject);
var caps: TWaveOutCapsA;
i,DevCount:integer;
begin
ListBox1.Clear;
DevCount:=waveOutGetNumDevs;
for i:=0 to devcount-1 do
begin
waveOutGetDevCaps(i, @caps,SizeOf(TWAVEOUTCAPSA));
ListBox1.Items.Add(caps.szPname);
end;
waveOutGetDevCaps(WAVE_MAPPER, @caps,SizeOf(TWAVEOUTCAPSA));
ListBox1.Items.Add(caps.szPname);
end;
procedure TForm2.ListBox1Click(Sender: TObject);
var caps: TWaveOutCapsA;
begin
if ListBox1.ItemIndex=ListBox1.Items.Count-1 then
Wdeviceind:=WAVE_MAPPER
else
WDeviceInd:=ListBox1.ItemIndex;
end;
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
form2.ModalResult:=WDeviceInd;
form2.Close;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
WDeviceInd:=WAVE_MAPPER;
end;
end.
Модуль окна выбора громкости
unit Vol;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons;
type
TForm3 = class(TForm)
TrackBar1: TTrackBar;
Label1: TLabel;
BitBtn1: TBitBtn;
procedure TrackBar1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.TrackBar1Change(Sender: TObject);
begin
label1.Caption:=inttostr(trunc((2048-TrackBar1.position)/ 2048 *100))+'%';
form3.Tag:=TrackBar1.Position;
end;
end.
Модуль с дополнительными функциями интерфейса
unit func;
interface
procedure RegisterFile(filename:string);
procedure UpdLastFilesList;
function CorPath(Path:String):string;
implementation
uses sysutils, registry, unit1, forms;
function CorPath(Path:String):string;
begin
if path='0' then result:='0' else
result:=copy(path,0,6)+'.. ..\'+ExtractFileName(path);
end;
procedure RegisterFile(filename:string);
var i: byte;
begin
i:=ini.ReadInteger('lastFiles','ind',0);
ini.WriteString('lastFiles','N'+inttostr(i+1),filename);
ini.WriteInteger('lastFiles','ind',(i+1) mod 6);
end;
procedure UpdLastFilesList;
begin
with form1 do begin
N12.Visible:=true;
N17.Visible:=true;
N21.Visible:=true;
N31.Visible:=true;
N41.Visible:=true;
N51.Visible:=true;
N61.Visible:=true;
LastFilesInd:=ini.ReadInteger('lastFiles','ind',0);
N17.Caption:= CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-1) mod 6),'0'));
N17.Tag:=1+(6+LastFilesInd-1) mod 6;
if N17.Caption='0' then N17.Visible:=false;
N21.Caption:= CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-2) mod 6),'0'));
N21.Tag:=1+(6+LastFilesInd-2) mod 6;
if N21.Caption='0' then N21.Visible:=false;
N31.Caption:= CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-3) mod 6),'0'));
N31.Tag:=1+(6+LastFilesInd-3) mod 6;
if N31.Caption='0' then N31.Visible:=false;
N41.Caption:= CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-4) mod 6),'0'));
N41.Tag:=1+(6+LastFilesInd-4) mod 6;
if N41.Caption='0' then N41.Visible:=false;
N51.Caption:=CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-5) mod 6),'0'));
N51.Tag:=1+(6+LastFilesInd-5) mod 6;
if N51.Caption='0' then N51.Visible:=false;
N61.Caption:=CorPath(ini.ReadString('lastFiles','N'+inttostr(1+(6+LastFilesInd-6) mod 6),'0'));
N61.Tag:=1+(6+LastFilesInd-6) mod 6;
if N61.Caption='0' then N61.Visible:=false;
if N17.Visible or N21.Visible or N31.Visible or N41.Visible or N51.Visible or N61.Visible then
N12.Visible:=false;
end;
end;
end.