18109

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

Курсовая

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

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

Русский

2014-11-23

138 KB

15 чел.

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


 

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

39332. Анализ линейной стационарной цепи 235.5 KB
  Доросинский АНАЛИЗ ЛИНЕЙНОЙ СТАЦИОНАРНОЙ ЦЕПИ: Методические указания к курсовой работе по дисциплине €œОсновы теории радиотехнических сигналов и цепей€ Т. АНАЛИЗ ЛИНЕЙНОЙ СТАЦИОНАРНОЙ ЦЕПИ Составитель Лысенко Тамара Михайловна Редактор Н. При этом особое внимание уделяется сущности процессов в цепи и фундаментальным понятиям важным для изучения любых линейных систем.
39333. АНАЛИЗ ЛИНЕЙНОЙ СТАЦИОНАРНОЙ ЦЕПИ 1.85 MB
  Найти операторный коэффициент передачи цепи по напряжению и записать его в виде отношения двух полиномов Составить таблицу значений коэффициентов полиномов для двух значений
39334. Основы теории цепей 271.88 KB
  Найти операторный коэффициент передачи цепи по напряжению и записать его в виде отношения двух полиномовСоставить таблицу значений коэффициентов полиномов для двух значений 1 и 2. Записать комплексную частотную характеристику цепи K j и соответствующие ей амплитудночастотную K и фазочастотную характеристики. По найденным аналитическим выражениям рассчитать и построить графики частотных характеристик цепи для двух значений коэффициента усиления 1 и 2 . Определить переходную ht и импульсную gt характеристики цепи.
39335. Устройство сбора данных 12.87 MB
  Москва 2006 Введение Информационноизмерительные и управляющие цифровые микропроцессорные системы к которым относится проектируемое устройство сбора данных УСД предназначены для измерения сбора обработки хранения и отображения информации с реальных объектов. Такие системы используются практически во всех отраслях народного хозяйства для контроля и управления...