VR
Virtual Reality On-line   Журнал
Новости   |     Журнал    |    Хаkер    |     Магазин   |   Проекты
[   Вход    ]
[Kарта сайтa]

[ Download  ]
[  Конкурс  ]
[ Анекдоты  ]
[  Ссылки   ]
[  Реклама  ]
[ Почтальон ]
[ О проекте ]






TopList
Программирование звука.
Подготавливаемся к записи и воспроизведению
:
Logo

Сегодня я заканчиваю рассказ о воспроизведении звука и немного затрону запись. Мы уже умеем воспроизводить звук, но только на устройстве установленном по умолчанию. Но у тебя может быть несколько плат и пользователь должен иметь право выбора (демократия всё же на дворе :)). Так что, я думаю, что ты понял о чём пойдёт сегодня речь.

В твоём компе может быть несколько устройств воспроизведения, точно так же, как и устройств записи. Чтобы узнать количество устройств вопроизведения можно воспользоваться функцией waveOutGetNumDevs. Возможности конкретного устройства можно узнать с помощью waveOutGetDevCaps. Это что касается воспроизведения. Для устройств записи существуют такие же функции, которые мы ещё не рассматривали. Сейчас нам это предстоит.

Начнём мы с waveOutGetNumDevs. Она выглядит так:

function waveOutGetNumDevs: UINT; stdcall;

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

Для получения количества устройств записи используется waveInGetNumDevs:

function waveInGetNumDevs: UINT; stdcall;

Эта функция так же не имеет параметров, а только возвращает количество установленных в системе устройств записи.

Теперь научимся получать инфу об установленных устройствах вопроизведения с помощью waveOutGetDevCaps. Эту функцию мы рассматривали в прошлый раз (когда изучали реальный пример) но сейчас я решил повторится, чтобы напомнить о чём идёт речь.

  Для С/С++
   MMRESULT waveOutGetDevCaps(
    UINT uDeviceID,    //Указатель на устройство воспроизведения
    LPWAVEOUTCAPS pwoc,//Структура, куда будут записаны данные
    UINT cbwoc         //Размер структуры
   );

  Для Delphi
   function waveOutGetDevCaps(
    uDeviceID: UINT;      //Указатель на устройство воспроизведения
    lpCaps: PWaveOutCaps; //Структура, куда будут записаны данные
    uSize: UINT           //Размер структуры
   ): MMRESULT; stdcall;

Подробное описание смотри в прошлом номере (март 2001). Можешь посмотреть на описание waveInGetDevCaps ниже и всё станет понятно, потому что эти функции очень похожи. А я перехожу к функции, с помощью которой можно получить инфу об устройствах записи звука waveInGetDevCaps:

  Для С/С++
   MMRESULT waveInGetDevCaps(
     UINT uDeviceID, //Указатель на устройство записи
     LPWAVEINCAPS pwic, //Структура, куда будут записаны данные
     UINT cbwic	//Размер структуры
    );	

  Для Delphi
    function waveInGetDevCaps(
      hwo: HWAVEOUT; //Указатель на устройство записи
      lpCaps: PWaveInCaps; //Структура, куда будут записаны данные
      uSize: UINT  //Размер структуры
     ): MMRESULT; stdcall; 

С первым параметром уже должно быть всё ясно. Второй параметр - структура типа ТWaveInCaps. Она выглядит так:

  Для С/С++

  typedef struct {  
    WORD      wMid;  //Идентификатор производителя
    WORD      wPid;   //Идентификатор устройства
    MMVERSION vDriverVersion; //Версия драйвера
    CHAR      szPname[MAXPNAMELEN]; //Название устройства
    DWORD     dwFormats; //Поддерживаемые форматы
    WORD      wChannels;  //Количество каналов
    WORD      wReserved1; //Зарезервировано, но здесь хранятся свойства
  } WAVEINCAPS;

  Для Delphi

   TWaveOutCaps = tagWAVEOUTCAPSA;
   tagWAVEOUTCAPSA = record
    wMid: Word;        //Идентификатор производителя 
    wPid: Word;        //Идентификатор устройства
    vDriverVersion: MMVERSION;       //Версия драйвера
    szPname: array[0..MAXPNAMELEN-1] of AnsiChar;  //Название устройства
    dwFormats: DWORD;      //Поддерживаемые форматы
    wChannels: Word;            //Количество каналов
    dwSupport: DWORD;      //Свойства
  end;

Параметр Support может принимать значения:

  • WAVECAPS_LRVOLUME - поддерживается изменение правого и левого каналов.
  • WAVECAPS_PITCH - Поддерживаются подтяжки
  • WAVECAPS_PLAYBACKRATE - поддерживается playback rate.
  • WAVECAPS_SYNC - драйвер сихронный и будет блокировать работу пока играет музыка.
  • WAVECAPS_VOLUME - поддержка громкости.
  • WAVECAPS_SAMPLEACCURATE - возвращает позицию.

Параметр wChannels может быть 1 (для моно) и 2 (для стерео).

Параметр dwFormats может быть комбинацией следующих значений:

  • WAVE_FORMAT_1M08 - 11.025 kHz, mono, 8-bit
  • WAVE_FORMAT_1M16 - 11.025 kHz, mono, 16-bit
  • WAVE_FORMAT_1S08 - 11.025 kHz, stereo, 8-bit
  • WAVE_FORMAT_1S16 - 11.025 kHz, stereo, 16-bit
  • WAVE_FORMAT_2M08 - 22.05 kHz, mono, 8-bit
  • WAVE_FORMAT_2M16 - 22.05 kHz, mono, 16-bit
  • WAVE_FORMAT_2S08 - 22.05 kHz, stereo, 8-bit
  • WAVE_FORMAT_2S16 - 22.05 kHz, stereo, 16-bit
  • WAVE_FORMAT_4M08 - 44.1 kHz, mono, 8-bit
  • WAVE_FORMAT_4M16 - 44.1 kHz, mono, 16-bit
  • WAVE_FORMAT_4S08 - 44.1 kHz, stereo, 8-bit
  • WAVE_FORMAT_4S16 - 44.1 kHz, stereo, 16-bit

