Помощь в написании студенческих работ
Антистрессовый сервис

Разработка синтезатора звука в среде визуального программирования Delphi. 
Программная реализация

КурсоваяПомощь в написанииУзнать стоимостьмоей работы

Основные сведения о генераторе звука Источниками звука могут стать любые явления, вызывающие местное изменение давления или механическое напряжение. Широко распространены источники звука в виде колеблющихся твёрдых тел (например, диффузоры громкоговорителей и мембраны телефонов, струны и деки музыкальных инструментов; в ультразвуковом диапазоне частот — пластинки и стержни из пьезоэлектрических… Читать ещё >

Разработка синтезатора звука в среде визуального программирования Delphi. Программная реализация (реферат, курсовая, диплом, контрольная)

Министерство образования Республики Беларусь Учреждение образования

«Гомельский государственный университет имени Франциска Скорины»

Факультет математический Кафедра вычислительной математики и программирования Разработка синтезатора звука в среде визуального программирования Delphi. Программная реализация Курсовой проект Исполнитель:

студент группы ПO-32

Дубовик Т. С.

Научный руководитель:

к.т.н., доцент кафедры Цурганова Л. А.

Гомель 2014

Введение

Звук — физическое явление, представляющее собой распространение в виде упругих волн механических колебаний в твёрдой, жидкой или газообразной среде. В узком смысле под звуком имеют в виду эти колебания, рассматриваемые по отношению к тому, как они воспринимаются органами чувств животных и человека.

Как и любая волна, звук характеризуется амплитудой и спектром частот. Обычно человек осознаёт колебания, передаваемые по воздуху, в диапазоне частот от 16—20 Гц до 15—20 кГц. Звук ниже диапазона слышимости человека называют инфразвуком; выше: до 1 ГГц, — ультразвуком, от 1 ГГц — гиперзвуком.

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

Среди слышимых звуков следует особо выделить фонетические, речевые звуки и фонемы (из которых состоит устная речь) и музыкальные звуки (из которых состоит музыка).

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

В своём проекте я подробно рассмотрю генерацию звуковых волн и создание собственного источника (генератора звука) с помощью средства разработки Delphi.

Целью данного курсового проекта является подробное ознакомление с принципами генерации звука и создание собственного генератора звука.

1. Основные сведения о генераторе звука Источниками звука могут стать любые явления, вызывающие местное изменение давления или механическое напряжение. Широко распространены источники звука в виде колеблющихся твёрдых тел (например, диффузоры громкоговорителей и мембраны телефонов, струны и деки музыкальных инструментов; в ультразвуковом диапазоне частот — пластинки и стержни из пьезоэлектрических материалов или магнитострикционных материалов). Источниками звука могут служить и колебания ограниченных объёмов самой среды (например, в органных трубах, духовых музыкальных инструментах, свистках и т. п.).

Чистый звуковой тон представляет собой звуковую волну, подчиняющуюся синусоидальному закону:

у =,

где — максимальная амплитуда синусоиды;

— частота (=);

— количество колебаний упругой среды в секунду ();

— период;

— время (параметрическая переменная).

Звук характеризуется частотой (f), обычно измеряемой в герцах, т. е. количеством колебаний в секунду, и амплитудой (у). Амплитуда звуковых колебаний определяет громкость звука.

Для монотонного звука (меандр.) характерно постоянство амплитуды во времени.

Затухающие звуковые колебания характеризуются уменьшением амплитуды с течением времени.

Человек воспринимает механические колебания частотой 20 Гц — 20 КГц (дети — до 30 КГц) как звуковые. Колебания с частотой менее 20 Гц называются инфразвуком, колебания с частотой более 20 КГц — ультразвуком. Для передачи разборчивой речи достаточен диапазон частот от 300 до 3000 Гц.

Если несколько чистых синусоидальных колебаний смешать, то вид колебания изменится — колебания станут несинусоидальными.

Особый случай, когда смешиваются не любые синусоидальные колебания, а строго определенные, частота которых отличается в два раза (гармоники).

Основная гармоника имеет частоту, и амплитуду а1; вторая гармоника — частоту f2 и амплитуду а2; третья гармоника соответственно f3 и a3.

Причем f1а2>а3,При бесконечном количестве таких гармоник образуется периодический сигнал, состоящий из прямоугольных импульсов.

На слух всякое отклонение от синусоиды приводит к изменению звучания. В IBM PC источником звуковых колебаний является динамик (PC Speaker), воспроизводящий частоты приблизительно от 2 до 8 КГц. Для генерации звука в PC Speaker используются прямоугольные импульсы.

Синусоидальные сигналы в ЭВМ можно получить только с помощью специальных устройств — аудиоплат.

1.1 Частотный синтез Многоголосый частотный синтезатор предназначен для генерации звуковых сигналов сложной формы. Существуют два принципиально различных способа синтеза звуковых сигналов:

частотный синтез (FM — Fregueney Modulation);

волновой синтез (WS — Ware Synthesys).

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

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

Впервые о применении частотной модуляции для синтеза звука задумался в 1966 году американец John Chowning, в будущем директор Центра компьютерных исследований музыки и акустики (CCRMA) Стенфордского университета, а на тот момент времени — преподаватель композиции кафедры электронной музыки.

В своём проекте я воспользовался методом генерации путём частотной модуляции, потому что он является достаточно эффективным и простым для реализации, к тому же спектр звуков, создаваемый с помощью частотной модуляции, действительно огромен.

2. Технология разработки генератора звука Я разработал программу генератор звука в среде Borland Delphi с использованием стандартных классов TMemoryStream (для хранения звука в виде бинарных данных) и TStrings (для хранения характеристик конкретной частоты). Также описал новый класс TFreqObj и использовал достаточно нестандартный класс TWaveFormatEx для хранения формата аудиоданных.

При запуске пользователь может настроить громкость и частоту звука, также он должен выбрать качество звука и время проигрывания в миллисекундах (0 — зациклить). После нажатия кнопки «Старт» пользователь услышит синусоидальный звук соответствующей громкости и частоты.

Сейчас я подробно опишу используемые классы, а в дальнейшем подробно разберу процедуру MakeComplexSound.

2.1 Класс TFreqObj

Я создал класс TFreqObj для удобства хранения и последующего использования характеристик частоты звука, таких, как:

— максимальная амплитуда синусоиды;

— частота (=);

— количество колебаний упругой среды в секунду ().

Также в нём описан простейший конструктор с параметрами и функция приведения всех параметров в одну форматированную строку.

2.2 Класс TWaveFormatEx

Для хранения информации об аудио-данных мы будем использовать класс TWaveFormatEx. Структура TWaveFormatEx определена следующим образом:

typedef struct

{

WORD wFormatTag;

WORD nChannels;

DWORD nSamplesPerSec;

DWORD nAvgBytesPerSec;

WORD nBlockAlign;

WORD wBitsPerSample;

WORD cbSize;

} WAVEFORMATEX;

Описание полей следующее:

wFormatTag указывает тип аудио-данных. Нас интересуют только несжатые аудио-данные (PCM), поэтому для нас нужно чтобы тут было значение 0×0001 (то есть 1).

nChannels определяет количество каналов.

nSamplesPerSec определяет норму отбора в секунду. Обычно используется значение 44 100 Гц.

nAvgBytesPerSec чаще всего определяет среднюю скорость передачи байтов в секунду.

nBlockAlign определяет выравнивание в байтах.

wBitsPerSample определяет количество бит для выборки. Обычно равно 8 либо 16.

cbSize определяет размер всей структуры WAVEFORMATEX. Что в итоге равняется 18 байтам.

3 Алгоритмы и программная реализация генератора звука Суть метода генерации состоит в следующем: в текстовом виде хранятся характеристики конкретной частоты (длина волны, частота и т. д.)в формате TFreqObj, затем создаётся экземпляр класса TWaveFormatEx (он предназначен для приведения звуковой информации в понятный аудиоплате вид), этот класс заполняется информацией о звуке и затем в него добавляется сгенерированная в зависимости от характеристик конкретной частоты информация (грубо говоря, звук в виде бинарных данных) и отсылается функцией PlaySound на аудиоплату.

3.1 Процедура MakeComplexSound

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

Заполнение формата TWaveFormatEx:

with WaveFormatEx do

begin

wFormatTag := WAVE_FORMAT_PCM;

nChannels := Mono;

nSamplesPerSec := SampleRate;

wBitsPerSample := $ 0008;

nBlockAlign := (nChannels * wBitsPerSample) div 8;

nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;

cbSize := 0;

end;

Заполнение объекта типа TMemoryStream для последующего его отправления в процедуру PlaySound:

MS[n] := TMemoryStream. Create;

with MS[n] do

begin

DataCount := (Duration * SampleRate) div 1000;

RiffCount := Length (WaveId) + Length (FmtId) + SizeOf (DWORD) +

SizeOf (TWaveFormatEx) + Length (DataId) + SizeOf (DWORD) + DataCount;

Write (RiffId[1], 4); // 'RIFF'

Write (RiffCount, SizeOf (DWORD)); // file data size

Write (WaveId[1], Length (WaveId)); // 'WAVE'

Write (FmtId[1], Length (FmtId)); // 'fmt '

TempInt := SizeOf (TWaveFormatEx);

Write (TempInt, SizeOf (DWORD)); // TWaveFormat data size

Write (WaveFormatEx, SizeOf (TWaveFormatEx)); // WaveFormatEx record

Write (DataId[1], Length (DataId)); // 'data'

Write (DataCount, SizeOf (DWORD)); // sound data size

minfreq:=TFreqObj (freqlist.objects[0]).ftemp;

maxval:=0;

freqerror:=false;

sampdiv2:=samplerate div 2;

for i := 0 to trunc (2/minfreq*samplerate) do

begin

soundvalue:=0;

for j:=0 to freqlist. count-1 do

if TFreqObj (freqlist.objects[j])<>nil then

with TFreqObj (freqlist.objects[j]) do

begin

if ftemp>sampdiv2 then freqerror:=true;

w := 2 * Pi * Ftemp;

ph:=p/pi;

SoundValue:=soundvalue+trunc (Volume*a/1000*sin (ph+i*w/SampleRate);

end;

If soundvalue>maxval

then maxval:=soundvalue;

end;

for i := 0 to DataCount — 1 do

begin

soundvalue:=127;

for j:=0 to freqlist. count-1 do

if TFreqObj (freqlist.objects[j])<>nil then

with TFreqObj (freqlist.objects[j]) do

begin

if ftemp< sampdiv2 then

begin

ptspercycle:=samplerate/Ftemp;

if j=0 then setlength (imagedata, min (datacount, trunc (5*ptspercycle)));

x:=frac (i/ptspercycle+p/360);

amp:=a/1000 ;

w := 2 * Pi * Ftemp;

ph:=p/pi;

SoundValue:=soundvalue+trunc (Volume*amp*sin (ph+i*w / SampleRate));

end;

end;

if maxval>127 then byteval:=soundvalue*127 div maxval

else byteval:=soundvalue;

Write (Byteval, SizeOf (Byte));

If i<=high (imagedata) then imagedata[i]: =byteval;

end;

end;

3.2 Запись звука в файл Получившийся звук можно записать в файл формата .WAV. Создавая поток для проигрывания нашей волны, мы уже задали в самом его начале формат данных, все характеристики нашей звуковой волны, то есть мы имеем заголовок и собственно звуковую волну в виде потока данных. Класс TMemoryStream, которым мы пользуемся для хранения потока в памяти, содержит метод SaveToFile. С помощью данного метода мы сохраняем наш поток в файл формата .WAV длиной в 1 секунду. Данный файл может быть воспроизведён в любом проигрывателе.

Ниже представлен код процедуры записи звука в файл:

procedure TForm1. Button1Click (Sender: TObject);

begin программа генератор звук

if Button1. Caption='Запись в файл' then

begin

PlayBtn.Click;

Button1.Caption:='Сохранить';

end

else if Button1. Caption='Сохранить' then

begin

PlaySound (nil, 0, SND_Purge);

playing:=false;

if SaveDialog2. Execute then

begin

ms[streaminuse]. SaveToFile (SaveDialog2.FileName);

Button1.Caption:='Запись в файл';

if assigned (ms[streaminuse]) then freeandnil (Ms[streaminuse]);

end;

end;

end;

Заключение

В ходе выполнения курсового проекта были изучены основы программирования для работы со звуком: изучены основные понятия, некоторые классы для работы со звуком, а также использование потоков в создаваемом приложении. В качестве примера полученных навыков было разработано приложение «Генератор звука».

Разработанное приложение состоит из следующих основных классов: TFreqObj, TMemoryStream, TWaveFormatEx; также был использован модуль MMSystem. Класс TFreqObj хранит в себе характеристики конкретной частоты, TMemoryStream используется для хранения аудиоданных в бинарном виде для последующего воспроизведения, а TWaveFormatEx — для хранения формата аудиоданных и таких его характеристик, как качество звуки и типа данных.

Результат работы может использоваться на любом ПК для создания и изучения синусоидального звука.

Список использованных источников

Википедия — свободная энциклопедия // URL: https://www.wikipedia.org

GameDev.ru — крупнейший ресурс в России о создании компьютерных игр // URL: https://www.gamedev.ru

Soundcoding.ru — программирование звука в среде Windows // URL: https://www.soundcoding.ru

Кинтцель, Т. Руководство программиста по работе со звуком / Т. Кинтцель. — М.: ДМК, 2000. — 432 с.

Приложение, А Скриншот работы программы

Приложение Б Исходный код

unit U_SoundGen2;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

MPlayer, mmsystem, StdCtrls, ComCtrls, Menus, CheckLst, ExtCtrls, shellAPI, Buttons;

type

TfreqObj=class (TObject)

ftemp, f, P, a, shape:INTEGER;

StringRep:String;

constructor Create (newf, newP, newA, newshape: integer);

procedure makestringrep;

end;

TVolumeLevel = 0.127 ;

TForm1 = class (TForm)

PageControl1: TPageControl;

IntroSheet: TTabSheet;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

SoundSheet: TTabSheet;

Label3: TLabel;

VolLbl: TLabel;

FreqLbl: TLabel;

Label1: TLabel;

Label6: TLabel;

PlayBtn: TButton;

StopBtn: TButton;

VolBar: TTrackBar;

ListBox1: TCheckListBox;

Freqbar: TTrackBar;

RateRgrp: TRadioGroup;

VolEdit: TEdit;

FreqEdit: TEdit;

Edit1: TEdit;

Unitsgrp: TRadioGroup;

Duration: TUpDown;

Label2: TLabel;

Label4: TLabel;

Label5: TLabel;

Button1: TButton;

SaveDialog2: TSaveDialog;

procedure PlayBtnClick (Sender: TObject);

procedure StopBtnClick (Sender: TObject);

procedure VolBarChange (Sender: TObject);

procedure FormCreate (Sender: TObject);

procedure FreqbarChange (Sender: TObject);

procedure RateRgrpClick (Sender: TObject);

procedure VolEditChange (Sender: TObject);

procedure FreqEditChange (Sender: TObject);

procedure FreqEditKeyPress (Sender: TObject; var Key: Char);

procedure Button1Click (Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

MS: array[0.1] of tmemorystream;

StreamInUse:integer;

datacount:integer;

soundname, soundfilename: string;

soundfilelist:TStringList;

modified:boolean;

playing:boolean;

checkclicked:boolean;

imagedata:array of byte;

procedure MakeComplexSound (n:integer; freqlist: TStrings;

Duration{mSec}: Integer; Volume: TVolumeLevel);

procedure MsPlaySound;

procedure savesound;

procedure LoadSound (name:string);

procedure checkplaying;

end;

var

Form1: TForm1;

SampleRate: Integer = 11 025; // 8000, 11 025, 22 050, or 44 100

implementation

{$R *.DFM}

uses math, U_SetFreq;

function makesoundname (name:string):string;

var n: integer;

s:string;

begin

s:=extractfilename (name);

n:=pos ('.', s);

if n>0 then delete (s, n, length (s)-n+1);

result:=s;

end;

var shapenames: array[0.3] of string=('Sine','Square','Sawtooth','Triangle');

defaultname:string='DEFAULT.SND';

Constructor TFreqObj. Create;

begin

inherited create;

f:=newf;

ftemp:=f;

p:=newp;

a:=newA;

shape:=newSHAPE;

makestringrep;

end;

procedure TFreqObj. makestringrep;

begin

stringrep:=format ('%5d (F:%4d, P:%4d, A:%4d %S)',[ftemp, f, p, a, SHAPENAMES[SHAPE]]);

end;

const

Mono: Word = $ 0001;

RiffId: string = 'RIFF';

WaveId: string = 'WAVE';

FmtId: string = 'fmt ';

DataId: string = 'data';

procedure TForm1. MakeComplexSound (N:integer {stream # to use};

freqlist:TStrings;

Duration{mSec}: Integer;

Volume: TVolumeLevel);

var

WaveFormatEx: TWaveFormatEx;

i, j, TempInt, RiffCount: integer;

SoundValue: integer;

Byteval:byte;

minfreq, maxval: integer;

w, ph, amp: double;

freqerror:boolean;

sampdiv2:integer;

msg:string;

ptspercycle, x: extended;

begin

with WaveFormatEx do

begin

wFormatTag := WAVE_FORMAT_PCM;

nChannels := Mono;

nSamplesPerSec := SampleRate;

wBitsPerSample := $ 0008;

nBlockAlign := (nChannels * wBitsPerSample) div 8;

nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;

cbSize := 0;

end;

MS[n] := TMemoryStream. Create;

with MS[n] do

begin

DataCount := (Duration * SampleRate) div 1000;

RiffCount := Length (WaveId) + Length (FmtId) + SizeOf (DWORD) +

SizeOf (TWaveFormatEx) + Length (DataId) + SizeOf (DWORD) + DataCount;

Write (RiffId[1], 4); // 'RIFF'

Write (RiffCount, SizeOf (DWORD)); // file data size

Write (WaveId[1], Length (WaveId)); // 'WAVE'

Write (FmtId[1], Length (FmtId)); // 'fmt '

TempInt := SizeOf (TWaveFormatEx);

Write (TempInt, SizeOf (DWORD)); // TWaveFormat data size

Write (WaveFormatEx, SizeOf (TWaveFormatEx)); // WaveFormatEx record

Write (DataId[1], Length (DataId)); // 'data'

Write (DataCount, SizeOf (DWORD)); // sound data size

minfreq:=TFreqObj (freqlist.objects[0]).ftemp;

maxval:=0;

freqerror:=false;

sampdiv2:=samplerate div 2;

for i := 0 to trunc (2/minfreq*samplerate) do

begin

soundvalue:=0;

for j:=0 to freqlist. count-1 do

if TFreqObj (freqlist.objects[j])<>nil then

with TFreqObj (freqlist.objects[j]) do

begin

if ftemp>sampdiv2 then freqerror:=true;

w := 2 * Pi * Ftemp;

ph:=p/pi;

SoundValue := soundvalue+ trunc (Volume * a/1000* sin (ph+i * w / SampleRate));

end;

If soundvalue>maxval

then maxval:=soundvalue;

end;

for i := 0 to DataCount — 1 do

begin

soundvalue:=127;

for j:=0 to freqlist. count-1 do

if TFreqObj (freqlist.objects[j])<>nil then

with TFreqObj (freqlist.objects[j]) do

begin

if ftemp< sampdiv2 then

begin

ptspercycle:=samplerate/Ftemp;

if j=0 then setlength (imagedata, min (datacount, trunc (5*ptspercycle)));

x:=frac (i/ptspercycle+p/360);

amp:=a/1000 ;

w := 2 * Pi * Ftemp;

ph:=p/pi;

SoundValue := soundvalue+ trunc (Volume * amp* sin (ph+i * w / SampleRate));

end;

end;

if maxval>127 then byteval:=soundvalue*127 div maxval

else byteval:=soundvalue;

Write (Byteval, SizeOf (Byte));

If i<=high (imagedata) then imagedata[i]: =byteval;

end;

end;

end;

procedure TForm1. msPlaySound;

var options: integer;

begin

options:=SND_MEMORY or SND_ASYNC;

if duration. position=0 then options:=options or SND_LOOP;

PlaySound (MS[streaminuse]. Memory, 0, options);

end;

procedure TForm1. PlayBtnClick (Sender: TObject);

var

nextstream:integer;

freqlist:TStringlist;

i:integer;

dur:integer;

begin

freqlist:=TStringlist.create;

with listbox1 do

if items. count>0 then

begin

for i:=0 to items. count-1 do if checked[i]

then freqlist. addobject (items[i], items. objects[i]);

nextstream:=(streaminuse+1) mod 2;

if freqlist. count>0 then

begin

dur:=duration.position;

if unitsgrp. itemindex=1 then dur:=dur*1000;

if dur=0 then dur:=5000;

MakeComplexSound (nextstream, freqlist, dur, Volbar. position);

stopbtnclick (sender);

playing:=true;

streaminuse:=nextstream;

MsPlaySound;

end

else stopbtnclick (sender);

freqlist.free;

end;

end;

procedure TForm1. StopBtnClick (Sender: TObject);

begin

PlaySound (nil, 0, SND_Purge);

if assigned (ms[streaminuse]) then freeandnil (Ms[streaminuse]);

playing:=false;

end;

procedure TForm1. FormCreate (Sender: TObject);

begin

streaminuse:=1;

pagecontrol1.activepage:=SoundSheet;

loadsound ('-Default.snd');

end;

procedure TForm1. CheckPlaying;

begin

if playing then playbtnclick (self)

else

begin

playbtnclick (self);

stopbtnclick (self);

end;

end;

Procedure TForm1. savesound;

var

ff:textfile;

i:integer;

begin

assignfile (ff, soundfilename);

rewrite (ff);

writeln (ff,'D',' ', duration. position,' ', unitsgrp. itemindex);

for i:=0 to listbox1.items.count-1 do

with listbox1, TFreqObj (items.objects[i]) do writeln (ff,

integer (checked[i]),' ', f,' ', p,' ', a,' ', shape,' ', stringrep);

closefile (ff);

modified:=false;

end;

Procedure TForm1. Loadsound (name:string);

var

ff:textfile;

t:TFreqobj;

chk:integer;

d:char;

dur, units: integer;

begin

soundfilename:=name;

assignfile (ff, soundfilename);

reset (ff);

read (ff, d);

if d='D' then

begin

readln (ff, dur, units);

duration.position:=dur;

unitsgrp.itemindex:=units;

end

else reset (ff);

soundname:=makesoundname (soundfilename);

listbox1.clear;

while not eof (ff) do

with listbox1 do

begin

t:=tfreqobj.create (0,0,0,0);

with t do readln (ff, chk, f, p, a, shape, stringrep);

t.ftemp:=t.f;

items.AddObject (t.stringrep, t);

checked[items.count-1]: =chk<>0

end;

closefile (ff);

modified:=false;

freqbar.position:=TFreqobj (listbox1.items.objects[0]).f;

volbar.position:=64;

volbarchange (self);

end;

procedure TForm1. FreqbarChange (Sender: TObject);

var

scale:extended;

i:integer;

begin

if freqbar. position>0 then

begin

with listbox1, items do

if count>=1 then

begin

scale:=freqbar.position/TFreqobj (objects[0]).f;

freqedit.text:=inttostr (freqbar.position);

for i:=0 to count-1 do

if objects[i]<>nil then

with TFreqObj (objects[i]) do

begin

ftemp:=round (f*scale);

makestringrep;

items[i]: =stringrep;

end;

end;

checkplaying;

end;

end;

var samprates: array[0.3] of integer=(8000,11 025,22050,44 100);

procedure TForm1. RateRgrpClick (Sender: TObject);

begin

samplerate:=samprates[rateRgrp.itemindex];

checkplaying;

end;

procedure TForm1. VolBarChange (Sender: TObject);

begin

volEdit.text:=inttostr (Volbar.position);

checkplaying;

end;

procedure TForm1. VolEditChange (Sender: TObject);

var n: integer;

begin

n:=volbar.position;

volbar.position:=strtointdef (VolEdit.text, n);

if n<>volbar.position then volbarchange (sender);

end;

procedure TForm1. FreqEditChange (Sender: TObject);

var n: integer;

begin

n:=freqbar.position;

freqbar.position:=strtointdef (freqedit.text, n);

if n<>freqbar.position then FreqBarchange (sender);

end;

procedure TForm1. FreqEditKeyPress (Sender: TObject; var Key: Char);

begin

if key=#13 then Freqeditchange (sender);

end;

procedure TForm1. Button1Click (Sender: TObject);

begin

if Button1. Caption='Запись в файл' then

begin

PlayBtn.Click;

Button1.Caption:='Сохранить';

end

else if Button1. Caption='Сохранить' then

begin

PlaySound (nil, 0, SND_Purge);

playing:=false;

if SaveDialog2. Execute then

begin

ms[streaminuse]. SaveToFile (SaveDialog2.FileName);

Button1.Caption:='Запись в файл';

if assigned (ms[streaminuse]) then freeandnil (Ms[streaminuse]);

end;

end;

end;

end.

Показать весь текст
Заполнить форму текущей работой