Пересечение данных
В графе фильтра звука звуковой поток может передаваться от исходного контакта одного фильтра к контакту приемника другого фильтра только в том случае, если два контакта поддерживают общий формат потока. Аналогичным образом клиент может отправлять аудиопоток в приемник на фильтре или получать аудиопоток из исходного закрепления на фильтре только в том случае, если клиент и закрепление поддерживают общий формат потока. Аудиофильтры используют метод, называемый пересечением данных (сокращение от пересечения диапазона данных), чтобы определить формат потока, общий для двух контактов или для клиента и контакта.
Например, в Windows Server 2003, Windows XP, Windows 2000 и Windows Me/98 системный драйвер SysAudio использует метод пересечения данных для создания графа фильтра звука путем соединения пар контактов фильтра, поддерживающих совместимые форматы аудиоданных.
Фабрика контактов задает набор форматов, поддерживаемых каждым закреплением в виде массива диапазонов данных, где каждый диапазон данных представляет собой структуру типа KSDATARANGE_AUDIO. Диапазон данных задает общий тип формата, который может быть KSDATAFORMAT_WAVEFORMATEX или KSDATAFORMAT_DSOUND. Кроме того, диапазон данных задает диапазон значений для каждого из следующих параметров:
Число бит на выборку
Частота выборки
Количество каналов
Структура KSDATARANGE_AUDIO задает как минимальное, так и максимальное значения для диапазонов битов на выборку и частоты выборки, но только максимальное значение для диапазона числа каналов. Минимальное количество каналов неявно равно одному.
Задача согласования общего формата данных для двух контактов состоит в поиске двух диапазонов данных ( по одному из каждого контакта), которые пересекаются друг с другом. Пара диапазонов данных пересекаются, если:
Они поддерживают один и тот же общий формат волны (KSDATAFORMAT_WAVEFORMATEX или KSDATAFORMAT_DSOUND).
Диапазоны битов на выборку перекрываются.
Диапазоны частот выборки перекрываются.
Как упоминалось ранее, структура KSDATAFORMAT_AUDIO подразумевает аппаратную модель, в которой минимальное количество каналов, поддерживаемых контактом, всегда равно одному. В соответствии с этой моделью диапазоны количества каналов для любых двух контактов всегда должны перекрываться, так как оба контакта поддерживают по крайней мере один канал. Очевидно, что аппаратный адаптер с минимальным количеством каналов, превышающим один, не соответствует этой модели, но драйвер адаптера может включать собственный обработчик пересечения данных для решения этой проблемы (см. пример в разделе Собственные обработчики Data-Intersection).
При поиске пары пересекающихся диапазонов данных для двух контактов обработчик выбирает общий формат данных из области пересечения следующим образом:
Число битов на выборку выбирается из региона, в котором перекрываются два диапазона битов на выборку.
Частота выборки выбирается из региона, в котором два диапазона частот выборки перекрываются.
Количество каналов выбирается из региона, в котором два диапазона количества каналов перекрываются.
Например, при согласовании общего формата для закрепления приемника драйвера аудиопорта и исходного контакта другого фильтра (обычно это системный драйвер KMixer), SysAudio сначала получает массив диапазона данных исходного контакта. Затем SysAudio отправляет запрос KSPROPERTY_PIN_DATAINTERSECTION в пин-код приемника и включает в этот запрос массив диапазона данных исходного контакта. Уровень потоковой передачи ядра перехватывает запрос и итеративно вызывает обработчик пересечения данных драйвера порта один раз для каждого последующего элемента в массиве диапазона данных исходного контакта, начиная с первого элемента, пока обработчик не будет успешно находить пересечение данных.
При каждом вызове, который SysAudio выполняет к обработчику пересечения данных драйвера порта, обработчик сначала получает массив диапазона данных приемника от драйвера мини-порта. Затем он выполняет итерацию по массиву, начиная с первого элемента, пока не сможет найти пересечение между диапазоном данных приемника и текущим диапазоном исходных контактов. Обработчик выбирает общий формат, который находится в пределах пересечения, и выводит этот формат вызывающей объекту.
На каждом шаге итерации драйвер порта вызывает собственный обработчик пересечения данных драйвера мини-порта с двумя диапазонами данных — по одному для каждого из двух контактов. Если на каком-либо шаге собственный обработчик отказывается обрабатывать проверка пересечения данных между двумя диапазонами данных, обработчик пересечения данных драйвера порта выполняет проверка.
Подводя итоги, поиск пересечения между диапазоном данных источника и диапазоном данных приемника является итеративным процессом:
Во внешнем цикле уровень потоковой передачи ядра выполняет итерацию по последовательным элементам в массиве диапазона данных исходного контакта, начиная с первого элемента массива.
Во внутреннем цикле драйвер порта выполняет итерацию по последовательным элементам в массиве диапазона данных приемника, начиная с первого элемента массива.
Поиск останавливается при поиске первого пересечения данных. Этот процесс, как правило, отдает предпочтение элементам в начале массива диапазона данных каждого контакта. При указании массива диапазонов данных для закрепления драйвер адаптера должен упорядочить элементы массива, разместив диапазоны данных для предпочтительных форматов в начале массива.