В прошлом я использовал это руководство по потоковой передаче XAudio2 с успехом при создании программы для потоковой передачи и воспроизведения аудио с диска (https://msdn.microsoft.com/en-us/library/windows/desktop/ee415791(v=vs.85).aspx).
Теперь, когда я переделываю код, мне выделяется что-то странное. Они создают отдельный поток для чтения аудиоданных небольшими порциями из файла и передачи этих порций в голосовой буфер. Отлично, теперь основной поток может делать все, что ему нужно во время воспроизведения аудио, но зачем также использовать асинхронное чтение файла в потоковом потоке? Насколько я могу судить, чтение файла выполняется на каждой итерации цикла, и поток немедленно ожидает, пока чанк не будет полностью прочитан, прежде чем отправить его в голосовой буфер.
Есть ли преимущество в том, что они делают, или это не нужно?
Причина, по которой в примере кода XAudio2 используется «асинхронный», а не «блокирующий» ввод-вывод, является наилучшей практикой. Причина в том, что это делается в «рабочем потоке», в основном для простоты, поскольку в игре обычно аудио обрабатывается собственным потоком, чтобы избежать сбоев и сохранения цикла рендеринга / обновления.
Вы можете обрабатывать асинхронное / отправить как часть вашего Update
цикл, но только если вы были уверены, что он всегда будет обрабатываться достаточно быстро, чтобы избежать сбоев. На самом деле это тот подход, который я использовал с последней унаследованной версией DirectX SDK примера потоковой передачи XAudio2 на GitHub
Более причудливая реализация могла бы использовать
ReadFileEx
, но рабочий подход был проще. Также из-за некоторых странностей того, как API-разбиение было реализовано еще в Windows 8,ReadFileEx
не был поддержан на платформе Windows Store / Windows phone 8 / UWP, поэтому в учебных руководствах / примерах не указывалось направление, не подходящее для всех платформ Microsoft. FWIW,ReadFileEx
а такжеWriteFileEx
был добавлен обратно в UWP в годовом обновлении Windows 10 (14393).
Обратите внимание, что есть некоторые причуды в событии, ожидающем с перекрывающимся вводом / выводом в том, как ERROR_IO_PENDING
сценарии обрабатываются. Это улучшается & в Windows 8 или более поздней версии GetOverlappedResultEx
функция. Для моего читателя банка волн в Набор инструментов DirectX для аудио, Я использовал этот шаблон для сборки как для старых, так и для новых платформ:
bool wait = false;
if( !ReadFile( hFile.get(), &m_data, sizeof( m_data ), nullptr, &request ) )
{
DWORD error = GetLastError();
if ( error != ERROR_IO_PENDING )
return HRESULT_FROM_WIN32( error );
wait = true;
}
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
result = GetOverlappedResultEx( hFile.get(), &request, &bytes, INFINITE, FALSE );
#else
if ( wait )
(void)WaitForSingleObject( m_event.get(), INFINITE );
result = GetOverlappedResult( hFile.get(), &request, &bytes, FALSE );
#endif
if ( !result || ( bytes != sizeof( m_data ) ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
Других решений пока нет …