18109

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

Курсовая

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

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

Русский

2014-11-23

138 KB

13 чел.

Разработка синтезатора звука в среде визуального программирования 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.


 

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

55712. Інтерактивні методи навчання як засіб формування інтересу до пізнання молодших школярів 284.5 KB
  Тому важливого значення на сучасному етапі набуває активізація пізнавальної діяльності учнів як необхідна умова шкільного навчання. Активізація пізнавальної діяльності учнів – необхідна умова шкільного навчання. Він – основа розвитку нахилів учнів а отже і їх професійного спрямування. Я помітила що стійкий пізнавальний інтерес пізнавальна активність учнів початкових класів виявляється в навчальній діяльності.
55713. Зведені таблиці Microsoft Excel (MICROSOFT OFFICE 2010) 610.5 KB
  Мета: Отримання учнями практичних навичок представлення інформації із традиційних списків у більш зручному вигляді.
55714. Використання на уроках географії літературних творів та фотографі 306 KB
  Допомогти розвитку пізнавальної діяльності, активності учнів можуть нестандартні прийоми на уроках. Педагог за допомогою мистецьких творів може акцентувати увагу на подіях, явищах природи, керувати сприйняттям і відтворенням образів.
55715. Розв’язування рівнянь та побудова графіків, що містять цілу та дробову частини числа 712 KB
  Розв’язування рівнянь що містять цілу і дробову частини. У роботі проаналізовано окремі способи розв’язування рівнянь зі змінною під знаком цілої та дробової частин зокрема графічний та аналітичні.
55716. Исследования графов и их изучение 126 KB
  Точки графа называются его вершинами а отрезки соединяющие их ребрами графа. Более того графы являются эквивалентными либо попросту одним и тем же графом если соответствующие вершины одного графа соединены так же как и соответствующие вершины другого то есть соединены...
55717. ВПРОВАДЖЕННЯ ІКТ ТА ІНТЕРАКТИВНИХ МЕТОДІВ ТА ФОРМ НАВЧАННЯ ЯК ЗАСІБ ФОРМУВАННЯ ПРЕДМЕТНИХ МАТЕМАТИЧНИХ ТА ІНФОРМАЦІЙНО-КОМУНІКАТИВНОЇ КОМПЕТЕНЦІЙ В УЧНІВ ПОЧАТКОВИХ КЛАСІВ 268 KB
  Активне навчання потребує залучення учнів у навчальний процес. У розв’язанні цих проблем важливе місце відводиться інформаційно комунікативним технологіям інтерактивним методам та формам навчання комп’ютерному програмному забезпеченню освітнього процесу.
55718. Використання засобів ІКТ у процесі вивчення біології та хімії 74.5 KB
  Біологія та хімія є одними з тих навчальних предметів що дають багатий матеріал для відпрацювання найрізноманітніших методів і прийомів роботи з інформацією.
55719. Інтеграція початкового і дошкільного навчання, як діалог двох освітніх структур в межах округу 51 KB
  І досі на цьому перехідному місточку виникає багато питань: це продовження соціалізації дитини забезпечення психологічного комфорту врахування особливостей здоров’я та розвитку дітей вивчення статусу сім’ї. Перевантаження в школах пов’язанні зі складністю навчальних програм надлишкові домашні завдання ведуть до погіршення стану здоров’я учнів. І це є проблема над якою працюють вчителі всіх освітніх округів міста бо як казав один мудрець: Здоров’я – це ще не все але без здоров’я все інше – ніщо. Тому вчителі всіма...
55720. Взаимодействие участников коррекционного пространства в условиях спецшколы-интерната для детей с тяжелыми нарушениями речи 43.5 KB
  В законодательных документах усиленное внимание общества обращено к проблеме детей с особенностями психического и речевого развития и создания благоприятных условий для их социальной адаптации и реабилитации.