Вот и все функции, которые я хотел тебе сегодня показать. Давай теперь перейдём к реальному примеру.
Logo
Рис 1. Выбор устройств

Для примера я не стал изобретать велосипед, а модернизировал исходник из прошлого номера. Основные изменения коснулись создания новой формы, в которой можно выбирать устройство воспроизведения и записи (рис 1). Для заполнения параметров я изменил функцию FillDevice:

procedure TSounderForm.FillDevice;
var
 Num,i:Integer;
 WaveCaps:TWaveOutCaps;
 pwoc:TWaveOutCaps;
begin
 //Очищаю ComboBox в котором хранится инфа об устройствах воспроизведения
 SoundOptionForm.AudioDeviceCBox.Items.Clear;
 //Запрашиваю инфу о количестве устройств воспроизведения
 Num:=waveOutGetNumDevs;
 //Запрашиваю параметры каждого
 for i:=0 to Num-1 do
  begin
   //Получить информацию об устройстве воспроизведения i
   WaveOutGetDevCaps(i,@WaveCaps,sizeof(WaveCaps));
   //Добавить новый элемент в ComboBox с именем устройства
   SoundOptionForm.AudioDeviceCBox.Items.Add(WaveCaps.szPName);
  end;
 //Добавить новый элемент в ComboBox устройство по умолчанию
 SoundOptionForm.AudioDeviceCBox.Items.Add('Automatic select audio device');

 //Очищаю ComboBox в котором хранится инфа об устройствах записи
 SoundOptionForm.RecDeviceCBox.Items.Clear;
 //Запрашиваю инфу о количестве устройств записи
 Num:=waveInGetNumDevs;
 //Запрашиваю параметры каждого
 for i:=0 to Num-1 do
  begin
   //Получить информацию об устройстве записи i
   WaveInGetDevCaps(i,@WaveCaps,sizeof(WaveCaps));
   //Добавить новый элемент в ComboBox с именем устройства
   SoundOptionForm.RecDeviceCBox.Items.Add(WaveCaps.szPName);
  end;
 //Добавить новый элемент в ComboBox устройство по умолчанию
 SoundOptionForm.RecDeviceCBox.Items.Add('Automatic select record device');

 //Это мы разбирали в прошлый раз. Здесь изменения нет
 waveOutGetDevCaps(w_DeviceID, @pwoc, sizeof(pwoc));
 if (pwoc.dwSupport and WAVECAPS_VOLUME)>0 then
  begin
   VolumeLBar.Enabled:=true;
   VolumeRBar.Enabled:=true;
  end;
end;

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

procedure TSounderForm.FormShow(Sender: TObject);
begin
 EnableBut(false);
 RestartPlay:=false;

 //Заполнить информацию об устройствах
 FillDevice;

 //Установить значение по умолчанию.
 SoundOptionForm.AudioDeviceCBox.ItemIndex:=
             SoundOptionForm.AudioDeviceCBox.Items.Count-1;

 SoundOptionForm.RecDeviceCBox.ItemIndex:=
             SoundOptionForm.RecDeviceCBox.Items.Count-1;
end;

Выбор записывающего устройства пока не используется, это мы сделаем позже, когда разберёмся с функциями записи звука. А для воспроизведения я всё сделал. Заглядываем в обработчик события "Когда нажали кнопку Play" :) и видим

procedure TSounderForm.PlayButtonClick(Sender: TObject);
begin
 //Здесь всё старое
 if ((w_Pause)and (w_hPlay<>0)) then
  begin
   waveOutRestart(w_hPlay);
   w_Pause:=not w_Pause;
   exit;
  end;

 if w_hPlay<>0 then StopButtonClick(nil);
 SoundTimer.Enabled:=true;
 w_Pause:=false; w_Restart:=false; w_Stop:=false;
 w_PlayPosition:=PositionBar.Position*1000;
 w_RestartPosition:=PositionBar.Position*1000;

 //Вот здесь мы берём выбранное в настройках значение звукового устройства
 w_DeviceID:=SoundOptionForm.AudioDeviceCBox.ItemIndex;

 //Если выбран последний элемент (туда мы засунули устройство по 
 //умолчанию", то 
 if SoundOptionForm.AudioDeviceCBox.ItemIndex=
            SoundOptionForm.AudioDeviceCBox.Items.Count-1 then
  //Изменяем значение на WAVE_MAPPER.
  w_DeviceID:=Integer(WAVE_MAPPER);

 //Дальше уже всё ясно
 CyDSounder1:=TSoundPlayer.Create(true);
 CyDSounder1.Priority:=tpHigher;
 CyDSounder1.Resume;
end;

Ну и самое главное :) я добавил кнопку, которая вызывает диалог с настройками устройств. По её нажатию я вызываю окно, которе ты видел на рис 2:

procedure TSounderForm.ToolButton3Click(Sender: TObject);
begin
 SoundOptionForm.ShowModal;
end;

Вот и всё, теперь ты готов изучить тонкости записи звука. Это будет в следующий раз.

 Исходники примера забирай здесь


Design by FMk group ©
Copyright©: Horrific aka Флёнов Михаил ©