18109

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

Курсовая

Информатика, кибернетика и программирование

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

Русский

2014-11-23

138 KB

20 чел.

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

Курсовой проект


Содержание

Введение…………………………………………………………………...

1 Основные сведения о генераторе звука………………………………..

 1.1 Частотный синтез…………………………………………………….

2 Технология разработки генератора звука……………………………...

 2.1 Класс TFreqObj……………………………………………………….

 2.2 Класс TWaveFormatEx……………………………………………….

3 Алгоритмы и программная реализация генератора звука……………

 3.1 Процедура MakeComplexSound…………………………………..

 3.2 Запись звука в файл………………………………………………….

Заключение………………………………………………………………...

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

Приложение А……………………………………………………………..

Приложение Б…………………………………………………………….

3

4

5

6

6

6

8

8

10

11

12

13

14


Введение

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

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

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

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

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

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

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


1 Основные сведения о генераторе звука

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

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

у =,

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

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

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

- период;

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

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

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

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

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

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

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

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

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

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

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

1.1 Частотный синтез

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

  1.  частотный синтез (FM - Fregueney Modulation);
  2.  волновой синтез (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), поэтому для нас нужно чтобы тут было значение 0x0001 (то есть 1).
  •  nChannels определяет количество каналов.
  •  nSamplesPerSec определяет норму отбора в секунду. Обычно используется значение 44100 Гц.
  •  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 - для хранения формата аудиоданных и таких его характеристик, как качество звуки и типа данных.

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


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

  1.  Википедия - свободная энциклопедия // URL: https://www.wikipedia.org
  2.  GameDev.ru - крупнейший ресурс в России о создании компьютерных игр // URL:  https://www.gamedev.ru
  3.  Soundcoding.ru - программирование звука в среде Windows // URL: https://www.soundcoding.ru
  4.  Кинтцель, Т. Руководство программиста по работе со звуком / Т. Кинтцель. - М.: ДМК, 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 = 11025; // 8000, 11025, 22050, or 44100

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,11025,22050,44100);

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.


 

А также другие работы, которые могут Вас заинтересовать

9221. Патофизиология эритропоэза 27.36 KB
  Патофизиология эритропоэза ОЦК: у женщин - 6,5-7% от массы тела у мужчин 7-7,5% Гематокрит: 0,36-0,46 - соотношение между клеточной и жидкой частью крови Объем циркулирующей крови: в пределах нормы - нормоволемия, при уменьшении...
9222. Анемии Анемии вследствие нарушения кровообразования 27.46 KB
  Анемии Анемии вследствие нарушения кровообразования Железодефицитные анемии. Причины дефицита железа: менструальные потери, лактации, беременность, растущий ребенок, подросток, поражение желчно-кишечного тракта. Проявления сидеропении Синдром сидеро...
9223. Опухолевый рост типический патологический процесс 27.25 KB
  Опухолевый рост Опухоль (новообразование) - типический патологический процесс. Возникает под действием канцерогена. Проявляется патологическим разрастанием структурных элементов ткани, не связанным с общим обменом веществ. Характеризуется атипизмом ...
9224. Стадии канцерогенеза (патогенез опухолей) 24.15 KB
  Стадии канцерогенеза (патогенез опухолей) Инициация (мутация) - превращение здоровой клетки в опухоль Промоция Опухолевая прогрессия (если опухоль злокачественная) Гемобластозы Правила опухолевой прогрессии Фулдаса-Воробьев...
9225. Воспаление - типический патологический процесс. 28.01 KB
  Воспаление Воспаление - типический патологический процесс. Возникает в ответ на действие патогенных (флогогенных) факторов Проявляется в идее комплекса местных и общих реакций, сформировавшихся в ходе эволюции в качестве защитных ме...
9226. Местные (кардиальные) признаки воспаления 28.84 KB
  Местные (кардиальные) признаки воспаления Жар (calor) - связан с притоком теплой артериальной крови в очаг воспаления, изменение обмена веществ в самом очаге воспаления, в связи с повреждением мембраны разобщается окислительно фосфорилировани и...
9227. Лихорадка (Febris) 30.48 KB
  Лихорадка (Febris) Термин лихорадка один из самых древних, раньше обозначал любое повышение температуры тела. Современные представления стали возможны благодаря нескольким учениям: Учение Мечникова о воспалениях - изучал в эволюционном пл...
9228. Иммунопатология Иммунодефицитные состояния 28.42 KB
  Иммунопатология Иммунодефицитные состояния Иммунитет - комплекс клеточных и гуморальных механизмов, способных противостоять нарушениям генного аппарата организма, т.е. система, обеспечивающая индивидуальность и целостность организма. Действие и...
9229. Аллергия (гиперчувствительность) - типовые иммунопатологические процессы 29.7 KB
  Аллергия Аллергия (гиперчувствительность) - типовые иммунопатологические процессы, развивающиеся в сенсибилизированном организме генетически предрасположенных индивидов, в режиме вторичного иммунного ответа при контакте с антигеном, вызвавшем с...