Статьи Королевства Дельфи


Еще раз о звуке - часть 2


Если Вы знаете, что устройство в системе одно, можно поступить так:

procedure TForm1.btnClick(Sender: TObject); var WOutCaps : TWAVEOUTCAPS; begin // проверка наличия устройства вывода FillChar(WOutCaps,SizeOf(TWAVEOUTCAPS),#0); if MMSYSERR_NOERROR <> WaveOutGetDevCaps(0,@WOutCaps,SizeOf(TWAVEOUTCAPS)) then begin ShowMessage('Ошибка аудиоустройства'); exit; end; end;

Так мы пытаемся узнать характеристики устройства с номером 0 (т.е. первого в системе) и если его нет, говорим об ошибке. Если у нас несколько звуковых карточек, используем waveOutGetNumDevs. Характеристики нам понадобятся позже.

Важно: если хотим узнать, есть ли устройство записи, миксер в системе, используем WaveIn***, mixer*** и т.д. Ведь этих устройств может и не быть (USB-колонки). Так что вопрос: "Есть ли звуковая карточка в компьютере?" не совсем корректен для наших целей, да и не нужен. Вам звук выводить или карточкой хвалиться?

Как использовать Multimedia API для записи/вывода звука.

Для вывода звука мы используем следующий набор функций и структур API:

  • waveOutGetDevCaps -- получить свойства аудиоустройства
  • waveOutOpen -- открыть аудиоустройство
  • waveOutPrepareHeader -- приготовить буфер вывода для воспроизведения
  • waveOutWrite -- вывести звук (поставить буфер на воспроизведение)
  • waveOutReset -- остановить воспроизведение и освободить буферы
  • waveOutUnprepareHeader -- вернуть буфер вывода
  • WaveOutClose -- закрыть устройство вывода звука
  • TWAVEOUTCAPS -- структура для WaveOutGetDevCaps
  • TWAVEFORMATEX -- формат звуковых данных
  • TWAVEHDR -- формат заголовка буфера вывода.

Как же мы выведем звук?

Во-первых, надо озаботиться способом общения с драйвером. Вариантов много: сообщения, callback-функции, объекты-события и т.д. По моему опыту, наиболее "приятно" работать с объектами-событиями, то есть использовать объекты ядра Events и потоки. Работает без особых проблем, лего управляется, нет ненужных задержек в очереди сообщений, можно поставить более высокий приоритет потоку, обрабатывающему звуковые данные. В общем, плюсов много, а главное … Microsoft рекомендует.

Так, с этим определились, теперь формат звуковых данных. Необходимо заполнить TWAVEFORMATEX, например, так:

var wfx : TWAVEFORMATEX; … // заполнение структуры формата FillChar(wfx,Sizeof(TWAVEFORMATEX),#0); with wfx do begin wFormatTag := WAVE_FORMAT_PCM; // используется PCM формат nChannels := 2; // это стереосигнал nSamplesPerSec := 44100; // частота дискретизации 44,1 Кгц wBitsPerSample := 16; // битовое разрешение выборки 16 бит nBlockAlign := wBitsPerSample div 8 * nChannels; // число байт в выборке для стереосигнала -- 4 байта nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; // число байт в секундном интервале для стереосигнала cbSize := 0; // не используется end;




Начало  Назад  Вперед



Книжный магазин