Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.12.2011, 00:09   #1
sergobrit
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 18
По умолчанию Генерация тонового сигнала с переменной частотой

Здравствуйте. Пытаюсь сгенерировать сигнал с частотой, которая меняется с заданным шагом во время воспроизведения. Идея сначала "накопить" значения частот как вектор/массив, а потом вставить в формулу sin, которая описывает сигнал. Только у меня выходит тон с одной частотой, и никуда она не меняется в итоге.
Код прилагаю. За любую помощь заранее спасибо.
Вложения
Тип файла: rar звук с переменной частотой.rar (236.0 Кб, 18 просмотров)
sergobrit вне форума Ответить с цитированием
Старый 12.12.2011, 01:31   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Параметр cbSize отвечает за размер структуры данных:
Код:
  //задание параметров wav файла
  with WaveFormatEx do
  begin
    wFormatTag := WAVE_FORMAT_PCM; //формат
    nChannels := Mono; //количество каналов
    nSamplesPerSec := SampleRate; //частота дискретизации??
    wBitsPerSample := $0008; //??
    nBlockAlign := (nChannels * wBitsPerSample) div 8; //??
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; //??
    cbSize := SizeOf(TWaveFormatEx); //??
  end;
не говоря уже об:
Код:
Access violation at address 004D3BEB in module 'Alfa.exe'. Write of address 00000000.
Вот здесь:
Код:
       //создание вектора частот
    for i := 0 to DataCount - 1 do
    begin
      Frequency[i]:= ((StrToFloat(Form1.edt1.Text) + (i - 1) *
        StrToFloat(form1.edt2.text)) *
        StrToFloat(form1.edt3.Text)) / StrToFloat(form1.edt3.Text);
    end;
массив Frequency - динамический массив, и он, ниразу не инициализирован и его размер не задан. А т.к. его размер должен быть равен размеру DataCount, то следовательно ему нужно установить число ячеек равное числу DataCount. Это делается при помощью SetLength(Array,size).


Вот исправленный код, что исправил - выделил жирным:
Код:
procedure MakeSound(Duration {mSec}: Integer; Volume: TVolumeLevel);

//пишет в память и читает оттуда

var
  WaveFormatEx: TWaveFormatEx;
  MS: TMemoryStream;
  i, TempInt, DataCount, RiffCount: integer;
  SoundValue: byte;
  Frequency: array of Double;

  //задание блоков структуры wav файла
const
  Mono: Word = $0001;
  SampleRate: Integer = 11025; // 8000, 11025, 22050, or 44100
  RiffId: string = 'RIFF';
  WaveId: string = 'WAVE';
  FmtId: string = 'fmt ';
  DataId: string = 'data';

begin
  // проверка частоты
  //if Frequency[i] > (0.6 * SampleRate) then
  //begin
  //   ShowMessage(Format('Sample rate of %d is too Low to play a tone of %dHz',
  //     [SampleRate, Frequency]));
  //   Exit;
  //end;

  //задание параметров wav файла
  with WaveFormatEx do
  begin
    wFormatTag := WAVE_FORMAT_PCM; //формат
    nChannels := Mono; //количество каналов
    nSamplesPerSec := SampleRate; //частота дискретизации??
    wBitsPerSample := $0008; //??
    nBlockAlign := (nChannels * wBitsPerSample) div 8; //??
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; //??
    cbSize := SizeOf(TWaveFormatEx); //size of record
  end;

  //собственно формирования звука
  MS := TMemoryStream.Create;
  try
    with MS do
    begin
      {Calculate length of sound data and of file data}
      DataCount := (Duration * SampleRate) div 1000; // sound data
      SetLength(Frequency, DataCount); //DataCount <=> length of frequency Dynamic array
      RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
        SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount;
      // file data
  {write out the wave header}
      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

      {calculate and write out the tone signal}// now the data values

         //создание вектора частот
      for i := 0 to DataCount - 1 do
      begin
        Frequency[i] := ((StrToFloat(Form1.edt1.Text) + (i - 1) *
          StrToFloat(form1.edt2.text)) *
          StrToFloat(form1.edt3.Text)) / StrToFloat(form1.edt3.Text);
      end;

      //создание сигнала
      for i := 0 to DataCount - 1 do
      begin
        SoundValue := 127 + trunc(Volume * sin(i * Frequency[i] / SampleRate));
        // wt = w * i / SampleRate
        Write(SoundValue, SizeOf(Byte));
      end;
      {now play the sound}
      sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
    {
     Не выйдя из With MS do
                      begin
                      Вы не можете освободить обьект который используете. 
                      А вы пыталить здесь вызвать MS.Free. Так делать нельзя. 
                      end;
    }
    end;
  finally
    FreeAndNil(MS); 
  end;
end;
переделанный архив с рабочим exe в прилепе.
Вложения
Тип файла: zip звук с переменной частотой.zip (152.3 Кб, 37 просмотров)

Последний раз редактировалось Человек_Борща; 12.12.2011 в 01:49.
Человек_Борща вне форума Ответить с цитированием
Старый 12.12.2011, 08:57   #3
sergobrit
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 18
По умолчанию

Спасибо огромное, туплю на каждом шагу--недавно программирую.Не совсем я тут ступенчато частоту изменяю, но это надо в формуле ковыряться.
sergobrit вне форума Ответить с цитированием
Старый 16.12.2011, 12:23   #4
sergobrit
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 18
По умолчанию

И снова я. Если тема не закрыта, сейчас встал на том, что тон у меня не изменяет линейно частоту с течением времени, а создает последовательность практически эдентичных импульсов (графически звук отобразил). Я так полагаю,что я неправильно накапливаю сам вектор частот, который потом и передаю в функцию сигнала. За любую помощь заранее спасибо.
Вложения
Тип файла: rar звук с переменной частотой.rar (233.9 Кб, 27 просмотров)
sergobrit вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как воспроизвести в win32 api на с или с++ тон с заданной частотой? добрый_фей Помощь студентам 1 15.01.2011 00:42
Программа для воспроизведения тонового звука через промежуток времени Vl-sn Помощь студентам 9 12.03.2010 20:27
Передача с определенной частотой megakatapuz Общие вопросы C/C++ 1 03.01.2010 01:47
Работа с файлами (создание, удаление, открытие, связываение с переменной, очищение памяти переменной) Arkuz Общие вопросы Delphi 12 25.09.2007 20:47
Как засинхронизировать таймер с частотой кадровой развертки монитора Saili Общие вопросы Delphi 2 07.12.2006 16:35