Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Определение абсолютной частоты дискретизации аудио с помощью waveOut в Windows

Delphi , ОС и Железо , Windows

Вопрос, который стоит перед разработчиками, использующими Windows waveOut API для работы с аудио, заключается в необходимости определения текущей частоты дискретизации воспроизведения. Это может быть важно для предупреждения пользователей о том, что операционная система будет передискретизировать выходной сигнал программы. В документации waveOutGetPlaybackRate указано, что функция возвращает процентное отношение текущего воспроизведения устройства к тому, что было задано программой, а не абсолютное значение частоты.

Для получения абсолютной частоты дискретизации можно использовать интерфейс IMMDevice и IPropertyStore, предоставляемые Windows Media Foundation. Ниже приведен пример кода на C++, который позволяет получить эту информацию для стандартного устройства воспроизведения.

//#include <iostream>
//#include <initguid.h>
//#include <mmdeviceapi.h>

int main() {
    HRESULT hr;
    IMMDevice *pDevice = NULL;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IPropertyStore* pStore = nullptr;
    PWAVEFORMATEX pDeviceFormatProperties;
    PROPVARIANT prop;

    CoInitialize(NULL);

    // Получение перечислителя устройств
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pEnumerator);

    // Получение стандартного аудио выхода
    hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);

    // Открытие хранилища свойств устройства
    hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
    if (FAILED(hr)) {
        std::cout << "OpenPropertyStore failed!" << std::endl;
    }

    // Получение свойства PKEY_AudioEngine_DeviceFormat
    hr = pStore->GetValue(PKEY_AudioEngine_DeviceFormat, &prop);
    if (FAILED(hr)) {
        std::cout << "GetValue failed!" << std::endl;
    }

    // Извлечение структуры WAVEFORMATEX
    pDeviceFormatProperties = (PWAVEFORMATEX)prop.blob.pBlobData;
    std::cout << "Channels    = " << pDeviceFormatProperties->nChannels << std::endl;
    std::cout << "Sample rate = " << pDeviceFormatProperties->nSamplesPerSec << std::endl;
    std::cout << "Bit depth   = " << pDeviceFormatProperties->wBitsPerSample << std::endl;

    // Освобождение ресурсов
    CoTaskMemFree(prop.blob.pBlobData);
    pStore->Release();
    pDevice->Release();
    pEnumerator->Release();
    CoUninitialize();

    system("pause");
    return 0;
}

Для программ, написанных на Pascal, данный код можно перевести, используя соответствующие типы данных и вызовы функций WinAPI.

Перейдем к переводу приведенного примера кода на Pascal, используя Delphi:

program GetDefaultPlaybackDeviceFormat;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Winapi.Windows,
  Winapi.ActiveX,
  Winapi.MMSystem,
  Winapi.MMDeviceApi;

var
  pDevice: IMMDevice;
  pEnumerator: IMMDeviceEnumerator;
  pStore: IPropertyStore;
  pDeviceFormatProperties: PWAVEFORMATEX;
  Prop: PROPVARIANT;
  hr: HRESULT;

procedure GetDefaultDeviceFormat(out Channels, SampleRate, BitDepth: Integer);
begin
  hr := CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, Pointer(pEnumerator));
  if SUCCEEDED(hr) then
  begin
    hr := pEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, Pointer(pDevice));
    if SUCCEEDED(hr) then
    begin
      hr := pDevice.OpenPropertyStore(STGM_READ, Pointer(pStore));
      if SUCCEEDED(hr) then
      begin
        hr := pStore.GetValue(PKEY_AudioEngine_DeviceFormat, Pointer(Prop));
        if SUCCEEDED(hr) then
        begin
          pDeviceFormatProperties := PWAVEFORMATEX(Prop.blob.pBlobData);
          Channels := pDeviceFormatProperties.nChannels;
          SampleRate := pDeviceFormatProperties.nSamplesPerSec;
          BitDepth := pDeviceFormatProperties.wBitsPerSample;
          CoTaskMemFree(Prop.blob.pBlobData);
        end;
        pStore.Release;
      end;
      pDevice.Release;
    end;
    pEnumerator.Release;
  end;
end;

begin
  var Channels, SampleRate, BitDepth: Integer;
  GetDefaultDeviceFormat(Channels, SampleRate, BitDepth);
  Writeln('Channels    = ', Channels);
  Writeln('Sample rate = ', SampleRate);
  Writeln('Bit depth   = ', BitDepth);
  Readln;
  CoUninitialize;
end.

Важно отметить, что перед использованием данного кода необходимо инициализировать COM-библиотеку, что делается вызовом CoInitialize. После завершения работы с COM-объектами необходимо вызвать CoUninitialize.

Также стоит помнить, что данный код предполагает наличие соответствующих заголовочных файлов и библиотек Windows, которые должны быть доступны в вашей среде разработки.

Создано по материалам из источника по ссылке.

Вопрос заключается в определении абсолютной частоты дискретизации аудио, используемого через waveOut на Windows, и способах её получения через интерфейс Windows Media Foundation.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Windows ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-17 04:56:48/0.0059788227081299/0